@@ -22,7 +22,8 @@ private class NokogiriXmlParserCall extends XmlParserCall::Range, DataFlow::Call
22
22
override DataFlow:: Node getInput ( ) { result = this .getArgument ( 0 ) }
23
23
24
24
override predicate externalEntitiesEnabled ( ) {
25
- this .getArgument ( 3 ) = trackNoEnt ( )
25
+ this .getArgument ( 3 ) =
26
+ [ trackEnableFeature ( TNOENT ( ) ) , trackEnableFeature ( TDTDLOAD ( ) ) , trackDisableFeature ( TNONET ( ) ) ]
26
27
or
27
28
this .asExpr ( )
28
29
.getExpr ( )
@@ -31,7 +32,7 @@ private class NokogiriXmlParserCall extends XmlParserCall::Range, DataFlow::Call
31
32
.getAStmt ( )
32
33
.getAChild * ( )
33
34
.( MethodCall )
34
- .getMethodName ( ) = "noent"
35
+ .getMethodName ( ) = [ "noent" , "nononet" ]
35
36
}
36
37
}
37
38
@@ -49,41 +50,95 @@ private class LibXmlRubyXmlParserCall extends XmlParserCall::Range, DataFlow::Ca
49
50
exists ( Pair pair |
50
51
pair = this .getArgument ( 1 ) .asExpr ( ) .getExpr ( ) .( HashLiteral ) .getAKeyValuePair ( ) and
51
52
pair .getKey ( ) .( Literal ) .getValueText ( ) = "options" and
52
- trackNoEnt ( ) .asExpr ( ) .getExpr ( ) = pair .getValue ( )
53
+ pair .getValue ( ) =
54
+ [
55
+ trackEnableFeature ( TNOENT ( ) ) , trackEnableFeature ( TDTDLOAD ( ) ) ,
56
+ trackDisableFeature ( TNONET ( ) )
57
+ ] .asExpr ( ) .getExpr ( )
53
58
)
54
59
}
55
60
}
56
61
57
- private DataFlow:: LocalSourceNode trackNoEnt ( TypeTracker t ) {
62
+ private newtype TFeature =
63
+ TNOENT ( ) or
64
+ TNONET ( ) or
65
+ TDTDLOAD ( )
66
+
67
+ class Feature extends TFeature {
68
+ abstract int getValue ( ) ;
69
+
70
+ string toString ( ) { result = getConstantName ( ) }
71
+
72
+ abstract string getConstantName ( ) ;
73
+ }
74
+
75
+ private class FeatureNOENT extends Feature , TNOENT {
76
+ override int getValue ( ) { result = 2 }
77
+
78
+ override string getConstantName ( ) { result = "NOENT" }
79
+ }
80
+
81
+ private class FeatureNONET extends Feature , TNONET {
82
+ override int getValue ( ) { result = 2048 }
83
+
84
+ override string getConstantName ( ) { result = "NONET" }
85
+ }
86
+
87
+ private class FeatureDTDLOAD extends Feature , TDTDLOAD {
88
+ override int getValue ( ) { result = 4 }
89
+
90
+ override string getConstantName ( ) { result = "DTDLOAD" }
91
+ }
92
+
93
+ private DataFlow:: LocalSourceNode trackFeature ( Feature f , boolean enable , TypeTracker t ) {
58
94
t .start ( ) and
59
95
(
60
- result .asExpr ( ) .getExpr ( ) .( IntegerLiteral ) .getValue ( ) .bitAnd ( 2 ) = 2
96
+ result .asExpr ( ) .getExpr ( ) .( IntegerLiteral ) .getValue ( ) .bitAnd ( f .getValue ( ) ) = f .getValue ( ) and
97
+ enable = true
61
98
or
99
+ enable = true and
62
100
result =
63
101
API:: getTopLevelMember ( "Nokogiri" )
64
102
.getMember ( "XML" )
65
103
.getMember ( "ParseOptions" )
66
- .getMember ( "NOENT" )
104
+ .getMember ( f . getConstantName ( ) )
67
105
.getAUse ( )
68
106
or
107
+ enable = true and
69
108
result =
70
109
[ API:: getTopLevelMember ( "LibXML" ) .getMember ( "XML" ) , API:: getTopLevelMember ( "XML" ) ]
71
110
.getMember ( "Options" )
72
- .getMember ( "NOENT" )
111
+ .getMember ( f . getConstantName ( ) )
73
112
.getAUse ( )
74
113
or
75
- result .asExpr ( ) .getExpr ( ) instanceof BitwiseOrExpr and
76
- result .asExpr ( ) .( CfgNodes:: ExprNodes:: OperationCfgNode ) .getAnOperand ( ) = trackNoEnt ( ) .asExpr ( )
114
+ (
115
+ result .asExpr ( ) .getExpr ( ) instanceof BitwiseOrExpr or
116
+ result .asExpr ( ) .getExpr ( ) instanceof AssignBitwiseOrExpr or
117
+ result .asExpr ( ) .getExpr ( ) instanceof BitwiseAndExpr or
118
+ result .asExpr ( ) .getExpr ( ) instanceof AssignBitwiseAndExpr
119
+ ) and
120
+ result .asExpr ( ) .( CfgNodes:: ExprNodes:: OperationCfgNode ) .getAnOperand ( ) =
121
+ trackFeature ( f , enable ) .asExpr ( )
122
+ or
123
+ result .asExpr ( ) .getExpr ( ) instanceof ComplementExpr and
124
+ result .asExpr ( ) .( CfgNodes:: ExprNodes:: OperationCfgNode ) .getAnOperand ( ) =
125
+ trackFeature ( f , enable .booleanNot ( ) ) .asExpr ( )
77
126
or
78
127
result =
79
128
API:: getTopLevelMember ( "Nokogiri" )
80
129
.getMember ( "XML" )
81
130
.getMember ( "ParseOptions" )
82
131
.getAnInstantiation ( ) and
83
- result .asExpr ( ) .( CfgNodes:: ExprNodes:: CallCfgNode ) .getArgument ( 0 ) = trackNoEnt ( ) .asExpr ( )
132
+ result .asExpr ( ) .( CfgNodes:: ExprNodes:: CallCfgNode ) .getArgument ( 0 ) =
133
+ trackFeature ( f , enable ) .asExpr ( )
84
134
or
85
135
exists ( CfgNodes:: ExprNodes:: CallCfgNode call |
86
- call .getExpr ( ) .( MethodCall ) .getMethodName ( ) = "noent" and
136
+ enable = true and
137
+ call .getExpr ( ) .( MethodCall ) .getMethodName ( ) = f .getConstantName ( ) .toLowerCase ( )
138
+ or
139
+ enable = false and
140
+ call .getExpr ( ) .( MethodCall ) .getMethodName ( ) = "no" + f .getConstantName ( ) .toLowerCase ( )
141
+ |
87
142
(
88
143
result .asExpr ( ) = call
89
144
or
@@ -92,12 +147,18 @@ private DataFlow::LocalSourceNode trackNoEnt(TypeTracker t) {
92
147
)
93
148
or
94
149
exists ( CfgNodes:: ExprNodes:: CallCfgNode call |
95
- trackNoEnt ( ) .asExpr ( ) = call .getReceiver ( ) and
150
+ trackFeature ( f , enable ) .asExpr ( ) = call .getReceiver ( ) and
96
151
result .asExpr ( ) = call
97
152
)
98
153
)
99
154
or
100
- exists ( TypeTracker t2 | result = trackNoEnt ( t2 ) .track ( t2 , t ) )
155
+ exists ( TypeTracker t2 | result = trackFeature ( f , enable , t2 ) .track ( t2 , t ) )
156
+ }
157
+
158
+ private DataFlow:: Node trackFeature ( Feature f , boolean enable ) {
159
+ trackFeature ( f , enable , TypeTracker:: end ( ) ) .flowsTo ( result )
101
160
}
102
161
103
- private DataFlow:: Node trackNoEnt ( ) { trackNoEnt ( TypeTracker:: end ( ) ) .flowsTo ( result ) }
162
+ private DataFlow:: Node trackEnableFeature ( Feature f ) { result = trackFeature ( f , true ) }
163
+
164
+ private DataFlow:: Node trackDisableFeature ( Feature f ) { result = trackFeature ( f , false ) }
0 commit comments