From 12905a571e60c1e1aff1428d75184bd462cc1eb0 Mon Sep 17 00:00:00 2001
From: stephann <3025661+stephannv@users.noreply.github.com>
Date: Sat, 12 Oct 2024 17:56:39 -0300
Subject: [PATCH] feat: Change attribute value escaper (#84)
---
spec/blueprint/html/safety_spec.cr | 4 +-
src/blueprint/html/attributes_handler.cr | 58 +++++++++++++++---------
src/blueprint/html/buffer_appender.cr | 8 +++-
src/blueprint/html/utils.cr | 2 +-
4 files changed, 46 insertions(+), 26 deletions(-)
diff --git a/spec/blueprint/html/safety_spec.cr b/spec/blueprint/html/safety_spec.cr
index 1542772..d2029b7 100644
--- a/spec/blueprint/html/safety_spec.cr
+++ b/spec/blueprint/html/safety_spec.cr
@@ -65,7 +65,7 @@ describe "safety" do
it "escapes attribute values" do
page = Example.new
expected_html = normalize_html <<-HTML
-
+
HTML
page.to_s.should contain(expected_html)
@@ -92,7 +92,7 @@ describe "safety" do
it "escapes custom tag content passed via block" do
page = Example.new
expected_html = normalize_html <<-HTML
- <script>alert('hello')</script>
+ <script>alert('hello')</script>
HTML
page.to_s.should contain(expected_html)
diff --git a/src/blueprint/html/attributes_handler.cr b/src/blueprint/html/attributes_handler.cr
index aa2d2e1..4cf0bac 100644
--- a/src/blueprint/html/attributes_handler.cr
+++ b/src/blueprint/html/attributes_handler.cr
@@ -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('"', """)
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
diff --git a/src/blueprint/html/buffer_appender.cr b/src/blueprint/html/buffer_appender.cr
index 154e98c..9410e8c 100644
--- a/src/blueprint/html/buffer_appender.cr
+++ b/src/blueprint/html/buffer_appender.cr
@@ -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)
@@ -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
diff --git a/src/blueprint/html/utils.cr b/src/blueprint/html/utils.cr
index f2eeb0c..253064a 100644
--- a/src/blueprint/html/utils.cr
+++ b/src/blueprint/html/utils.cr
@@ -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