[PATCH] D92777: [clang-tidy] Add bugprone-strlen-in-array-index checker
Whisperity via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 9 04:42:44 PDT 2021
whisperity added a comment.
The tests are a bit slim. We definitely need more cases... what if the array isn't allocated locally, but received as a parameter? I take that we need both an `fgets` and a `strlen` call in the same function(?) to emit diagnostics. Are we sure it will work if the array is originally from somewhere else?
================
Comment at: clang-tools-extra/clang-tidy/bugprone/StrlenInArrayIndexCheck.cpp:21
+ Finder->addMatcher(
+ arraySubscriptExpr(
+ allOf(hasBase(implicitCastExpr(hasSourceExpression(
----------------
While certainly not natural, if we're already here, it wouldn't take more than a few additional lines to match the equivalent but "expanded" version of array indexing:
```
*(buf + strlen(buf) - 1) = 0;
```
================
Comment at: clang-tools-extra/clang-tidy/bugprone/StrlenInArrayIndexCheck.cpp:22
+ arraySubscriptExpr(
+ allOf(hasBase(implicitCastExpr(hasSourceExpression(
+ declRefExpr(to(varDecl().bind("buf")))))),
----------------
What's a hard `implicitCastExpr` doing here? Does a cast always happen? I feel this might be a bit too restrictive... there are matcher adaptors like `ignoringParenImpCasts`, that route should be investigated.
================
Comment at: clang-tools-extra/clang-tidy/bugprone/StrlenInArrayIndexCheck.cpp:26-28
+ allOf(callee(functionDecl(
+ hasAnyName("::strlen", "::std::strlen",
+ "::wcslen", "::std::wcslen"))),
----------------
`strlen_s`, `wcslen_s`? If I am reading [[ http://en.cppreference.com/w/c/string/byte/strlen | this correctly ]] then in case the input buffer starts with a `NUL` (and the //safe size// is large enough) then it behaves the same way `strlen` and will still return 0.
If we are already here, it might be worth to also check for [[ http://pubs.opengroup.org/onlinepubs/9699919799/functions/strlen.html | strnlen ]]. It is POSIX and BSD specific, but behaves the same way as `strlen_s`.
================
Comment at: clang-tools-extra/clang-tidy/bugprone/StrlenInArrayIndexCheck.cpp:31-32
+ equalsBoundNode("buf")))))))),
+ anyOf(hasDescendant(binaryOperator(hasOperatorName("-"))),
+ binaryOperator(hasOperatorName("-")))))))
+ .bind("arrayExpr"),
----------------
Why is the inner matcher duplicated here? What cases do we have a direct (?) `-` and a non-direct (descendant) one?
================
Comment at: clang-tools-extra/test/clang-tidy/checkers/bugprone-strlen-in-array-index.cpp:16-17
+
+// Examples were copied from the cert-fio37-c issue (with some added calls):
+// https://wiki.sei.cmu.edu/confluence/display/c/FIO37-C.+Do+not+assume+that+fgets%28%29+or+fgetws%28%29+returns+a+nonempty+string+when+successful
+
----------------
Such code examples might be covered by non-permissive copyright, which might be incompatible with LLVM's licence. I was unable to find anything wrt. copyright on SEI CERT's Confluence, which in this case makes the work to be //(strictly) copyrighted// by default. I am not sure what the actual situation is, but such a **direct mention** of copying //could// lead to problems.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D92777/new/
https://reviews.llvm.org/D92777
More information about the cfe-commits
mailing list