@@ -230,6 +230,8 @@ class UrlsplitUrlparseTempSanitizer extends Sanitizer {
230230 private predicate clears_taint ( ControlFlowNode final_test , ControlFlowNode tainted , ControlFlowNode test , boolean sense ) {
231231 test_equality_with_const ( final_test , tainted , sense )
232232 or
233+ test_in_const_seq ( final_test , tainted , sense )
234+ or
233235 test .( UnaryExprNode ) .getNode ( ) .getOp ( ) instanceof Not and
234236 exists ( ControlFlowNode nested_test |
235237 nested_test = test .( UnaryExprNode ) .getOperand ( ) and
@@ -238,19 +240,34 @@ class UrlsplitUrlparseTempSanitizer extends Sanitizer {
238240 }
239241
240242 /** holds for `== "KNOWN_VALUE"` on `true` edge, and `!= "KNOWN_VALUE"` on `false` edge */
241- private predicate test_equality_with_const ( CompareNode cmp , ControlFlowNode operand , boolean sense ) {
243+ private predicate test_equality_with_const ( CompareNode cmp , ControlFlowNode tainted , boolean sense ) {
242244 exists ( ControlFlowNode const , Cmpop op |
243245 const .getNode ( ) instanceof StrConst
244246 |
245247 (
246- cmp .operands ( const , op , operand )
248+ cmp .operands ( const , op , tainted )
247249 or
248- cmp .operands ( operand , op , const )
249- ) and (
250+ cmp .operands ( tainted , op , const )
251+ ) and
252+ (
250253 op instanceof Eq and sense = true
251254 or
252255 op instanceof NotEq and sense = false
253256 )
254257 )
255258 }
259+
260+ /** holds for `in ["KNOWN_VALUE", ...]` on `true` edge, and `not in ["KNOWN_VALUE", ...]` on `false` edge */
261+ private predicate test_in_const_seq ( CompareNode cmp , ControlFlowNode tainted , boolean sense ) {
262+ exists ( SequenceNode const_seq , Cmpop op |
263+ forall ( ControlFlowNode elem | elem = const_seq .getAnElement ( ) | elem .getNode ( ) instanceof StrConst )
264+ |
265+ cmp .operands ( tainted , op , const_seq ) and
266+ (
267+ op instanceof In and sense = true
268+ or
269+ op instanceof NotIn and sense = false
270+ )
271+ )
272+ }
256273}
0 commit comments