Skip to content

Commit 41f44f5

Browse files
committed
C++: Explicitly check that a check for EOF isn't present.
1 parent 3a66fd7 commit 41f44f5

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

cpp/ql/src/Critical/ScanfChecks.qll

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,37 @@ private predicate isLinuxKernel() {
2020
exists(Macro macro | macro.getName() in ["_LINUX_KERNEL_SPRINTF_H_", "_LINUX_KERNEL_H"])
2121
}
2222

23+
/**
24+
* Gets the value of the EOF macro.
25+
*
26+
* This is typically `"-1"`, but this is not guaranteed to be the case on all
27+
* systems.
28+
*/
29+
private string getEofValue() {
30+
exists(MacroInvocation mi |
31+
mi.getMacroName() = "EOF" and
32+
result = unique( | | mi.getExpr().getValue())
33+
)
34+
}
35+
36+
/**
37+
* Holds if the value of `call` has been checked to not equal `EOF`.
38+
*/
39+
private predicate checkedForEof(ScanfFunctionCall call) {
40+
exists(IRGuardCondition gc |
41+
exists(Instruction i, ConstantInstruction eof |
42+
eof.getValue() = getEofValue() and
43+
i.getUnconvertedResultExpression() = call and
44+
gc.comparesEq(valueNumber(i).getAUse(), eof.getAUse(), 0, _, _)
45+
)
46+
)
47+
}
48+
2349
/**
2450
* Holds if `call` is a `scanf`-like call were the result is only checked against 0, but it can also return EOF.
2551
*/
2652
predicate incorrectlyCheckedScanf(ScanfFunctionCall call) {
2753
exprInBooleanContext(call) and
54+
not checkedForEof(call) and
2855
not isLinuxKernel() // scanf in the linux kernel can't return EOF
2956
}

0 commit comments

Comments
 (0)