safe_yaml 0.9.7 → 1.0.0rc1

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