使用范围分析来分析 C 和 C++ 代码¶
您可以使用范围分析来确定表达式的上限或下限,或表达式是否可能发生上溢或下溢。
关于范围分析库¶
范围分析库(定义在 semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
中)提供了一组谓词,用于确定表达式常数上限和下限,以及识别整数溢出。出于性能考虑,该库执行自动扩展,因此可能无法提供最严格的界限。
边界谓词¶
upperBound
和 lowerBound
谓词提供表达式的常数边界。边界中不包括参数的任何转换。在您的查询需要考虑转换的常见情况下,请在转换后的形式上调用它们,例如 upperBound(expr.getFullyConverted())
。
溢出谓词¶
exprMightOverflow
和相关谓词在相关表达式可能溢出时成立,如范围分析库所确定。 convertedExprMightOverflow
系列谓词将考虑转换。
示例¶
此查询使用 upperBound
来确定在循环中使用时,snprintf
的结果是否被检查。
from FunctionCall call, DataFlow::Node source, DataFlow::Node sink, Expr convSink
where
// the call is an snprintf with a string format argument
call.getTarget().getName() = "snprintf" and
call.getArgument(2).getValue().regexpMatch(".*%s.*") and
// the result of the call influences its size argument in later iterations
TaintTracking::localTaint(source, sink) and
source.asExpr() = call and
sink.asExpr() = call.getArgument(1) and
// there is no fixed bound on the snprintf's size argument
upperBound(convSink) = typeUpperBound(convSink.getType().getUnspecifiedType()) and
convSink = call.getArgument(1).getFullyConverted()
select call, upperBound(call.getArgument(1).getFullyConverted())