psych 1.3.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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