Skip to content

Commit c986ea1

Browse files
committed
Ruby: scope local_assigns synthetic globals to both render call and template file
1 parent 14c8962 commit c986ea1

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

ruby/ql/lib/codeql/ruby/frameworks/Rails.qll

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -298,16 +298,18 @@ private class CookiesSameSiteProtectionSetting extends Settings::NillableStringl
298298

299299
// TODO: initialization hooks, e.g. before_configuration, after_initialize...
300300
// TODO: initializers
301-
private string getErbFileIdentifier(ErbFile erbFile) { result = erbFile.getRelativePath() }
302-
303301
/** A synthetic global to represent the value passed to the `locals` argument of a render call for a specific ERB file. */
304302
private class LocalAssignsHashSyntheticGlobal extends SummaryComponent::SyntheticGlobal {
305303
private ErbFile erbFile;
306304
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;
307307

308308
LocalAssignsHashSyntheticGlobal() {
309309
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
311313
}
312314

313315
/** Gets the `ErbFile` which this locals hash is accessible from. */
@@ -317,7 +319,7 @@ private class LocalAssignsHashSyntheticGlobal extends SummaryComponent::Syntheti
317319
string getId() { result = id }
318320

319321
/** Gets a call to render that can write to this hash. */
320-
Rails::RenderCall getARenderCall() { result.getTemplateFile() = erbFile }
322+
Rails::RenderCall getARenderCall() { result = renderCall }
321323
}
322324

323325
/** A summary for `render` calls linked to some specific ERB file. */
@@ -326,7 +328,7 @@ private class RenderLocalsSummary extends SummarizedCallable {
326328

327329
RenderLocalsSummary() { this = "rails_render_locals()" + glob.getId() }
328330

329-
override Rails::RenderCall getACall() { result.getTemplateFile() = glob.getErbFile() }
331+
override Rails::RenderCall getACall() { result = glob.getARenderCall() }
330332

331333
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
332334
input = "Argument[locals:]" and
@@ -342,7 +344,7 @@ private class AccessLocalsSummary extends SummarizedCallable {
342344
AccessLocalsSummary() { this = "rails_local_assigns()" + glob.getId() }
343345

344346
override MethodCall getACall() {
345-
glob.getId() = getErbFileIdentifier(result.getLocation().getFile()) and
347+
glob.getErbFile() = result.getLocation().getFile() and
346348
result.getMethodName() = "local_assigns"
347349
}
348350

0 commit comments

Comments
 (0)