diff --git a/cfg/cppcheck-cfg.rng b/cfg/cppcheck-cfg.rng index b81a35335..1f7b37de2 100644 --- a/cfg/cppcheck-cfg.rng +++ b/cfg/cppcheck-cfg.rng @@ -283,7 +283,6 @@ strlen - argvalue sizeof mul @@ -310,6 +309,24 @@ + + + + argvalue + + + + + + + + + + + + + + diff --git a/cfg/posix.cfg b/cfg/posix.cfg index 9fa1597f4..83766ed12 100644 --- a/cfg/posix.cfg +++ b/cfg/posix.cfg @@ -5449,7 +5449,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s - + diff --git a/cfg/std.cfg b/cfg/std.cfg index 86ce3954a..a7387dfb3 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -5359,7 +5359,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index f929bdbeb..d8160e81b 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -593,10 +593,16 @@ static bool checkBufferSize(const Token *ftok, const Library::ArgumentChecks::Mi return Token::getStrLength(strtoken) < bufferSize; } break; - case Library::ArgumentChecks::MinSize::Type::ARGVALUE: - if (arg && arg->hasKnownIntValue()) - return arg->getKnownIntValue() <= bufferSize; + case Library::ArgumentChecks::MinSize::Type::ARGVALUE: { + if (arg && arg->hasKnownIntValue()) { + MathLib::bigint myMinsize = arg->getKnownIntValue(); + unsigned int baseSize = tokenizer->sizeOfType(minsize.baseType); + if (baseSize != 0) + myMinsize *= baseSize; + return myMinsize <= bufferSize; + } break; + } case Library::ArgumentChecks::MinSize::Type::SIZEOF: // TODO break; diff --git a/lib/library.cpp b/lib/library.cpp index c22d76c3c..f74b000ed 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -783,9 +783,6 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co return Error(ErrorCode::BAD_ATTRIBUTE_VALUE, valueattr); ac.minsizes.emplace_back(type, 0); ac.minsizes.back().value = minsizevalue; - const char* baseTypeAttr = argnode->Attribute("baseType"); - if (baseTypeAttr) - ac.minsizes.back().baseType = baseTypeAttr; } else { const char *argattr = argnode->Attribute("arg"); if (!argattr) @@ -804,6 +801,9 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co ac.minsizes.back().arg2 = arg2attr[0] - '0'; } } + const char* baseTypeAttr = argnode->Attribute("baseType"); // used by VALUE, ARGVALUE + if (baseTypeAttr) + ac.minsizes.back().baseType = baseTypeAttr; } else if (argnodename == "iterator") { diff --git a/test/cfg/posix.c b/test/cfg/posix.c index aad6217ee..195f86f85 100644 --- a/test/cfg/posix.c +++ b/test/cfg/posix.c @@ -564,6 +564,14 @@ size_t bufferAccessOutOfBounds_strnlen(const char *s, size_t maxlen) return len; } +void bufferAccessOutOfBounds_wcpncpy() +{ + wchar_t s[16]; + wcpncpy(s, L"abc", 16); + // cppcheck-suppress bufferAccessOutOfBounds + wcpncpy(s, L"abc", 17); +} + size_t nullPointer_strnlen(const char *s, size_t maxlen) { // No warning shall be shown: diff --git a/test/cfg/std.c b/test/cfg/std.c index 9ca3a61f0..e60e90637 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -556,6 +556,14 @@ void bufferAccessOutOfBounds_wcsftime(wchar_t* ptr, size_t maxsize, const wchar_ (void)wcsftime(ptr, maxsize, format, timeptr); } +void bufferAccessOutOfBounds_wcsncpy() +{ + wchar_t s[16]; + wcsncpy(s, L"abc", 16); + // cppcheck-suppress bufferAccessOutOfBounds + wcsncpy(s, L"abc", 17); +} + int nullPointer_wcsncmp(const wchar_t* s1, const wchar_t* s2, size_t n) { // cppcheck-suppress nullPointer