psych 2.2.1 → 5.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. data/CONTRIBUTING.md +24 -0
  3. data/{ext/psych/yaml/LICENSE → LICENSE} +9 -7
  4. data/README.md +13 -13
  5. data/ext/psych/depend +14 -0
  6. data/ext/psych/extconf.rb +43 -29
  7. data/ext/psych/psych.c +6 -3
  8. data/ext/psych/psych_emitter.c +10 -9
  9. data/ext/psych/psych_parser.c +69 -72
  10. data/ext/psych/psych_yaml_tree.c +0 -12
  11. data/lib/psych/class_loader.rb +11 -9
  12. data/lib/psych/coder.rb +1 -1
  13. data/lib/psych/core_ext.rb +3 -20
  14. data/lib/psych/exception.rb +17 -3
  15. data/lib/psych/handler.rb +8 -3
  16. data/lib/psych/handlers/document_stream.rb +2 -2
  17. data/lib/psych/handlers/recorder.rb +2 -2
  18. data/lib/psych/json/ruby_events.rb +1 -1
  19. data/lib/psych/json/stream.rb +3 -3
  20. data/lib/psych/json/tree_builder.rb +2 -2
  21. data/lib/psych/json/yaml_events.rb +1 -1
  22. data/lib/psych/nodes/alias.rb +3 -1
  23. data/lib/psych/nodes/document.rb +3 -1
  24. data/lib/psych/nodes/mapping.rb +3 -1
  25. data/lib/psych/nodes/node.rb +24 -5
  26. data/lib/psych/nodes/scalar.rb +4 -2
  27. data/lib/psych/nodes/sequence.rb +3 -1
  28. data/lib/psych/nodes/stream.rb +3 -1
  29. data/lib/psych/nodes.rb +8 -8
  30. data/lib/psych/omap.rb +1 -1
  31. data/lib/psych/parser.rb +14 -1
  32. data/lib/psych/scalar_scanner.rb +39 -47
  33. data/lib/psych/set.rb +1 -1
  34. data/lib/psych/stream.rb +1 -1
  35. data/lib/psych/streaming.rb +1 -1
  36. data/lib/psych/syntax_error.rb +2 -2
  37. data/lib/psych/tree_builder.rb +48 -8
  38. data/lib/psych/versions.rb +5 -4
  39. data/lib/psych/visitors/depth_first.rb +1 -1
  40. data/lib/psych/visitors/emitter.rb +1 -1
  41. data/lib/psych/visitors/json_tree.rb +2 -2
  42. data/lib/psych/visitors/to_ruby.rb +61 -31
  43. data/lib/psych/visitors/visitor.rb +18 -4
  44. data/lib/psych/visitors/yaml_tree.rb +111 -123
  45. data/lib/psych/visitors.rb +7 -7
  46. data/lib/psych/y.rb +1 -1
  47. data/lib/psych.rb +333 -96
  48. metadata +16 -52
  49. data/.gitignore +0 -14
  50. data/.travis.yml +0 -18
  51. data/CHANGELOG.rdoc +0 -576
  52. data/Gemfile +0 -3
  53. data/Mavenfile +0 -7
  54. data/Rakefile +0 -33
  55. data/bin/console +0 -7
  56. data/bin/setup +0 -6
  57. data/ext/psych/.gitignore +0 -11
  58. data/ext/psych/yaml/api.c +0 -1392
  59. data/ext/psych/yaml/config.h +0 -10
  60. data/ext/psych/yaml/dumper.c +0 -394
  61. data/ext/psych/yaml/emitter.c +0 -2329
  62. data/ext/psych/yaml/loader.c +0 -444
  63. data/ext/psych/yaml/parser.c +0 -1374
  64. data/ext/psych/yaml/reader.c +0 -469
  65. data/ext/psych/yaml/scanner.c +0 -3576
  66. data/ext/psych/yaml/writer.c +0 -141
  67. data/ext/psych/yaml/yaml.h +0 -1971
  68. data/ext/psych/yaml/yaml_private.h +0 -662
  69. data/lib/psych/deprecated.rb +0 -86
  70. data/psych.gemspec +0 -43
@@ -1,7 +1,7 @@
1
- # frozen_string_literal: false
2
- require 'psych/tree_builder'
3
- require 'psych/scalar_scanner'
4
- require 'psych/class_loader'
1
+ # frozen_string_literal: true
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
@@ -15,30 +15,29 @@ module Psych
15
15
  class YAMLTree < Psych::Visitors::Visitor
16
16
  class Registrar # :nodoc:
17
17
  def initialize
18
- @obj_to_id = {}
19
- @obj_to_node = {}
18
+ @obj_to_id = {}.compare_by_identity
19
+ @obj_to_node = {}.compare_by_identity
20
20
  @targets = []
21
21
  @counter = 0
22
22
  end
23
23
 
24
24
  def register target, node
25
- return unless target.respond_to? :object_id
26
25
  @targets << target
27
- @obj_to_node[target.object_id] = node
26
+ @obj_to_node[target] = node
28
27
  end
29
28
 
30
29
  def key? target
31
- @obj_to_node.key? target.object_id
30
+ @obj_to_node.key? target
32
31
  rescue NoMethodError
33
32
  false
34
33
  end
35
34
 
36
35
  def id_for target
37
- @obj_to_id[target.object_id] ||= (@counter += 1)
36
+ @obj_to_id[target] ||= (@counter += 1)
38
37
  end
39
38
 
40
39
  def node_for target
41
- @obj_to_node[target.object_id]
40
+ @obj_to_node[target]
42
41
  end
43
42
  end
44
43
 
@@ -53,15 +52,6 @@ module Psych
53
52
  new(emitter, ss, options)
54
53
  end
55
54
 
56
- def self.new emitter = nil, ss = nil, options = nil
57
- return super if emitter && ss && options
58
-
59
- if $VERBOSE
60
- warn "This API is deprecated, please pass an emitter, scalar scanner, and options or call #{self}.create() (#{caller.first})"
61
- end
62
- create emitter, ss
63
- end
64
-
65
55
  def initialize emitter, ss, options
66
56
  super()
67
57
  @started = false
@@ -89,7 +79,7 @@ module Psych
89
79
  raise(TypeError, "Can't dump #{target.class}") unless method
90
80
 
91
81
  h[klass] = method
92
- end
82
+ end.compare_by_identity
93
83
  end
94
84
 
95
85
  def start encoding = Nodes::Stream::UTF8
@@ -139,24 +129,6 @@ module Psych
139
129
  return @emitter.alias anchor
140
130
  end
141
131
 
142
- if target.respond_to?(:to_yaml)
143
- begin
144
- loc = target.method(:to_yaml).source_location.first
145
- if loc !~ /(syck\/rubytypes.rb|psych\/core_ext.rb)/
146
- unless target.respond_to?(:encode_with)
147
- if $VERBOSE
148
- warn "implementing to_yaml is deprecated, please implement \"encode_with\""
149
- end
150
-
151
- target.to_yaml(:nodump => true)
152
- end
153
- end
154
- rescue
155
- # public_method or source_location might be overridden,
156
- # and it's OK to skip it since it's only to emit a warning
157
- end
158
- end
159
-
160
132
  if target.respond_to?(:encode_with)
161
133
  dump_coder target
162
134
  else
@@ -191,6 +163,8 @@ module Psych
191
163
  @emitter.end_mapping
192
164
  end
193
165
 
166
+ alias :visit_Delegator :visit_Object
167
+
194
168
  def visit_Struct o
195
169
  tag = ['!ruby/struct', o.class.name].compact.join(':')
196
170
 
@@ -206,53 +180,24 @@ module Psych
206
180
  end
207
181
 
208
182
  def visit_Exception o
209
- tag = ['!ruby/exception', o.class.name].join ':'
210
-
211
- @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK
212
-
213
- {
214
- 'message' => private_iv_get(o, 'mesg'),
215
- 'backtrace' => private_iv_get(o, 'backtrace'),
216
- }.each do |k,v|
217
- next unless v
218
- @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY
219
- accept v
220
- end
221
-
222
- dump_ivars o
223
-
224
- @emitter.end_mapping
183
+ dump_exception o, o.message.to_s
225
184
  end
226
185
 
227
186
  def visit_NameError o
228
- tag = ['!ruby/exception', o.class.name].join ':'
229
-
230
- @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK
231
-
232
- {
233
- 'message' => o.message.to_s,
234
- 'backtrace' => private_iv_get(o, 'backtrace'),
235
- }.each do |k,v|
236
- next unless v
237
- @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY
238
- accept v
239
- end
240
-
241
- dump_ivars o
242
-
243
- @emitter.end_mapping
187
+ dump_exception o, o.message.to_s
244
188
  end
245
189
 
246
190
  def visit_Regexp o
247
191
  register o, @emitter.scalar(o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY)
248
192
  end
249
193
 
194
+ def visit_Date o
195
+ register o, visit_Integer(o.gregorian)
196
+ end
197
+
250
198
  def visit_DateTime o
251
- formatted = if o.offset.zero?
252
- o.strftime("%Y-%m-%d %H:%M:%S.%9N Z".freeze)
253
- else
254
- o.strftime("%Y-%m-%d %H:%M:%S.%9N %:z".freeze)
255
- end
199
+ t = o.italy
200
+ formatted = format_time t, t.offset.zero?
256
201
  tag = '!ruby/object:DateTime'
257
202
  register o, @emitter.scalar(formatted, nil, tag, false, false, Nodes::Scalar::ANY)
258
203
  end
@@ -290,7 +235,6 @@ module Psych
290
235
  end
291
236
  alias :visit_TrueClass :visit_Integer
292
237
  alias :visit_FalseClass :visit_Integer
293
- alias :visit_Date :visit_Integer
294
238
 
295
239
  def visit_Float o
296
240
  if o.nan?
@@ -327,6 +271,8 @@ module Psych
327
271
  tag = 'tag:yaml.org,2002:str'
328
272
  plain = false
329
273
  quote = false
274
+ elsif o == 'y' || o == 'n'
275
+ style = Nodes::Scalar::DOUBLE_QUOTED
330
276
  elsif @line_width && o.length > @line_width
331
277
  style = Nodes::Scalar::FOLDED
332
278
  elsif o =~ /^[^[:word:]][^"]*$/
@@ -336,7 +282,7 @@ module Psych
336
282
  end
337
283
 
338
284
  is_primitive = o.class == ::String
339
- ivars = find_ivars o, is_primitive
285
+ ivars = is_primitive ? [] : o.instance_variables
340
286
 
341
287
  if ivars.empty?
342
288
  unless is_primitive
@@ -346,7 +292,7 @@ module Psych
346
292
  end
347
293
  @emitter.scalar o, nil, tag, plain, quote, style
348
294
  else
349
- maptag = '!ruby/string'
295
+ maptag = '!ruby/string'.dup
350
296
  maptag << ":#{o.class}" unless o.class == ::String
351
297
 
352
298
  register o, @emitter.start_mapping(nil, maptag, false, Nodes::Mapping::BLOCK)
@@ -403,14 +349,18 @@ module Psych
403
349
 
404
350
  def visit_Array o
405
351
  if o.class == ::Array
406
- register o, @emitter.start_sequence(nil, nil, true, Nodes::Sequence::BLOCK)
407
- o.each { |c| accept c }
408
- @emitter.end_sequence
352
+ visit_Enumerator o
409
353
  else
410
354
  visit_array_subclass o
411
355
  end
412
356
  end
413
357
 
358
+ def visit_Enumerator o
359
+ register o, @emitter.start_sequence(nil, nil, true, Nodes::Sequence::BLOCK)
360
+ o.each { |c| accept c }
361
+ @emitter.end_sequence
362
+ end
363
+
414
364
  def visit_NilClass o
415
365
  @emitter.scalar('', nil, 'tag:yaml.org,2002:null', true, false, Nodes::Scalar::ANY)
416
366
  end
@@ -436,15 +386,9 @@ module Psych
436
386
  end
437
387
 
438
388
  private
439
- # FIXME: Remove the index and count checks in Psych 3.0
440
- NULL = "\x00"
441
- BINARY_RANGE = "\x00-\x7F"
442
- WS_RANGE = "^ -~\t\r\n"
443
389
 
444
390
  def binary? string
445
- (string.encoding == Encoding::ASCII_8BIT && !string.ascii_only?) ||
446
- string.index(NULL) ||
447
- string.count(BINARY_RANGE, WS_RANGE).fdiv(string.length) > 0.3
391
+ string.encoding == Encoding::ASCII_8BIT && !string.ascii_only?
448
392
  end
449
393
 
450
394
  def visit_array_subclass o
@@ -485,15 +429,6 @@ module Psych
485
429
  node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK)
486
430
  register(o, node)
487
431
 
488
- # Dump the elements
489
- accept 'elements'
490
- @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
491
- o.each do |k,v|
492
- accept k
493
- accept v
494
- end
495
- @emitter.end_mapping
496
-
497
432
  # Dump the ivars
498
433
  accept 'ivars'
499
434
  @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
@@ -503,6 +438,15 @@ module Psych
503
438
  end
504
439
  @emitter.end_mapping
505
440
 
441
+ # Dump the elements
442
+ accept 'elements'
443
+ @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
444
+ o.each do |k,v|
445
+ accept k
446
+ accept v
447
+ end
448
+ @emitter.end_mapping
449
+
506
450
  @emitter.end_mapping
507
451
  else
508
452
  tag = "!ruby/hash:#{o.class}"
@@ -519,30 +463,30 @@ module Psych
519
463
  def dump_list o
520
464
  end
521
465
 
522
- def format_time time
523
- if time.utc?
524
- time.strftime("%Y-%m-%d %H:%M:%S.%9N Z")
525
- else
526
- time.strftime("%Y-%m-%d %H:%M:%S.%9N %:z")
466
+ def dump_exception o, msg
467
+ tag = ['!ruby/exception', o.class.name].join ':'
468
+
469
+ @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK
470
+
471
+ if msg
472
+ @emitter.scalar 'message', nil, nil, true, false, Nodes::Scalar::ANY
473
+ accept msg
527
474
  end
475
+
476
+ @emitter.scalar 'backtrace', nil, nil, true, false, Nodes::Scalar::ANY
477
+ accept o.backtrace
478
+
479
+ dump_ivars o
480
+
481
+ @emitter.end_mapping
528
482
  end
529
483
 
530
- # FIXME: remove this method once "to_yaml_properties" is removed
531
- def find_ivars target, is_primitive=false
532
- begin
533
- loc = target.method(:to_yaml_properties).source_location.first
534
- unless loc.start_with?(Psych::DEPRECATED) || loc.end_with?('rubytypes.rb')
535
- if $VERBOSE
536
- warn "#{loc}: to_yaml_properties is deprecated, please implement \"encode_with(coder)\""
537
- end
538
- return target.to_yaml_properties
539
- end
540
- rescue
541
- # public_method or source_location might be overridden,
542
- # and it's OK to skip it since it's only to emit a warning.
484
+ def format_time time, utc = time.utc?
485
+ if utc
486
+ time.strftime("%Y-%m-%d %H:%M:%S.%9N Z")
487
+ else
488
+ time.strftime("%Y-%m-%d %H:%M:%S.%9N %:z")
543
489
  end
544
-
545
- is_primitive ? [] : target.instance_variables
546
490
  end
547
491
 
548
492
  def register target, yaml_obj
@@ -566,9 +510,9 @@ module Psych
566
510
  def emit_coder c, o
567
511
  case c.type
568
512
  when :scalar
569
- @emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, Nodes::Scalar::ANY
513
+ @emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, c.style
570
514
  when :seq
571
- @emitter.start_sequence nil, c.tag, c.tag.nil?, Nodes::Sequence::BLOCK
515
+ @emitter.start_sequence nil, c.tag, c.tag.nil?, c.style
572
516
  c.seq.each do |thing|
573
517
  accept thing
574
518
  end
@@ -586,13 +530,57 @@ module Psych
586
530
  end
587
531
 
588
532
  def dump_ivars target
589
- ivars = find_ivars target
590
-
591
- ivars.each do |iv|
533
+ target.instance_variables.each do |iv|
592
534
  @emitter.scalar("#{iv.to_s.sub(/^@/, '')}", nil, nil, true, false, Nodes::Scalar::ANY)
593
535
  accept target.instance_variable_get(iv)
594
536
  end
595
537
  end
596
538
  end
539
+
540
+ class RestrictedYAMLTree < YAMLTree
541
+ DEFAULT_PERMITTED_CLASSES = {
542
+ TrueClass => true,
543
+ FalseClass => true,
544
+ NilClass => true,
545
+ Integer => true,
546
+ Float => true,
547
+ String => true,
548
+ Array => true,
549
+ Hash => true,
550
+ }.compare_by_identity.freeze
551
+
552
+ def initialize emitter, ss, options
553
+ super
554
+ @permitted_classes = DEFAULT_PERMITTED_CLASSES.dup
555
+ Array(options[:permitted_classes]).each do |klass|
556
+ @permitted_classes[klass] = true
557
+ end
558
+ @permitted_symbols = {}.compare_by_identity
559
+ Array(options[:permitted_symbols]).each do |symbol|
560
+ @permitted_symbols[symbol] = true
561
+ end
562
+ @aliases = options.fetch(:aliases, false)
563
+ end
564
+
565
+ def accept target
566
+ if !@aliases && @st.key?(target)
567
+ raise BadAlias, "Tried to dump an aliased object"
568
+ end
569
+
570
+ unless Symbol === target || @permitted_classes[target.class]
571
+ raise DisallowedClass.new('dump', target.class.name || target.class.inspect)
572
+ end
573
+
574
+ super
575
+ end
576
+
577
+ def visit_Symbol sym
578
+ unless @permitted_classes[Symbol] || @permitted_symbols[sym]
579
+ raise DisallowedClass.new('dump', "Symbol(#{sym.inspect})")
580
+ end
581
+
582
+ super
583
+ end
584
+ end
597
585
  end
598
586
  end
@@ -1,7 +1,7 @@
1
- # frozen_string_literal: false
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'
1
+ # frozen_string_literal: true
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/y.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  module Kernel
3
3
  ###
4
4
  # An alias for Psych.dump_stream meant to be used with IRB.