safe_yaml 0.1 → 0.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.
- data/.gitignore +1 -0
- data/lib/safe_yaml.rb +2 -2
- data/lib/{handler.rb → safe_yaml/handler.rb} +47 -14
- data/lib/{version.rb → safe_yaml/version.rb} +1 -1
- data/safe_yaml.gemspec +6 -4
- data/spec/handler_spec.rb +65 -1
- metadata +22 -6
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
dist/
|
data/lib/safe_yaml.rb
CHANGED
@@ -2,7 +2,20 @@ require "yaml"
|
|
2
2
|
|
3
3
|
module SafeYAML
|
4
4
|
class Handler < Psych::Handler
|
5
|
+
PREDEFINED_VALUES = {
|
6
|
+
"" => nil,
|
7
|
+
"~" => nil,
|
8
|
+
"null" => nil,
|
9
|
+
"yes" => true,
|
10
|
+
"on" => true,
|
11
|
+
"true" => true,
|
12
|
+
"no" => false,
|
13
|
+
"off" => false,
|
14
|
+
"false" => false
|
15
|
+
}.freeze
|
16
|
+
|
5
17
|
def initialize
|
18
|
+
@anchors = {}
|
6
19
|
@stack = []
|
7
20
|
end
|
8
21
|
|
@@ -10,7 +23,11 @@ module SafeYAML
|
|
10
23
|
@result
|
11
24
|
end
|
12
25
|
|
13
|
-
def add_to_current_structure(value)
|
26
|
+
def add_to_current_structure(value, anchor=nil)
|
27
|
+
value = transform_value(value)
|
28
|
+
|
29
|
+
@anchors[anchor] = value if anchor
|
30
|
+
|
14
31
|
if @result.nil?
|
15
32
|
@result = value
|
16
33
|
@current_structure = @result
|
@@ -19,13 +36,19 @@ module SafeYAML
|
|
19
36
|
|
20
37
|
case @current_structure
|
21
38
|
when Array
|
22
|
-
@current_structure.push(
|
39
|
+
@current_structure.push(value)
|
23
40
|
|
24
41
|
when Hash
|
25
42
|
if @current_key.nil?
|
26
|
-
@current_key =
|
43
|
+
@current_key = value
|
44
|
+
|
27
45
|
else
|
28
|
-
@
|
46
|
+
if @current_key == "<<"
|
47
|
+
@current_structure.merge!(value)
|
48
|
+
else
|
49
|
+
@current_structure[@current_key] = value
|
50
|
+
end
|
51
|
+
|
29
52
|
@current_key = nil
|
30
53
|
end
|
31
54
|
|
@@ -36,7 +59,10 @@ module SafeYAML
|
|
36
59
|
|
37
60
|
def transform_value(value)
|
38
61
|
if value.is_a?(String)
|
39
|
-
if value.
|
62
|
+
if PREDEFINED_VALUES.include?(value.downcase)
|
63
|
+
return PREDEFINED_VALUES[value.downcase]
|
64
|
+
|
65
|
+
elsif value.match(/^:\w+$/)
|
40
66
|
return value[1..-1].to_sym
|
41
67
|
|
42
68
|
elsif value.match(/^\d+$/)
|
@@ -50,37 +76,44 @@ module SafeYAML
|
|
50
76
|
value
|
51
77
|
end
|
52
78
|
|
79
|
+
def end_current_structure
|
80
|
+
@stack.pop
|
81
|
+
@current_structure = @stack.last
|
82
|
+
end
|
83
|
+
|
53
84
|
def streaming?
|
54
85
|
false
|
55
86
|
end
|
56
87
|
|
57
88
|
# event handlers
|
89
|
+
def alias(anchor)
|
90
|
+
add_to_current_structure(@anchors[anchor])
|
91
|
+
end
|
92
|
+
|
58
93
|
def scalar(value, anchor, tag, plain, quoted, style)
|
59
|
-
add_to_current_structure(value)
|
94
|
+
add_to_current_structure(value, anchor)
|
60
95
|
end
|
61
96
|
|
62
|
-
def start_mapping(
|
97
|
+
def start_mapping(anchor, tag, implicit, style)
|
63
98
|
map = {}
|
64
|
-
self.add_to_current_structure(map)
|
99
|
+
self.add_to_current_structure(map, anchor)
|
65
100
|
@current_structure = map
|
66
101
|
@stack.push(map)
|
67
102
|
end
|
68
103
|
|
69
104
|
def end_mapping
|
70
|
-
|
71
|
-
@current_structure = @stack.last
|
105
|
+
self.end_current_structure()
|
72
106
|
end
|
73
107
|
|
74
|
-
def start_sequence(
|
108
|
+
def start_sequence(anchor, tag, implicit, style)
|
75
109
|
seq = []
|
76
|
-
self.add_to_current_structure(seq)
|
110
|
+
self.add_to_current_structure(seq, anchor)
|
77
111
|
@current_structure = seq
|
78
112
|
@stack.push(seq)
|
79
113
|
end
|
80
114
|
|
81
115
|
def end_sequence
|
82
|
-
|
83
|
-
@current_structure = @stack.last
|
116
|
+
self.end_current_structure()
|
84
117
|
end
|
85
118
|
end
|
86
119
|
end
|
data/safe_yaml.gemspec
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
require File.
|
2
|
+
require File.join(File.dirname(__FILE__), "lib", "safe_yaml", "version")
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
5
|
gem.name = "safe_yaml"
|
6
|
-
gem.
|
7
|
-
gem.
|
6
|
+
gem.version = SafeYAML::VERSION
|
7
|
+
gem.authors = "Dan Tao"
|
8
|
+
gem.email = "daniel.tao@gmail.com"
|
8
9
|
gem.description = %q{Parse (simple) YAML safely, without that pesky arbitrary code execution vulnerability.}
|
9
10
|
gem.summary = %q{SameYAML adds a ::safe_load method to Ruby's built-in YAML module to parse YAML data for only basic types (strings, symbols, numbers, arrays, and hashes).}
|
10
11
|
gem.homepage = "http://dtao.github.com/safe_yaml/"
|
@@ -12,5 +13,6 @@ Gem::Specification.new do |gem|
|
|
12
13
|
gem.files = `git ls-files`.split($\)
|
13
14
|
gem.test_files = gem.files.grep(%r{^spec/})
|
14
15
|
gem.require_paths = ["lib"]
|
15
|
-
|
16
|
+
|
17
|
+
gem.add_dependency("psych")
|
16
18
|
end
|
data/spec/handler_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
2
|
|
3
|
-
require "handler"
|
3
|
+
require "safe_yaml/handler"
|
4
4
|
|
5
5
|
describe SafeYAML::Handler do
|
6
6
|
let(:handler) { SafeYAML::Handler.new }
|
@@ -31,6 +31,27 @@ describe SafeYAML::Handler do
|
|
31
31
|
result.should == { "float" => 3.14 }
|
32
32
|
end
|
33
33
|
|
34
|
+
it "translates valid true/false values to booleans" do
|
35
|
+
parser.parse <<-YAML
|
36
|
+
- yes
|
37
|
+
- true
|
38
|
+
- no
|
39
|
+
- false
|
40
|
+
YAML
|
41
|
+
|
42
|
+
result.should == [true, true, false, false]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "translates valid nulls to nil" do
|
46
|
+
parser.parse <<-YAML
|
47
|
+
-
|
48
|
+
- ~
|
49
|
+
- null
|
50
|
+
YAML
|
51
|
+
|
52
|
+
result.should == [nil] * 3
|
53
|
+
end
|
54
|
+
|
34
55
|
it "applies the same transformations to values as to keys" do
|
35
56
|
parse <<-YAML
|
36
57
|
string: value
|
@@ -105,4 +126,47 @@ describe SafeYAML::Handler do
|
|
105
126
|
|
106
127
|
result.should == { "foo" => { "bar" => { "marco" => "polo" } } }
|
107
128
|
end
|
129
|
+
|
130
|
+
it "deals just fine with aliases and anchors" do
|
131
|
+
parse <<-YAML
|
132
|
+
- &id001 {}
|
133
|
+
- *id001
|
134
|
+
- *id001
|
135
|
+
YAML
|
136
|
+
|
137
|
+
result.should == [{}, {}, {}]
|
138
|
+
end
|
139
|
+
|
140
|
+
it "deals just fine with sections" do
|
141
|
+
parse <<-YAML
|
142
|
+
mysql: &mysql
|
143
|
+
adapter: mysql
|
144
|
+
pool: 30
|
145
|
+
login: &login
|
146
|
+
username: dan
|
147
|
+
password: gobbledygook
|
148
|
+
local: &local
|
149
|
+
<<: *mysql
|
150
|
+
<<: *login
|
151
|
+
host: localhost
|
152
|
+
YAML
|
153
|
+
|
154
|
+
result.should == {
|
155
|
+
"mysql" => {
|
156
|
+
"adapter" => "mysql",
|
157
|
+
"pool" => 30
|
158
|
+
},
|
159
|
+
"login" => {
|
160
|
+
"username" => "dan",
|
161
|
+
"password" => "gobbledygook"
|
162
|
+
},
|
163
|
+
"local" => {
|
164
|
+
"adapter" => "mysql",
|
165
|
+
"pool" => 30,
|
166
|
+
"username" => "dan",
|
167
|
+
"password" => "gobbledygook",
|
168
|
+
"host" => "localhost"
|
169
|
+
}
|
170
|
+
}
|
171
|
+
end
|
108
172
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: safe_yaml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.2'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,21 +10,37 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
date: 2013-01-17 00:00:00.000000000 Z
|
13
|
-
dependencies:
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: psych
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
14
30
|
description: Parse (simple) YAML safely, without that pesky arbitrary code execution
|
15
31
|
vulnerability.
|
16
|
-
email:
|
17
|
-
- daniel.tao@gmail.com
|
32
|
+
email: daniel.tao@gmail.com
|
18
33
|
executables: []
|
19
34
|
extensions: []
|
20
35
|
extra_rdoc_files: []
|
21
36
|
files:
|
37
|
+
- .gitignore
|
22
38
|
- Gemfile
|
23
39
|
- Gemfile.lock
|
24
40
|
- Rakefile
|
25
|
-
- lib/handler.rb
|
26
41
|
- lib/safe_yaml.rb
|
27
|
-
- lib/
|
42
|
+
- lib/safe_yaml/handler.rb
|
43
|
+
- lib/safe_yaml/version.rb
|
28
44
|
- safe_yaml.gemspec
|
29
45
|
- spec/handler_spec.rb
|
30
46
|
- spec/safe_yaml_spec.rb
|