Fix crash in programmemory, crash found in daca@home package system-root

This commit is contained in:
Daniel Marjamäki 2021-08-25 06:56:19 +02:00
parent f7ddd7a35d
commit 11916171fe
4 changed files with 19 additions and 6 deletions

View File

@ -420,12 +420,12 @@ ProgramMemory getProgramMemory(const Token *tok, const ProgramMemory::Map& vars)
return programMemory; return programMemory;
} }
ProgramMemory getProgramMemory(const Token* tok, nonneg int exprid, const ValueFlow::Value& value) ProgramMemory getProgramMemory(const Token* tok, nonneg int exprid, const ValueFlow::Value& value, const Settings *settings)
{ {
ProgramMemory programMemory; ProgramMemory programMemory;
programMemory.replace(getInitialProgramState(tok, value.tokvalue)); programMemory.replace(getInitialProgramState(tok, value.tokvalue));
programMemory.replace(getInitialProgramState(tok, value.condition)); programMemory.replace(getInitialProgramState(tok, value.condition));
fillProgramMemoryFromConditions(programMemory, tok, nullptr); fillProgramMemoryFromConditions(programMemory, tok, settings);
programMemory.setValue(exprid, value); programMemory.setValue(exprid, value);
if (value.varId) if (value.varId)
programMemory.setIntValue(value.varId, value.varvalue); programMemory.setIntValue(value.varId, value.varvalue);

View File

@ -88,7 +88,7 @@ bool conditionIsTrue(const Token *condition, const ProgramMemory &programMemory)
/** /**
* Get program memory by looking backwards from given token. * Get program memory by looking backwards from given token.
*/ */
ProgramMemory getProgramMemory(const Token* tok, nonneg int exprid, const ValueFlow::Value& value); ProgramMemory getProgramMemory(const Token* tok, nonneg int exprid, const ValueFlow::Value& value, const Settings *settings);
ProgramMemory getProgramMemory(const Token *tok, const ProgramMemory::Map& vars); ProgramMemory getProgramMemory(const Token *tok, const ProgramMemory::Map& vars);

View File

@ -5691,7 +5691,7 @@ static void valueFlowForLoopSimplify(Token * const bodyStart, const nonneg int v
} }
if (Token::Match(tok2, "%oror%|&&")) { if (Token::Match(tok2, "%oror%|&&")) {
const ProgramMemory programMemory(getProgramMemory(tok2->astTop(), varid, ValueFlow::Value(value))); const ProgramMemory programMemory(getProgramMemory(tok2->astTop(), varid, ValueFlow::Value(value), settings));
if ((tok2->str() == "&&" && !conditionIsTrue(tok2->astOperand1(), programMemory)) || if ((tok2->str() == "&&" && !conditionIsTrue(tok2->astOperand1(), programMemory)) ||
(tok2->str() == "||" && !conditionIsFalse(tok2->astOperand1(), programMemory))) { (tok2->str() == "||" && !conditionIsFalse(tok2->astOperand1(), programMemory))) {
// Skip second expression.. // Skip second expression..
@ -5708,8 +5708,8 @@ static void valueFlowForLoopSimplify(Token * const bodyStart, const nonneg int v
} }
} }
if ((tok2->str() == "&&" && conditionIsFalse(tok2->astOperand1(), getProgramMemory(tok2->astTop(), varid, ValueFlow::Value(value)))) || if ((tok2->str() == "&&" && conditionIsFalse(tok2->astOperand1(), getProgramMemory(tok2->astTop(), varid, ValueFlow::Value(value), settings))) ||
(tok2->str() == "||" && conditionIsTrue(tok2->astOperand1(), getProgramMemory(tok2->astTop(), varid, ValueFlow::Value(value))))) (tok2->str() == "||" && conditionIsTrue(tok2->astOperand1(), getProgramMemory(tok2->astTop(), varid, ValueFlow::Value(value), settings))))
break; break;
else if (Token::simpleMatch(tok2, ") {") && Token::findmatch(tok2->link(), "%varid%", tok2, varid)) { else if (Token::simpleMatch(tok2, ") {") && Token::findmatch(tok2->link(), "%varid%", tok2, varid)) {

View File

@ -3728,6 +3728,19 @@ private:
"}"; "}";
testValueOfX(code,0,0); // <- don't hang testValueOfX(code,0,0); // <- don't hang
// crash (daca@home)
code = "void foo(char *z, int n) {\n"
" int i;\n"
" if (fPScript) {\n"
" i = 1;\n"
" } else if (strncmp(&z[n], \"<!--\", 4) == 0) {\n"
" for (i = 4;;) {\n"
" if (z[n] && strncmp(&z[n+i], \"-->\", 3) == 0) ;\n"
" }\n"
" }\n"
"}";
testValueOfX(code,0,0); // <- don't crash
// conditional code in loop // conditional code in loop
code = "void f(int mask) {\n" // #6000 code = "void f(int mask) {\n" // #6000
" for (int x = 10; x < 14; x++) {\n" " for (int x = 10; x < 14; x++) {\n"