psych 3.3.0 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Mavenfile +1 -1
  4. data/README.md +6 -5
  5. data/Rakefile +11 -4
  6. data/ext/psych/depend +13 -1
  7. data/ext/psych/extconf.rb +40 -30
  8. data/ext/psych/psych_parser.c +19 -33
  9. data/lib/psych/class_loader.rb +5 -5
  10. data/lib/psych/core_ext.rb +1 -1
  11. data/lib/psych/exception.rb +16 -2
  12. data/lib/psych/handler.rb +1 -1
  13. data/lib/psych/handlers/document_stream.rb +1 -1
  14. data/lib/psych/handlers/recorder.rb +1 -1
  15. data/lib/psych/json/stream.rb +2 -2
  16. data/lib/psych/json/tree_builder.rb +1 -1
  17. data/lib/psych/nodes/node.rb +4 -4
  18. data/lib/psych/nodes/scalar.rb +1 -1
  19. data/lib/psych/nodes.rb +7 -7
  20. data/lib/psych/parser.rb +13 -0
  21. data/lib/psych/scalar_scanner.rb +22 -16
  22. data/lib/psych/syntax_error.rb +1 -1
  23. data/lib/psych/tree_builder.rb +3 -3
  24. data/lib/psych/versions.rb +3 -3
  25. data/lib/psych/visitors/json_tree.rb +1 -1
  26. data/lib/psych/visitors/to_ruby.rb +19 -15
  27. data/lib/psych/visitors/visitor.rb +1 -1
  28. data/lib/psych/visitors/yaml_tree.rb +61 -13
  29. data/lib/psych/visitors.rb +6 -6
  30. data/lib/psych.rb +162 -84
  31. data/psych.gemspec +5 -5
  32. metadata +20 -17
  33. data/ext/psych/yaml/LICENSE +0 -19
  34. data/ext/psych/yaml/api.c +0 -1393
  35. data/ext/psych/yaml/config.h +0 -80
  36. data/ext/psych/yaml/dumper.c +0 -394
  37. data/ext/psych/yaml/emitter.c +0 -2358
  38. data/ext/psych/yaml/loader.c +0 -544
  39. data/ext/psych/yaml/parser.c +0 -1375
  40. data/ext/psych/yaml/reader.c +0 -469
  41. data/ext/psych/yaml/scanner.c +0 -3598
  42. data/ext/psych/yaml/writer.c +0 -141
  43. data/ext/psych/yaml/yaml.h +0 -1985
  44. data/ext/psych/yaml/yaml_private.h +0 -688
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
- require 'psych/scalar_scanner'
3
- require 'psych/class_loader'
4
- require 'psych/exception'
2
+ require_relative '../scalar_scanner'
3
+ require_relative '../class_loader'
4
+ require_relative '../exception'
5
5
 
6
6
  unless defined?(Regexp::NOENCODING)
7
7
  Regexp::NOENCODING = 32
@@ -12,9 +12,9 @@ module Psych
12
12
  ###
13
13
  # This class walks a YAML AST, converting each node to Ruby
14
14
  class ToRuby < Psych::Visitors::Visitor
15
- def self.create(symbolize_names: false, freeze: false)
15
+ def self.create(symbolize_names: false, freeze: false, strict_integer: false)
16
16
  class_loader = ClassLoader.new
17
- scanner = ScalarScanner.new class_loader
17
+ scanner = ScalarScanner.new class_loader, strict_integer: strict_integer
18
18
  new(scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze)
19
19
  end
20
20
 
@@ -24,6 +24,7 @@ module Psych
24
24
  super()
25
25
  @st = {}
26
26
  @ss = ss
27
+ @load_tags = Psych.load_tags
27
28
  @domain_types = Psych.domain_types
28
29
  @class_loader = class_loader
29
30
  @symbolize_names = symbolize_names
@@ -48,7 +49,7 @@ module Psych
48
49
  end
49
50
 
50
51
  def deserialize o
51
- if klass = resolve_class(Psych.load_tags[o.tag])
52
+ if klass = resolve_class(@load_tags[o.tag])
52
53
  instance = klass.allocate
53
54
 
54
55
  if instance.respond_to?(:init_with)
@@ -79,7 +80,9 @@ module Psych
79
80
  when "!ruby/object:DateTime"
80
81
  class_loader.date_time
81
82
  require 'date' unless defined? DateTime
82
- @ss.parse_time(o.value).to_datetime
83
+ t = @ss.parse_time(o.value)
84
+ DateTime.civil(*t.to_a[0, 6].reverse, Rational(t.utc_offset, 86400)) +
85
+ (t.subsec/86400)
83
86
  when '!ruby/encoding'
84
87
  ::Encoding.find o.value
85
88
  when "!ruby/object:Complex"
@@ -128,7 +131,7 @@ module Psych
128
131
  end
129
132
 
130
133
  def visit_Psych_Nodes_Sequence o
131
- if klass = resolve_class(Psych.load_tags[o.tag])
134
+ if klass = resolve_class(@load_tags[o.tag])
132
135
  instance = klass.allocate
133
136
 
134
137
  if instance.respond_to?(:init_with)
@@ -160,8 +163,8 @@ module Psych
160
163
  end
161
164
 
162
165
  def visit_Psych_Nodes_Mapping o
163
- if Psych.load_tags[o.tag]
164
- return revive(resolve_class(Psych.load_tags[o.tag]), o)
166
+ if @load_tags[o.tag]
167
+ return revive(resolve_class(@load_tags[o.tag]), o)
165
168
  end
166
169
  return revive_hash(register(o, {}), o) unless o.tag
167
170
 
@@ -322,10 +325,11 @@ module Psych
322
325
  end
323
326
 
324
327
  def visit_Psych_Nodes_Alias o
325
- @st.fetch(o.anchor) { raise BadAlias, "Unknown alias: #{o.anchor}" }
328
+ @st.fetch(o.anchor) { raise AnchorNotDefined, o.anchor }
326
329
  end
327
330
 
328
331
  private
332
+
329
333
  def register node, object
330
334
  @st[node.anchor] = object if node.anchor
331
335
  object
@@ -337,7 +341,7 @@ module Psych
337
341
  list
338
342
  end
339
343
 
340
- def revive_hash hash, o
344
+ def revive_hash hash, o, tagged= false
341
345
  o.children.each_slice(2) { |k,v|
342
346
  key = accept(k)
343
347
  val = accept(v)
@@ -364,7 +368,7 @@ module Psych
364
368
  hash[key] = val
365
369
  end
366
370
  else
367
- if @symbolize_names
371
+ if !tagged && @symbolize_names && key.is_a?(String)
368
372
  key = key.to_sym
369
373
  elsif !@freeze
370
374
  key = deduplicate(key)
@@ -402,7 +406,7 @@ module Psych
402
406
 
403
407
  def revive klass, node
404
408
  s = register(node, klass.allocate)
405
- init_with(s, revive_hash({}, node), node)
409
+ init_with(s, revive_hash({}, node, true), node)
406
410
  end
407
411
 
408
412
  def init_with o, h, node
@@ -425,7 +429,7 @@ module Psych
425
429
 
426
430
  class NoAliasRuby < ToRuby
427
431
  def visit_Psych_Nodes_Alias o
428
- raise BadAlias, "Unknown alias: #{o.anchor}"
432
+ raise AliasesNotEnabled
429
433
  end
430
434
  end
431
435
  end
@@ -17,7 +17,7 @@ module Psych
17
17
 
18
18
  if defined?(Ractor)
19
19
  def dispatch
20
- Ractor.current[:Psych_Visitors_Visitor] ||= Visitor.dispatch_cache
20
+ @dispatch_cache ||= (Ractor.current[:Psych_Visitors_Visitor] ||= Visitor.dispatch_cache)
21
21
  end
22
22
  else
23
23
  DISPATCH = dispatch_cache
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
- require 'psych/tree_builder'
3
- require 'psych/scalar_scanner'
4
- require 'psych/class_loader'
2
+ require_relative '../tree_builder'
3
+ require_relative '../scalar_scanner'
4
+ require_relative '../class_loader'
5
5
 
6
6
  module Psych
7
7
  module Visitors
@@ -192,12 +192,13 @@ module Psych
192
192
  register o, @emitter.scalar(o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY)
193
193
  end
194
194
 
195
+ def visit_Date o
196
+ register o, visit_Integer(o.gregorian)
197
+ end
198
+
195
199
  def visit_DateTime o
196
- formatted = if o.offset.zero?
197
- o.strftime("%Y-%m-%d %H:%M:%S.%9N Z".freeze)
198
- else
199
- o.strftime("%Y-%m-%d %H:%M:%S.%9N %:z".freeze)
200
- end
200
+ t = o.italy
201
+ formatted = format_time t, t.offset.zero?
201
202
  tag = '!ruby/object:DateTime'
202
203
  register o, @emitter.scalar(formatted, nil, tag, false, false, Nodes::Scalar::ANY)
203
204
  end
@@ -235,7 +236,6 @@ module Psych
235
236
  end
236
237
  alias :visit_TrueClass :visit_Integer
237
238
  alias :visit_FalseClass :visit_Integer
238
- alias :visit_Date :visit_Integer
239
239
 
240
240
  def visit_Float o
241
241
  if o.nan?
@@ -272,6 +272,8 @@ module Psych
272
272
  tag = 'tag:yaml.org,2002:str'
273
273
  plain = false
274
274
  quote = false
275
+ elsif o == 'y' || o == 'n'
276
+ style = Nodes::Scalar::DOUBLE_QUOTED
275
277
  elsif @line_width && o.length > @line_width
276
278
  style = Nodes::Scalar::FOLDED
277
279
  elsif o =~ /^[^[:word:]][^"]*$/
@@ -480,8 +482,8 @@ module Psych
480
482
  @emitter.end_mapping
481
483
  end
482
484
 
483
- def format_time time
484
- if time.utc?
485
+ def format_time time, utc = time.utc?
486
+ if utc
485
487
  time.strftime("%Y-%m-%d %H:%M:%S.%9N Z")
486
488
  else
487
489
  time.strftime("%Y-%m-%d %H:%M:%S.%9N %:z")
@@ -509,9 +511,9 @@ module Psych
509
511
  def emit_coder c, o
510
512
  case c.type
511
513
  when :scalar
512
- @emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, Nodes::Scalar::ANY
514
+ @emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, c.style
513
515
  when :seq
514
- @emitter.start_sequence nil, c.tag, c.tag.nil?, Nodes::Sequence::BLOCK
516
+ @emitter.start_sequence nil, c.tag, c.tag.nil?, c.style
515
517
  c.seq.each do |thing|
516
518
  accept thing
517
519
  end
@@ -535,5 +537,51 @@ module Psych
535
537
  end
536
538
  end
537
539
  end
540
+
541
+ class RestrictedYAMLTree < YAMLTree
542
+ DEFAULT_PERMITTED_CLASSES = {
543
+ TrueClass => true,
544
+ FalseClass => true,
545
+ NilClass => true,
546
+ Integer => true,
547
+ Float => true,
548
+ String => true,
549
+ Array => true,
550
+ Hash => true,
551
+ }.compare_by_identity.freeze
552
+
553
+ def initialize emitter, ss, options
554
+ super
555
+ @permitted_classes = DEFAULT_PERMITTED_CLASSES.dup
556
+ Array(options[:permitted_classes]).each do |klass|
557
+ @permitted_classes[klass] = true
558
+ end
559
+ @permitted_symbols = {}.compare_by_identity
560
+ Array(options[:permitted_symbols]).each do |symbol|
561
+ @permitted_symbols[symbol] = true
562
+ end
563
+ @aliases = options.fetch(:aliases, false)
564
+ end
565
+
566
+ def accept target
567
+ if !@aliases && @st.key?(target)
568
+ raise BadAlias, "Tried to dump an aliased object"
569
+ end
570
+
571
+ unless Symbol === target || @permitted_classes[target.class]
572
+ raise DisallowedClass.new('dump', target.class.name || target.class.inspect)
573
+ end
574
+
575
+ super
576
+ end
577
+
578
+ def visit_Symbol sym
579
+ unless @permitted_classes[Symbol] || @permitted_symbols[sym]
580
+ raise DisallowedClass.new('dump', "Symbol(#{sym.inspect})")
581
+ end
582
+
583
+ super
584
+ end
585
+ end
538
586
  end
539
587
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
- require 'psych/visitors/visitor'
3
- require 'psych/visitors/to_ruby'
4
- require 'psych/visitors/emitter'
5
- require 'psych/visitors/yaml_tree'
6
- require 'psych/visitors/json_tree'
7
- require 'psych/visitors/depth_first'
2
+ require_relative 'visitors/visitor'
3
+ require_relative 'visitors/to_ruby'
4
+ require_relative 'visitors/emitter'
5
+ require_relative 'visitors/yaml_tree'
6
+ require_relative 'visitors/json_tree'
7
+ require_relative 'visitors/depth_first'
data/lib/psych.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
- require 'psych/versions'
2
+ require_relative 'psych/versions'
3
3
  case RUBY_ENGINE
4
4
  when 'jruby'
5
- require 'psych_jars'
5
+ require_relative 'psych_jars'
6
6
  if JRuby::Util.respond_to?(:load_ext)
7
7
  JRuby::Util.load_ext('org.jruby.ext.psych.PsychLibrary')
8
8
  else
@@ -12,28 +12,28 @@ when 'jruby'
12
12
  else
13
13
  require 'psych.so'
14
14
  end
15
- require 'psych/nodes'
16
- require 'psych/streaming'
17
- require 'psych/visitors'
18
- require 'psych/handler'
19
- require 'psych/tree_builder'
20
- require 'psych/parser'
21
- require 'psych/omap'
22
- require 'psych/set'
23
- require 'psych/coder'
24
- require 'psych/core_ext'
25
- require 'psych/stream'
26
- require 'psych/json/tree_builder'
27
- require 'psych/json/stream'
28
- require 'psych/handlers/document_stream'
29
- require 'psych/class_loader'
15
+ require_relative 'psych/nodes'
16
+ require_relative 'psych/streaming'
17
+ require_relative 'psych/visitors'
18
+ require_relative 'psych/handler'
19
+ require_relative 'psych/tree_builder'
20
+ require_relative 'psych/parser'
21
+ require_relative 'psych/omap'
22
+ require_relative 'psych/set'
23
+ require_relative 'psych/coder'
24
+ require_relative 'psych/core_ext'
25
+ require_relative 'psych/stream'
26
+ require_relative 'psych/json/tree_builder'
27
+ require_relative 'psych/json/stream'
28
+ require_relative 'psych/handlers/document_stream'
29
+ require_relative 'psych/class_loader'
30
30
 
31
31
  ###
32
32
  # = Overview
33
33
  #
34
34
  # Psych is a YAML parser and emitter.
35
35
  # Psych leverages libyaml [Home page: https://pyyaml.org/wiki/LibYAML]
36
- # or [HG repo: https://bitbucket.org/xi/libyaml] for its YAML parsing
36
+ # or [git repo: https://github.com/yaml/libyaml] for its YAML parsing
37
37
  # and emitting capabilities. In addition to wrapping libyaml, Psych also
38
38
  # knows how to serialize and de-serialize most Ruby objects to and from
39
39
  # the YAML format.
@@ -234,9 +234,6 @@ require 'psych/class_loader'
234
234
  module Psych
235
235
  # The version of libyaml Psych is using
236
236
  LIBYAML_VERSION = Psych.libyaml_version.join('.').freeze
237
- # Deprecation guard
238
- NOT_GIVEN = Object.new.freeze
239
- private_constant :NOT_GIVEN
240
237
 
241
238
  ###
242
239
  # Load +yaml+ in to a Ruby data structure. If multiple documents are
@@ -249,11 +246,11 @@ module Psych
249
246
  #
250
247
  # Example:
251
248
  #
252
- # Psych.load("--- a") # => 'a'
253
- # Psych.load("---\n - a\n - b") # => ['a', 'b']
249
+ # Psych.unsafe_load("--- a") # => 'a'
250
+ # Psych.unsafe_load("---\n - a\n - b") # => ['a', 'b']
254
251
  #
255
252
  # begin
256
- # Psych.load("--- `", filename: "file.txt")
253
+ # Psych.unsafe_load("--- `", filename: "file.txt")
257
254
  # rescue Psych::SyntaxError => ex
258
255
  # ex.file # => 'file.txt'
259
256
  # ex.message # => "(file.txt): found character that cannot start any token"
@@ -262,24 +259,19 @@ module Psych
262
259
  # When the optional +symbolize_names+ keyword argument is set to a
263
260
  # true value, returns symbols for keys in Hash objects (default: strings).
264
261
  #
265
- # Psych.load("---\n foo: bar") # => {"foo"=>"bar"}
266
- # Psych.load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
262
+ # Psych.unsafe_load("---\n foo: bar") # => {"foo"=>"bar"}
263
+ # Psych.unsafe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
267
264
  #
268
265
  # Raises a TypeError when `yaml` parameter is NilClass
269
266
  #
270
267
  # NOTE: This method *should not* be used to parse untrusted documents, such as
271
268
  # YAML documents that are supplied via user input. Instead, please use the
272
- # safe_load method.
269
+ # load method or the safe_load method.
273
270
  #
274
- def self.load yaml, legacy_filename = NOT_GIVEN, filename: nil, fallback: false, symbolize_names: false, freeze: false
275
- if legacy_filename != NOT_GIVEN
276
- warn_with_uplevel 'Passing filename with the 2nd argument of Psych.load is deprecated. Use keyword argument like Psych.load(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
277
- filename = legacy_filename
278
- end
279
-
271
+ def self.unsafe_load yaml, filename: nil, fallback: false, symbolize_names: false, freeze: false, strict_integer: false
280
272
  result = parse(yaml, filename: filename)
281
273
  return fallback unless result
282
- result.to_ruby(symbolize_names: symbolize_names, freeze: freeze)
274
+ result.to_ruby(symbolize_names: symbolize_names, freeze: freeze, strict_integer: strict_integer)
283
275
  end
284
276
 
285
277
  ###
@@ -289,7 +281,8 @@ module Psych
289
281
  # * TrueClass
290
282
  # * FalseClass
291
283
  # * NilClass
292
- # * Numeric
284
+ # * Integer
285
+ # * Float
293
286
  # * String
294
287
  # * Array
295
288
  # * Hash
@@ -314,7 +307,7 @@ module Psych
314
307
  # A Psych::DisallowedClass exception will be raised if the yaml contains a
315
308
  # class that isn't in the +permitted_classes+ list.
316
309
  #
317
- # A Psych::BadAlias exception will be raised if the yaml contains aliases
310
+ # A Psych::AliasesNotEnabled exception will be raised if the yaml contains aliases
318
311
  # but the +aliases+ keyword argument is set to false.
319
312
  #
320
313
  # +filename+ will be used in the exception message if any exception is raised
@@ -326,33 +319,13 @@ module Psych
326
319
  # Psych.safe_load("---\n foo: bar") # => {"foo"=>"bar"}
327
320
  # Psych.safe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
328
321
  #
329
- def self.safe_load yaml, legacy_permitted_classes = NOT_GIVEN, legacy_permitted_symbols = NOT_GIVEN, legacy_aliases = NOT_GIVEN, legacy_filename = NOT_GIVEN, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false
330
- if legacy_permitted_classes != NOT_GIVEN
331
- warn_with_uplevel 'Passing permitted_classes with the 2nd argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, permitted_classes: ...) instead.', uplevel: 1 if $VERBOSE
332
- permitted_classes = legacy_permitted_classes
333
- end
334
-
335
- if legacy_permitted_symbols != NOT_GIVEN
336
- warn_with_uplevel 'Passing permitted_symbols with the 3rd argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, permitted_symbols: ...) instead.', uplevel: 1 if $VERBOSE
337
- permitted_symbols = legacy_permitted_symbols
338
- end
339
-
340
- if legacy_aliases != NOT_GIVEN
341
- warn_with_uplevel 'Passing aliases with the 4th argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, aliases: ...) instead.', uplevel: 1 if $VERBOSE
342
- aliases = legacy_aliases
343
- end
344
-
345
- if legacy_filename != NOT_GIVEN
346
- warn_with_uplevel 'Passing filename with the 5th argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
347
- filename = legacy_filename
348
- end
349
-
322
+ def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false
350
323
  result = parse(yaml, filename: filename)
351
324
  return fallback unless result
352
325
 
353
326
  class_loader = ClassLoader::Restricted.new(permitted_classes.map(&:to_s),
354
327
  permitted_symbols.map(&:to_s))
355
- scanner = ScalarScanner.new class_loader
328
+ scanner = ScalarScanner.new class_loader, strict_integer: strict_integer
356
329
  visitor = if aliases
357
330
  Visitors::ToRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze
358
331
  else
@@ -362,6 +335,47 @@ module Psych
362
335
  result
363
336
  end
364
337
 
338
+ ###
339
+ # Load +yaml+ in to a Ruby data structure. If multiple documents are
340
+ # provided, the object contained in the first document will be returned.
341
+ # +filename+ will be used in the exception message if any exception
342
+ # is raised while parsing. If +yaml+ is empty, it returns
343
+ # the specified +fallback+ return value, which defaults to +false+.
344
+ #
345
+ # Raises a Psych::SyntaxError when a YAML syntax error is detected.
346
+ #
347
+ # Example:
348
+ #
349
+ # Psych.load("--- a") # => 'a'
350
+ # Psych.load("---\n - a\n - b") # => ['a', 'b']
351
+ #
352
+ # begin
353
+ # Psych.load("--- `", filename: "file.txt")
354
+ # rescue Psych::SyntaxError => ex
355
+ # ex.file # => 'file.txt'
356
+ # ex.message # => "(file.txt): found character that cannot start any token"
357
+ # end
358
+ #
359
+ # When the optional +symbolize_names+ keyword argument is set to a
360
+ # true value, returns symbols for keys in Hash objects (default: strings).
361
+ #
362
+ # Psych.load("---\n foo: bar") # => {"foo"=>"bar"}
363
+ # Psych.load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
364
+ #
365
+ # Raises a TypeError when `yaml` parameter is NilClass. This method is
366
+ # similar to `safe_load` except that `Symbol` objects are allowed by default.
367
+ #
368
+ def self.load yaml, permitted_classes: [Symbol], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false
369
+ safe_load yaml, permitted_classes: permitted_classes,
370
+ permitted_symbols: permitted_symbols,
371
+ aliases: aliases,
372
+ filename: filename,
373
+ fallback: fallback,
374
+ symbolize_names: symbolize_names,
375
+ freeze: freeze,
376
+ strict_integer: strict_integer
377
+ end
378
+
365
379
  ###
366
380
  # Parse a YAML string in +yaml+. Returns the Psych::Nodes::Document.
367
381
  # +filename+ is used in the exception message if a Psych::SyntaxError is
@@ -381,22 +395,12 @@ module Psych
381
395
  # end
382
396
  #
383
397
  # See Psych::Nodes for more information about YAML AST.
384
- def self.parse yaml, legacy_filename = NOT_GIVEN, filename: nil, fallback: NOT_GIVEN
385
- if legacy_filename != NOT_GIVEN
386
- warn_with_uplevel 'Passing filename with the 2nd argument of Psych.parse is deprecated. Use keyword argument like Psych.parse(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
387
- filename = legacy_filename
388
- end
389
-
398
+ def self.parse yaml, filename: nil
390
399
  parse_stream(yaml, filename: filename) do |node|
391
400
  return node
392
401
  end
393
402
 
394
- if fallback != NOT_GIVEN
395
- warn_with_uplevel 'Passing the `fallback` keyword argument of Psych.parse is deprecated.', uplevel: 1 if $VERBOSE
396
- fallback
397
- else
398
- false
399
- end
403
+ false
400
404
  end
401
405
 
402
406
  ###
@@ -445,12 +449,7 @@ module Psych
445
449
  # Raises a TypeError when NilClass is passed.
446
450
  #
447
451
  # See Psych::Nodes for more information about YAML AST.
448
- def self.parse_stream yaml, legacy_filename = NOT_GIVEN, filename: nil, &block
449
- if legacy_filename != NOT_GIVEN
450
- warn_with_uplevel 'Passing filename with the 2nd argument of Psych.parse_stream is deprecated. Use keyword argument like Psych.parse_stream(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
451
- filename = legacy_filename
452
- end
453
-
452
+ def self.parse_stream yaml, filename: nil, &block
454
453
  if block_given?
455
454
  parser = Psych::Parser.new(Handlers::DocumentStream.new(&block))
456
455
  parser.parse yaml, filename
@@ -514,6 +513,79 @@ module Psych
514
513
  visitor.tree.yaml io, options
515
514
  end
516
515
 
516
+ ###
517
+ # call-seq:
518
+ # Psych.safe_dump(o) -> string of yaml
519
+ # Psych.safe_dump(o, options) -> string of yaml
520
+ # Psych.safe_dump(o, io) -> io object passed in
521
+ # Psych.safe_dump(o, io, options) -> io object passed in
522
+ #
523
+ # Safely dump Ruby object +o+ to a YAML string. Optional +options+ may be passed in
524
+ # to control the output format. If an IO object is passed in, the YAML will
525
+ # be dumped to that IO object. By default, only the following
526
+ # classes are allowed to be serialized:
527
+ #
528
+ # * TrueClass
529
+ # * FalseClass
530
+ # * NilClass
531
+ # * Integer
532
+ # * Float
533
+ # * String
534
+ # * Array
535
+ # * Hash
536
+ #
537
+ # Arbitrary classes can be allowed by adding those classes to the +permitted_classes+
538
+ # keyword argument. They are additive. For example, to allow Date serialization:
539
+ #
540
+ # Psych.safe_dump(yaml, permitted_classes: [Date])
541
+ #
542
+ # Now the Date class can be dumped in addition to the classes listed above.
543
+ #
544
+ # A Psych::DisallowedClass exception will be raised if the object contains a
545
+ # class that isn't in the +permitted_classes+ list.
546
+ #
547
+ # Currently supported options are:
548
+ #
549
+ # [<tt>:indentation</tt>] Number of space characters used to indent.
550
+ # Acceptable value should be in <tt>0..9</tt> range,
551
+ # otherwise option is ignored.
552
+ #
553
+ # Default: <tt>2</tt>.
554
+ # [<tt>:line_width</tt>] Max character to wrap line at.
555
+ #
556
+ # Default: <tt>0</tt> (meaning "wrap at 81").
557
+ # [<tt>:canonical</tt>] Write "canonical" YAML form (very verbose, yet
558
+ # strictly formal).
559
+ #
560
+ # Default: <tt>false</tt>.
561
+ # [<tt>:header</tt>] Write <tt>%YAML [version]</tt> at the beginning of document.
562
+ #
563
+ # Default: <tt>false</tt>.
564
+ #
565
+ # Example:
566
+ #
567
+ # # Dump an array, get back a YAML string
568
+ # Psych.safe_dump(['a', 'b']) # => "---\n- a\n- b\n"
569
+ #
570
+ # # Dump an array to an IO object
571
+ # Psych.safe_dump(['a', 'b'], StringIO.new) # => #<StringIO:0x000001009d0890>
572
+ #
573
+ # # Dump an array with indentation set
574
+ # Psych.safe_dump(['a', ['b']], indentation: 3) # => "---\n- a\n- - b\n"
575
+ #
576
+ # # Dump an array to an IO with indentation set
577
+ # Psych.safe_dump(['a', ['b']], StringIO.new, indentation: 3)
578
+ def self.safe_dump o, io = nil, options = {}
579
+ if Hash === io
580
+ options = io
581
+ io = nil
582
+ end
583
+
584
+ visitor = Psych::Visitors::RestrictedYAMLTree.create options
585
+ visitor << o
586
+ visitor.tree.yaml io, options
587
+ end
588
+
517
589
  ###
518
590
  # Dump a list of objects as separate documents to a document stream.
519
591
  #
@@ -551,12 +623,7 @@ module Psych
551
623
  # end
552
624
  # list # => ['foo', 'bar']
553
625
  #
554
- def self.load_stream yaml, legacy_filename = NOT_GIVEN, filename: nil, fallback: [], **kwargs
555
- if legacy_filename != NOT_GIVEN
556
- warn_with_uplevel 'Passing filename with the 2nd argument of Psych.load_stream is deprecated. Use keyword argument like Psych.load_stream(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
557
- filename = legacy_filename
558
- end
559
-
626
+ def self.load_stream yaml, filename: nil, fallback: [], **kwargs
560
627
  result = if block_given?
561
628
  parse_stream(yaml, filename: filename) do |node|
562
629
  yield node.to_ruby(**kwargs)
@@ -577,9 +644,9 @@ module Psych
577
644
  # NOTE: This method *should not* be used to parse untrusted documents, such as
578
645
  # YAML documents that are supplied via user input. Instead, please use the
579
646
  # safe_load_file method.
580
- def self.load_file filename, **kwargs
647
+ def self.unsafe_load_file filename, **kwargs
581
648
  File.open(filename, 'r:bom|utf-8') { |f|
582
- self.load f, filename: filename, **kwargs
649
+ self.unsafe_load f, filename: filename, **kwargs
583
650
  }
584
651
  end
585
652
 
@@ -594,6 +661,17 @@ module Psych
594
661
  }
595
662
  end
596
663
 
664
+ ###
665
+ # Loads the document contained in +filename+. Returns the yaml contained in
666
+ # +filename+ as a Ruby object, or if the file is empty, it returns
667
+ # the specified +fallback+ return value, which defaults to +false+.
668
+ # See load for options.
669
+ def self.load_file filename, **kwargs
670
+ File.open(filename, 'r:bom|utf-8') { |f|
671
+ self.load f, filename: filename, **kwargs
672
+ }
673
+ end
674
+
597
675
  # :stopdoc:
598
676
  def self.add_domain_type domain, type_tag, &block
599
677
  key = ['tag', domain, type_tag].join ':'
data/psych.gemspec CHANGED
@@ -27,9 +27,6 @@ DESCRIPTION
27
27
  "bin/setup", "ext/psych/depend", "ext/psych/extconf.rb", "ext/psych/psych.c", "ext/psych/psych.h",
28
28
  "ext/psych/psych_emitter.c", "ext/psych/psych_emitter.h", "ext/psych/psych_parser.c", "ext/psych/psych_parser.h",
29
29
  "ext/psych/psych_to_ruby.c", "ext/psych/psych_to_ruby.h", "ext/psych/psych_yaml_tree.c", "ext/psych/psych_yaml_tree.h",
30
- "ext/psych/yaml/LICENSE", "ext/psych/yaml/api.c", "ext/psych/yaml/config.h", "ext/psych/yaml/dumper.c",
31
- "ext/psych/yaml/emitter.c", "ext/psych/yaml/loader.c", "ext/psych/yaml/parser.c", "ext/psych/yaml/reader.c",
32
- "ext/psych/yaml/scanner.c", "ext/psych/yaml/writer.c", "ext/psych/yaml/yaml.h", "ext/psych/yaml/yaml_private.h",
33
30
  "lib/psych.rb", "lib/psych/class_loader.rb", "lib/psych/coder.rb", "lib/psych/core_ext.rb", "lib/psych/exception.rb",
34
31
  "lib/psych/handler.rb", "lib/psych/handlers/document_stream.rb", "lib/psych/handlers/recorder.rb",
35
32
  "lib/psych/json/ruby_events.rb", "lib/psych/json/stream.rb", "lib/psych/json/tree_builder.rb",
@@ -55,13 +52,16 @@ DESCRIPTION
55
52
  "ext/java/org/jruby/ext/psych/PsychLibrary.java",
56
53
  "ext/java/org/jruby/ext/psych/PsychParser.java",
57
54
  "ext/java/org/jruby/ext/psych/PsychToRuby.java",
58
- "ext/java/org/jruby/ext/psych/PsychYamlTree.java",
59
55
  "lib/psych_jars.rb",
60
56
  "lib/psych.jar"
61
57
  ]
62
- s.requirements = "jar org.yaml:snakeyaml, #{version_module::Psych::DEFAULT_SNAKEYAML_VERSION}"
58
+ s.requirements = "jar org.snakeyaml:snakeyaml-engine, #{version_module::Psych::DEFAULT_SNAKEYAML_VERSION}"
63
59
  s.add_dependency 'jar-dependencies', '>= 0.1.7'
64
60
  else
65
61
  s.extensions = ["ext/psych/extconf.rb"]
62
+ s.add_dependency 'stringio'
66
63
  end
64
+
65
+ s.metadata['msys2_mingw_dependencies'] = 'libyaml'
66
+
67
67
  end