Skip to content

Commit 3d30316

Browse files
committed
Implement INT34-C
1 parent 1b5c862 commit 3d30316

File tree

2 files changed

+336
-4
lines changed

2 files changed

+336
-4
lines changed

c/cert/src/rules/INT34-C/ExprShiftedbyNegativeOrGreaterPrecisionOperand.ql

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,65 @@
1313
import cpp
1414
import codingstandards.c.cert
1515

16-
from
16+
/* Precision predicate based on a sample implementaion from https://wiki.sei.cmu.edu/confluence/display/c/INT35-C.+Use+correct+integer+precisions */
17+
int getPrecision(BuiltInType type) {
18+
type.(CharType).isExplicitlyUnsigned() and result = 8
19+
or
20+
type.(ShortType).isExplicitlyUnsigned() and result = 16
21+
or
22+
type.(IntType).isExplicitlyUnsigned() and result = 32
23+
or
24+
type.(LongType).isExplicitlyUnsigned() and result = 32
25+
or
26+
type.(LongLongType).isExplicitlyUnsigned() and result = 64
27+
or
28+
type instanceof CharType and not type.(CharType).isExplicitlyUnsigned() and result = 7
29+
or
30+
type instanceof ShortType and not type.(ShortType).isExplicitlyUnsigned() and result = 15
31+
or
32+
type instanceof IntType and not type.(IntType).isExplicitlyUnsigned() and result = 31
33+
or
34+
type instanceof LongType and not type.(LongType).isExplicitlyUnsigned() and result = 31
35+
or
36+
type instanceof LongLongType and not type.(LongLongType).isExplicitlyUnsigned() and result = 63
37+
}
38+
39+
class MinusNumberLiteral extends UnaryMinusExpr {
40+
MinusNumberLiteral() { this.getOperand() instanceof Literal }
41+
42+
override string toString() { result = "-" + this.getOperand().toString() }
43+
}
44+
45+
class ForbiddenShiftExpr extends BinaryBitwiseOperation {
46+
ForbiddenShiftExpr() {
47+
(
48+
/* Precision mismatch between operands */
49+
getPrecision(this.(LShiftExpr).getLeftOperand().getUnderlyingType()) <=
50+
getPrecision(this.(LShiftExpr).getRightOperand().getUnderlyingType()) or
51+
getPrecision(this.(RShiftExpr).getLeftOperand().getUnderlyingType()) <=
52+
getPrecision(this.(RShiftExpr).getRightOperand().getUnderlyingType()) or
53+
/* Shifting by a negative number literal */
54+
this.(LShiftExpr).getRightOperand() instanceof MinusNumberLiteral or
55+
this.(RShiftExpr).getRightOperand() instanceof MinusNumberLiteral
56+
)
57+
}
58+
59+
predicate hasNegativeOperand() {
60+
this.(LShiftExpr).getRightOperand() instanceof MinusNumberLiteral or
61+
this.(RShiftExpr).getRightOperand() instanceof MinusNumberLiteral
62+
}
63+
}
64+
65+
from ForbiddenShiftExpr badShift, string message
1766
where
18-
not isExcluded(x, TypesPackage::exprShiftedbyNegativeOrGreaterPrecisionOperandQuery()) and
19-
select
67+
not isExcluded(badShift, TypesPackage::exprShiftedbyNegativeOrGreaterPrecisionOperandQuery()) and
68+
if badShift.hasNegativeOperand()
69+
then
70+
message =
71+
"The operand " + badShift.getLeftOperand() + " is shifted by a negative expression " +
72+
badShift.getRightOperand() + "."
73+
else
74+
message =
75+
"The operand " + badShift.getLeftOperand() + " is shifted by an expression " +
76+
badShift.getRightOperand() + " which is greater than or equal to in precision."
77+
select badShift, message

0 commit comments

Comments
 (0)