@@ -15,34 +15,36 @@ import codingstandards.c.misra
1515import codingstandards.cpp.ReadErrorsAndEOF
1616import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
1717import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
18- import semmle.code.cpp.dataflow.DataFlow // TODO use this...
1918
20- query predicate isCtypeFunction ( Function function ) {
21- function .getADeclaration ( ) .getAFile ( ) .( HeaderFile ) .getShortName ( ) = "_ctype" // TODO: change it back to `ctype`
19+ class CtypeFunction extends Function {
20+ CtypeFunction ( ) { this .getADeclaration ( ) .getAFile ( ) .( HeaderFile ) .getShortName ( ) = "_ctype" }
2221}
2322
24- query predicate isInUnsignedCharRange ( Expr var ) {
25- // TODO: shouldn't be an Expr, instead get it as an argument from a FunctionCall that isCtypeFunction
23+ predicate unsignedCharRange ( int lower , int upper , EOFInvocation eof ) {
2624 exists ( UnsignedCharType unsignedChar |
27- // Consider cases where the argument's value is cast to some smaller type, clipping the range.
28- typeLowerBound ( unsignedChar ) <= lowerBound ( var .getFullyConverted ( ) ) and
29- upperBound ( var .getFullyConverted ( ) ) <= typeUpperBound ( unsignedChar )
25+ lower = typeLowerBound ( unsignedChar ) and
26+ upper = upperBound ( eof .getExpr ( ) ) and
27+ typeLowerBound ( unsignedChar ) <= lowerBound ( eof .getExpr ( ) ) and
28+ upperBound ( eof .getExpr ( ) ) <= typeUpperBound ( unsignedChar )
3029 )
3130}
3231
33- // Uh oh, this is empty
34- query predicate isEOFInvocation ( EOFInvocation eof ) {
35- any ( )
32+ predicate isEquivToEOF ( Expr expr ) {
33+ exists ( EOFInvocation eof | DataFlow:: localFlow ( DataFlow:: exprNode ( eof .getExpr ( ) ) , DataFlow:: exprNode ( expr ) ) )
3634}
3735
38- /* very early draft */
39- query predicate equivToEOF ( FunctionCall fc , EOFInvocation eof ) {
40- // var is a param of ctypefunctioncall
41- isCtypeFunction ( fc .getTarget ( ) ) and
42- DataFlow:: localFlow ( DataFlow:: exprNode ( eof .getExpr ( ) ) , DataFlow:: exprNode ( fc .getArgument ( 0 ) ) )
43- }
44- from Element x
36+ from FunctionCall ctypeCall
4537where
46- not isExcluded ( x , StandardLibraryFunctionTypesPackage:: ctypeFunctionArgNotUnsignedCharOrEofQuery ( ) ) and
47- any ( )
48- select 1
38+ not isExcluded ( ctypeCall ,
39+ StandardLibraryFunctionTypesPackage:: ctypeFunctionArgNotUnsignedCharOrEofQuery ( ) ) and
40+ exists ( CtypeFunction ctype , UnsignedCharType unsignedChar |
41+ ctypeCall = ctype .getACallToThisFunction ( )
42+ |
43+ /* The argument's value should be in the `unsigned char` range. */
44+ typeLowerBound ( unsignedChar ) <= lowerBound ( ctypeCall .getAnArgument ( ) .getExplicitlyConverted ( ) ) and // consider casts
45+ upperBound ( ctypeCall .getAnArgument ( ) .getExplicitlyConverted ( ) ) <= typeUpperBound ( unsignedChar )
46+ or
47+ /* The argument's value is reachable from EOF. */
48+ exists ( EOFInvocation eof | DataFlow:: localFlow ( DataFlow:: exprNode ( eof .getExpr ( ) ) , DataFlow:: exprNode ( ctypeCall .getAnArgument ( ) ) ) )
49+ )
50+ select ctypeCall , ctypeCall .getAnArgument ( )
0 commit comments