diff --git a/lib/gollum-lib/filter/yaml.rb b/lib/gollum-lib/filter/yaml.rb
index 4c1003fa..efb204a4 100644
--- a/lib/gollum-lib/filter/yaml.rb
+++ b/lib/gollum-lib/filter/yaml.rb
@@ -10,7 +10,7 @@ def extract(data)
data.gsub!(YAML_FRONT_MATTER_REGEXP) do
@markup.metadata ||= {}
begin
- frontmatter = ::YAML.safe_load(sanitize(Regexp.last_match[1]))
+ frontmatter = sanitize_frontmatter(::YAML.safe_load(Regexp.last_match[1]))
@markup.metadata.merge!(frontmatter) if frontmatter.respond_to?(:keys) && frontmatter.respond_to?(:values)
rescue ::Psych::SyntaxError, ::Psych::DisallowedClass, ::Psych::BadAlias => error
@markup.metadata['errors'] ||= []
@@ -24,4 +24,23 @@ def extract(data)
def process(data)
data
end
+
+ private
+
+ def sanitize_frontmatter(obj)
+ case obj
+ when Hash
+ obj.map do |k, v|
+ [sanitize(k.to_s), sanitize_frontmatter(v)]
+ end.to_h
+ when Array
+ obj.map! do |v|
+ sanitize_frontmatter(v)
+ end
+ when String
+ sanitize(obj)
+ else
+ obj
+ end
+ end
end
diff --git a/test/filter/test_yaml.rb b/test/filter/test_yaml.rb
new file mode 100644
index 00000000..ef20f6b4
--- /dev/null
+++ b/test/filter/test_yaml.rb
@@ -0,0 +1,75 @@
+path = File.join(File.dirname(__FILE__), "..", "helper")
+require File.expand_path(path)
+
+context "Gollum::Filter::YAML" do
+ setup do
+ @page = mock_page
+ @markup = Gollum::Markup.new(@page)
+ @filter = Gollum::Filter::YAML.new(@markup)
+ end
+
+ def filter(content)
+ @filter.process(@filter.extract(content))
+ end
+
+ test 'process yaml' do
+ markup = <<~EOF
+ ---
+ Literal Scalar: |
+ abc
+
+ 123
+ Folded Scalar: >
+ abc
+
+ 123
+ Escaped: "abc\n\n123"
+ ---
+
+ # Markdown content here
+ EOF
+
+ result = {"Escaped"=> "abc\n" + "123",
+ "Folded Scalar" => "abc\n" + "123\n",
+ "Literal Scalar" => "abc\n" + "\n" + "123\n"
+ }
+
+ assert_equal "# Markdown content here\n", filter(markup)
+ assert_nil @markup.metadata['errors']
+ assert_equal result, @markup.metadata
+ end
+
+ test 'escape yaml' do
+ markup = <<~EOF
+ ---
+ BadStuffInKey: foo
+ Literal Scalar: |
+
+
+ 123
+ Folded Scalar: >
+ >abc
+
+ <123
+ Escaped: "abc"
+ NestedBadStuff:
+ Baz:
+ - [1, ""]
+ - [1, 2, 3]
+ ---
+
+ # Markdown content here
+ EOF
+
+ result = {"Escaped"=> "abc",
+ "Folded Scalar" => ">abc\n" + "<123\n",
+ "Literal Scalar" => "\n" + "\n" + "123\n",
+ "BadStuffInKey" => "foo",
+ "NestedBadStuff"=> {"Baz"=>[[1, ""], [1, 2, 3]]}
+ }
+ filter(markup)
+ assert_nil @markup.metadata['errors']
+ assert_equal result, @markup.metadata
+ end
+
+end
\ No newline at end of file
diff --git a/test/helper.rb b/test/helper.rb
index 9c50c72b..56655d38 100644
--- a/test/helper.rb
+++ b/test/helper.rb
@@ -88,6 +88,10 @@ def metadata(val={})
val
end
+ def sanitizer
+ Gollum::Sanitization.new(Gollum::Markup.to_xml_opts)
+ end
+
attr_reader :repo_is_bare
attr_reader :base_path
end