From 8ae2fc53760b5a73120ecb14e70bfb8f7ac6c0a3 Mon Sep 17 00:00:00 2001 From: Michael Herold Date: Sun, 13 Aug 2023 23:01:09 -0500 Subject: [PATCH] Move the responsibility of safe loading to Node This change moves the responsibility of safely loading a YAML tree from an internal detail of `Psych.safe_load` into `Psych::Nodes::Node`. The advantage of this is that you can now more easily safely load trees that you're working on without replicating the safety constraints of `Psych.safe_load`. The delegation of responsibilities also now matches for safely and unsafely loading a tree. --- lib/psych.rb | 14 ++------------ lib/psych/nodes/node.rb | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/lib/psych.rb b/lib/psych.rb index ae167472..b8cc08c0 100644 --- a/lib/psych.rb +++ b/lib/psych.rb @@ -319,20 +319,10 @@ def self.unsafe_load yaml, filename: nil, fallback: false, symbolize_names: fals # Psych.safe_load("---\n foo: bar") # => {"foo"=>"bar"} # Psych.safe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"} # - def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false + def self.safe_load yaml, filename: nil, fallback: nil, **kwargs result = parse(yaml, filename: filename) return fallback unless result - - class_loader = ClassLoader::Restricted.new(permitted_classes.map(&:to_s), - permitted_symbols.map(&:to_s)) - scanner = ScalarScanner.new class_loader, strict_integer: strict_integer - visitor = if aliases - Visitors::ToRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze - else - Visitors::NoAliasRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze - end - result = visitor.accept result - result + result.to_safe_ruby(**kwargs) end ### diff --git a/lib/psych/nodes/node.rb b/lib/psych/nodes/node.rb index f44fce5f..0ccb74e1 100644 --- a/lib/psych/nodes/node.rb +++ b/lib/psych/nodes/node.rb @@ -51,6 +51,23 @@ def to_ruby(symbolize_names: false, freeze: false, strict_integer: false) end alias :transform :to_ruby + ### + # Safely convert this node to Ruby. + # + # See also Psych.safe_load + # + def to_safe_ruby(permitted_classes: [], permitted_symbols: [], aliases: false, symbolize_names: false, freeze: false, strict_integer: false) + class_loader = ClassLoader::Restricted.new( + permitted_classes.map(&:to_s), + permitted_symbols.map(&:to_s) + ) + scanner = ScalarScanner.new(class_loader, strict_integer: strict_integer) + visitor_class = aliases ? Visitors::ToRuby : Visitors::NoAliasRuby + + visitor_class.new(scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze).accept(self) + end + alias :safe_transform :to_safe_ruby + ### # Convert this node to YAML. #