From 95235cade8c1298c6dde8d612bb7506d4857ebe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Fri, 16 Feb 2024 10:12:06 +0100 Subject: [PATCH] add `test/cli/fuzz_test.py` to easily integrate oss-fuzz findings into tests (#5985) This adds a Python test which processes input files from a folder and checks that they do not cause any crashes. This will later be extended to include timeouts as well. --- lib/checkfunctions.cpp | 2 +- lib/checkother.cpp | 2 +- lib/checkuninitvar.cpp | 2 +- lib/programmemory.cpp | 2 +- lib/tokenlist.cpp | 2 +- ...ash-26edfe9761d3b681c841dfe80398847dee332f83 | Bin 0 -> 18 bytes ...ash-3ea64296c8518edb538e0047c3eba0792d5deeba | Bin 0 -> 103 bytes ...ash-7ead2ccf9be8b03b2d9c8c82891f58081390a560 | Bin 0 -> 106 bytes ...ash-9ef938bba7d752386e24f2438c73cec66f6b972b | 12 ++++++++++++ ...ash-e4a26f2d7d0a73836bf086f54e48204d8914b95a | Bin 0 -> 159 bytes test/cli/fuzz_test.py | 16 ++++++++++++++++ 11 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 test/cli/fuzz-crash/crash-26edfe9761d3b681c841dfe80398847dee332f83 create mode 100644 test/cli/fuzz-crash/crash-3ea64296c8518edb538e0047c3eba0792d5deeba create mode 100644 test/cli/fuzz-crash/crash-7ead2ccf9be8b03b2d9c8c82891f58081390a560 create mode 100644 test/cli/fuzz-crash/crash-9ef938bba7d752386e24f2438c73cec66f6b972b create mode 100644 test/cli/fuzz-crash/crash-e4a26f2d7d0a73836bf086f54e48204d8914b95a create mode 100644 test/cli/fuzz_test.py diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 7ce557bfc92..5aa979b0bcf 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -766,7 +766,7 @@ void CheckFunctions::useStandardLibrary() continue; // 3. we expect idx incrementing by 1 - const bool inc = stepToken->str() == "++" && stepToken->astOperand1()->varId() == idxVarId; + const bool inc = stepToken->str() == "++" && stepToken->astOperand1() && stepToken->astOperand1()->varId() == idxVarId; const bool plusOne = stepToken->isBinaryOp() && stepToken->str() == "+=" && stepToken->astOperand1()->varId() == idxVarId && stepToken->astOperand2()->str() == "1"; diff --git a/lib/checkother.cpp b/lib/checkother.cpp index af2ca4ea432..35e514dc0f2 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1938,7 +1938,7 @@ void CheckOther::checkIncompleteStatement() continue; if (isVoidStmt(tok)) continue; - if (mTokenizer->isCPP() && tok->str() == "&" && !(tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->isIntegral())) + if (mTokenizer->isCPP() && tok->str() == "&" && !(tok->astOperand1() && tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->isIntegral())) // Possible archive continue; const bool inconclusive = tok->isConstOp(); diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 8458ffe4d5c..e4038adfbf9 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1287,7 +1287,7 @@ const Token* CheckUninitVar::isVariableUsage(const Token *vartok, const Library& if (Token::Match((derefValue ? derefValue : vartok)->astParent(), "(|=") && astIsRhs(derefValue ? derefValue : vartok)) { const Token *rhstok = derefValue ? derefValue : vartok; const Token *lhstok = rhstok->astParent()->astOperand1(); - const Variable *lhsvar = lhstok->variable(); + const Variable *lhsvar = lhstok ? lhstok->variable() : nullptr; if (lhsvar && lhsvar->isReference() && lhsvar->nameToken() == lhstok) return nullptr; } diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 6b082514f14..b5558233206 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -320,7 +320,7 @@ void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Toke else pm.setIntValue(tok, 0, then); } - } else if (tok->exprId() > 0) { + } else if (tok && tok->exprId() > 0) { if (endTok && findExpressionChanged(tok, tok->next(), endTok, settings, true)) return; pm.setIntValue(tok, 0, then); diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index a0706491dac..b6e312625d9 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -960,7 +960,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state) Token* const curlyBracket = squareBracket->link()->next(); squareBracket->astOperand1(curlyBracket); state.op.push(squareBracket); - tok = curlyBracket->link()->next(); + tok = curlyBracket->link() ? curlyBracket->link()->next() : nullptr; continue; } } diff --git a/test/cli/fuzz-crash/crash-26edfe9761d3b681c841dfe80398847dee332f83 b/test/cli/fuzz-crash/crash-26edfe9761d3b681c841dfe80398847dee332f83 new file mode 100644 index 0000000000000000000000000000000000000000..37965deed0be75554c596307860cf4987f3c8b3a GIT binary patch literal 18 Zcma#%W-y3lU{J6rF3C*N%izjW001LL1TX*q literal 0 HcmV?d00001 diff --git a/test/cli/fuzz-crash/crash-3ea64296c8518edb538e0047c3eba0792d5deeba b/test/cli/fuzz-crash/crash-3ea64296c8518edb538e0047c3eba0792d5deeba new file mode 100644 index 0000000000000000000000000000000000000000..f096de3bf78f2d3cfd6f9fdd8db97552501f0059 GIT binary patch literal 103 zcmc~S%Tvfr%*@l!k{00sXR-T(jq literal 0 HcmV?d00001 diff --git a/test/cli/fuzz-crash/crash-7ead2ccf9be8b03b2d9c8c82891f58081390a560 b/test/cli/fuzz-crash/crash-7ead2ccf9be8b03b2d9c8c82891f58081390a560 new file mode 100644 index 0000000000000000000000000000000000000000..80a938891ac6ecaf058992612cecd407a43a606d GIT binary patch literal 106 zcmW-ZI|_g>6a-V}6l)i;@q<;&NkWPgDo-$i#5CgFUEOZjVWcGNQ8rWSTZ5C75q%#l sX;n&*Gvp&+IZhaXqXpYe7%Ze|>i^>%9lQjfqg?@I&exe38yS1_3u%iPR{#J2 literal 0 HcmV?d00001 diff --git a/test/cli/fuzz-crash/crash-9ef938bba7d752386e24f2438c73cec66f6b972b b/test/cli/fuzz-crash/crash-9ef938bba7d752386e24f2438c73cec66f6b972b new file mode 100644 index 00000000000..cf4921c19c7 --- /dev/null +++ b/test/cli/fuzz-crash/crash-9ef938bba7d752386e24f2438c73cec66f6b972b @@ -0,0 +1,12 @@ +#include +sho main() +{ + std::veCtor items(2); + stdtryector::iterator iter; + for (iter -= items.begin(); i&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&ter != items.end();) { + if (*iter == 2) { + iter = items.erase//(iter); + } else { + } + } +} diff --git a/test/cli/fuzz-crash/crash-e4a26f2d7d0a73836bf086f54e48204d8914b95a b/test/cli/fuzz-crash/crash-e4a26f2d7d0a73836bf086f54e48204d8914b95a new file mode 100644 index 0000000000000000000000000000000000000000..89b9bf0f48b6c7dbef2981c39f35a120410c64ba GIT binary patch literal 159 zcmd1gXJBAp1mcpS%DfVV+{Da0jhy^+O|EJ#1t7=-iX}!H$6AAw00EmqrZre1Ex$-X zBU8av!N6J}Q^7{T*jgbwO-)-{6D$kTni#E}84FfW;usuk9~4r80D=gn6`TpyS(I8* LT2unHrIrf-yLu`4 literal 0 HcmV?d00001 diff --git a/test/cli/fuzz_test.py b/test/cli/fuzz_test.py new file mode 100644 index 00000000000..91f1dc84a9f --- /dev/null +++ b/test/cli/fuzz_test.py @@ -0,0 +1,16 @@ +import os +from testutils import cppcheck + +__script_dir = os.path.dirname(os.path.abspath(__file__)) + + +def test_fuzz_crash(): + failures = {} + + fuzz_crash_dir = os.path.join(__script_dir, 'fuzz-crash') + for f in os.listdir(fuzz_crash_dir): + ret, stdout, _ = cppcheck(['-q', '--enable=all', '--inconclusive', f], cwd=fuzz_crash_dir) + if ret != 0: + failures[f] = stdout + + assert failures == {}