Skip to content

Partial fix for #8328 (build dir: hash the addon files) - #9029

Open
g-chauvel wants to merge 1 commit into
cppcheck-opensource:mainfrom
g-chauvel:addon-cache-hash
Open

g-chauvel wants to merge 1 commit into
cppcheck-opensource:mainfrom
g-chauvel:addon-cache-hash

Conversation

@g-chauvel

Copy link
Copy Markdown
Contributor

With --cppcheck-build-dir, the hash only includes the name and the arguments of the addons. After editing the addon script, its json file or a file given in its arguments, cppcheck shows the cached results.

This hashes the json file, the script or the executable, and the files given as OPTION=FILE in the arguments, when the addon is loaded.

Still not hashed: an executable found through the PATH, a file given as a separate argument ("--rule-texts", "FILE"), and the files the script reads or imports itself.

t.c

void f(int a) { }

rules.txt

Appendix A Summary of guidelines
Rule 2.7
V1

misra.json

{"script": "misra.py", "args": ["--rule-texts=rules.txt"]}
mkdir bd
cppcheck -q --enable=style --addon=misra.json --cppcheck-build-dir=bd --template="{file}:{line}: {message} [{id}]" t.c
t.c:1: V1 [misra-c2012-2.7]
t.c:1: misra violation 804 with no text in the supplied rule-texts-file [misra-c2012-8.4]

Change V1 to V2 in rules.txt and run the same command again.

Before PR (stale results from the cache):

t.c:1: V1 [misra-c2012-2.7]
t.c:1: misra violation 804 with no text in the supplied rule-texts-file [misra-c2012-8.4]

After PR (cache invalidated):

t.c:1: V2 [misra-c2012-2.7]
t.c:1: misra violation 804 with no text in the supplied rule-texts-file [misra-c2012-8.4]

@dmcppcheck dmcppcheck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI review

One new problem: splitArgs says it splits "as the shell running the addon does", but it only handles double quotes. On Linux and macOS the addon command is run through popen(), so /bin/sh also strips single quotes. A file given as --rules='rules.txt' (with or without spaces in the name) is still passed to the addon, but Path::isFile gets the path with the quote characters in it and fails, so the file is not hashed. Editing that file then still shows the cached results. I reproduced this. It is a false negative inside a fix that is already partial, and nothing else turned up. The CLI and GUI load addons in the right order relative to buildDir, and the existing tests pass.

Testing

I built cppcheck and testrunner in pr/ without errors. I did not build the GUI.

  • ./testrunner TestCppcheck: 21 tests, 0 failed.
  • python3 -m pytest other_test.py -k builddir in test/cli: 13 passed, 1 xfailed. This includes the new test_builddir_hash_addon.

Manual check. I wrote a small addon in /work/scratch that reports the content of the file given in --rules=FILE.

myaddon.py:

import sys, json
txt=None
for a in sys.argv[1:]:
    if a.startswith('--rules='): txt=open(a[8:]).read().strip()
sys.stdout.write(json.dumps({"file":"t.c","linenr":1,"column":1,"severity":"style","message":str(txt),"addon":"myaddon","errorId":"x","extra":""})+"\n")

t.c: void f(int a) { }

The command for every case was:

rm -rf bd; mkdir bd; printf 'V1\n' > rs.txt
cppcheck -q --enable=style --addon=a.json --cppcheck-build-dir=bd --template="{file}:{line}: {message} [{id}]" t.c
printf 'V2\n' > rs.txt
cppcheck ... (same command again)

Results:

  • "args": ["--rules=rs.txt"]: V1, then V2. The cache is invalidated correctly.
  • "args": ["--rules=\"r s.txt\""]: V1, then V2. Correct.
  • Editing myaddon.py gave the new output. Correct.
  • "args": ["--rules='rs.txt'"]: V1, then V1. The result is stale, although the addon itself reads rs.txt because the shell removes the quotes.
  • "args": ["--rules='r s.txt'"]: V1, then V1. Also stale.

Automated review of 8c748bb by Claude. The pull request was built and tested locally.

Comment thread lib/addoninfo.cpp Outdated
std::vector<std::string> ret(1);
bool quoted = false;
for (const char c : args) {
if (c == '\"')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI review

The addon command goes through popen(), which runs /bin/sh on POSIX systems. The shell also removes single quotes, but splitArgs only handles ". For "args": ["--rules='rs.txt'"] the addon reads rs.txt, while this code checks Path::isFile("'rs.txt'"). That check fails, so the file is not hashed and the build dir keeps returning stale results after rs.txt is edited. I reproduced this both with and without a space in the file name. Either handle single quotes here (at least on non-Windows), or change the comment so it does not claim to match the shell.

…iles)

The build dir hash only included the name and the arguments of the
addons. Also hash the content of the json file, the script or the
executable, and of the files given as OPTION=FILE in the arguments,
such as --rule-texts=FILE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants