Skip to content

Commit

Permalink
feat: Add escape_once helper (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephannv authored Oct 14, 2024
1 parent 12905a5 commit 2192bba
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 9 deletions.
30 changes: 30 additions & 0 deletions spec/blueprint/html/helpers_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,34 @@ describe "helpers" do
page.to_s.should contain expected_html
end
end

describe "#escape_once" do
it "escapes HTML without affecting existing escaped entities" do
actual_html = Blueprint::HTML.build do
span escape_once("<< Accept & Checkout")

div escape_once(MarkdownLink.new("1 < 2 &amp; 3", "example.com"))
end

expected_html = normalize_html <<-HTML
<span>&lt;&lt; Accept &amp; Checkout</span>
<div>[1 &lt; 2 &amp; 3](example.com)</div>
HTML

actual_html.to_s.should eq expected_html
end

it "escapes unsafe content" do
actual_html = Blueprint::HTML.build do
span escape_once("<script>alert('content')</script>")
end

expected_html = normalize_html <<-HTML
<span>&lt;script&gt;alert(&#39;content&#39;)&lt;/script&gt;</span>
HTML

actual_html.to_s.should eq expected_html
end
end
end
8 changes: 0 additions & 8 deletions spec/blueprint/html/utils_spec.cr
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
require "../../spec_helper"

private class MarkdownLink
def initialize(@text : String, @href : String); end

def to_s
"[#{@text}](#{@href})"
end
end

private class ExamplePage
include Blueprint::HTML

Expand Down
8 changes: 8 additions & 0 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
require "spec"
require "../src/blueprint/html"

class MarkdownLink
def initialize(@text : String, @href : String); end

def to_s
"[#{@text}](#{@href})"
end
end

def normalize_html(html : String) : String
html.strip.gsub(/\R\s+/, "")
end
14 changes: 13 additions & 1 deletion src/blueprint/html/helpers.cr
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
module Blueprint::HTML::Helpers
def safe(value) : SafeValue
HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/

HTML_ESCAPE = {"&": "&amp;", ">": "&gt;", "<": "&lt;", %("): "&quot;", "'": "&#39;"}

private def safe(value) : SafeValue
Blueprint::SafeValue.new(value)
end

private def escape_once(value : String) : SafeValue
safe value.gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
end

private def escape_once(value) : SafeValue
escape_once(value.to_s)
end

@[Experimental]
macro tokens(**conditions)
String.build do |io|
Expand Down

0 comments on commit 2192bba

Please sign in to comment.