@@ -298,16 +298,18 @@ private class CookiesSameSiteProtectionSetting extends Settings::NillableStringl
298
298
299
299
// TODO: initialization hooks, e.g. before_configuration, after_initialize...
300
300
// TODO: initializers
301
- private string getErbFileIdentifier ( ErbFile erbFile ) { result = erbFile .getRelativePath ( ) }
302
-
303
301
/** A synthetic global to represent the value passed to the `locals` argument of a render call for a specific ERB file. */
304
302
private class LocalAssignsHashSyntheticGlobal extends SummaryComponent:: SyntheticGlobal {
305
303
private ErbFile erbFile ;
306
304
private string id ;
305
+ // Note that we can't use an actual `Rails::RenderCall` here due to problems with non-monotonic recursion
306
+ private MethodCall renderCall ;
307
307
308
308
LocalAssignsHashSyntheticGlobal ( ) {
309
309
this = "LocalAssignsHashSyntheticGlobal+" + id and
310
- id = getErbFileIdentifier ( erbFile )
310
+ id = erbFile .getRelativePath ( ) + "+" + renderCall .getLocation ( ) and
311
+ renderCall .getMethodName ( ) = "render" and
312
+ RenderCallUtils:: getTemplateFile ( renderCall ) = erbFile
311
313
}
312
314
313
315
/** Gets the `ErbFile` which this locals hash is accessible from. */
@@ -317,7 +319,7 @@ private class LocalAssignsHashSyntheticGlobal extends SummaryComponent::Syntheti
317
319
string getId ( ) { result = id }
318
320
319
321
/** Gets a call to render that can write to this hash. */
320
- Rails:: RenderCall getARenderCall ( ) { result . getTemplateFile ( ) = erbFile }
322
+ Rails:: RenderCall getARenderCall ( ) { result = renderCall }
321
323
}
322
324
323
325
/** A summary for `render` calls linked to some specific ERB file. */
@@ -326,7 +328,7 @@ private class RenderLocalsSummary extends SummarizedCallable {
326
328
327
329
RenderLocalsSummary ( ) { this = "rails_render_locals()" + glob .getId ( ) }
328
330
329
- override Rails:: RenderCall getACall ( ) { result . getTemplateFile ( ) = glob .getErbFile ( ) }
331
+ override Rails:: RenderCall getACall ( ) { result = glob .getARenderCall ( ) }
330
332
331
333
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
332
334
input = "Argument[locals:]" and
@@ -342,7 +344,7 @@ private class AccessLocalsSummary extends SummarizedCallable {
342
344
AccessLocalsSummary ( ) { this = "rails_local_assigns()" + glob .getId ( ) }
343
345
344
346
override MethodCall getACall ( ) {
345
- glob .getId ( ) = getErbFileIdentifier ( result .getLocation ( ) .getFile ( ) ) and
347
+ glob .getErbFile ( ) = result .getLocation ( ) .getFile ( ) and
346
348
result .getMethodName ( ) = "local_assigns"
347
349
}
348
350
0 commit comments