Skip to content

Commit

Permalink
YAML cache: do not cache documents containing tags
Browse files Browse the repository at this point in the history
  • Loading branch information
byroot committed Mar 19, 2021
1 parent 69d710a commit 7ec692c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
20 changes: 18 additions & 2 deletions lib/bootsnap/compile_cache/yaml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ class << self
attr_accessor(:msgpack_factory, :cache_dir, :supported_options)

def input_to_storage(contents, _)
raise(Uncompilable) if contents.index("!ruby/object")
obj = ::YAML.load(contents)
obj = strict_load(contents)
msgpack_factory.dump(obj)
rescue NoMethodError, RangeError
# The object included things that we can't serialize
Expand All @@ -27,6 +26,12 @@ def input_to_output(data, kwargs)
::YAML.load(data, **(kwargs || {}))
end

def strict_load(payload, **kwargs)
ast = ::YAML.parse(payload)
return ast unless ast
strict_visitor.create(**kwargs).visit(ast)
end

def precompile(path, cache_dir: YAML.cache_dir)
Bootsnap::CompileCache::Native.precompile(
cache_dir,
Expand Down Expand Up @@ -86,6 +91,17 @@ def init!
end
self.supported_options.freeze
end

def strict_visitor
self::NoTagsVisitor ||= Class.new(Psych::Visitors::ToRuby) do
def visit(target)
if target.tag
raise Uncompilable, "YAML tags are not supported: #{target.tag}"
end
super
end
end
end
end

module Patch
Expand Down
25 changes: 25 additions & 0 deletions test/compile_cache/yaml_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,31 @@ def setup
Bootsnap::CompileCache::YAML.init!
end

def test_yaml_strict_load
document = ::Bootsnap::CompileCache::YAML.strict_load(<<~YAML)
---
:foo: 42
bar: [1]
YAML
expected = {
foo: 42,
'bar' => [1],
}
assert_equal expected, document
end

def test_yaml_tags
error = assert_raises Bootsnap::CompileCache::Uncompilable do
::Bootsnap::CompileCache::YAML.strict_load('!many Boolean')
end
assert_equal "YAML tags are not supported: !many", error.message

error = assert_raises Bootsnap::CompileCache::Uncompilable do
::Bootsnap::CompileCache::YAML.strict_load('!ruby/object {}')
end
assert_equal "YAML tags are not supported: !ruby/object", error.message
end

def test_load_file
Help.set_file('a.yml', "---\nfoo: bar", 100)
assert_equal({'foo' => 'bar'}, FakeYaml.load_file('a.yml'))
Expand Down

0 comments on commit 7ec692c

Please sign in to comment.