@@ -20,6 +20,8 @@ class StringSubstitutionCall extends DataFlow::CallNode {
20
20
this .getMethodName ( ) = [ "sub" , "sub!" , "gsub" , "gsub!" ] and
21
21
exists ( this .getReceiver ( ) ) and
22
22
this .getNumberOfArguments ( ) = 2
23
+ or
24
+ this .getNumberOfArguments ( ) = 1 and exists ( this .getBlock ( ) )
23
25
}
24
26
25
27
/**
@@ -45,9 +47,10 @@ class StringSubstitutionCall extends DataFlow::CallNode {
45
47
* call, if any.
46
48
*/
47
49
RE:: RegExpPatternSource getPatternRegExp ( ) {
48
- // TODO: using local flow means we miss regexps defined as constants outside
49
- // of the function scope.
50
50
result .( DataFlow:: LocalSourceNode ) .flowsTo ( this .getPatternArgument ( ) )
51
+ or
52
+ result .asExpr ( ) .getExpr ( ) =
53
+ this .getPatternArgument ( ) .asExpr ( ) .getExpr ( ) .( ConstantReadAccess ) .getValue ( )
51
54
}
52
55
53
56
/**
@@ -59,11 +62,19 @@ class StringSubstitutionCall extends DataFlow::CallNode {
59
62
}
60
63
61
64
/**
62
- * Gets the string value passed as the second (replacement) argument in this
63
- * call, if any.
65
+ * Gets the string value used to replace instances of the pattern, if any.
66
+ * This includes values passed explicitly as the second argument and values
67
+ * returned from the block, if one is given.
64
68
*/
65
69
string getReplacementString ( ) {
66
70
result = this .getReplacementArgument ( ) .asExpr ( ) .getConstantValue ( ) .getString ( )
71
+ or
72
+ exists ( DataFlow:: Node blockReturnNode , DataFlow:: LocalSourceNode stringNode |
73
+ exprNodeReturnedFrom ( blockReturnNode , this .getBlock ( ) .asExpr ( ) .getExpr ( ) )
74
+ |
75
+ stringNode .flowsTo ( blockReturnNode ) and
76
+ result = stringNode .asExpr ( ) .getConstantValue ( ) .getString ( )
77
+ )
67
78
}
68
79
69
80
/** Gets a string that is being replaced by this call. */
@@ -77,7 +88,6 @@ class StringSubstitutionCall extends DataFlow::CallNode {
77
88
predicate replaces ( string old , string new ) {
78
89
old = this .getAReplacedString ( ) and
79
90
new = this .getReplacementString ( )
80
- // TODO: handle block-variant of the call
81
91
}
82
92
}
83
93
0 commit comments