From 57d1da3910569a7a6d762efc1ccbea0f3f3fadc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 6 Jan 2010 20:19:27 +0100 Subject: [PATCH] Ticket #1228 : Handle tokensBack in the Token class. When adding&removing tokens the Token class can make sure that this pointer is updated accordingly. It is very important that the tokensBack has the same scope as the token list, otherwise there will be a dead pointer problem. --- lib/checkbufferoverrun.cpp | 2 +- lib/checkmemoryleak.cpp | 2 +- lib/token.cpp | 18 ++++++++++++++++-- lib/token.h | 8 +++++++- lib/tokenize.cpp | 5 ++--- test/testbufferoverrun.cpp | 8 ++++---- test/testsimplifytokens.cpp | 2 +- test/testtoken.cpp | 19 ++++++++++++++++--- 8 files changed, 48 insertions(+), 16 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index e2283578a..c98980177 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -769,7 +769,7 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable() if (varid == 0) continue; - Token sizeTok; + Token sizeTok(0); sizeTok.str(type); int total_size = size * _tokenizer->sizeOfType(&sizeTok); if (total_size == 0) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index d27d52f36..cb8e090d0 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -660,7 +660,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::liststr(_str); \ } \ diff --git a/lib/token.cpp b/lib/token.cpp index fa1f76e04..22840878f 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -26,7 +26,8 @@ #include #include -Token::Token() : +Token::Token(Token **t) : + tokensBack(t), _str(""), _isName(false), _isNumber(false), @@ -87,6 +88,8 @@ void Token::deleteNext() delete n; if (_next) _next->previous(this); + else if (tokensBack) + *tokensBack = this; } void Token::deleteThis() @@ -139,6 +142,13 @@ void Token::replace(Token *replaceThis, Token *start, Token *end) start->previous(replaceThis->previous()); end->next(replaceThis->next()); + if (end->tokensBack && *(end->tokensBack) == replaceThis) + { + while (end->next()) + end = end->next(); + *(end->tokensBack) = end; + } + // Delete old token, which is replaced delete replaceThis; } @@ -569,7 +579,7 @@ const Token *Token::findmatch(const Token *tok, const char pattern[], unsigned i void Token::insertToken(const char str[]) { - Token *newToken = new Token; + Token *newToken = new Token(tokensBack); newToken->str(str); newToken->_linenr = _linenr; newToken->_fileIndex = _fileIndex; @@ -578,6 +588,10 @@ void Token::insertToken(const char str[]) newToken->next(this->next()); newToken->next()->previous(newToken); } + else if (tokensBack) + { + *tokensBack = newToken; + } this->next(newToken); newToken->previous(this); diff --git a/lib/token.h b/lib/token.h index 6b7430abd..b5e32e844 100644 --- a/lib/token.h +++ b/lib/token.h @@ -37,8 +37,14 @@ */ class Token { -public: +private: + Token **tokensBack; + + // Not implemented.. Token(); + +public: + Token(Token **tokensBack); ~Token(); void str(const std::string &s); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 407ac5bbe..35e091977 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -104,11 +104,10 @@ void Tokenizer::addtoken(const char str[], const unsigned int lineno, const unsi if (_tokensBack) { _tokensBack->insertToken(str2.str().c_str()); - _tokensBack = _tokensBack->next(); } else { - _tokens = new Token; + _tokens = new Token(&_tokensBack); _tokensBack = _tokens; _tokensBack->str(str2.str()); } @@ -1929,7 +1928,7 @@ void Tokenizer::simplifySizeof() else if (Token::Match(tok->tokAt(-1), "%type% %var% [ %num% ] [,)]") || Token::Match(tok->tokAt(-2), "%type% * %var% [ %num% ] [,)]")) { - Token tempTok; + Token tempTok(0); tempTok.str("*"); sizeOfVar[varId] = MathLib::toString(sizeOfType(&tempTok)); } diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 912e32365..24f4f547e 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -1385,7 +1385,7 @@ private: ASSERT_EQUALS(10, CheckBufferOverrun::countSprintfLength("\\\\\\\\Hello%d \\0Text\\\\\\\\", unknownParameter)); ASSERT_EQUALS(4, CheckBufferOverrun::countSprintfLength("%%%%%d", unknownParameter)); - Token strTok; + Token strTok(0); strTok.str("\"12345\""); std::list stringAsParameter; stringAsParameter.push_back(&strTok); @@ -1400,7 +1400,7 @@ private: ASSERT_EQUALS(7, CheckBufferOverrun::countSprintfLength("%6.6s", stringAsParameter)); std::list intAsParameter; - Token numTok; + Token numTok(0); numTok.str("12345"); intAsParameter.push_back(&numTok); ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%02ld", intAsParameter)); @@ -1416,7 +1416,7 @@ private: ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%5.1x", intAsParameter)); std::list floatAsParameter; - Token floatTok; + Token floatTok(0); floatTok.str("1.12345f"); floatAsParameter.push_back(&floatTok); TODO_ASSERT_EQUALS(5, CheckBufferOverrun::countSprintfLength("%.2f", floatAsParameter)); @@ -1424,7 +1424,7 @@ private: TODO_ASSERT_EQUALS(5, CheckBufferOverrun::countSprintfLength("%2.2f", floatAsParameter)); std::list floatAsParameter2; - Token floatTok2; + Token floatTok2(0); floatTok2.str("100.12345f"); floatAsParameter2.push_back(&floatTok2); TODO_ASSERT_EQUALS(7, CheckBufferOverrun::countSprintfLength("%2.2f", floatAsParameter2)); diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index e8dd26843..773ce5481 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -632,7 +632,7 @@ private: std::istringstream istr(""); tokenizer.tokenize(istr, "test.cpp"); tokenizer.simplifyTokenList(); - Token tok; + Token tok(0); tok.str(type); return tokenizer.sizeOfType(&tok); } diff --git a/test/testtoken.cpp b/test/testtoken.cpp index 62e0f6d17..1b0c8a6d5 100644 --- a/test/testtoken.cpp +++ b/test/testtoken.cpp @@ -37,11 +37,13 @@ private: TEST_CASE(multiCompare); TEST_CASE(getStrLength); TEST_CASE(strValue); + + TEST_CASE(deleteLast); } void nextprevious() { - Token *token = new Token; + Token *token = new Token(0); token->str("1"); token->insertToken("2"); token->next()->insertToken("3"); @@ -84,7 +86,7 @@ private: void getStrLength() { - Token tok; + Token tok(0); tok.str("\"\""); ASSERT_EQUALS(0, Token::getStrLength(&tok)); @@ -101,13 +103,24 @@ private: void strValue() { - Token tok; + Token tok(0); tok.str("\"\""); ASSERT_EQUALS(std::string(""), tok.strValue()); tok.str("\"0\""); ASSERT_EQUALS(std::string("0"), tok.strValue()); } + + + void deleteLast() + { + Token *tokensBack = 0; + Token tok(&tokensBack); + tok.insertToken("aba"); + ASSERT_EQUALS((unsigned int)tok.next(), (unsigned int)tokensBack); + tok.deleteNext(); + ASSERT_EQUALS((unsigned int)&tok, (unsigned int)tokensBack); + } }; REGISTER_TEST(TestTOKEN)