Skip to content

Commit 6525abf

Browse files
Update checkbufferoverrun.cpp
1 parent fe77659 commit 6525abf

1 file changed

Lines changed: 21 additions & 7 deletions

File tree

lib/checkbufferoverrun.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ static const CWE CWE_BUFFER_OVERRUN(788U); // Access of Memory Location After
6565
static const ValueFlow::Value *getBufferSizeValue(const Token *tok)
6666
{
6767
const std::list<ValueFlow::Value> &tokenValues = tok->values();
68-
const auto it = std::find_if(tokenValues.cbegin(), tokenValues.cend(), std::mem_fn(&ValueFlow::Value::isBufferSizeValue));
68+
auto it = std::find_if(tokenValues.cbegin(), tokenValues.cend(), std::mem_fn(&ValueFlow::Value::isBufferSizeValue));
69+
if (it != tokenValues.cend())
70+
return &*it;
71+
it = std::find_if(tokenValues.cbegin(), tokenValues.cend(), std::mem_fn(&ValueFlow::Value::isContainerSizeValue));
6972
return it == tokenValues.cend() ? nullptr : &*it;
7073
}
7174

@@ -552,7 +555,7 @@ void CheckBufferOverrunImpl::pointerArithmeticError(const Token *tok, const Toke
552555

553556
//---------------------------------------------------------------------------
554557

555-
ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok) const
558+
ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, const Settings& settings) const
556559
{
557560
if (!bufTok->valueType())
558561
return ValueFlow::Value(-1);
@@ -569,9 +572,20 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok) cons
569572
const Variable *var = bufTok->variable();
570573

571574
if (!var || var->dimensions().empty()) {
572-
const ValueFlow::Value *value = getBufferSizeValue(bufTok);
573-
if (value)
574-
return *value;
575+
if (const ValueFlow::Value *value = getBufferSizeValue(bufTok)) {
576+
if (value->isBufferSizeValue())
577+
return *value;
578+
else if (value->isContainerSizeValue() && bufTok->valueType() && bufTok->valueType()->container) {
579+
const ValueType vtElement = ValueType::parseDecl(bufTok->valueType()->containerTypeToken, settings);
580+
const size_t elementSize = vtElement.getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer);
581+
if (elementSize > 0) {
582+
ValueFlow::Value bufSizeVal;
583+
bufSizeVal.valueType = ValueFlow::Value::ValueType::BUFFER_SIZE;
584+
bufSizeVal.intvalue = value->intvalue * elementSize;
585+
return bufSizeVal;
586+
}
587+
}
588+
}
575589
}
576590

577591
if (!var || var->isPointer() || (astIsContainer(bufTok) && var->getTypeName() != "std::array"))
@@ -671,7 +685,7 @@ void CheckBufferOverrunImpl::bufferOverflow()
671685
if (argtok->valueType() && argtok->valueType()->pointer == 0)
672686
continue;
673687
// TODO: strcpy(buf+10, "hello");
674-
const ValueFlow::Value bufferSize = getBufferSize(argtok);
688+
const ValueFlow::Value bufferSize = getBufferSize(argtok, mSettings);
675689
if (bufferSize.intvalue <= 0)
676690
continue;
677691
// buffer size == 1 => do not warn for dynamic memory
@@ -782,7 +796,7 @@ void CheckBufferOverrunImpl::stringNotZeroTerminated()
782796
const Token *sizeToken = args[2];
783797
if (!sizeToken->hasKnownIntValue())
784798
continue;
785-
const ValueFlow::Value &bufferSize = getBufferSize(args[0]);
799+
const ValueFlow::Value &bufferSize = getBufferSize(args[0], mSettings);
786800
if (bufferSize.intvalue < 0 || sizeToken->getKnownIntValue() < bufferSize.intvalue)
787801
continue;
788802
if (Token::simpleMatch(args[1], "(") && Token::simpleMatch(args[1]->astOperand1(), ". c_str") && args[1]->astOperand1()->astOperand1()) {

0 commit comments

Comments
 (0)