From 1ec3c9f634803fe0d2b011c08ff874eaed90f7b2 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Sun, 29 Jul 2012 06:11:48 -0700 Subject: [PATCH] Fixed hang in libreoffice code (simplification of K&R style function declaration tried to simplify a function with parameters without name whose implementation contained "; {". Test cases of this simplification only need basic simplifications done in Tokenizer::tokenize --- lib/tokenize.cpp | 23 +++++++++++++++++------ test/testtokenize.cpp | 28 +++++++++++++++++++--------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 1125f1dc6..ae9fb5b7d 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4555,14 +4555,11 @@ bool Tokenizer::simplifyFunctionParameters() Token * tokparam = NULL; //take count of the function name.. - const std::string funcName(tok->str()); + const std::string& funcName(tok->str()); //floating token used to check for parameters Token *tok1 = tok; - //goto '(' - tok = tok->next(); - while (NULL != (tok1 = tok1->tokAt(2))) { if (!Token::Match(tok1, "%var% [,)]")) { bailOut = true; @@ -4600,13 +4597,27 @@ bool Tokenizer::simplifyFunctionParameters() } } + //goto '(' + tok = tok->next(); + if (bailOut) { tok = tok->link(); continue; } - //there should be the sequence '; {' after the round parenthesis - if (!Token::findsimplematch(tok1, "; {")) { + tok1 = tok->link()->next(); + + // there should be the sequence '; {' after the round parenthesis + for (const Token* tok2 = tok1; tok2; tok2 = tok2->next()) { + if (Token::simpleMatch(tok2, "; {")) + break; + else if (tok2->str() == "{") { + bailOut = true; + break; + } + } + + if (bailOut) { tok = tok->link(); continue; } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index ef4683787..b7b7b2b66 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -4280,21 +4280,21 @@ private: void simplifyFunctionParameters() { { const char code[] = "char a [ ABC ( DEF ) ] ;"; - ASSERT_EQUALS(code, tokenizeAndStringify(code, true)); + ASSERT_EQUALS(code, tokenizeAndStringify(code)); } { const char code[] = "module ( a , a , sizeof ( a ) , 0444 ) ;"; - ASSERT_EQUALS("module ( a , a , sizeof ( a ) , 292 ) ;", tokenizeAndStringify(code, true)); + ASSERT_EQUALS("module ( a , a , sizeof ( a ) , 292 ) ;", tokenizeAndStringify(code)); } - ASSERT_EQUALS("void f ( int x ) { }", tokenizeAndStringify("void f(x) int x; { }", true)); - ASSERT_EQUALS("void f ( int x , char y ) { }", tokenizeAndStringify("void f(x,y) int x; char y; { }", true)); - ASSERT_EQUALS("int main ( int argc , char * argv [ ] ) { }", tokenizeAndStringify("int main(argc,argv) int argc; char *argv[]; { }", true)); - ASSERT_EQUALS("int f ( int p , int w , float d ) { }", tokenizeAndStringify("int f(p,w,d) float d; { }", true)); + ASSERT_EQUALS("void f ( int x ) { }", tokenizeAndStringify("void f(x) int x; { }")); + ASSERT_EQUALS("void f ( int x , char y ) { }", tokenizeAndStringify("void f(x,y) int x; char y; { }")); + ASSERT_EQUALS("int main ( int argc , char * argv [ ] ) { }", tokenizeAndStringify("int main(argc,argv) int argc; char *argv[]; { }")); + ASSERT_EQUALS("int f ( int p , int w , float d ) { }", tokenizeAndStringify("int f(p,w,d) float d; { }")); // #1067 - Not simplified. Feel free to fix so it is simplified correctly but this syntax is obsolete. - ASSERT_EQUALS("int ( * d ( a , b , c ) ) ( ) int a ; int b ; int c ; { }", tokenizeAndStringify("int (*d(a,b,c))()int a,b,c; { }", true)); + ASSERT_EQUALS("int ( * d ( a , b , c ) ) ( ) int a ; int b ; int c ; { }", tokenizeAndStringify("int (*d(a,b,c))()int a,b,c; { }")); { // This is not a function but the pattern is similar.. @@ -4317,7 +4317,7 @@ private: " {" " }" "}"; - ASSERT_EQUALS("MACRO ( a ) void f ( ) { SetLanguage ( ) ; { } }", tokenizeAndStringify(code, true)); + ASSERT_EQUALS("MACRO ( a ) void f ( ) { SetLanguage ( ) ; { } }", tokenizeAndStringify(code)); } } @@ -4330,7 +4330,7 @@ private: "}\n"; ASSERT_EQUALS("int f ( float * p , int w , int d , int e , short len )\n" "{\n" - "}", tokenizeAndStringify(code,true)); + "}", tokenizeAndStringify(code)); } void simplifyFunctionParametersErrors() { @@ -4350,6 +4350,16 @@ private: tokenizeAndStringify("void foo(int, int)\n" "{}\n"); ASSERT_EQUALS("", errout.str()); + + // #3848 - Don't hang + tokenizeAndStringify("sal_Bool ShapeHasText(sal_uLong, sal_uLong) const {\n" + " return sal_True;\n" + "}\n" + "void CreateSdrOLEFromStorage() {\n" + " comphelper::EmbeddedObjectContainer aCnt( xDestStorage );\n" + " { }\n" + "}"); + ASSERT_EQUALS("", errout.str()); } // Simplify "((..))" into "(..)"