diff options
author | Aaron Patterson <tenderlove@ruby-lang.org> | 2021-05-21 11:38:55 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-21 11:38:55 -0700 |
commit | 5d8b7fb0f8393e8ce1aed7642f509818e4e5c211 (patch) | |
tree | b879281965f51d4f2224a70b2b34f0887c1e199e /lib/psych | |
parent | 38e4b5115f170ae7d79debfc9219331a6d52babe (diff) | |
parent | 441958396f40d526a62e564761d2bad534465a5b (diff) | |
download | psych-5d8b7fb0f8393e8ce1aed7642f509818e4e5c211.zip |
Implement YAML.safe_dump to make safe_load more usable.
Diffstat (limited to 'lib/psych')
-rw-r--r-- | lib/psych/class_loader.rb | 4 | ||||
-rw-r--r-- | lib/psych/exception.rb | 4 | ||||
-rw-r--r-- | lib/psych/visitors/yaml_tree.rb | 46 |
3 files changed, 50 insertions, 4 deletions
diff --git a/lib/psych/class_loader.rb b/lib/psych/class_loader.rb index a5d1a7a..088373c 100644 --- a/lib/psych/class_loader.rb +++ b/lib/psych/class_loader.rb @@ -86,7 +86,7 @@ module Psych if @symbols.include? sym super else - raise DisallowedClass, 'Symbol' + raise DisallowedClass.new('load', 'Symbol') end end @@ -96,7 +96,7 @@ module Psych if @classes.include? klassname super else - raise DisallowedClass, klassname + raise DisallowedClass.new('load', klassname) end end end diff --git a/lib/psych/exception.rb b/lib/psych/exception.rb index fac0c42..f473b95 100644 --- a/lib/psych/exception.rb +++ b/lib/psych/exception.rb @@ -7,8 +7,8 @@ module Psych end class DisallowedClass < Exception - def initialize klass_name - super "Tried to load unspecified class: #{klass_name}" + def initialize action, klass_name + super "Tried to #{action} unspecified class: #{klass_name}" end end end diff --git a/lib/psych/visitors/yaml_tree.rb b/lib/psych/visitors/yaml_tree.rb index bf7c0bb..05748dd 100644 --- a/lib/psych/visitors/yaml_tree.rb +++ b/lib/psych/visitors/yaml_tree.rb @@ -535,5 +535,51 @@ module Psych end end end + + class RestrictedYAMLTree < YAMLTree + DEFAULT_PERMITTED_CLASSES = { + TrueClass => true, + FalseClass => true, + NilClass => true, + Integer => true, + Float => true, + String => true, + Array => true, + Hash => true, + }.compare_by_identity.freeze + + def initialize emitter, ss, options + super + @permitted_classes = DEFAULT_PERMITTED_CLASSES.dup + Array(options[:permitted_classes]).each do |klass| + @permitted_classes[klass] = true + end + @permitted_symbols = {}.compare_by_identity + Array(options[:permitted_symbols]).each do |symbol| + @permitted_symbols[symbol] = true + end + @aliases = options.fetch(:aliases, false) + end + + def accept target + if !@aliases && @st.key?(target) + raise BadAlias, "Tried to dump an aliased object" + end + + unless @permitted_classes[target.class] + raise DisallowedClass.new('dump', target.class.name || target.class.inspect) + end + + super + end + + def visit_Symbol sym + unless @permitted_symbols[sym] + raise DisallowedClass.new('dump', "Symbol(#{sym.inspect})") + end + + super + end + end end end |