Skip to content

Commit

Permalink
Fix infinite loop computing ERB dependencies with non-trailing interp…
Browse files Browse the repository at this point in the history
…olations

Calling
```ruby
ActionView::DependencyTracker::ERBTracker#add_static_dependency( []  "test/\#{bucket.bucketable_name.pluralize}/status/show" "\"")
```
Will loop indefinitely. Fixes it by parsing only template strings with a trailing template interpolation.

Co-authored-by: Hartley McGuire @skipkayhil
  • Loading branch information
intrip committed Sep 19, 2024
1 parent dfd1e95 commit 773d640
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 15 deletions.
33 changes: 18 additions & 15 deletions actionview/lib/action_view/dependency_tracker/erb_tracker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,23 +122,26 @@ def add_static_dependency(dependencies, dependency, quote_type)
wildcard_dependency = +""

while !scanner.eos?
next unless scanner.scan_until(/\#{/)

unmatched_brackets = 1
wildcard_dependency << scanner.pre_match

while unmatched_brackets > 0 && !scanner.eos?
scanner.scan_until(/[{}]/)

case scanner.matched
when "{"
unmatched_brackets += 1
when "}"
unmatched_brackets -= 1
if scanner.scan_until(/\#{/)
unmatched_brackets = 1
wildcard_dependency << scanner.pre_match

while unmatched_brackets > 0 && !scanner.eos?
scanner.scan_until(/[{}]/)

case scanner.matched
when "{"
unmatched_brackets += 1
when "}"
unmatched_brackets -= 1
end
end
end

wildcard_dependency << "*"
wildcard_dependency << "*"
else
wildcard_dependency << scanner.rest
scanner.terminate
end
end

dependencies << wildcard_dependency
Expand Down
12 changes: 12 additions & 0 deletions actionview/test/template/dependency_tracker_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,18 @@ def test_dependencies_with_interpolation_are_resolved_with_view_paths

assert_equal ["events/_completed", "events/_event", "events/index"], tracker.dependencies
end

def test_dependencies_with_interpolation_non_trailing
view_paths = ActionView::PathSet.new([File.expand_path("../fixtures/digestor", __dir__)])

template = FakeTemplate.new(%q{
<%= render "#{type}/comments" %>
}, :erb)

tracker = make_tracker("interpolation/_string", template, view_paths)

assert_equal [ "*/comments" ], tracker.dependencies
end
end

class ERBTrackerTest < ActiveSupport::TestCase
Expand Down

0 comments on commit 773d640

Please sign in to comment.