Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lib/erb_lint/linters/allowed_script_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ class ConfigSchema < LinterConfig
def run(processed_source)
parser = processed_source.parser
parser.nodes_with_type(:tag).each do |tag_node|
# Fast path: check tag name from AST node directly before creating Tag object
tag_name_node = tag_node.to_a[1]
next unless tag_name_node&.loc&.source == "script"

tag = BetterHtml::Tree::Tag.from_node(tag_node)
next if tag.closing?
next unless tag.name == "script"

if @config.disallow_inline_scripts?
name_node = tag_node.to_a[1]
Expand Down
3 changes: 3 additions & 0 deletions lib/erb_lint/linters/no_javascript_tag_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ def run(processed_source)

source = code_node.loc.source

# Fast path: skip expensive parsing if source can't contain the target method
next unless source.include?("javascript_tag")

ruby_node =
begin
BetterHtml::TestHelper::RubyNode.parse(source)
Expand Down
10 changes: 10 additions & 0 deletions lib/erb_lint/linters/require_input_autocomplete.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ def run(processed_source)

def find_html_input_tags(parser)
parser.nodes_with_type(:tag).each do |tag_node|
# Fast path: check tag name from AST node directly before creating Tag object
tag_name_node = tag_node.to_a[1]
next unless tag_name_node&.loc&.source == "input"

tag = BetterHtml::Tree::Tag.from_node(tag_node)

autocomplete_attribute = tag.attributes["autocomplete"]
Expand Down Expand Up @@ -82,10 +86,16 @@ def html_type_requires_autocomplete_attribute?(type_attribute)
type_present && HTML_INPUT_TYPES_REQUIRING_AUTOCOMPLETE.include?(type_attribute.value)
end

FORM_HELPER_NAMES_PATTERN = Regexp.union(FORM_HELPERS_REQUIRING_AUTOCOMPLETE.map(&:to_s)).freeze

def find_rails_helper_input_tags(parser)
parser.ast.descendants(:erb).each do |erb_node|
indicator_node, _, code_node, _ = *erb_node
source = code_node.loc.source

# Fast path: skip expensive parsing if source can't contain any form helper name
next unless source.match?(FORM_HELPER_NAMES_PATTERN)

ruby_node = extract_ruby_node(source)
send_node = ruby_node&.descendants(:send)&.first

Expand Down
10 changes: 10 additions & 0 deletions lib/erb_lint/linters/require_script_nonce.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ def run(processed_source)

def find_html_script_tags(parser)
parser.nodes_with_type(:tag).each do |tag_node|
# Fast path: check tag name from AST node directly before creating Tag object
tag_name_node = tag_node.to_a[1]
next unless tag_name_node&.loc&.source == "script"

tag = BetterHtml::Tree::Tag.from_node(tag_node)
nonce_attribute = tag.attributes["nonce"]

Expand Down Expand Up @@ -52,10 +56,16 @@ def html_javascript_type_attribute?(tag)
type_attribute.value_node.to_a[1] != "application/javascript"
end

TAG_HELPER_PATTERN = /javascript_tag|javascript_include_tag|javascript_pack_tag/

def find_rails_helper_script_tags(parser)
parser.ast.descendants(:erb).each do |erb_node|
indicator_node, _, code_node, _ = *erb_node
source = code_node.loc.source

# Fast path: skip expensive parsing if source can't contain any tag helper name
next unless source.match?(TAG_HELPER_PATTERN)

ruby_node = extract_ruby_node(source)
send_node = ruby_node&.descendants(:send)&.first

Expand Down
Loading