@@ -1990,16 +1990,22 @@ class FieldOrProperty extends Assignable, Modifiable {
19901990 }
19911991}
19921992
1993- /** A string that is a reference to a late-bound target of a dynamic member access . */
1993+ /** A member name used by a dynamic access or a property pattern without type information . */
19941994class DynamicProperty extends string {
1995- private DynamicMemberAccess dma ;
1996-
1997- DynamicProperty ( ) { this = dma .getLateBoundTargetName ( ) }
1995+ DynamicProperty ( ) {
1996+ this = any ( DynamicMemberAccess dma ) .getLateBoundTargetName ( )
1997+ or
1998+ exists ( PatternExpr qualifier , LabeledPatternExpr label |
1999+ propertyPatternQualifier ( qualifier , label ) and
2000+ qualifier .getType ( ) instanceof NullType and
2001+ this = label .getLabel ( )
2002+ )
2003+ }
19982004
19992005 ContentSet getContentSet ( ) { result .isDynamicProperty ( this ) }
20002006
20012007 /** Gets an access of this dynamic property. */
2002- DynamicMemberAccess getAnAccess ( ) { result = dma }
2008+ DynamicMemberAccess getAnAccess ( ) { result . getLateBoundTargetName ( ) = this }
20032009}
20042010
20052011private class InstanceFieldOrProperty extends FieldOrProperty {
@@ -2308,6 +2314,40 @@ private predicate readStepDelegateCall(Node node1, ContentSet c, OutNode node2)
23082314 )
23092315}
23102316
2317+ private predicate propertyPatternQualifier ( PatternExpr qualifier , LabeledPatternExpr label ) {
2318+ qualifier .( RecursivePatternExpr ) .getPropertyPatterns ( ) .getPattern ( _) = label
2319+ or
2320+ qualifier instanceof LabeledPatternExpr and
2321+ qualifier .( PropertyPatternExpr ) .getPattern ( _) = label
2322+ }
2323+
2324+ /**
2325+ * Holds if data can flow from `node1` to `node2` via a property pattern.
2326+ */
2327+ private predicate fieldOrPropertyPatternRead ( Node node1 , ContentSet c , Node node2 ) {
2328+ exists ( PatternExpr pattern , LabeledPatternExpr label |
2329+ node1 .asExpr ( ) = pattern and
2330+ propertyPatternQualifier ( pattern , label ) and
2331+ if pattern .getType ( ) instanceof NullType
2332+ then c .isDynamicProperty ( label .getLabel ( ) )
2333+ else
2334+ exists ( FieldOrProperty f |
2335+ c = f .getContentSet ( ) and
2336+ f .getName ( ) = label .getLabel ( ) and
2337+ pattern .getType ( ) .( ValueOrRefType ) .hasMember ( f )
2338+ )
2339+ |
2340+ node2 .asExpr ( ) = label .( RecursivePatternExpr )
2341+ or
2342+ node2 .asExpr ( ) = label .( PropertyPatternExpr )
2343+ or
2344+ exists ( AssignableDefinitions:: PatternDefinition lvd |
2345+ node2 .( AssignableDefinitionNode ) .getDefinition ( ) = lvd and
2346+ label .( BindingPatternExpr ) .getVariableDeclExpr ( ) = lvd .getDeclaration ( )
2347+ )
2348+ )
2349+ }
2350+
23112351/**
23122352 * Holds if data can flow from `node1` to `node2` via a read of content `c`.
23132353 */
@@ -2319,6 +2359,8 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
23192359 or
23202360 fieldOrPropertyRead ( node1 .asExpr ( ) , c , node2 .asExpr ( ) )
23212361 or
2362+ fieldOrPropertyPatternRead ( node1 , c , node2 )
2363+ or
23222364 dynamicPropertyRead ( node1 .asExpr ( ) , c , node2 .asExpr ( ) )
23232365 or
23242366 node2 .asExpr ( ) .( AwaitExpr ) .getExpr ( ) = node1 .asExpr ( ) and
0 commit comments