Skip to content

Commit 417514c

Browse files
committed
IntegerOverflow: Implement INT35-C
Add query to find incorrect precision checks.
1 parent 9afa81e commit 417514c

File tree

5 files changed

+95
-0
lines changed

5 files changed

+95
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# INT35-C: Use correct integer precisions
2+
3+
This query implements the CERT-C rule INT35-C:
4+
5+
> Use correct integer precisions
6+
7+
8+
## CERT
9+
10+
** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py` **
11+
12+
## Implementation notes
13+
14+
None
15+
16+
## References
17+
18+
* CERT-C: [INT35-C: Use correct integer precisions](https://wiki.sei.cmu.edu/confluence/display/c)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* @id c/cert/use-correct-integer-precisions
3+
* @name INT35-C: Use correct integer precisions
4+
* @description
5+
* @kind problem
6+
* @precision high
7+
* @problem.severity error
8+
* @tags external/cert/id/int35-c
9+
* correctness
10+
* external/cert/obligation/rule
11+
*/
12+
13+
import cpp
14+
import codingstandards.c.cert
15+
16+
class CharBitMacroInvocation extends MacroInvocation {
17+
CharBitMacroInvocation() { this.getMacroName() = "CHAR_BIT" }
18+
}
19+
20+
from SizeofOperator so, RelationalOperation comparison, MulExpr m, Expr charSize
21+
where
22+
not isExcluded(so, IntegerOverflowPackage::useCorrectIntegerPrecisionsQuery()) and
23+
// Multiplication of a sizeof operator and a constant that's probably a char size
24+
m.getAnOperand() = so and
25+
m.getAnOperand() = charSize and
26+
not so = charSize and
27+
(
28+
charSize.getValue().toInt() = 8
29+
or
30+
charSize = any(CharBitMacroInvocation c).getExpr()
31+
) and
32+
// The result is compared against something, which is probably related to the number of bits
33+
comparison.getAnOperand() = m
34+
select so, "sizeof operator used to determine the precision of an integer type."
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| test.c:11:12:11:31 | sizeof(unsigned int) | sizeof operator used to determine the precision of an integer type. |
2+
| test.c:27:25:27:42 | sizeof(signed int) | sizeof operator used to determine the precision of an integer type. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/INT35-C/UseCorrectIntegerPrecisions.ql

c/cert/test/rules/INT35-C/test.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include <limits.h>
2+
#include <math.h>
3+
#include <stddef.h>
4+
#include <stdint.h>
5+
6+
size_t popcount(uintmax_t num);
7+
8+
#define PRECISION(umax_value) popcount(umax_value)
9+
10+
void test_incorrect_precision_check(int e) {
11+
if (e >= sizeof(unsigned int) * CHAR_BIT) { // NON_COMPLIANT
12+
// handle error
13+
} else {
14+
1 << e;
15+
}
16+
}
17+
18+
void test_correct_precision_check(int e) {
19+
if (e >= PRECISION(UINT_MAX)) { // COMPLIANT
20+
/* Handle error */
21+
} else {
22+
1 << e;
23+
}
24+
}
25+
26+
void test_incorrect_precision_check_cast(float f) {
27+
if (log2f(fabsf(f)) > sizeof(signed int) * CHAR_BIT) { // NON_COMPLIANT
28+
// handle error
29+
} else {
30+
(signed int)f;
31+
}
32+
}
33+
34+
void test_correct_precision_check_cast(float f) {
35+
if (log2f(fabsf(f)) > PRECISION(INT_MAX)) { // COMPLIANT
36+
/* Handle error */
37+
} else {
38+
(signed int)f;
39+
}
40+
}

0 commit comments

Comments
 (0)