Hi,
I have a question regarding rule S3519 (“Array index out of bounds”) in SonarCloud.
We see two types of cases reported by this rule:
Some issues are clear because an actual out-of-bounds access can occur.
Others are safe at runtime but rely on an invariant that is not guaranteed. This is definitely bad practice and poor design, but we are not sure if Sonar is intended to cover such cases, which is why I’m asking.
Could you clarify:
Does Sonar report only real, guaranteed problems, or does it also include potential problems when safety cannot be proven?
How does the analysis handle values that come from external constants or macros that are not const and not visible in the same file?
Is detection based purely on syntax and operations (e.g., array indexing), or does Sonar attempt to infer values and validate invariants?
Thanks for explaining how this rule works internally.
As usual, we are trying to find the balance between the level of noise the rule produces and the amount of bugs it helps you to discover. The rule aims at discovering plausible scenarios leading to an out-of-bounds access. Since Sonar never executes your code, it cannot have 100% confidence that a discovered bug occurs in any actual execution. Any of the code it analyzes might turn out to be dead code.
That being said, I agree with you that some findings seem closer to a bug and some might seem closer to a “code smell”.
The rule detects an out-of-bounds access as in this function (Compiler Explorer):
int oob(int idx) {
int arr[5] = {0};
if (idx < 10) {
return 0;
}
return arr[idx]; // S3519
}
Note that your code might never call oob with idx >= 10, so the bug might not be actually infeasible, but that means this function contains never-executed code, which is a code smell.
It also detects a pointer for out-of-bounds part of an array as in this example (Compiler Explorer):
Note that here no out-of-bounds access happened yet. You might consider it a non-bug, yet same rule raises an issue. Since you are forming an invalid pointer in some cases, you have a high risk of dereferencing it. Here, all the code might execute, and further down the execution, you might still not hit undefined behavior because you’ll have additional logic that prevents you from dereferencing an invalid pointer.
Finally, as static analysis is undecidable there is always a risk of false positives: the issues raised by Sonar that are false alarms.
To answer your questions:
S3519 rule raises an issue when it is reasonably sure the code in question can lead to an out-of-bounds access. Sonar has other rules that flag “code-smells” - patterns in code that often lead to problems, even if the problem have not occurred yet in the particular part of the code.
Our analysis uses heuristics. If simplified, it assumes such values are arbitrary. Yet, it does not report issues that require specific concrete instantiation of these unknown values unless it has evidence from the current translation unit that such instantiation can happen.
S3519 is based on semantic modelling (specifically Symbolic Execution). It does try to infer values and validate invariants. Sonar has many other rules and some of them are also semantic based, ans dome of them are syntax-based.