diff --git a/cfg/cppcheck-cfg.rng b/cfg/cppcheck-cfg.rng
index b87c07152..a6dba3351 100644
--- a/cfg/cppcheck-cfg.rng
+++ b/cfg/cppcheck-cfg.rng
@@ -474,11 +474,9 @@
-
- malloc
- calloc
- strdup
-
+
+ malloc(:[1-5])?|calloc(:[1-5],[1-5])?|strdup(:[1-5])?
+
diff --git a/lib/library.cpp b/lib/library.cpp
index 181d00294..53f4187cd 100644
--- a/lib/library.cpp
+++ b/lib/library.cpp
@@ -204,14 +204,25 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc)
const char *bufferSize = memorynode->Attribute("buffer-size");
if (!bufferSize)
temp.bufferSize = AllocFunc::BufferSize::none;
- else if (std::strcmp(bufferSize, "malloc") == 0)
- temp.bufferSize = AllocFunc::BufferSize::malloc;
- else if (std::strcmp(bufferSize, "calloc") == 0)
- temp.bufferSize = AllocFunc::BufferSize::calloc;
- else if (std::strcmp(bufferSize, "strdup") == 0)
- temp.bufferSize = AllocFunc::BufferSize::strdup;
- else
- return Error(BAD_ATTRIBUTE_VALUE, bufferSize);
+ else {
+ if (std::strncmp(bufferSize, "malloc", 6) == 0)
+ temp.bufferSize = AllocFunc::BufferSize::malloc;
+ else if (std::strncmp(bufferSize, "calloc", 6) == 0)
+ temp.bufferSize = AllocFunc::BufferSize::calloc;
+ else if (std::strncmp(bufferSize, "strdup", 6) == 0)
+ temp.bufferSize = AllocFunc::BufferSize::strdup;
+ else
+ return Error(BAD_ATTRIBUTE_VALUE, bufferSize);
+ if (bufferSize[6] == 0) {
+ temp.bufferSizeArg1 = 1;
+ temp.bufferSizeArg2 = 2;
+ } else if (bufferSize[6] == ':' && bufferSize[7] >= '1' && bufferSize[7] <= '5') {
+ temp.bufferSizeArg1 = bufferSize[7] - '0';
+ if (bufferSize[8] == ',' && bufferSize[9] >= '1' && bufferSize[9] <= '5')
+ temp.bufferSizeArg2 = bufferSize[9] - '0';
+ } else
+ return Error(BAD_ATTRIBUTE_VALUE, bufferSize);
+ }
mAlloc[memorynode->GetText()] = temp;
} else if (memorynodename == "dealloc") {
diff --git a/lib/library.h b/lib/library.h
index 204bebb7e..315215f1a 100644
--- a/lib/library.h
+++ b/lib/library.h
@@ -75,6 +75,8 @@ public:
int arg;
enum class BufferSize {none,malloc,calloc,strdup};
BufferSize bufferSize;
+ int bufferSizeArg1;
+ int bufferSizeArg2;
};
/** get allocation info for function */
diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp
index 6d35dce33..49bc3611c 100644
--- a/lib/valueflow.cpp
+++ b/lib/valueflow.cpp
@@ -5130,21 +5130,24 @@ static void valueFlowDynamicBufferSize(TokenList *tokenlist, SymbolDatabase *sym
const std::vector args = getArguments(rhs->previous());
+ const Token * const arg1 = (args.size() >= allocFunc->bufferSizeArg1) ? args[allocFunc->bufferSizeArg1 - 1] : nullptr;
+ const Token * const arg2 = (args.size() >= allocFunc->bufferSizeArg2) ? args[allocFunc->bufferSizeArg2 - 1] : nullptr;
+
MathLib::bigint sizeValue = -1;
switch (allocFunc->bufferSize) {
case Library::AllocFunc::BufferSize::none:
break;
case Library::AllocFunc::BufferSize::malloc:
- if (args.size() == 1 && args[0]->hasKnownIntValue())
- sizeValue = args[0]->getKnownIntValue();
+ if (arg1 && arg1->hasKnownIntValue())
+ sizeValue = arg1->getKnownIntValue();
break;
case Library::AllocFunc::BufferSize::calloc:
- if (args.size() == 2 && args[0]->hasKnownIntValue() && args[1]->hasKnownIntValue())
- sizeValue = args[0]->getKnownIntValue() * args[1]->getKnownIntValue();
+ if (arg1 && arg2 && arg1->hasKnownIntValue() && arg2->hasKnownIntValue())
+ sizeValue = arg1->getKnownIntValue() * arg2->getKnownIntValue();
break;
case Library::AllocFunc::BufferSize::strdup:
- if (args.size() == 1 && args[0]->hasKnownValue()) {
- const ValueFlow::Value &value = args[0]->values().back();
+ if (arg1 && arg1->hasKnownValue()) {
+ const ValueFlow::Value &value = arg1->values().back();
if (value.isTokValue() && value.tokvalue->tokType() == Token::eString)
sizeValue = Token::getStrLength(value.tokvalue);
}