@@ -168,7 +168,13 @@ class InvokeNode extends DataFlow::SourceNode {
168168 private ObjectLiteralNode getOptionsArgument ( int i ) { result .flowsTo ( getArgument ( i ) ) }
169169
170170 /** Gets an abstract value representing possible callees of this call site. */
171- final AbstractValue getACalleeValue ( ) { result = getCalleeNode ( ) .analyze ( ) .getAValue ( ) }
171+ final AbstractValue getACalleeValue ( ) {
172+ exists ( DataFlow:: Node callee , DataFlow:: AnalyzedNode analyzed |
173+ pragma [ only_bind_into ] ( callee ) = getCalleeNode ( ) and
174+ pragma [ only_bind_into ] ( analyzed ) = callee .analyze ( ) and
175+ pragma [ only_bind_into ] ( result ) = analyzed .getAValue ( )
176+ )
177+ }
172178
173179 /**
174180 * Gets a potential callee of this call site.
@@ -1166,6 +1172,16 @@ module ClassNode {
11661172 result .getFile ( ) = f
11671173 }
11681174
1175+ /**
1176+ * Gets a reference to the function `func`, where there exists a read/write of the "prototype" property on that reference.
1177+ */
1178+ pragma [ noinline]
1179+ private DataFlow:: SourceNode getAFunctionValueWithPrototype ( AbstractValue func ) {
1180+ exists ( result .getAPropertyReference ( "prototype" ) ) and
1181+ result .analyze ( ) .getAValue ( ) = pragma [ only_bind_into ] ( func ) and
1182+ func instanceof AbstractFunction // the join-order goes bad if `func` has type `AbstractFunction`.
1183+ }
1184+
11691185 /**
11701186 * A function definition with prototype manipulation as a `ClassNode` instance.
11711187 */
@@ -1176,10 +1192,7 @@ module ClassNode {
11761192 FunctionStyleClass ( ) {
11771193 function .getFunction ( ) = astNode and
11781194 (
1179- exists ( DataFlow:: PropRef read |
1180- read .getPropertyName ( ) = "prototype" and
1181- read .getBase ( ) .analyze ( ) .getAValue ( ) = function
1182- )
1195+ exists ( getAFunctionValueWithPrototype ( function ) )
11831196 or
11841197 exists ( string name |
11851198 this = AccessPath:: getAnAssignmentTo ( name ) and
@@ -1240,7 +1253,7 @@ module ClassNode {
12401253 * Gets a reference to the prototype of this class.
12411254 */
12421255 DataFlow:: SourceNode getAPrototypeReference ( ) {
1243- exists ( DataFlow:: SourceNode base | base . analyze ( ) . getAValue ( ) = function |
1256+ exists ( DataFlow:: SourceNode base | base = getAFunctionValueWithPrototype ( function ) |
12441257 result = base .getAPropertyRead ( "prototype" )
12451258 or
12461259 result = base .getAPropertySource ( "prototype" )
0 commit comments