psych 1.3.4 → 2.0.0

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 (88) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.rdoc +138 -0
  3. data/Manifest.txt +27 -8
  4. data/README.rdoc +23 -2
  5. data/Rakefile +1 -1
  6. data/ext/psych/depend +3 -0
  7. data/ext/psych/extconf.rb +27 -11
  8. data/ext/psych/psych.h +4 -4
  9. data/ext/psych/{emitter.c → psych_emitter.c} +0 -0
  10. data/ext/psych/{emitter.h → psych_emitter.h} +0 -0
  11. data/ext/psych/{parser.c → psych_parser.c} +1 -1
  12. data/ext/psych/{parser.h → psych_parser.h} +0 -0
  13. data/ext/psych/{to_ruby.c → psych_to_ruby.c} +3 -1
  14. data/ext/psych/{to_ruby.h → psych_to_ruby.h} +0 -0
  15. data/ext/psych/{yaml_tree.c → psych_yaml_tree.c} +0 -0
  16. data/ext/psych/{yaml_tree.h → psych_yaml_tree.h} +0 -0
  17. data/ext/psych/yaml/LICENSE +19 -0
  18. data/ext/psych/yaml/api.c +1392 -0
  19. data/ext/psych/yaml/config.h +11 -0
  20. data/ext/psych/yaml/dumper.c +394 -0
  21. data/ext/psych/yaml/emitter.c +2329 -0
  22. data/ext/psych/yaml/loader.c +432 -0
  23. data/ext/psych/yaml/parser.c +1374 -0
  24. data/ext/psych/yaml/reader.c +465 -0
  25. data/ext/psych/yaml/scanner.c +3570 -0
  26. data/ext/psych/yaml/writer.c +141 -0
  27. data/ext/psych/yaml/yaml.h +1971 -0
  28. data/ext/psych/yaml/yaml_private.h +643 -0
  29. data/lib/psych.rb +217 -51
  30. data/lib/psych/class_loader.rb +101 -0
  31. data/lib/psych/core_ext.rb +1 -8
  32. data/lib/psych/deprecated.rb +3 -1
  33. data/lib/psych/exception.rb +13 -0
  34. data/lib/psych/handler.rb +13 -0
  35. data/lib/psych/handlers/recorder.rb +39 -0
  36. data/lib/psych/json/stream.rb +1 -0
  37. data/lib/psych/nodes/node.rb +3 -1
  38. data/lib/psych/scalar_scanner.rb +46 -25
  39. data/lib/psych/stream.rb +1 -0
  40. data/lib/psych/streaming.rb +10 -5
  41. data/lib/psych/syntax_error.rb +3 -1
  42. data/lib/psych/visitors/json_tree.rb +5 -2
  43. data/lib/psych/visitors/to_ruby.rb +123 -75
  44. data/lib/psych/visitors/yaml_tree.rb +59 -17
  45. data/lib/psych/y.rb +9 -0
  46. data/test/psych/handlers/test_recorder.rb +25 -0
  47. data/test/psych/helper.rb +30 -1
  48. data/test/psych/test_alias_and_anchor.rb +1 -1
  49. data/test/psych/test_array.rb +1 -1
  50. data/test/psych/test_boolean.rb +1 -1
  51. data/test/psych/test_class.rb +1 -1
  52. data/test/psych/test_coder.rb +3 -3
  53. data/test/psych/test_date_time.rb +1 -1
  54. data/test/psych/test_deprecated.rb +6 -2
  55. data/test/psych/test_document.rb +1 -1
  56. data/test/psych/test_emitter.rb +1 -1
  57. data/test/psych/test_encoding.rb +51 -65
  58. data/test/psych/test_engine_manager.rb +1 -11
  59. data/test/psych/test_exception.rb +40 -19
  60. data/test/psych/test_hash.rb +1 -1
  61. data/test/psych/test_json_tree.rb +1 -1
  62. data/test/psych/test_merge_keys.rb +52 -1
  63. data/test/psych/test_nil.rb +1 -1
  64. data/test/psych/test_null.rb +1 -1
  65. data/test/psych/test_numeric.rb +21 -1
  66. data/test/psych/test_object.rb +1 -1
  67. data/test/psych/test_object_references.rb +3 -3
  68. data/test/psych/test_omap.rb +1 -1
  69. data/test/psych/test_parser.rb +1 -1
  70. data/test/psych/test_psych.rb +15 -15
  71. data/test/psych/test_safe_load.rb +97 -0
  72. data/test/psych/test_scalar.rb +1 -1
  73. data/test/psych/test_scalar_scanner.rb +17 -2
  74. data/test/psych/test_serialize_subclasses.rb +1 -1
  75. data/test/psych/test_set.rb +1 -1
  76. data/test/psych/test_stream.rb +1 -1
  77. data/test/psych/test_string.rb +51 -3
  78. data/test/psych/test_struct.rb +1 -1
  79. data/test/psych/test_symbol.rb +1 -1
  80. data/test/psych/test_tainted.rb +8 -8
  81. data/test/psych/test_to_yaml_properties.rb +1 -1
  82. data/test/psych/test_tree_builder.rb +1 -1
  83. data/test/psych/test_yaml.rb +22 -2
  84. data/test/psych/test_yamldbm.rb +1 -1
  85. data/test/psych/test_yamlstore.rb +1 -1
  86. data/test/psych/visitors/test_to_ruby.rb +5 -4
  87. data/test/psych/visitors/test_yaml_tree.rb +19 -1
  88. metadata +45 -34
@@ -1,12 +1,8 @@
1
- require 'psych/helper'
1
+ require_relative 'helper'
2
2
  require 'yaml'
3
3
 
4
4
  module Psych
5
5
  class TestEngineManager < TestCase
6
- def teardown
7
- YAML::ENGINE.yamler = 'syck'
8
- end
9
-
10
6
  def test_bad_engine
11
7
  assert_raises(ArgumentError) do
12
8
  YAML::ENGINE.yamler = 'foooo'
@@ -19,12 +15,6 @@ module Psych
19
15
  assert_equal 'psych', YAML::ENGINE.yamler
20
16
  end
21
17
 
22
- def test_set_syck
23
- YAML::ENGINE.yamler = 'syck'
24
- assert_equal ::Syck, YAML
25
- assert_equal 'syck', YAML::ENGINE.yamler
26
- end
27
-
28
18
  A = Struct.new(:name)
29
19
 
30
20
  def test_dump_types
@@ -1,4 +1,4 @@
1
- require 'psych/helper'
1
+ require_relative 'helper'
2
2
 
3
3
  module Psych
4
4
  class TestException < TestCase
@@ -56,27 +56,27 @@ module Psych
56
56
  end
57
57
 
58
58
  def test_parse_file_exception
59
- t = Tempfile.new(['parsefile', 'yml'])
60
- t.binmode
61
- t.write '--- `'
62
- t.close
63
- ex = assert_raises(Psych::SyntaxError) do
64
- Psych.parse_file t.path
65
- end
66
- assert_equal t.path, ex.file
67
- t.close(true)
59
+ Tempfile.create(['parsefile', 'yml']) {|t|
60
+ t.binmode
61
+ t.write '--- `'
62
+ t.close
63
+ ex = assert_raises(Psych::SyntaxError) do
64
+ Psych.parse_file t.path
65
+ end
66
+ assert_equal t.path, ex.file
67
+ }
68
68
  end
69
69
 
70
70
  def test_load_file_exception
71
- t = Tempfile.new(['loadfile', 'yml'])
72
- t.binmode
73
- t.write '--- `'
74
- t.close
75
- ex = assert_raises(Psych::SyntaxError) do
76
- Psych.load_file t.path
77
- end
78
- assert_equal t.path, ex.file
79
- t.close(true)
71
+ Tempfile.create(['loadfile', 'yml']) {|t|
72
+ t.binmode
73
+ t.write '--- `'
74
+ t.close
75
+ ex = assert_raises(Psych::SyntaxError) do
76
+ Psych.load_file t.path
77
+ end
78
+ assert_equal t.path, ex.file
79
+ }
80
80
  end
81
81
 
82
82
  def test_psych_parse_takes_file
@@ -126,5 +126,26 @@ module Psych
126
126
  assert_equal 1, w.foo
127
127
  assert_nil w.bar
128
128
  end
129
+
130
+ def test_psych_syntax_error
131
+ Tempfile.create(['parsefile', 'yml']) do |t|
132
+ t.binmode
133
+ t.write '--- `'
134
+ t.close
135
+
136
+ begin
137
+ Psych.parse_file t.path
138
+ rescue StandardError
139
+ assert true # count assertion
140
+ ensure
141
+ return unless $!
142
+
143
+ ancestors = $!.class.ancestors.inspect
144
+
145
+ flunk "Psych::SyntaxError not rescued by StandardError: #{ancestors}"
146
+ end
147
+ end
148
+ end
149
+
129
150
  end
130
151
  end
@@ -1,4 +1,4 @@
1
- require 'psych/helper'
1
+ require_relative 'helper'
2
2
 
3
3
  module Psych
4
4
  class TestHash < TestCase
@@ -1,4 +1,4 @@
1
- require 'psych/helper'
1
+ require_relative 'helper'
2
2
 
3
3
  module Psych
4
4
  class TestJSONTree < TestCase
@@ -1,7 +1,58 @@
1
- require 'psych/helper'
1
+ require_relative 'helper'
2
2
 
3
3
  module Psych
4
4
  class TestMergeKeys < TestCase
5
+ def test_merge_nil
6
+ yaml = <<-eoyml
7
+ defaults: &defaults
8
+ development:
9
+ <<: *defaults
10
+ eoyml
11
+ assert_equal({'<<' => nil }, Psych.load(yaml)['development'])
12
+ end
13
+
14
+ def test_merge_array
15
+ yaml = <<-eoyml
16
+ foo: &hello
17
+ - 1
18
+ baz:
19
+ <<: *hello
20
+ eoyml
21
+ assert_equal({'<<' => [1]}, Psych.load(yaml)['baz'])
22
+ end
23
+
24
+ def test_merge_is_not_partial
25
+ yaml = <<-eoyml
26
+ default: &default
27
+ hello: world
28
+ foo: &hello
29
+ - 1
30
+ baz:
31
+ <<: [*hello, *default]
32
+ eoyml
33
+ doc = Psych.load yaml
34
+ refute doc['baz'].key? 'hello'
35
+ assert_equal({'<<' => [[1], {"hello"=>"world"}]}, Psych.load(yaml)['baz'])
36
+ end
37
+
38
+ def test_merge_seq_nil
39
+ yaml = <<-eoyml
40
+ foo: &hello
41
+ baz:
42
+ <<: [*hello]
43
+ eoyml
44
+ assert_equal({'<<' => [nil]}, Psych.load(yaml)['baz'])
45
+ end
46
+
47
+ def test_bad_seq_merge
48
+ yaml = <<-eoyml
49
+ defaults: &defaults [1, 2, 3]
50
+ development:
51
+ <<: *defaults
52
+ eoyml
53
+ assert_equal({'<<' => [1,2,3]}, Psych.load(yaml)['development'])
54
+ end
55
+
5
56
  def test_missing_merge_key
6
57
  yaml = <<-eoyml
7
58
  bar:
@@ -1,4 +1,4 @@
1
- require 'psych/helper'
1
+ require_relative 'helper'
2
2
 
3
3
  module Psych
4
4
  class TestNil < TestCase
@@ -1,4 +1,4 @@
1
- require 'psych/helper'
1
+ require_relative 'helper'
2
2
 
3
3
  module Psych
4
4
  ###
@@ -1,4 +1,4 @@
1
- require 'psych/helper'
1
+ require_relative 'helper'
2
2
  require 'bigdecimal'
3
3
 
4
4
  module Psych
@@ -7,6 +7,19 @@ module Psych
7
7
  # http://yaml.org/type/float.html
8
8
  # http://yaml.org/type/int.html
9
9
  class TestNumeric < TestCase
10
+ def setup
11
+ @old_debug = $DEBUG
12
+ $DEBUG = true
13
+ end
14
+
15
+ def teardown
16
+ $DEBUG = @old_debug
17
+ end
18
+
19
+ def test_load_float_with_dot
20
+ assert_equal 1.0, Psych.load('--- 1.')
21
+ end
22
+
10
23
  def test_non_float_with_0
11
24
  str = Psych.load('--- 090')
12
25
  assert_equal '090', str
@@ -21,5 +34,12 @@ module Psych
21
34
  decimal = BigDecimal("12.34")
22
35
  assert_cycle decimal
23
36
  end
37
+
38
+ def test_does_not_attempt_numeric
39
+ str = Psych.load('--- 4 roses')
40
+ assert_equal '4 roses', str
41
+ str = Psych.load('--- 1.1.1')
42
+ assert_equal '1.1.1', str
43
+ end
24
44
  end
25
45
  end
@@ -1,4 +1,4 @@
1
- require 'psych/helper'
1
+ require_relative 'helper'
2
2
 
3
3
  module Psych
4
4
  class Tagged
@@ -1,4 +1,4 @@
1
- require 'psych/helper'
1
+ require_relative 'helper'
2
2
 
3
3
  module Psych
4
4
  class TestObjectReferences < TestCase
@@ -35,7 +35,7 @@ module Psych
35
35
 
36
36
  def test_float_references
37
37
  data = Psych.load <<-eoyml
38
- ---
38
+ ---\s
39
39
  - &name 1.2
40
40
  - *name
41
41
  eoyml
@@ -56,7 +56,7 @@ module Psych
56
56
 
57
57
  def test_regexp_references
58
58
  data = Psych.load <<-eoyml
59
- ---
59
+ ---\s
60
60
  - &name !ruby/regexp /pattern/i
61
61
  - *name
62
62
  eoyml
@@ -1,4 +1,4 @@
1
- require 'psych/helper'
1
+ require_relative 'helper'
2
2
 
3
3
  module Psych
4
4
  class TestOmap < TestCase
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'psych/helper'
3
+ require_relative 'helper'
4
4
 
5
5
  module Psych
6
6
  class TestParser < TestCase
@@ -1,4 +1,4 @@
1
- require 'psych/helper'
1
+ require_relative 'helper'
2
2
 
3
3
  require 'stringio'
4
4
  require 'tempfile'
@@ -20,7 +20,7 @@ class TestPsych < Psych::TestCase
20
20
 
21
21
  def test_canonical
22
22
  yml = Psych.dump({:a => {'b' => 'c'}}, {:canonical => true})
23
- assert_match(/\? ! "b/, yml)
23
+ assert_match(/\? "b/, yml)
24
24
  end
25
25
 
26
26
  def test_header
@@ -64,7 +64,7 @@ class TestPsych < Psych::TestCase
64
64
 
65
65
  def test_dump_file
66
66
  hash = {'hello' => 'TGIF!'}
67
- Tempfile.open('fun.yml') do |io|
67
+ Tempfile.create('fun.yml') do |io|
68
68
  assert_equal io, Psych.dump(hash, io)
69
69
  io.rewind
70
70
  assert_equal Psych.dump(hash), io.read
@@ -125,21 +125,21 @@ class TestPsych < Psych::TestCase
125
125
  end
126
126
 
127
127
  def test_load_file
128
- t = Tempfile.new(['yikes', 'yml'])
129
- t.binmode
130
- t.write('--- hello world')
131
- t.close
132
- assert_equal 'hello world', Psych.load_file(t.path)
133
- t.close(true)
128
+ Tempfile.create(['yikes', 'yml']) {|t|
129
+ t.binmode
130
+ t.write('--- hello world')
131
+ t.close
132
+ assert_equal 'hello world', Psych.load_file(t.path)
133
+ }
134
134
  end
135
135
 
136
136
  def test_parse_file
137
- t = Tempfile.new(['yikes', 'yml'])
138
- t.binmode
139
- t.write('--- hello world')
140
- t.close
141
- assert_equal 'hello world', Psych.parse_file(t.path).transform
142
- t.close(true)
137
+ Tempfile.create(['yikes', 'yml']) {|t|
138
+ t.binmode
139
+ t.write('--- hello world')
140
+ t.close
141
+ assert_equal 'hello world', Psych.parse_file(t.path).transform
142
+ }
143
143
  end
144
144
 
145
145
  def test_degenerate_strings
@@ -0,0 +1,97 @@
1
+ require 'psych/helper'
2
+
3
+ module Psych
4
+ class TestSafeLoad < TestCase
5
+ class Foo; end
6
+
7
+ [1, 2.2, {}, [], "foo"].each do |obj|
8
+ define_method(:"test_basic_#{obj.class}") do
9
+ assert_safe_cycle obj
10
+ end
11
+ end
12
+
13
+ def test_no_recursion
14
+ x = []
15
+ x << x
16
+ assert_raises(Psych::BadAlias) do
17
+ Psych.safe_load Psych.dump(x)
18
+ end
19
+ end
20
+
21
+ def test_explicit_recursion
22
+ x = []
23
+ x << x
24
+ assert_equal(x, Psych.safe_load(Psych.dump(x), [], [], true))
25
+ end
26
+
27
+ def test_symbol_whitelist
28
+ yml = Psych.dump :foo
29
+ assert_raises(Psych::DisallowedClass) do
30
+ Psych.safe_load yml
31
+ end
32
+ assert_equal(:foo, Psych.safe_load(yml, [Symbol], [:foo]))
33
+ end
34
+
35
+ def test_symbol
36
+ assert_raises(Psych::DisallowedClass) do
37
+ assert_safe_cycle :foo
38
+ end
39
+ assert_raises(Psych::DisallowedClass) do
40
+ Psych.safe_load '--- !ruby/symbol foo', []
41
+ end
42
+ assert_safe_cycle :foo, [Symbol]
43
+ assert_safe_cycle :foo, %w{ Symbol }
44
+ assert_equal :foo, Psych.safe_load('--- !ruby/symbol foo', [Symbol])
45
+ end
46
+
47
+ def test_foo
48
+ assert_raises(Psych::DisallowedClass) do
49
+ Psych.safe_load '--- !ruby/object:Foo {}', [Foo]
50
+ end
51
+ assert_raises(Psych::DisallowedClass) do
52
+ assert_safe_cycle Foo.new
53
+ end
54
+ assert_kind_of(Foo, Psych.safe_load(Psych.dump(Foo.new), [Foo]))
55
+ end
56
+
57
+ X = Struct.new(:x)
58
+ def test_struct_depends_on_sym
59
+ assert_safe_cycle(X.new, [X, Symbol])
60
+ assert_raises(Psych::DisallowedClass) do
61
+ cycle X.new, [X]
62
+ end
63
+ end
64
+
65
+ def test_anon_struct
66
+ assert Psych.safe_load(<<-eoyml, [Struct, Symbol])
67
+ --- !ruby/struct
68
+ foo: bar
69
+ eoyml
70
+
71
+ assert_raises(Psych::DisallowedClass) do
72
+ Psych.safe_load(<<-eoyml, [Struct])
73
+ --- !ruby/struct
74
+ foo: bar
75
+ eoyml
76
+ end
77
+
78
+ assert_raises(Psych::DisallowedClass) do
79
+ Psych.safe_load(<<-eoyml, [Symbol])
80
+ --- !ruby/struct
81
+ foo: bar
82
+ eoyml
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ def cycle object, whitelist = []
89
+ Psych.safe_load(Psych.dump(object), whitelist)
90
+ end
91
+
92
+ def assert_safe_cycle object, whitelist = []
93
+ other = cycle object, whitelist
94
+ assert_equal object, other
95
+ end
96
+ end
97
+ end
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- require 'psych/helper'
3
+ require_relative 'helper'
4
4
 
5
5
  module Psych
6
6
  class TestScalar < TestCase
@@ -1,4 +1,4 @@
1
- require 'psych/helper'
1
+ require_relative 'helper'
2
2
  require 'date'
3
3
 
4
4
  module Psych
@@ -7,7 +7,7 @@ module Psych
7
7
 
8
8
  def setup
9
9
  super
10
- @ss = Psych::ScalarScanner.new
10
+ @ss = Psych::ScalarScanner.new ClassLoader.new
11
11
  end
12
12
 
13
13
  def test_scan_time
@@ -21,6 +21,17 @@ module Psych
21
21
  end
22
22
  end
23
23
 
24
+ def test_scan_bad_time
25
+ [ '2001-12-15T02:59:73.1Z',
26
+ '2001-12-14t90:59:43.10-05:00',
27
+ '2001-92-14 21:59:43.10 -5',
28
+ '2001-12-15 92:59:43.10',
29
+ '2011-02-24 81:17:06 -0800',
30
+ ].each do |time_str|
31
+ assert_equal time_str, @ss.tokenize(time_str)
32
+ end
33
+ end
34
+
24
35
  def test_scan_bad_dates
25
36
  x = '2000-15-01'
26
37
  assert_equal x, @ss.tokenize(x)
@@ -87,5 +98,9 @@ module Psych
87
98
  def test_scan_true
88
99
  assert_equal true, ss.tokenize('true')
89
100
  end
101
+
102
+ def test_scan_strings_starting_with_underscores
103
+ assert_equal "_100", ss.tokenize('_100')
104
+ end
90
105
  end
91
106
  end