diff --git a/lib/haml/precompiler.rb b/lib/haml/precompiler.rb
index ff9a70b7..3851d168 100644
--- a/lib/haml/precompiler.rb
+++ b/lib/haml/precompiler.rb
@@ -83,7 +83,7 @@ module Haml
DOCTYPE_REGEX = /(\d\.\d)?[\s]*([a-z]*)/i
# The Regex that matches a literal string or symbol value
- LITERAL_VALUE_REGEX = /^\s*(:(\w*)|(('|")([^\\\#'"]*?)\4))\s*$/
+ LITERAL_VALUE_REGEX = /:(\w*)|(["'])([^\\#'"]|\\.)*\2/
private
@@ -451,29 +451,18 @@ END
attributes
end
- def parse_literal_value(text)
- return nil unless text
- text.match(LITERAL_VALUE_REGEX)
-
- # $2 holds the value matched by a symbol, but is nil for a string match
- # $5 holds the value matched by a string
- $2 || $5
- end
-
def parse_static_hash(text)
return {} unless text
attributes = {}
- text.split(',').each do |attrib|
- key, value, more = attrib.split('=>')
-
- # Make sure the key and value and only the key and value exist
- # Otherwise, it's too complicated or dynamic and we'll defer it to the actual Ruby parser
- key = parse_literal_value key
- value = parse_literal_value value
- return nil if more || key.nil? || value.nil?
-
- attributes[key] = value
+ scanner = StringScanner.new(text)
+ scanner.scan(/\s+/)
+ until scanner.eos?
+ return unless key = scanner.scan(LITERAL_VALUE_REGEX)
+ return unless scanner.scan(/\s*=>\s*/)
+ return unless value = scanner.scan(LITERAL_VALUE_REGEX)
+ attributes[eval(key).to_s] = eval(value).to_s
+ scanner.scan(/[,\s]*/)
end
attributes
end
diff --git a/test/haml/engine_test.rb b/test/haml/engine_test.rb
index efb4779c..d75df3b9 100644
--- a/test/haml/engine_test.rb
+++ b/test/haml/engine_test.rb
@@ -618,6 +618,13 @@ END
assert_raise(Haml::Error, "Invalid output format :html1") { engine("%br", :format => :html1) }
end
+ def test_static_hashes
+ assert_equal("\n", render("%a{:b => 'a => b'}", :suppress_eval => true))
+ assert_equal("\n", render("%a{:b => 'a, b'}", :suppress_eval => true))
+ assert_equal("\n", render('%a{:b => "a\tb"}', :suppress_eval => true))
+ assert_equal("\n", render('%a{:b => "a\\#{foo}b"}', :suppress_eval => true))
+ end
+
# HTML 4.0
def test_html_has_no_self_closing_tags