@@ -229,9 +229,16 @@ private module Propagation {
229229 }
230230
231231 pragma [ nomagic]
232- string getNonSymbolValue ( ) {
232+ string getStringValue ( ) {
233233 result = this .getValue ( ) and
234- not this .getExpr ( ) instanceof SymbolLiteral
234+ not this .getExpr ( ) instanceof SymbolLiteral and
235+ not this .getExpr ( ) instanceof RegExpLiteral
236+ }
237+
238+ pragma [ nomagic]
239+ string getRegExpValue ( string flags ) {
240+ result = this .getValue ( ) and
241+ flags = this .getExpr ( ) .( RegExpLiteral ) .getFlagString ( )
235242 }
236243 }
237244
@@ -251,7 +258,7 @@ private module Propagation {
251258 s = left + right
252259 )
253260 or
254- s = e .( StringlikeLiteralWithInterpolationCfgNode ) .getNonSymbolValue ( )
261+ s = e .( StringlikeLiteralWithInterpolationCfgNode ) .getStringValue ( )
255262 or
256263 // If last statement in the interpolation is a constant or local variable read,
257264 // we attempt to look up its string value.
@@ -267,13 +274,15 @@ private module Propagation {
267274 exists ( ExprCfgNode last | last = e .( RegExpInterpolationComponentCfgNode ) .getLastStmt ( ) |
268275 isInt ( last , any ( int i | s = i .toString ( ) ) ) or
269276 isFloat ( last , any ( float f | s = f .toString ( ) ) ) or
270- isString ( last , s )
277+ isString ( last , s ) or
278+ isRegExp ( last , s , _) // Note: we lose the flags for interpolated regexps here.
271279 )
272280 }
273281
274282 private predicate isStringExprNoCfg ( Expr e , string s ) {
275283 s = e .( StringlikeLiteralImpl ) .getStringValue ( ) and
276- not e instanceof SymbolLiteral
284+ not e instanceof SymbolLiteral and
285+ not e instanceof RegExpLiteral
277286 or
278287 s = e .( EncodingLiteralImpl ) .getValue ( )
279288 or
@@ -319,6 +328,31 @@ private module Propagation {
319328 forex ( ExprCfgNode n | n = e .getAControlFlowNode ( ) | isSymbol ( n , s ) )
320329 }
321330
331+ predicate isRegExp ( ExprCfgNode e , string s , string flags ) {
332+ isRegExpExprNoCfg ( e .getExpr ( ) , s , flags )
333+ or
334+ isRegExpExpr ( e .getExpr ( ) .( ConstantReadAccess ) .getValue ( ) , s , flags )
335+ or
336+ isRegExp ( getSource ( e ) , s , flags )
337+ or
338+ s = e .( StringlikeLiteralWithInterpolationCfgNode ) .getRegExpValue ( flags )
339+ }
340+
341+ private predicate isRegExpExprNoCfg ( Expr e , string s , string flags ) {
342+ s = e .( StringlikeLiteralImpl ) .getStringValue ( ) and
343+ e .( RegExpLiteral ) .getFlagString ( ) = flags
344+ or
345+ isRegExpExprNoCfg ( e .( ConstantReadAccess ) .getValue ( ) , s , flags )
346+ }
347+
348+ predicate isRegExpExpr ( Expr e , string s , string flags ) {
349+ isRegExpExprNoCfg ( e , s , flags )
350+ or
351+ isRegExpExpr ( e .( ConstantReadAccess ) .getValue ( ) , s , flags )
352+ or
353+ forex ( ExprCfgNode n | n = e .getAControlFlowNode ( ) | isRegExp ( n , s , flags ) )
354+ }
355+
322356 predicate isBoolean ( ExprCfgNode e , boolean b ) {
323357 isBooleanExprNoCfg ( e .getExpr ( ) , b )
324358 or
@@ -388,9 +422,18 @@ private module Cached {
388422 s = any ( StringComponentImpl c ) .getValue ( )
389423 } or
390424 TSymbol ( string s ) { isString ( _, s ) or isSymbolExpr ( _, s ) } or
425+ TRegExp ( string s , string flags ) {
426+ isRegExp ( _, s , flags )
427+ or
428+ isRegExpExpr ( _, s , flags )
429+ or
430+ s = any ( StringComponentImpl c ) .getValue ( ) and flags = ""
431+ } or
391432 TBoolean ( boolean b ) { b in [ false , true ] } or
392433 TNil ( )
393434
435+ class TStringlike = TString or TSymbol or TRegExp ;
436+
394437 cached
395438 ConstantValue getConstantValue ( ExprCfgNode n ) {
396439 result .isInt ( any ( int i | isInt ( n , i ) ) )
@@ -411,6 +454,8 @@ private module Cached {
411454 or
412455 result .isSymbol ( any ( string s | isSymbol ( n , s ) ) )
413456 or
457+ exists ( string s , string flags | isRegExp ( n , s , flags ) and result = TRegExp ( s , flags ) )
458+ or
414459 result .isBoolean ( any ( boolean b | isBoolean ( n , b ) ) )
415460 or
416461 result .isNil ( ) and
@@ -437,6 +482,8 @@ private module Cached {
437482 or
438483 result .isSymbol ( any ( string s | isSymbolExpr ( e , s ) ) )
439484 or
485+ exists ( string s , string flags | isRegExpExpr ( e , s , flags ) and result = TRegExp ( s , flags ) )
486+ or
440487 result .isBoolean ( any ( boolean b | isBooleanExpr ( e , b ) ) )
441488 or
442489 result .isNil ( ) and
0 commit comments