Skip to content

Commit

Permalink
Match company style guide
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelfranca committed Mar 14, 2024
1 parent e1a14db commit 4a1cbc0
Show file tree
Hide file tree
Showing 25 changed files with 830 additions and 483 deletions.
2 changes: 1 addition & 1 deletion lib/better_html/better_erb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def generate(template, source)

generator = klass.new(
erb,
**options
**options,
)
generator.validate! if generator.respond_to?(:validate!)
generator.src
Expand Down
4 changes: 2 additions & 2 deletions lib/better_html/better_erb/runtime_checks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def check_tag_name(type, start, stop, line, column)
return if text.upcase == "!DOCTYPE"
return if @config.partial_tag_name_pattern.match?(text)

s = +"Invalid tag name #{text.inspect} does not match "\
s = +"Invalid tag name #{text.inspect} does not match " \
"regular expression #{@config.partial_tag_name_pattern.inspect}\n"
s << build_location(line, column, text.size)
raise BetterHtml::HtmlError, s
Expand All @@ -129,7 +129,7 @@ def check_attribute_name(type, start, stop, line, column)
text = @parser.document[start...stop]
return if @config.partial_attribute_name_pattern.match?(text)

s = +"Invalid attribute name #{text.inspect} does not match "\
s = +"Invalid attribute name #{text.inspect} does not match " \
"regular expression #{@config.partial_attribute_name_pattern.inspect}\n"
s << build_location(line, column, text.size)
raise BetterHtml::HtmlError, s
Expand Down
34 changes: 17 additions & 17 deletions lib/better_html/better_erb/validated_output_buffer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,23 @@ def safe_quoted_value_append=(value)
value = properly_escaped(value)

if value.include?(@context[:quote_character])
raise UnsafeHtmlError, "Detected invalid characters as part of the interpolation "\
raise UnsafeHtmlError, "Detected invalid characters as part of the interpolation " \
"into a quoted attribute value. The value cannot contain the character #{@context[:quote_character]}."
end

@output.safe_append = value
end

def safe_unquoted_value_append=(value)
raise DontInterpolateHere, "Do not interpolate without quotes around this "\
"attribute value. Instead of "\
"<#{@context[:tag_name]} #{@context[:attribute_name]}=#{@context[:attribute_value]}<%=#{@code}%>> "\
raise DontInterpolateHere, "Do not interpolate without quotes around this " \
"attribute value. Instead of " \
"<#{@context[:tag_name]} #{@context[:attribute_name]}=#{@context[:attribute_value]}<%=#{@code}%>> " \
"try <#{@context[:tag_name]} #{@context[:attribute_name]}=\"#{@context[:attribute_value]}<%=#{@code}%>\">."
end

def safe_space_after_attribute_append=(value)
raise DontInterpolateHere, "Add a space after this attribute value. Instead of "\
"<#{@context[:tag_name]} #{@context[:attribute_name]}=\"#{@context[:attribute_value]}\"<%=#{@code}%>> "\
raise DontInterpolateHere, "Add a space after this attribute value. Instead of " \
"<#{@context[:tag_name]} #{@context[:attribute_name]}=\"#{@context[:attribute_value]}\"<%=#{@code}%>> " \
"try <#{@context[:tag_name]} #{@context[:attribute_name]}=\"#{@context[:attribute_value]}\" <%=#{@code}%>>."
end

Expand All @@ -43,7 +43,7 @@ def safe_attribute_name_append=(value)
value = value.to_s

unless value =~ /\A[a-z0-9\-]*\z/
raise UnsafeHtmlError, "Detected invalid characters as part of the interpolation "\
raise UnsafeHtmlError, "Detected invalid characters as part of the interpolation " \
"into a attribute name around '#{@context[:attribute_name]}<%=#{@code}%>'."
end

Expand All @@ -54,25 +54,25 @@ def safe_after_attribute_name_append=(value)
return if value.nil?

unless value.is_a?(BetterHtml::HtmlAttributes)
raise DontInterpolateHere, "Do not interpolate #{value.class} in a tag. "\
"Instead of <#{@context[:tag_name]} <%=#{@code}%>> please "\
raise DontInterpolateHere, "Do not interpolate #{value.class} in a tag. " \
"Instead of <#{@context[:tag_name]} <%=#{@code}%>> please " \
"try <#{@context[:tag_name]} <%= html_attributes(attr: value) %>>."
end

@output.safe_append = value.to_s
end

def safe_after_equal_append=(value)
raise DontInterpolateHere, "Do not interpolate without quotes after "\
raise DontInterpolateHere, "Do not interpolate without quotes after " \
"attribute around '#{@context[:attribute_name]}=<%=#{@code}%>'."
end

def safe_tag_append=(value)
return if value.nil?

unless value.is_a?(BetterHtml::HtmlAttributes)
raise DontInterpolateHere, "Do not interpolate #{value.class} in a tag. "\
"Instead of <#{@context[:tag_name]} <%=#{@code}%>> please "\
raise DontInterpolateHere, "Do not interpolate #{value.class} in a tag. " \
"Instead of <#{@context[:tag_name]} <%=#{@code}%>> please " \
"try <#{@context[:tag_name]} <%= html_attributes(attr: value) %>>."
end

Expand All @@ -85,7 +85,7 @@ def safe_tag_name_append=(value)
value = value.to_s

unless value =~ /\A[a-z0-9\:\-]*\z/
raise UnsafeHtmlError, "Detected invalid characters as part of the interpolation "\
raise UnsafeHtmlError, "Detected invalid characters as part of the interpolation " \
"into a tag name around: <#{@context[:tag_name]}<%=#{@code}%>>."
end

Expand All @@ -100,12 +100,12 @@ def safe_rawtext_append=(value)
if @context[:tag_name].downcase == "script" &&
(value =~ /<script/i || value =~ %r{</script}i)
# https://www.w3.org/TR/html5/scripting-1.html#restrictions-for-contents-of-script-elements
raise UnsafeHtmlError, "Detected invalid characters as part of the interpolation "\
"into a script tag around: <#{@context[:tag_name]}>#{@context[:rawtext_text]}<%=#{@code}%>. "\
raise UnsafeHtmlError, "Detected invalid characters as part of the interpolation " \
"into a script tag around: <#{@context[:tag_name]}>#{@context[:rawtext_text]}<%=#{@code}%>. " \
"A script tag cannot contain <script or </script anywhere inside of it."
elsif value =~ /<#{Regexp.escape(@context[:tag_name].downcase)}/i ||
value =~ %r{</#{Regexp.escape(@context[:tag_name].downcase)}}i
raise UnsafeHtmlError, "Detected invalid characters as part of the interpolation "\
raise UnsafeHtmlError, "Detected invalid characters as part of the interpolation " \
"into a #{@context[:tag_name].downcase} tag around: " \
"<#{@context[:tag_name]}>#{@context[:rawtext_text]}<%=#{@code}%>."
end
Expand All @@ -120,7 +120,7 @@ def safe_comment_append=(value)

# in a <!-- ...here --> we disallow -->
if value =~ /-->/
raise UnsafeHtmlError, "Detected invalid characters as part of the interpolation "\
raise UnsafeHtmlError, "Detected invalid characters as part of the interpolation " \
"into a html comment around: <!--#{@context[:comment_text]}<%=#{@code}%>."
end

Expand Down
2 changes: 1 addition & 1 deletion lib/better_html/html_attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def to_s
value = value.to_s
escaped_value = value.html_safe? ? value : CGI.escapeHTML(value)
if escaped_value.include?('"')
raise ArgumentError, "The value provided for attribute '#{key}' contains a `\"` "\
raise ArgumentError, "The value provided for attribute '#{key}' contains a `\"` " \
"character which is not allowed. Did you call .html_safe without properly escaping this data?"
end
"#{key}=\"#{escaped_value}\""
Expand Down
23 changes: 16 additions & 7 deletions lib/better_html/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def parser_errors
@erb.parser.errors.map do |error|
Error.new(
error.message,
location: Tokenizer::Location.new(@buffer, error.position, error.position + 1)
location: Tokenizer::Location.new(@buffer, error.position, error.position + 1),
)
end
end
Expand Down Expand Up @@ -183,9 +183,13 @@ def build_attribute_name_node(tokens)
end

def build_attribute_value_node(tokens)
children = shift_all_with_interpolation(tokens,
:attribute_quoted_value_start, :attribute_quoted_value,
:attribute_quoted_value_end, :attribute_unquoted_value)
children = shift_all_with_interpolation(
tokens,
:attribute_quoted_value_start,
:attribute_quoted_value,
:attribute_quoted_value_end,
:attribute_unquoted_value,
)

build_node(:attribute_value, children)
end
Expand All @@ -199,7 +203,7 @@ def build_node(type, tokens, pre: nil, post: nil)
BetterHtml::AST::Node.new(
type,
tokens.present? ? wrap_tokens(tokens) : [],
loc: tokens.present? ? build_location([pre, *tokens, post]) : empty_location
loc: tokens.present? ? build_location([pre, *tokens, post]) : empty_location,
)
end

Expand Down Expand Up @@ -298,8 +302,13 @@ def wrap_token(object)

if object.is_a?(::AST::Node)
object
elsif [:text, :tag_name, :attribute_name, :attribute_quoted_value,
:attribute_unquoted_value,].include?(object.type)
elsif [
:text,
:tag_name,
:attribute_name,
:attribute_quoted_value,
:attribute_unquoted_value,
].include?(object.type)
object.loc.source
elsif [:attribute_quoted_value_start, :attribute_quoted_value_end].include?(object.type)
BetterHtml::AST::Node.new(:quote, [object.loc.source], loc: object.loc)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def validate_type(tag)

add_error(
"#{type_attribute.value} is not a valid type, valid types are #{VALID_JAVASCRIPT_TAG_TYPES.join(", ")}",
location: type_attribute.loc
location: type_attribute.loc,
)
end
end
Expand Down
32 changes: 21 additions & 11 deletions lib/better_html/test_helper/safe_erb/tag_interpolation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,18 @@ module BetterHtml
module TestHelper
module SafeErb
class TagInterpolation < Base
NO_HTML_TAGS = ["title", "textarea", "script", "style", "xmp", "iframe", "noembed", "noframes", "listing",
"plaintext",]
NO_HTML_TAGS = [
"title",
"textarea",
"script",
"style",
"xmp",
"iframe",
"noembed",
"noframes",
"listing",
"plaintext",
]

def validate
@parser.nodes_with_type(:tag).each do |tag_node|
Expand All @@ -28,8 +38,8 @@ def validate
def no_html_tag?(node)
ast = @parser.ast.to_a
index = ast.find_index(node)
return unless (previous_node = ast[index - 1])
return unless previous_node.type == :tag
return false unless (previous_node = ast[index - 1])
return false unless previous_node.type == :tag

tag = BetterHtml::Tree::Tag.from_node(previous_node)
NO_HTML_TAGS.include?(tag.name) && !tag.closing?
Expand Down Expand Up @@ -57,7 +67,7 @@ def validate_attribute(attribute)
elsif indicator == "=="
add_error(
"erb interpolation with '<%==' inside html attribute is never safe",
location: erb_node.loc
location: erb_node.loc,
)
end
end
Expand Down Expand Up @@ -122,14 +132,14 @@ def handle_missing_safe_wrapper(parent_node, ruby_node, attr_name)
if method_calls.empty?
add_error(
"erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'",
location: nested_location(parent_node, ruby_node)
location: nested_location(parent_node, ruby_node),
)
true
elsif unsafe_calls.any?
unsafe_calls.each do |call_node|
add_error(
"erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'",
location: nested_location(parent_node, call_node)
location: nested_location(parent_node, call_node),
)
end
true
Expand All @@ -148,7 +158,7 @@ def validate_tag_interpolation(parent_node, ruby_node, attr_name)

add_error(
"erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'",
location: nested_location(parent_node, ruby_node)
location: nested_location(parent_node, ruby_node),
)
end
end
Expand All @@ -158,12 +168,12 @@ def no_unsafe_calls(parent_node, ruby_node)
if call.method_name?(:raw)
add_error(
"erb interpolation with '<%= raw(...) %>' in this context is never safe",
location: nested_location(parent_node, ruby_node)
location: nested_location(parent_node, ruby_node),
)
elsif call.method_name?(:html_safe)
add_error(
"erb interpolation with '<%= (...).html_safe %>' in this context is never safe",
location: nested_location(parent_node, ruby_node)
location: nested_location(parent_node, ruby_node),
)
end
end
Expand All @@ -173,7 +183,7 @@ def nested_location(parent_node, ruby_node)
Tokenizer::Location.new(
parent_node.loc.source_buffer,
parent_node.loc.begin_pos + ruby_node.loc.expression.begin_pos,
parent_node.loc.begin_pos + ruby_node.loc.expression.end_pos
parent_node.loc.begin_pos + ruby_node.loc.expression.end_pos,
)
end
end
Expand Down
10 changes: 5 additions & 5 deletions lib/better_html/test_helper/safe_lodash_tester.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def validate!

add_error(
"No script tags allowed nested in lodash templates",
location: tag_node.loc
location: tag_node.loc,
)
end

Expand Down Expand Up @@ -104,7 +104,7 @@ def validate_tag_attributes(tag)
elsif indicator_node.loc.source == "!"
add_error(
"lodash interpolation with '[%!' inside html attribute is never safe",
location: lodash_node.loc
location: lodash_node.loc,
)
end
end
Expand All @@ -116,9 +116,9 @@ def validate_tag_expression(attribute, lodash_node)
source = code_node.loc.source.strip
if @config.javascript_attribute_name?(attribute.name) && !@config.lodash_safe_javascript_expression?(source)
add_error(
"lodash interpolation in javascript attribute "\
"lodash interpolation in javascript attribute " \
"`#{attribute.name}` must call `JSON.stringify(#{source})`",
location: lodash_node.loc
location: lodash_node.loc,
)
end
end
Expand All @@ -132,7 +132,7 @@ def validate_no_statements(node)
def add_no_statement_error(loc)
add_error(
"javascript statement not allowed here; did you mean '[%=' ?",
location: loc
location: loc,
)
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/better_html/tokenizer/base_erb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def add_erb_tokens(ltrim, indicator, code, rtrim)
def add_token(type, begin_pos, end_pos)
token = Token.new(
type: type,
loc: Location.new(@buffer, begin_pos, end_pos)
loc: Location.new(@buffer, begin_pos, end_pos),
)
@tokens << token
token
Expand Down
2 changes: 1 addition & 1 deletion lib/better_html/tokenizer/html_lodash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def add_lodash_tokens(indicator, code)
def add_token(type, begin_pos: nil, end_pos: nil)
token = Token.new(
type: type,
loc: Location.new(@buffer, begin_pos, end_pos)
loc: Location.new(@buffer, begin_pos, end_pos),
)
@tokens << token
token
Expand Down
2 changes: 1 addition & 1 deletion lib/better_html/tokenizer/location.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def line_range
def line_source_with_underline
spaces = source_line.scan(/\A\s*/).first
column_without_spaces = [column - spaces.length, 0].max
underscore_length = [[end_pos - begin_pos, source_line.length - column_without_spaces].min, 1].max
underscore_length = (end_pos - begin_pos).clamp(1, (source_line.length - column_without_spaces))
"#{source_line.gsub(/\A\s*/, "")}\n#{" " * column_without_spaces}#{"^" * underscore_length}"
end

Expand Down
1 change: 1 addition & 0 deletions lib/tasks/better_html_tasks.rake
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true

# desc "Explaining what the task does"
# task :better_html do
# # Task goes here
Expand Down
Loading

0 comments on commit 4a1cbc0

Please sign in to comment.