Skip to content

Commit

Permalink
feat: Change attribute value escaper (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephannv authored Oct 12, 2024
1 parent ba01afa commit 12905a5
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 26 deletions.
4 changes: 2 additions & 2 deletions spec/blueprint/html/safety_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ describe "safety" do
it "escapes attribute values" do
page = Example.new
expected_html = normalize_html <<-HTML
<div class="some-class&quot; onblur=&quot;alert(&#39;Attribute&#39;)"></div>
<div class="some-class&quot; onblur=&quot;alert('Attribute')"></div>
HTML

page.to_s.should contain(expected_html)
Expand All @@ -92,7 +92,7 @@ describe "safety" do
it "escapes custom tag content passed via block" do
page = Example.new
expected_html = normalize_html <<-HTML
<v-btn class="some-class&quot; onclick=&quot;alert(&#39;Attribute&#39;)">&lt;script&gt;alert(&#39;hello&#39;)&lt;/script&gt;</v-btn>
<v-btn class="some-class&quot; onclick=&quot;alert('Attribute')">&lt;script&gt;alert(&#39;hello&#39;)&lt;/script&gt;</v-btn>
HTML

page.to_s.should contain(expected_html)
Expand Down
58 changes: 37 additions & 21 deletions src/blueprint/html/attributes_handler.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,63 @@ module Blueprint::HTML::AttributesHandler
end
end

private def append_attribute(attribute_name, attribute_value) : Nil
case attribute_value
private def append_attribute(name, value) : Nil
case value
when Nil, false
# does nothing
when true
append_boolean_attribute(attribute_name)
append_boolean_attribute(name)
when NamedTuple
process_named_tuple_attribute(attribute_name, attribute_value)
process_named_tuple_attribute(name, value)
when Array
append_array_attribute(attribute_name, attribute_value)
append_array_attribute(name, value)
else
append_normal_attribute(attribute_name, attribute_value)
append_normal_attribute(name, value)
end
end

private def append_normal_attribute(attribute_name, attribute_value) : Nil
private def append_boolean_attribute(name) : Nil
@buffer << " "
@buffer << parse_attribute_name(attribute_name)
@buffer << parse_name(name)
end

private def append_array_attribute(name, value : Array) : Nil
append_normal_attribute(name, value.flatten.compact.join(" "))
end

private def process_named_tuple_attribute(name, value : NamedTuple) : Nil
name_prefix = parse_name(name)

value.each do |attr_name, attr_value|
append_attribute("#{name_prefix}-#{parse_name(attr_name)}", attr_value)
end
end

private def append_normal_attribute(name, value) : Nil
@buffer << " "
@buffer << parse_name(name)
@buffer << %(=")
append_to_buffer(attribute_value)
append_attribute_value(value)
@buffer << %(")
end

private def append_boolean_attribute(attribute_name) : Nil
@buffer << " "
@buffer << parse_attribute_name(attribute_name)
private def append_attribute_value(value : String) : Nil
@buffer << value.gsub('"', "&quot;")
end

private def append_array_attribute(attribute_name, attribute_value : Array) : Nil
append_normal_attribute(attribute_name, attribute_value.flatten.compact.join(" "))
private def append_attribute_value(value : SafeObject) : Nil
value.to_s @buffer
end

private def process_named_tuple_attribute(attribute_name, attribute_value : NamedTuple) : Nil
attribute_name_prefix = parse_attribute_name(attribute_name)
private def append_attribute_value(value : Number) : Nil
value.to_s @buffer
end

attribute_value.each do |name, value|
append_attribute("#{attribute_name_prefix}-#{parse_attribute_name(name)}", value)
end
private def append_attribute_value(value) : Nil
append_attribute_value value.to_s
end

private def parse_attribute_name(attribute_name) : String
attribute_name.to_s.gsub("_", "-")
private def parse_name(name) : String
name.to_s.gsub("_", "-")
end
end
8 changes: 6 additions & 2 deletions src/blueprint/html/buffer_appender.cr
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Blueprint::HTML::BufferAppender
private def append_to_buffer(content : String)
::HTML.escape(content, @buffer)
escape(content, @buffer)
end

private def append_to_buffer(content : SafeObject)
Expand All @@ -11,6 +11,10 @@ module Blueprint::HTML::BufferAppender
end

private def append_to_buffer(content)
::HTML.escape(content.to_s, @buffer)
escape(content.to_s, @buffer)
end

private def escape(value : String, io : IO)
::HTML.escape(value, io)
end
end
2 changes: 1 addition & 1 deletion src/blueprint/html/utils.cr
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module Blueprint::HTML::Utils
@buffer << " "
end

def raw(content : SafeObject) : Nil
private def raw(content : SafeObject) : Nil
append_to_buffer(content)
end
end

0 comments on commit 12905a5

Please sign in to comment.