I'm using the 2.5 release of cppcheck, and hope to use it to check for use of banned functions. I've seen the two PDFs about writing rules, and have followed them, creating an XML file called BannedFunctions.rule. I'm using a batch file to launch cppcheck, with the following:
I now have three questions about using cppcheck in this manner:
1. The following is emitted for every file that's evaluated:
Handling of "simple" rules is deprecated and will be removed in Cppcheck 2.5.
That's obviously untrue since I'm using 2.5 and it works, but the question is what's replacing it? I don't see any mention of "complex" rules.
2. I don't want cppcheck doing any of the normal static code analysis for this purpose - I'll be running it separately for normal code analysis. Is there a way to disable all the normal static code analysis? If I use rule suppression I'd have to know the name of every built-in rule.
3. It isn't stated in the PDFs, but the XML format of the rule file supports only a single rule, and I have a long list of banned functions. How can I specify all the rules in a single file?
4. There's a problem with my rule that I need help with. I'm looking for strlen, but it's matching lstrlenW. I tried the following rule with and without spaces around the function. Even when using "strlen (", it's matching lstrlenW. Here's the rule file:
This is awesome, ty!
One follow-up question: The following is tagged as a use of a banned function, even though it's the definition of a similarly named function with in a namespace:
I've found that I need to make the check more comprehensive, and I'm running into some strange behavior. I've attached a test file. When I try to analyze the test file, cppcheck has been failing with:
Bailing out from checking BannedFunctionsTest.cpp since there was an internal error: Failed to execute 'python.exe BannedFunctions.py --cli BannedFunctionsTest.cpp.dump'.
I've attached the python addin file, the test source file, and the dump file.
This is what gets output, but I don't see where it's getting StringUtil from line 10 - it doesn't occur in the source file until line 14.
you get the internal error because you are printing stuff from the addon. feel free to do that during debugging.. but cppcheck unfortunately expects to get errors from the addon on the stdout. maybe we could tweak it somehow so some debug messages will also be allowed.
Last edit: Daniel Marjamäki 2021-07-21
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The token.function is not none if the function is declared somewhere in the analysed code.. and if that happens you can use token.function to lookup where it is declared and stuff.. but since cppcheck does not try to include system headers that token.function should be None for the standard strlen function.
that will not work well for c++ code because of token.next != token.astParent .. but I guess it would be good to have some similar utility function in cppcheckdata.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks for all your assistance! Sorry for the file confusion - I sent you the wrong test file in the previous attachments. I believe the attached has everything working the way I want it to.
Update: Spoke too soon. Getting a false negative on this line:
pos += static_cast<size_t>( impl::StringUtil::vsnprintf( buffer + pos, kMaxLogSize - pos, format, argptr ) );</size_t>
My presumption is that the private strlen function is failing the token.function is None check, even though the symbol is defined in the .h file. It seems to me that cppcheck isn't handling nested namespaces. A suggestion would be to represent impl::StringUtil as implStringUtil. I tried adding "using namespace impl;" to the source file (so that the invocation would be simply StringUtil::strlen, but that didn't work.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm using the 2.5 release of cppcheck, and hope to use it to check for use of banned functions. I've seen the two PDFs about writing rules, and have followed them, creating an XML file called BannedFunctions.rule. I'm using a batch file to launch cppcheck, with the following:
"%CPPCHECK_INSTALL%\cppcheck.exe" --enable=warning --rule-file="BannedFunctions.rule" -i "../../src/external" --xml --xml-version=2 "....\src" 2> cppcheck-result.xml
I now have three questions about using cppcheck in this manner:
<rule version="1"> <pattern> strlen (</pattern> <message> <id>strlenBF</id> <severity>error</severity>1. The following is emitted for every file that's evaluated:
Handling of "simple" rules is deprecated and will be removed in Cppcheck 2.5.
That's obviously untrue since I'm using 2.5 and it works, but the question is what's replacing it? I don't see any mention of "complex" rules.
2. I don't want cppcheck doing any of the normal static code analysis for this purpose - I'll be running it separately for normal code analysis. Is there a way to disable all the normal static code analysis? If I use rule suppression I'd have to know the name of every built-in rule.
3. It isn't stated in the PDFs, but the XML format of the rule file supports only a single rule, and I have a long list of banned functions. How can I specify all the rules in a single file?
4. There's a problem with my rule that I need help with. I'm looking for strlen, but it's matching lstrlenW. I tried the following rule with and without spaces around the function. Even when using "strlen (", it's matching lstrlenW. Here's the rule file:
Thanks!
John
Please use addons instead of rules that is so much better.
You can put this code in BannedFunctions.py:
The file
cppcheckdata.py
is distributed with cppcheck put that in the same folder asBannedFunctions.py
.If you have python.exe / python3.exe in your PATH then execute Cppcheck like this:
Normal static code analysis is always run. You can execute the addon like this if you want:
You can ignore all warnings from the cppcheck command then. But well with this approach the addon does not generate xml.
The names of the built-in rules can be extracted. Try this command:
cppcheck --errorlist
..This is awesome, ty!
One follow-up question: The following is tagged as a use of a banned function, even though it's the definition of a similarly named function with in a namespace:
I'd rather not exclude the entire file, and I'm wondering if this is a bug.
Update: One use of that function is also tagged, even though there are at least 4 in the source code:
Last edit: John Schmitz 2021-07-16
with addons you have lots of freedom. To fix that particular false positive you can for instance write:
Daniel,
I've found that I need to make the check more comprehensive, and I'm running into some strange behavior. I've attached a test file. When I try to analyze the test file, cppcheck has been failing with:
I've attached the python addin file, the test source file, and the dump file.
This is what gets output, but I don't see where it's getting StringUtil from line 10 - it doesn't occur in the source file until line 14.
Output:
Thanks!
John
you get the internal error because you are printing stuff from the addon. feel free to do that during debugging.. but cppcheck unfortunately expects to get errors from the addon on the stdout. maybe we could tweak it somehow so some debug messages will also be allowed.
Last edit: Daniel Marjamäki 2021-07-21
I don't know.. in the cpp file you attached line 10 says:
you can also experiment with this:
The
token.function
is not none if the function is declared somewhere in the analysed code.. and if that happens you can usetoken.function
to lookup where it is declared and stuff.. but since cppcheck does not try to include system headers thattoken.function
should be None for the standardstrlen
function.in cert.py there is this function:
that will not work well for c++ code because of
token.next != token.astParent
.. but I guess it would be good to have some similar utility function in cppcheckdata.here is one more example code:
For information you can for example use token.function.tokenDef to see where the function definition is..
Last edit: Daniel Marjamäki 2021-07-21
I think we should create some utility function.. something like:
for the function call in the Foo constructor above, the
function_name
would beFoo::strlen
.Thanks for all your assistance! Sorry for the file confusion - I sent you the wrong test file in the previous attachments. I believe the attached has everything working the way I want it to.
Update: Spoke too soon. Getting a false negative on this line:
pos += static_cast<size_t>( impl::StringUtil::vsnprintf( buffer + pos, kMaxLogSize - pos, format, argptr ) );</size_t>
Last edit: John Schmitz 2021-07-23
My presumption is that the private strlen function is failing the token.function is None check, even though the symbol is defined in the .h file. It seems to me that cppcheck isn't handling nested namespaces. A suggestion would be to represent impl::StringUtil as implStringUtil. I tried adding "using namespace impl;" to the source file (so that the invocation would be simply StringUtil::strlen, but that didn't work.
nested namespaces is handled.
from dump output:
I added
cppcheckdata.get_function_call_name_args
.. could you try it out? I guess some tweaks will be needed.Code:
Addon:
Output: