diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 4216a5977..af9969dfb 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -1540,13 +1540,7 @@ void CheckBufferOverrun::checkStringArgument() const std::list *minsizes = _settings->library.argminsizes(tok->str(), argnr); if (!minsizes) continue; - unsigned int sizeofstring = 1; - for (unsigned int i = 0U; i < argtok->str().size(); i++) { - if (argtok->str()[i] == '\\') - ++i; - ++sizeofstring; - } - if (checkMinSizes(*minsizes, tok, sizeofstring, nullptr)) + if (checkMinSizes(*minsizes, tok, Token::getStrSize(argtok), nullptr)) bufferOverrunError(argtok); } } diff --git a/lib/token.cpp b/lib/token.cpp index d2ff0bf1d..18a39fbd9 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -651,6 +651,19 @@ std::size_t Token::getStrLength(const Token *tok) return len; } +std::size_t Token::getStrSize(const Token *tok) +{ + assert(tok != nullptr && tok->type() == eString); + const std::string &str = tok->str(); + unsigned int sizeofstring = 1U; + for (unsigned int i = 1U; i < str.size() - 1U; i++) { + if (str[i] == '\\') + ++i; + ++sizeofstring; + } + return sizeofstring; +} + std::string Token::getCharAt(const Token *tok, std::size_t index) { assert(tok != nullptr); diff --git a/lib/token.h b/lib/token.h index 341479ffb..ed35d586a 100644 --- a/lib/token.h +++ b/lib/token.h @@ -197,6 +197,15 @@ public: **/ static std::size_t getStrLength(const Token *tok); + /** + * @return sizeof of C-string. + * + * Should be called for %%str%% tokens only. + * + * @param tok token with C-string + **/ + static std::size_t getStrSize(const Token *tok); + /** * @return char of C-string at index (possible escaped "\\n") * diff --git a/test/testtoken.cpp b/test/testtoken.cpp index 4179ef069..8398a8ea3 100644 --- a/test/testtoken.cpp +++ b/test/testtoken.cpp @@ -48,6 +48,7 @@ private: TEST_CASE(multiCompare4); TEST_CASE(multiCompare5); TEST_CASE(getStrLength); + TEST_CASE(getStrSize); TEST_CASE(strValue); TEST_CASE(deleteLast); @@ -266,6 +267,19 @@ private: ASSERT_EQUALS(1, (int)Token::getStrLength(&tok)); } + void getStrSize() const { + Token tok(0); + + tok.str("\"abc\""); + ASSERT_EQUALS(sizeof("abc"), Token::getStrSize(&tok)); + + tok.str("\"\\0abc\""); + ASSERT_EQUALS(sizeof("\0abc"), Token::getStrSize(&tok)); + + tok.str("\"\\\\\""); + ASSERT_EQUALS(sizeof("\\"), Token::getStrSize(&tok)); + } + void strValue() const { Token tok(0); tok.str("\"\"");