Skip to content

Commit

Permalink
Fixes parsing of ERB comments without a space
Browse files Browse the repository at this point in the history
The ERB parser we're using misparses comments of the form:

    <%# ... #>

(no space between % and #)

With a space the AST is:

    s(:erb, nil, nil,
      s(:code, " # this should not fail: ' "), nil)

Without a space the AST is:

    s(:erb,
      s(:indicator, "#"), nil,
      s(:code, " this should not fail: ' "), nil)

The latter AST causes a crash when parsing the `:code` node as Ruby.

Works around the issue by transforming the latter AST to the former.

Fixes #429
  • Loading branch information
glebm committed Mar 25, 2022
1 parent 6a2e995 commit ef007fb
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
32 changes: 32 additions & 0 deletions lib/i18n/tasks/scanners/erb_ast_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ def on_code(node)
node
end

# @param node [::Parser::AST::Node]
# @return [::Parser::AST::Node]
def handler_missing(node)
node = transform_misparsed_comment(node)
node.updated(
nil,
node.children.map { |child| node?(child) ? process(child) : child }
Expand All @@ -44,6 +47,35 @@ def handler_missing(node)

private

# Works around incorrect handling of comments of the form:
# <%# ... #>
# (no space between % and #)
#
# With a space the AST is:
#
# s(:erb, nil, nil,
# s(:code, " # this should not fail: ' "), nil)
#
# Without a space the AST is:
#
# s(:erb,
# s(:indicator, "#"), nil,
# s(:code, " this should not fail: ' "), nil)
# @param node [::Parser::AST::Node]
# @return [::Parser::AST::Node]
def transform_misparsed_comment(node)
return node unless node.type == :erb && node.children.size == 4 &&
node.children[0]&.type == :indicator && node.children[0].children[0] == "#" &&
node.children[1].nil? &&
node.children[2]&.type == :code &&
node.children[3].nil?
code_node = node.children[2]
node.updated(
nil,
[nil, nil, code_node.updated(nil, ["##{code_node.children[0]}"]), nil]
)
end

def node?(node)
node.is_a?(::Parser::AST::Node)
end
Expand Down
2 changes: 2 additions & 0 deletions spec/fixtures/used_keys/app/views/application/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ I18n.t("this_should_not")
<%= render Blacklight::Document::CitationComponent.with_collection(@documents) if @documents.present? %>
<% end %>

<%# this should not fail: ' %>
</h3>

0 comments on commit ef007fb

Please sign in to comment.