summaryrefslogtreecommitdiff
path: root/ext/psych/lib/psych.rb
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2021-05-19 16:07:24 +0200
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2021-06-07 19:15:14 +0900
commitfd6225c7a974e5154099c9f7be82bebd44a19116 (patch)
treed68741ae9aed69894c2475c75c47b935088b845d /ext/psych/lib/psych.rb
parent430883158f3d01f80917d6eefbaa82521c95c05a (diff)
[ruby/psych] Implement YAML.safe_dump to make safe_load more usable.
In case where Psych is used as a two way serializers, e.g. to serialize some cache or config, it is preferable to have the same restrictions on both load and dump. Otherwise you might dump and persist some objects payloads that you later won't be able to read. https://github.com/ruby/psych/commit/441958396f
Diffstat (limited to 'ext/psych/lib/psych.rb')
-rw-r--r--ext/psych/lib/psych.rb76
1 files changed, 75 insertions, 1 deletions
diff --git a/ext/psych/lib/psych.rb b/ext/psych/lib/psych.rb
index 6205061d0b5..1efe8d5f620 100644
--- a/ext/psych/lib/psych.rb
+++ b/ext/psych/lib/psych.rb
@@ -282,7 +282,8 @@ module Psych
# * TrueClass
# * FalseClass
# * NilClass
- # * Numeric
+ # * Integer
+ # * Float
# * String
# * Array
# * Hash
@@ -513,6 +514,79 @@ module Psych
end
###
+ # call-seq:
+ # Psych.safe_dump(o) -> string of yaml
+ # Psych.safe_dump(o, options) -> string of yaml
+ # Psych.safe_dump(o, io) -> io object passed in
+ # Psych.safe_dump(o, io, options) -> io object passed in
+ #
+ # Safely dump Ruby object +o+ to a YAML string. Optional +options+ may be passed in
+ # to control the output format. If an IO object is passed in, the YAML will
+ # be dumped to that IO object. By default, only the following
+ # classes are allowed to be serialized:
+ #
+ # * TrueClass
+ # * FalseClass
+ # * NilClass
+ # * Integer
+ # * Float
+ # * String
+ # * Array
+ # * Hash
+ #
+ # Arbitrary classes can be allowed by adding those classes to the +permitted_classes+
+ # keyword argument. They are additive. For example, to allow Date serialization:
+ #
+ # Psych.safe_dump(yaml, permitted_classes: [Date])
+ #
+ # Now the Date class can be dumped in addition to the classes listed above.
+ #
+ # A Psych::DisallowedClass exception will be raised if the object contains a
+ # class that isn't in the +permitted_classes+ list.
+ #
+ # Currently supported options are:
+ #
+ # [<tt>:indentation</tt>] Number of space characters used to indent.
+ # Acceptable value should be in <tt>0..9</tt> range,
+ # otherwise option is ignored.
+ #
+ # Default: <tt>2</tt>.
+ # [<tt>:line_width</tt>] Max character to wrap line at.
+ #
+ # Default: <tt>0</tt> (meaning "wrap at 81").
+ # [<tt>:canonical</tt>] Write "canonical" YAML form (very verbose, yet
+ # strictly formal).
+ #
+ # Default: <tt>false</tt>.
+ # [<tt>:header</tt>] Write <tt>%YAML [version]</tt> at the beginning of document.
+ #
+ # Default: <tt>false</tt>.
+ #
+ # Example:
+ #
+ # # Dump an array, get back a YAML string
+ # Psych.safe_dump(['a', 'b']) # => "---\n- a\n- b\n"
+ #
+ # # Dump an array to an IO object
+ # Psych.safe_dump(['a', 'b'], StringIO.new) # => #<StringIO:0x000001009d0890>
+ #
+ # # Dump an array with indentation set
+ # Psych.safe_dump(['a', ['b']], indentation: 3) # => "---\n- a\n- - b\n"
+ #
+ # # Dump an array to an IO with indentation set
+ # Psych.safe_dump(['a', ['b']], StringIO.new, indentation: 3)
+ def self.safe_dump o, io = nil, options = {}
+ if Hash === io
+ options = io
+ io = nil
+ end
+
+ visitor = Psych::Visitors::RestrictedYAMLTree.create options
+ visitor << o
+ visitor.tree.yaml io, options
+ end
+
+ ###
# Dump a list of objects as separate documents to a document stream.
#
# Example: