safe_yaml 0.9.7 → 1.0.0rc1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d56ceb5aefcdb8415178936b17589f26139ec062
4
- data.tar.gz: cd7b6f5d702b6680eb17116a832f0e651737d599
3
+ metadata.gz: 580842b6e20aa79420ad2b898f635bab6d29656c
4
+ data.tar.gz: 487551f91fc91dbbe0ccd00eae31ded1953a7ab3
5
5
  SHA512:
6
- metadata.gz: 4c4686cc5c8a087bbebdc706862223a3d9df7e28b559d32ff6c9ea1bf8db02d273b5b8cc425f903b8ed20e31915381149e3f330b8815ef20bc6de9f428963dff
7
- data.tar.gz: ded13cfdc5044e90220bc24d058a79c89c7a319cbe3b120a09ca1e73d78d6dc2d2a32b90f358c06dd2d3f9585e3836246a6df855dcd5cdcc6a4cd38bc9df6b29
6
+ metadata.gz: 51987bc5bf1d65dd88b90a2837bf7006ed0bb61d663c60e8f4f05cd3a2d864bdfd3feb386e47df1bbc81f495627aa739f745a1436d874d3fdeda6a1595c0eb18
7
+ data.tar.gz: f4d748e76546f251788d7e8b2f83b12592773b08ee95132807656bc195583b0c8b017a34468b14bdceb63540b06c78e5c789ba60439fedf992053377bf50d5d7
data/.travis.yml CHANGED
@@ -29,6 +29,7 @@ matrix:
29
29
  - rvm: ruby-head
30
30
  - rvm: rbx-19mode
31
31
  - rvm: rbx-18mode
32
+ - rvm: jruby-head
32
33
  - rvm: ree
33
34
 
34
35
  exclude:
data/README.md CHANGED
@@ -97,6 +97,15 @@ The most important option is the `:safe` option (default: `true`), which control
97
97
 
98
98
  All of the above options can be set at the global level via `SafeYAML::OPTIONS`. You can also set each one individually per call to `YAML.load`; an option explicitly passed to `load` will take precedence over an option specified globally.
99
99
 
100
+ What if I don't *want* to patch `YAML`?
101
+ ---------------------------------------
102
+
103
+ [Excellent question](https://github.com/dtao/safe_yaml/issues/47)! You can also get the methods `SafeYAML.load` and `SafeYAML.load_file` without touching the `YAML` module at all like this:
104
+
105
+ require "safe_yaml/load"
106
+
107
+ This way, you can use `SafeYAML.load` to parse YAML that *you* don't trust, without affecting the rest of an application (if you're developing a library, for example).
108
+
100
109
  Supported Types
101
110
  ---------------
102
111
 
data/Rakefile CHANGED
@@ -1,13 +1,23 @@
1
1
  require "rspec/core/rake_task"
2
2
 
3
3
  desc "Run specs"
4
- RSpec::Core::RakeTask.new(:spec) do |t|
5
- t.rspec_opts = %w(--color)
6
- end
4
+ task :spec => ['spec:app', 'spec:lib']
7
5
 
8
6
  namespace :spec do
9
7
  desc "Run only specs tagged 'solo'"
10
8
  RSpec::Core::RakeTask.new(:solo) do |t|
11
9
  t.rspec_opts = %w(--color --tag solo)
12
10
  end
11
+
12
+ desc "Run only specs tagged NOT tagged 'libraries' (for applications)"
13
+ RSpec::Core::RakeTask.new(:app) do |t|
14
+ puts "Running specs w/ monkeypatch"
15
+ t.rspec_opts = %w(--color --tag ~libraries)
16
+ end
17
+
18
+ desc "Run only specs tagged 'libraries'"
19
+ RSpec::Core::RakeTask.new(:lib) do |t|
20
+ puts "Running specs w/o monkeypatch"
21
+ t.rspec_opts = %w(--color --tag libraries)
22
+ end
13
23
  end
@@ -0,0 +1,18 @@
1
+ #!/bin/bash
2
+
3
+ [[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"
4
+
5
+ rvm use 1.8.7
6
+ bundle install
7
+
8
+ rvm use 1.9.2
9
+ bundle install
10
+
11
+ rvm use 1.9.3
12
+ bundle install
13
+
14
+ rvm use 2.0.0
15
+ bundle install
16
+
17
+ rvm use jruby
18
+ bundle install
data/lib/safe_yaml.rb CHANGED
@@ -1,133 +1,4 @@
1
- require "yaml"
2
-
3
- # This needs to be defined up front in case any internal classes need to base
4
- # their behavior off of this.
5
- module SafeYAML
6
- YAML_ENGINE = defined?(YAML::ENGINE) ? YAML::ENGINE.yamler : "syck"
7
- end
8
-
9
- require "set"
10
- require "safe_yaml/deep"
11
- require "safe_yaml/parse/hexadecimal"
12
- require "safe_yaml/parse/sexagesimal"
13
- require "safe_yaml/parse/date"
14
- require "safe_yaml/transform/transformation_map"
15
- require "safe_yaml/transform/to_boolean"
16
- require "safe_yaml/transform/to_date"
17
- require "safe_yaml/transform/to_float"
18
- require "safe_yaml/transform/to_integer"
19
- require "safe_yaml/transform/to_nil"
20
- require "safe_yaml/transform/to_symbol"
21
- require "safe_yaml/transform"
22
- require "safe_yaml/resolver"
23
- require "safe_yaml/syck_hack" if defined?(JRUBY_VERSION)
24
-
25
- module SafeYAML
26
- MULTI_ARGUMENT_YAML_LOAD = YAML.method(:load).arity != 1
27
-
28
- DEFAULT_OPTIONS = Deep.freeze({
29
- :default_mode => nil,
30
- :suppress_warnings => false,
31
- :deserialize_symbols => false,
32
- :whitelisted_tags => [],
33
- :custom_initializers => {},
34
- :raise_on_unknown_tag => false
35
- })
36
-
37
- OPTIONS = Deep.copy(DEFAULT_OPTIONS)
38
-
39
- module_function
40
- def restore_defaults!
41
- OPTIONS.clear.merge!(Deep.copy(DEFAULT_OPTIONS))
42
- end
43
-
44
- def tag_safety_check!(tag, options)
45
- return if tag.nil? || tag == "!"
46
- if options[:raise_on_unknown_tag] && !options[:whitelisted_tags].include?(tag) && !tag_is_explicitly_trusted?(tag)
47
- raise "Unknown YAML tag '#{tag}'"
48
- end
49
- end
50
-
51
- def whitelist!(*classes)
52
- classes.each do |klass|
53
- whitelist_class!(klass)
54
- end
55
- end
56
-
57
- def whitelist_class!(klass)
58
- raise "#{klass} not a Class" unless klass.is_a?(::Class)
59
-
60
- klass_name = klass.name
61
- raise "#{klass} cannot be anonymous" if klass_name.nil? || klass_name.empty?
62
-
63
- # Whitelist any built-in YAML tags supplied by Syck or Psych.
64
- predefined_tag = predefined_tags[klass]
65
- if predefined_tag
66
- OPTIONS[:whitelisted_tags] << predefined_tag
67
- return
68
- end
69
-
70
- # Exception is exceptional (har har).
71
- tag_class = klass < Exception ? "exception" : "object"
72
-
73
- tag_prefix = case YAML_ENGINE
74
- when "psych" then "!ruby/#{tag_class}"
75
- when "syck" then "tag:ruby.yaml.org,2002:#{tag_class}"
76
- else raise "unknown YAML_ENGINE #{YAML_ENGINE}"
77
- end
78
- OPTIONS[:whitelisted_tags] << "#{tag_prefix}:#{klass_name}"
79
- end
80
-
81
- def predefined_tags
82
- if @predefined_tags.nil?
83
- @predefined_tags = {}
84
-
85
- if YAML_ENGINE == "syck"
86
- YAML.tagged_classes.each do |tag, klass|
87
- @predefined_tags[klass] = tag
88
- end
89
-
90
- else
91
- # Special tags appear to be hard-coded in Psych:
92
- # https://github.com/tenderlove/psych/blob/v1.3.4/lib/psych/visitors/to_ruby.rb
93
- # Fortunately, there aren't many that SafeYAML doesn't already support.
94
- @predefined_tags.merge!({
95
- Exception => "!ruby/exception",
96
- Range => "!ruby/range",
97
- Regexp => "!ruby/regexp",
98
- })
99
- end
100
- end
101
-
102
- @predefined_tags
103
- end
104
-
105
- if YAML_ENGINE == "psych"
106
- def tag_is_explicitly_trusted?(tag)
107
- false
108
- end
109
-
110
- else
111
- TRUSTED_TAGS = Set.new([
112
- "tag:yaml.org,2002:binary",
113
- "tag:yaml.org,2002:bool#no",
114
- "tag:yaml.org,2002:bool#yes",
115
- "tag:yaml.org,2002:float",
116
- "tag:yaml.org,2002:float#fix",
117
- "tag:yaml.org,2002:int",
118
- "tag:yaml.org,2002:map",
119
- "tag:yaml.org,2002:null",
120
- "tag:yaml.org,2002:seq",
121
- "tag:yaml.org,2002:str",
122
- "tag:yaml.org,2002:timestamp",
123
- "tag:yaml.org,2002:timestamp#ymd"
124
- ]).freeze
125
-
126
- def tag_is_explicitly_trusted?(tag)
127
- TRUSTED_TAGS.include?(tag)
128
- end
129
- end
130
- end
1
+ require "safe_yaml/load"
131
2
 
132
3
  module YAML
133
4
  def self.load_with_options(yaml, *original_arguments)
@@ -154,65 +25,27 @@ module YAML
154
25
  end
155
26
  end
156
27
 
157
- if SafeYAML::YAML_ENGINE == "psych"
158
- require "safe_yaml/psych_handler"
159
- require "safe_yaml/psych_resolver"
160
- require "safe_yaml/safe_to_ruby_visitor"
161
-
162
- def self.safe_load(yaml, filename=nil, options={})
163
- return false if yaml =~ /\A\s*\Z/
164
-
165
- # If the user hasn't whitelisted any tags, we can go with this implementation which is
166
- # significantly faster.
167
- if (options && options[:whitelisted_tags] || SafeYAML::OPTIONS[:whitelisted_tags]).empty?
168
- safe_handler = SafeYAML::PsychHandler.new(options) do |result|
169
- return result
170
- end
171
- arguments_for_parse = [yaml]
172
- arguments_for_parse << filename if SafeYAML::MULTI_ARGUMENT_YAML_LOAD
173
- Psych::Parser.new(safe_handler).parse(*arguments_for_parse)
174
-
175
- else
176
- safe_resolver = SafeYAML::PsychResolver.new(options)
177
- tree = SafeYAML::MULTI_ARGUMENT_YAML_LOAD ?
178
- Psych.parse(yaml, filename) :
179
- Psych.parse(yaml)
180
- return safe_resolver.resolve_node(tree)
181
- end
182
- end
183
-
184
- def self.safe_load_file(filename, options={})
185
- File.open(filename, 'r:bom|utf-8') { |f| self.safe_load(f, filename, options) }
186
- end
187
-
188
- def self.unsafe_load_file(filename)
189
- if SafeYAML::MULTI_ARGUMENT_YAML_LOAD
190
- # https://github.com/tenderlove/psych/blob/v1.3.2/lib/psych.rb#L296-298
191
- File.open(filename, 'r:bom|utf-8') { |f| self.unsafe_load(f, filename) }
192
- else
193
- # https://github.com/tenderlove/psych/blob/v1.2.2/lib/psych.rb#L231-233
194
- self.unsafe_load File.open(filename)
195
- end
196
- end
197
-
198
- else
199
- require "safe_yaml/syck_resolver"
200
- require "safe_yaml/syck_node_monkeypatch"
28
+ def self.safe_load(*args)
29
+ SafeYAML.load(*args)
30
+ end
201
31
 
202
- def self.safe_load(yaml, options={})
203
- resolver = SafeYAML::SyckResolver.new(SafeYAML::OPTIONS.merge(options || {}))
204
- tree = YAML.parse(yaml)
205
- return resolver.resolve_node(tree)
206
- end
32
+ def self.safe_load_file(*args)
33
+ SafeYAML.load_file(*args)
34
+ end
207
35
 
208
- def self.safe_load_file(filename, options={})
209
- File.open(filename) { |f| self.safe_load(f, options) }
36
+ def self.unsafe_load_file(filename)
37
+ if SafeYAML::MULTI_ARGUMENT_YAML_LOAD
38
+ # https://github.com/tenderlove/psych/blob/v1.3.2/lib/psych.rb#L296-298
39
+ File.open(filename, 'r:bom|utf-8') { |f| self.unsafe_load(f, filename) }
40
+ else
41
+ # https://github.com/tenderlove/psych/blob/v1.2.2/lib/psych.rb#L231-233
42
+ self.unsafe_load File.open(filename)
210
43
  end
44
+ end
211
45
 
212
- def self.unsafe_load_file(filename)
213
- # https://github.com/indeyets/syck/blob/master/ext/ruby/lib/yaml.rb#L133-135
214
- File.open(filename) { |f| self.unsafe_load(f) }
215
- end
46
+ def self.unsafe_load_file(filename)
47
+ # https://github.com/indeyets/syck/blob/master/ext/ruby/lib/yaml.rb#L133-135
48
+ File.open(filename) { |f| self.unsafe_load(f) }
216
49
  end
217
50
 
218
51
  class << self
@@ -0,0 +1,183 @@
1
+ require "yaml"
2
+
3
+ # This needs to be defined up front in case any internal classes need to base
4
+ # their behavior off of this.
5
+ module SafeYAML
6
+ YAML_ENGINE = defined?(YAML::ENGINE) ? YAML::ENGINE.yamler : "syck"
7
+ end
8
+
9
+ require "set"
10
+ require "safe_yaml/deep"
11
+ require "safe_yaml/parse/hexadecimal"
12
+ require "safe_yaml/parse/sexagesimal"
13
+ require "safe_yaml/parse/date"
14
+ require "safe_yaml/transform/transformation_map"
15
+ require "safe_yaml/transform/to_boolean"
16
+ require "safe_yaml/transform/to_date"
17
+ require "safe_yaml/transform/to_float"
18
+ require "safe_yaml/transform/to_integer"
19
+ require "safe_yaml/transform/to_nil"
20
+ require "safe_yaml/transform/to_symbol"
21
+ require "safe_yaml/transform"
22
+ require "safe_yaml/resolver"
23
+ require "safe_yaml/syck_hack" if SafeYAML::YAML_ENGINE == "syck" && defined?(JRUBY_VERSION)
24
+
25
+ module SafeYAML
26
+ MULTI_ARGUMENT_YAML_LOAD = YAML.method(:load).arity != 1
27
+
28
+ DEFAULT_OPTIONS = Deep.freeze({
29
+ :default_mode => nil,
30
+ :suppress_warnings => false,
31
+ :deserialize_symbols => false,
32
+ :whitelisted_tags => [],
33
+ :custom_initializers => {},
34
+ :raise_on_unknown_tag => false
35
+ })
36
+
37
+ OPTIONS = Deep.copy(DEFAULT_OPTIONS)
38
+
39
+ module_function
40
+ def restore_defaults!
41
+ OPTIONS.clear.merge!(Deep.copy(DEFAULT_OPTIONS))
42
+ end
43
+
44
+ def tag_safety_check!(tag, options)
45
+ return if tag.nil? || tag == "!"
46
+ if options[:raise_on_unknown_tag] && !options[:whitelisted_tags].include?(tag) && !tag_is_explicitly_trusted?(tag)
47
+ raise "Unknown YAML tag '#{tag}'"
48
+ end
49
+ end
50
+
51
+ def whitelist!(*classes)
52
+ classes.each do |klass|
53
+ whitelist_class!(klass)
54
+ end
55
+ end
56
+
57
+ def whitelist_class!(klass)
58
+ raise "#{klass} not a Class" unless klass.is_a?(::Class)
59
+
60
+ klass_name = klass.name
61
+ raise "#{klass} cannot be anonymous" if klass_name.nil? || klass_name.empty?
62
+
63
+ # Whitelist any built-in YAML tags supplied by Syck or Psych.
64
+ predefined_tag = predefined_tags[klass]
65
+ if predefined_tag
66
+ OPTIONS[:whitelisted_tags] << predefined_tag
67
+ return
68
+ end
69
+
70
+ # Exception is exceptional (har har).
71
+ tag_class = klass < Exception ? "exception" : "object"
72
+
73
+ tag_prefix = case YAML_ENGINE
74
+ when "psych" then "!ruby/#{tag_class}"
75
+ when "syck" then "tag:ruby.yaml.org,2002:#{tag_class}"
76
+ else raise "unknown YAML_ENGINE #{YAML_ENGINE}"
77
+ end
78
+ OPTIONS[:whitelisted_tags] << "#{tag_prefix}:#{klass_name}"
79
+ end
80
+
81
+ def predefined_tags
82
+ if @predefined_tags.nil?
83
+ @predefined_tags = {}
84
+
85
+ if YAML_ENGINE == "syck"
86
+ YAML.tagged_classes.each do |tag, klass|
87
+ @predefined_tags[klass] = tag
88
+ end
89
+
90
+ else
91
+ # Special tags appear to be hard-coded in Psych:
92
+ # https://github.com/tenderlove/psych/blob/v1.3.4/lib/psych/visitors/to_ruby.rb
93
+ # Fortunately, there aren't many that SafeYAML doesn't already support.
94
+ @predefined_tags.merge!({
95
+ Exception => "!ruby/exception",
96
+ Range => "!ruby/range",
97
+ Regexp => "!ruby/regexp",
98
+ })
99
+ end
100
+ end
101
+
102
+ @predefined_tags
103
+ end
104
+
105
+ if YAML_ENGINE == "psych"
106
+ def tag_is_explicitly_trusted?(tag)
107
+ false
108
+ end
109
+
110
+ else
111
+ TRUSTED_TAGS = Set.new([
112
+ "tag:yaml.org,2002:binary",
113
+ "tag:yaml.org,2002:bool#no",
114
+ "tag:yaml.org,2002:bool#yes",
115
+ "tag:yaml.org,2002:float",
116
+ "tag:yaml.org,2002:float#fix",
117
+ "tag:yaml.org,2002:int",
118
+ "tag:yaml.org,2002:map",
119
+ "tag:yaml.org,2002:null",
120
+ "tag:yaml.org,2002:seq",
121
+ "tag:yaml.org,2002:str",
122
+ "tag:yaml.org,2002:timestamp",
123
+ "tag:yaml.org,2002:timestamp#ymd"
124
+ ]).freeze
125
+
126
+ def tag_is_explicitly_trusted?(tag)
127
+ TRUSTED_TAGS.include?(tag)
128
+ end
129
+ end
130
+
131
+ if SafeYAML::YAML_ENGINE == "psych"
132
+ require "safe_yaml/psych_handler"
133
+ require "safe_yaml/psych_resolver"
134
+ require "safe_yaml/safe_to_ruby_visitor"
135
+
136
+ def self.load(yaml, filename=nil, options={})
137
+ # If the user hasn't whitelisted any tags, we can go with this implementation which is
138
+ # significantly faster.
139
+ if (options && options[:whitelisted_tags] || SafeYAML::OPTIONS[:whitelisted_tags]).empty?
140
+ safe_handler = SafeYAML::PsychHandler.new(options) do |result|
141
+ return result
142
+ end
143
+ arguments_for_parse = [yaml]
144
+ arguments_for_parse << filename if SafeYAML::MULTI_ARGUMENT_YAML_LOAD
145
+ Psych::Parser.new(safe_handler).parse(*arguments_for_parse)
146
+ return safe_handler.result
147
+
148
+ else
149
+ safe_resolver = SafeYAML::PsychResolver.new(options)
150
+ tree = SafeYAML::MULTI_ARGUMENT_YAML_LOAD ?
151
+ Psych.parse(yaml, filename) :
152
+ Psych.parse(yaml)
153
+ return safe_resolver.resolve_node(tree)
154
+ end
155
+ end
156
+
157
+ def self.load_file(filename, options={})
158
+ if SafeYAML::MULTI_ARGUMENT_YAML_LOAD
159
+ File.open(filename, 'r:bom|utf-8') { |f| self.load(f, filename, options) }
160
+
161
+ else
162
+ # Ruby pukes on 1.9.2 if we try to open an empty file w/ 'r:bom|utf-8';
163
+ # so we'll not specify those flags here. This mirrors the behavior for
164
+ # unsafe_load_file so it's probably preferable anyway.
165
+ self.load File.open(filename), nil, options
166
+ end
167
+ end
168
+
169
+ else
170
+ require "safe_yaml/syck_resolver"
171
+ require "safe_yaml/syck_node_monkeypatch"
172
+
173
+ def self.load(yaml, options={})
174
+ resolver = SafeYAML::SyckResolver.new(SafeYAML::OPTIONS.merge(options || {}))
175
+ tree = YAML.parse(yaml)
176
+ return resolver.resolve_node(tree)
177
+ end
178
+
179
+ def self.load_file(filename, options={})
180
+ File.open(filename) { |f| self.load(f, options) }
181
+ end
182
+ end
183
+ end
@@ -17,10 +17,18 @@ module SafeYAML
17
17
  # reasonably -- to seconds.
18
18
  SEC_FRACTION_MULTIPLIER = RUBY_VERSION == "1.8.7" ? (SECONDS_PER_DAY * MICROSECONDS_PER_SECOND) : MICROSECONDS_PER_SECOND
19
19
 
20
+ # The DateTime class has a #to_time method in Ruby 1.9+;
21
+ # Before that we'll just need to convert DateTime to Time ourselves.
22
+ TO_TIME_AVAILABLE = DateTime.new.respond_to?(:to_time)
23
+
20
24
  def self.value(value)
21
25
  d = DateTime.parse(value)
26
+
27
+ return d.to_time if TO_TIME_AVAILABLE
28
+
22
29
  usec = d.sec_fraction * SEC_FRACTION_MULTIPLIER
23
- Time.utc(d.year, d.month, d.day, d.hour, d.min, d.sec, usec) - (d.offset * SECONDS_PER_DAY)
30
+ time = Time.utc(d.year, d.month, d.day, d.hour, d.min, d.sec, usec) - (d.offset * SECONDS_PER_DAY)
31
+ time.getlocal
24
32
  end
25
33
  end
26
34
  end
@@ -11,10 +11,11 @@ module SafeYAML
11
11
  @stack = []
12
12
  @current_key = nil
13
13
  @result = nil
14
+ @begun = false
14
15
  end
15
16
 
16
17
  def result
17
- @result
18
+ @begun ? @result : false
18
19
  end
19
20
 
20
21
  def add_to_current_structure(value, anchor=nil, quoted=nil, tag=nil)
@@ -22,7 +23,8 @@ module SafeYAML
22
23
 
23
24
  @anchors[anchor] = value if anchor
24
25
 
25
- if @result.nil?
26
+ if !@begun
27
+ @begun = true
26
28
  @result = value
27
29
  @current_structure = @result
28
30
  return
@@ -1,7 +1,19 @@
1
1
  module SafeYAML
2
2
  class SafeToRubyVisitor < Psych::Visitors::ToRuby
3
+ INITIALIZE_ARITY = superclass.instance_method(:initialize).arity
4
+
3
5
  def initialize(resolver)
4
- super()
6
+ case INITIALIZE_ARITY
7
+ when 2
8
+ # https://github.com/tenderlove/psych/blob/v2.0.0/lib/psych/visitors/to_ruby.rb#L14-L28
9
+ loader = ClassLoader.new
10
+ scanner = ScalarScanner.new(loader)
11
+ super(scanner, loader)
12
+
13
+ else
14
+ super()
15
+ end
16
+
5
17
  @resolver = resolver
6
18
  end
7
19
 
@@ -1,3 +1,3 @@
1
1
  module SafeYAML
2
- VERSION = "0.9.7"
2
+ VERSION = "1.0.0rc1"
3
3
  end
@@ -2,20 +2,26 @@
2
2
 
3
3
  [[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"
4
4
 
5
- rvm use 1.8.7@safe_yaml
6
- rake spec
5
+ rvm use 1.8.7
6
+ bundle exec rake spec
7
7
 
8
- rvm use 1.9.2@safe_yaml
9
- YAMLER=syck rake spec
8
+ rvm use 1.9.2
9
+ YAMLER=syck bundle exec rake spec
10
10
 
11
- rvm use 1.9.3@safe_yaml
12
- YAMLER=syck rake spec
11
+ rvm use 1.9.3
12
+ YAMLER=syck bundle exec rake spec
13
13
 
14
- rvm use 1.9.2@safe_yaml
15
- YAMLER=psych rake spec
14
+ rvm use 1.9.2
15
+ YAMLER=psych bundle exec rake spec
16
16
 
17
- rvm use 1.9.3@safe_yaml
18
- YAMLER=psych rake spec
17
+ rvm use 1.9.3
18
+ YAMLER=psych bundle exec rake spec
19
19
 
20
- rvm use 2.0.0@safe_yaml
21
- YAMLER=psych rake spec
20
+ rvm use 2.0.0
21
+ YAMLER=psych bundle exec rake spec
22
+
23
+ rvm use jruby
24
+ JRUBY_OPTS=--1.8 bundle exec rake spec
25
+
26
+ rvm use jruby
27
+ JRUBY_OPTS=--1.9 bundle exec rake spec
data/spec/issue49.yml ADDED
File without changes
@@ -4,6 +4,11 @@ module ResolverSpecs
4
4
  let(:resolver) { nil }
5
5
  let(:result) { @result }
6
6
 
7
+ before :each do
8
+ # See the comment in the first before :each block in safe_yaml_spec.rb.
9
+ require "safe_yaml"
10
+ end
11
+
7
12
  def parse(yaml)
8
13
  tree = YAML.parse(yaml.unindent)
9
14
  @result = resolver.resolve_node(tree)
@@ -1,7 +1,5 @@
1
1
  require File.join(File.dirname(__FILE__), "spec_helper")
2
2
 
3
- require "exploitable_back_door"
4
-
5
3
  describe YAML do
6
4
  # Essentially stolen from:
7
5
  # https://github.com/rails/rails/blob/3-2-stable/activesupport/lib/active_support/core_ext/kernel/reporting.rb#L10-25
@@ -21,6 +19,12 @@ describe YAML do
21
19
  end
22
20
 
23
21
  before :each do
22
+ # Need to require this here (as opposed to somewhere up higher in the file)
23
+ # to ensure that safe_yaml isn't loaded and therefore YAML isn't monkey-
24
+ # patched, for tests that require only safe_yaml/load.
25
+ require "safe_yaml"
26
+ require "exploitable_back_door"
27
+
24
28
  SafeYAML.restore_defaults!
25
29
  end
26
30
 
@@ -257,7 +261,7 @@ describe YAML do
257
261
  "grandcustom" => { "foo" => "foo", "bar" => "custom_bar", "baz" => "custom_baz" }
258
262
  }
259
263
  end
260
-
264
+
261
265
  it "returns false when parsing an empty document" do
262
266
  [
263
267
  YAML.safe_load(""),
@@ -507,6 +511,10 @@ describe YAML do
507
511
  object = YAML.safe_load_file "spec/exploit.1.9.2.yaml"
508
512
  object.should_not be_a(ExploitableBackDoor)
509
513
  end
514
+
515
+ it "returns false when parsing an empty file" do
516
+ YAML.safe_load_file("spec/issue49.yml").should == false
517
+ end
510
518
  end
511
519
 
512
520
  describe "load" do
data/spec/spec_helper.rb CHANGED
@@ -10,7 +10,16 @@ if ENV["YAMLER"] && defined?(YAML::ENGINE)
10
10
  puts "Running specs in Ruby #{RUBY_VERSION} with '#{YAML::ENGINE.yamler}' YAML engine."
11
11
  end
12
12
 
13
- require "safe_yaml"
13
+ if defined?(JRUBY_VERSION) && ENV["JRUBY_OPTS"]
14
+ puts "Running JRuby in #{RUBY_VERSION} mode."
15
+ end
16
+
17
+ # Caching references to these methods before loading safe_yaml in order to test
18
+ # that they aren't touched unless you actually require safe_yaml (see yaml_spec.rb).
19
+ ORIGINAL_YAML_LOAD = YAML.method(:load)
20
+ ORIGINAL_YAML_LOAD_FILE = YAML.method(:load_file)
21
+
22
+ require "safe_yaml/load"
14
23
  require "ostruct"
15
24
  require "hashie"
16
25
  require "heredoc_unindent"
@@ -31,4 +31,11 @@ describe SafeYAML::Transform::ToDate do
31
31
  result.should == Time.utc(2001, 12, 15, 2, 59, 43, 100000)
32
32
  end
33
33
  end
34
+
35
+ it "converts times to the local timezone" do
36
+ success, result = subject.transform?("2012-12-01 10:33:45 +11:00")
37
+ success.should be_true
38
+ result.should == Time.utc(2012, 11, 30, 23, 33, 45)
39
+ result.gmt_offset.should == Time.now.gmt_offset
40
+ end
34
41
  end
data/spec/yaml_spec.rb ADDED
@@ -0,0 +1,15 @@
1
+ # See https://github.com/dtao/safe_yaml/issues/47
2
+
3
+ require File.join(File.dirname(__FILE__), "spec_helper")
4
+
5
+ describe YAML do
6
+ context "when you've only required safe_yaml/load", :libraries => true do
7
+ it "YAML.load doesn't get monkey patched" do
8
+ YAML.method(:load).should == ORIGINAL_YAML_LOAD
9
+ end
10
+
11
+ it "YAML.load_file doesn't get monkey patched" do
12
+ YAML.method(:load_file).should == ORIGINAL_YAML_LOAD_FILE
13
+ end
14
+ end
15
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safe_yaml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.7
4
+ version: 1.0.0rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Tao
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-17 00:00:00.000000000 Z
11
+ date: 2013-12-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Parse YAML safely, without that pesky arbitrary object deserialization
14
14
  vulnerability
@@ -24,8 +24,10 @@ files:
24
24
  - LICENSE.txt
25
25
  - README.md
26
26
  - Rakefile
27
+ - bundle_install_all_ruby_versions.sh
27
28
  - lib/safe_yaml.rb
28
29
  - lib/safe_yaml/deep.rb
30
+ - lib/safe_yaml/load.rb
29
31
  - lib/safe_yaml/parse/date.rb
30
32
  - lib/safe_yaml/parse/hexadecimal.rb
31
33
  - lib/safe_yaml/parse/sexagesimal.rb
@@ -50,6 +52,7 @@ files:
50
52
  - spec/exploit.1.9.2.yaml
51
53
  - spec/exploit.1.9.3.yaml
52
54
  - spec/issue48.txt
55
+ - spec/issue49.yml
53
56
  - spec/psych_resolver_spec.rb
54
57
  - spec/resolver_specs.rb
55
58
  - spec/safe_yaml_spec.rb
@@ -61,6 +64,7 @@ files:
61
64
  - spec/transform/to_float_spec.rb
62
65
  - spec/transform/to_integer_spec.rb
63
66
  - spec/transform/to_symbol_spec.rb
67
+ - spec/yaml_spec.rb
64
68
  homepage: http://dtao.github.com/safe_yaml/
65
69
  licenses:
66
70
  - MIT
@@ -76,9 +80,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
80
  version: 1.8.7
77
81
  required_rubygems_version: !ruby/object:Gem::Requirement
78
82
  requirements:
79
- - - '>='
83
+ - - '>'
80
84
  - !ruby/object:Gem::Version
81
- version: '0'
85
+ version: 1.3.1
82
86
  requirements: []
83
87
  rubyforge_project:
84
88
  rubygems_version: 2.0.6
@@ -90,6 +94,7 @@ test_files:
90
94
  - spec/exploit.1.9.2.yaml
91
95
  - spec/exploit.1.9.3.yaml
92
96
  - spec/issue48.txt
97
+ - spec/issue49.yml
93
98
  - spec/psych_resolver_spec.rb
94
99
  - spec/resolver_specs.rb
95
100
  - spec/safe_yaml_spec.rb
@@ -101,3 +106,4 @@ test_files:
101
106
  - spec/transform/to_float_spec.rb
102
107
  - spec/transform/to_integer_spec.rb
103
108
  - spec/transform/to_symbol_spec.rb
109
+ - spec/yaml_spec.rb