C++: Explicitly check that a check for EOF isn't present.

This commit is contained in:
Mathias Vorreiter Pedersen
2024-01-29 11:30:18 +00:00
parent 3a66fd7175
commit 41f44f598a

View File

@@ -20,10 +20,37 @@ private predicate isLinuxKernel() {
exists(Macro macro | macro.getName() in ["_LINUX_KERNEL_SPRINTF_H_", "_LINUX_KERNEL_H"])
}
/**
* Gets the value of the EOF macro.
*
* This is typically `"-1"`, but this is not guaranteed to be the case on all
* systems.
*/
private string getEofValue() {
exists(MacroInvocation mi |
mi.getMacroName() = "EOF" and
result = unique( | | mi.getExpr().getValue())
)
}
/**
* Holds if the value of `call` has been checked to not equal `EOF`.
*/
private predicate checkedForEof(ScanfFunctionCall call) {
exists(IRGuardCondition gc |
exists(Instruction i, ConstantInstruction eof |
eof.getValue() = getEofValue() and
i.getUnconvertedResultExpression() = call and
gc.comparesEq(valueNumber(i).getAUse(), eof.getAUse(), 0, _, _)
)
)
}
/**
* Holds if `call` is a `scanf`-like call were the result is only checked against 0, but it can also return EOF.
*/
predicate incorrectlyCheckedScanf(ScanfFunctionCall call) {
exprInBooleanContext(call) and
not checkedForEof(call) and
not isLinuxKernel() // scanf in the linux kernel can't return EOF
}