44 */
55
66import semmle.code.cpp.Function
7+ import semmle.code.cpp.commons.Scanf
78import semmle.code.cpp.models.interfaces.ArrayFunction
89import semmle.code.cpp.models.interfaces.Taint
910import semmle.code.cpp.models.interfaces.Alias
@@ -12,53 +13,32 @@ import semmle.code.cpp.models.interfaces.SideEffect
1213/**
1314 * The standard function `sscanf`, `fscanf` and its assorted variants
1415 */
15- private class Sscanf extends ArrayFunction , TaintFunction , AliasFunction , SideEffectFunction {
16- Sscanf ( ) {
17- this .hasGlobalOrStdName ( [
18- "sscanf" , // sscanf(src, format, args...)
19- "swscanf" , // swscanf(src, format, args...)
20- "fscanf" , // fscanf(src_stream, format, args...)
21- "fwscanf" // fwscanf(src_stream, format, args...)
22- ] ) or
23- this .hasGlobalName ( [
24- "_sscanf_l" , // _sscanf_l(src, format, locale, args...)
25- "_swscanf_l" , // _swscanf_l(src, format, locale, args...)
26- "_snscanf" , // _snscanf(src, length, format, args...)
27- "_snscanf_l" , // _snscanf_l(src, length, format, locale, args...)
28- "_snwscanf" , // _snwscanf(src, length, format, args...)
29- "_snwscanf_l" , // _snwscanf_l(src, length, format, locale, args...)
30- "_fscanf_l" , // _fscanf_l(src_stream, format, locale, args...)
31- "_fwscanf_l" // _fwscanf_l(src_stream, format, locale, args...)
32- ] )
33- }
34-
35- private predicate isSscanf ( ) { this .getName ( ) .regexpMatch ( ".*sn?w?scanf.*" ) }
16+ private class SscanfModel extends ArrayFunction , TaintFunction , AliasFunction , SideEffectFunction {
17+ SscanfModel ( ) { this instanceof Sscanf or this instanceof Fscanf or this instanceof Snscanf }
3618
3719 override predicate hasArrayWithNullTerminator ( int bufParam ) {
38- bufParam = getFormatPosition ( )
20+ bufParam = this . ( ScanfFunction ) . getFormatParameterIndex ( )
3921 or
40- isSscanf ( ) and
41- bufParam = 0
22+ bufParam = this .( Sscanf ) .getInputParameterIndex ( )
4223 }
4324
4425 override predicate hasArrayInput ( int bufParam ) { hasArrayWithNullTerminator ( bufParam ) }
4526
46- private int getLengthPosition ( ) {
47- this .getName ( ) .matches ( "\\_sn%" ) and
48- result = 1
49- }
27+ private int getLengthParameterIndex ( ) { result = this .( Snscanf ) .getInputLengthParameterIndex ( ) }
5028
51- private int getLocalePosition ( ) {
29+ private int getLocaleParameterIndex ( ) {
5230 this .getName ( ) .matches ( "%\\_l" ) and
53- ( if exists ( getLengthPosition ( ) ) then result = getLengthPosition ( ) + 2 else result = 2 )
31+ (
32+ if exists ( getLengthParameterIndex ( ) )
33+ then result = getLengthParameterIndex ( ) + 2
34+ else result = 2
35+ )
5436 }
5537
56- private int getFormatPosition ( ) { if exists ( getLengthPosition ( ) ) then result = 2 else result = 1 }
57-
5838 private int getArgsStartPosition ( ) {
5939 exists ( int nLength , int nLocale |
60- ( if exists ( getLocalePosition ( ) ) then nLocale = 1 else nLocale = 0 ) and
61- ( if exists ( getLengthPosition ( ) ) then nLength = 1 else nLength = 0 ) and
40+ ( if exists ( getLocaleParameterIndex ( ) ) then nLocale = 1 else nLocale = 0 ) and
41+ ( if exists ( getLengthParameterIndex ( ) ) then nLength = 1 else nLength = 0 ) and
6242 result = 2 + nLocale + nLength
6343 )
6444 }
@@ -88,6 +68,10 @@ private class Sscanf extends ArrayFunction, TaintFunction, AliasFunction, SideEf
8868
8969 override predicate hasSpecificReadSideEffect ( ParameterIndex i , boolean buffer ) {
9070 buffer = true and
91- i = [ 0 , getFormatPosition ( ) , getLocalePosition ( ) ]
71+ i =
72+ [
73+ this .( ScanfFunction ) .getFormatParameterIndex ( ) ,
74+ this .( ScanfFunction ) .getFormatParameterIndex ( ) , getLocaleParameterIndex ( )
75+ ]
9276 }
9377}
0 commit comments