Skip to content

Commit

Permalink
Allow consistent permitting classes (#795)
Browse files Browse the repository at this point in the history
By default, Bridgetown expects to be able to load its special Rb class
for YAML front matter. The original implementation made it hard to have
extra permitted classes in front matter while retaining that
expectation.

This change makes it so the default permitted classes are merged into
any passed permitted classes across both string and file loading.
  • Loading branch information
michaelherold authored Oct 23, 2023
1 parent b5f8622 commit 1bf58eb
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
19 changes: 15 additions & 4 deletions bridgetown-core/lib/bridgetown-core/yaml_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,23 @@ class YAMLParser

class << self
def load_file(filename, **kwargs)
kwargs = { permitted_classes: PERMITTED_CLASSES }.merge(kwargs)
YAML.safe_load_file(filename, **kwargs)
YAML.safe_load_file filename, **merge_permitted_classes(kwargs)
end

def load(yaml)
YAML.safe_load yaml, permitted_classes: PERMITTED_CLASSES
def load(yaml, **kwargs)
YAML.safe_load yaml, **merge_permitted_classes(kwargs)
end

private

def merge_permitted_classes(kwargs)
if kwargs.key?(:permitted_classes)
kwargs[:permitted_classes] |= PERMITTED_CLASSES
else
kwargs[:permitted_classes] = PERMITTED_CLASSES
end

kwargs
end
end
end
Expand Down
6 changes: 6 additions & 0 deletions bridgetown-core/test/fixtures/extra_yaml.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
date: 2020-05-14
time: 2019-07-14 19:22:00 +0100
rb: !ruby/string:Rb |
21 * 2
symbol: :symbol
25 changes: 25 additions & 0 deletions bridgetown-core/test/test_yaml_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,21 @@ def initialize
assert_equal Rb, parsed_yaml["rb"].class
end

should "allows passing other permitted classes" do
parsed_yaml = Bridgetown::YAMLParser.load(<<~YAML, permitted_classes: [Symbol])
date: 2020-05-14
time: 2019-07-14 19:22:00 +0100
rb: !ruby/string:Rb |
21 * 2
symbol: :symbol
YAML

assert_equal Date, parsed_yaml["date"].class
assert_equal Time, parsed_yaml["time"].class
assert_equal Rb, parsed_yaml["rb"].class
assert_equal :symbol, parsed_yaml["symbol"]
end

should "error when trying to parse types not on the allowlist" do
assert_raises(Psych::DisallowedClass) do
Bridgetown::YAMLParser.load(CustomYAMLSerializable.new.to_yaml)
Expand All @@ -51,6 +66,16 @@ def initialize
assert_equal Rb, parsed_yaml["rb"].class
end

should "allows passing other permitted classes" do
yaml_file = test_dir("fixtures", "extra_yaml.yml")
parsed_yaml = Bridgetown::YAMLParser.load_file(yaml_file, permitted_classes: [Symbol])

assert_equal Date, parsed_yaml["date"].class
assert_equal Time, parsed_yaml["time"].class
assert_equal Rb, parsed_yaml["rb"].class
assert_equal :symbol, parsed_yaml["symbol"]
end

should "error when trying to parse types not on the allowlist" do
yaml_file = test_dir("fixtures", "disallowed_yaml.yml")

Expand Down

0 comments on commit 1bf58eb

Please sign in to comment.