Skip to content

Commit

Permalink
fixed #13440 - do not crash when whole program analysis addon executi…
Browse files Browse the repository at this point in the history
…on fails

Co-authored-by: Daniel Marjamäki <[email protected]>
  • Loading branch information
firewave and danmar committed Dec 17, 2024
1 parent 6209da5 commit e2f28db
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 11 deletions.
18 changes: 10 additions & 8 deletions lib/cppcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1682,8 +1682,15 @@ void CppCheck::executeAddons(const std::vector<std::string>& files, const std::s
if (isCtuInfo && addonInfo.name != "misra" && !addonInfo.ctu)
continue;

const std::vector<picojson::value> results =
executeAddon(addonInfo, mSettings.addonPython, fileList.empty() ? files[0] : fileList, mSettings.premiumArgs, mExecuteCommand);
std::vector<picojson::value> results;

try {
results = executeAddon(addonInfo, mSettings.addonPython, fileList.empty() ? files[0] : fileList, mSettings.premiumArgs, mExecuteCommand);
} catch (const InternalError& e) {
const std::string ctx = isCtuInfo ? "Whole program analysis" : "Checking file";
const ErrorMessage errmsg = ErrorMessage::fromInternalError(e, nullptr, file0, "Bailing out from analysis: " + ctx + " failed");
mErrorLogger.reportErr(errmsg);
}

const bool misraC2023 = mSettings.premiumArgs.find("--misra-c-2023") != std::string::npos;

Expand Down Expand Up @@ -1779,12 +1786,7 @@ void CppCheck::executeAddonsWholeProgram(const std::list<FileWithDetails> &files
ctuInfoFiles.push_back(getCtuInfoFileName(dumpFileName));
}

try {
executeAddons(ctuInfoFiles, "");
} catch (const InternalError& e) {
const ErrorMessage errmsg = ErrorMessage::fromInternalError(e, nullptr, "", "Bailing out from analysis: Whole program analysis failed");
mErrorLogger.reportErr(errmsg);
}
executeAddons(ctuInfoFiles, "");
}

Settings &CppCheck::settings()
Expand Down
57 changes: 54 additions & 3 deletions test/cli/other_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ def test_progress_j(tmpdir):
assert stderr == ""


def test_execute_addon_failure(tmpdir):
def test_execute_addon_failure_py_auto(tmpdir):
test_file = os.path.join(tmpdir, 'test.cpp')
with open(test_file, 'wt') as f:
f.write("""
Expand All @@ -212,21 +212,72 @@ def test_execute_addon_failure(tmpdir):
assert stderr == '{}:0:0: error: Bailing out from analysis: Checking file failed: Failed to auto detect python [internalError]\n\n^\n'.format(test_file)


def test_execute_addon_failure_2(tmpdir):
def test_execute_addon_failure_py_notexist(tmpdir):
test_file = os.path.join(tmpdir, 'test.cpp')
with open(test_file, 'wt') as f:
f.write("""
void f();
""")

# specify non-existent python executbale so execution of addon fails
# specify non-existent python executable so execution of addon fails
args = ['--addon=naming', '--addon-python=python5.x', test_file]

_, _, stderr = cppcheck(args)
ec = 1 if os.name == 'nt' else 127
assert stderr == "{}:0:0: error: Bailing out from analysis: Checking file failed: Failed to execute addon 'naming' - exitcode is {} [internalError]\n\n^\n".format(test_file, ec)


def test_execute_addon_failure_json_notexist(tmpdir):
# specify non-existent python executable so execution of addon fails
addon_json = os.path.join(tmpdir, 'addon.json')
with open(addon_json, 'wt') as f:
f.write(json.dumps({'executable': 'notexist'}))

test_file = os.path.join(tmpdir, 'test.cpp')
with open(test_file, 'wt') as f:
f.write("""
void f();
""")

args = [
'--addon={}'.format(addon_json),
test_file
]

_, _, stderr = cppcheck(args)
ec = 1 if os.name == 'nt' else 127
assert stderr == "{}:0:0: error: Bailing out from analysis: Checking file failed: Failed to execute addon 'addon.json' - exitcode is {} [internalError]\n\n^\n".format(test_file, ec)


def test_execute_addon_failure_json_ctu_notexist(tmpdir):
# specify non-existent python executable so execution of addon fails
addon_json = os.path.join(tmpdir, 'addon.json')
with open(addon_json, 'wt') as f:
f.write(json.dumps({
'executable': 'notexist',
'ctu': True
}))

test_file = os.path.join(tmpdir, 'test.cpp')
with open(test_file, 'wt') as f:
f.write("""
void f(); """)

args = [
'--template=simple',
'--addon={}'.format(addon_json),
test_file
]

_, _, stderr = cppcheck(args)
ec = 1 if os.name == 'nt' else 127
print(stderr)
assert stderr.splitlines() == [
"{}:0:0: error: Bailing out from analysis: Checking file failed: Failed to execute addon 'addon.json' - exitcode is {} [internalError]".format(test_file, ec),
":0:0: error: Bailing out from analysis: Whole program analysis failed: Failed to execute addon 'addon.json' - exitcode is {} [internalError]".format(ec)
]


def test_execute_addon_file0(tmpdir):
test_file = os.path.join(tmpdir, 'test.c')
with open(test_file, 'wt') as f:
Expand Down

0 comments on commit e2f28db

Please sign in to comment.