@@ -214,43 +214,28 @@ module Closure {
214214 )
215215 }
216216
217+ /**
218+ * Holds if a prefix of `name` is a closure namespace.
219+ */
220+ bindingset [ name]
221+ private predicate hasClosureNamespacePrefix ( string name ) {
222+ isClosureNamespace ( name .substring ( 0 , name .indexOf ( "." ) ) )
223+ }
224+
217225 /**
218226 * Gets the closure namespace path addressed by the given data flow node, if any.
219227 */
220228 string getClosureNamespaceFromSourceNode ( DataFlow:: SourceNode node ) {
221- isClosureNamespace ( result ) and
222- node = DataFlow:: globalVarRef ( result )
223- or
224- exists ( DataFlow:: SourceNode base , string basePath , string prop |
225- basePath = getClosureNamespaceFromSourceNode ( base ) and
226- node = base .getAPropertyRead ( prop ) and
227- result = basePath + "." + prop and
228- // ensure finiteness
229- (
230- isClosureNamespace ( basePath )
231- or
232- // direct access, no indirection
233- node .( DataFlow:: PropRead ) .getBase ( ) = base
234- )
235- )
236- or
237- // Associate an access path with the immediate RHS of a store on a closure namespace.
238- // This is to support patterns like:
239- // foo.bar = { baz() {} }
240- exists ( DataFlow:: PropWrite write |
241- node = write .getRhs ( ) and
242- result = getWrittenClosureNamespace ( write )
243- )
244- or
245- result = node .( ClosureNamespaceAccess ) .getClosureNamespace ( )
229+ result = GlobalAccessPath:: getAccessPath ( node ) and
230+ hasClosureNamespacePrefix ( result )
246231 }
247232
248233 /**
249234 * Gets the closure namespace path written to by the given property write, if any.
250235 */
251236 string getWrittenClosureNamespace ( DataFlow:: PropWrite node ) {
252- result = getClosureNamespaceFromSourceNode ( node .getBase ( ) . getALocalSource ( ) ) + "." +
253- node . getPropertyName ( )
237+ result = GlobalAccessPath :: fromRhs ( node .getRhs ( ) ) and
238+ hasClosureNamespacePrefix ( result )
254239 }
255240
256241 /**
0 commit comments