json 1.0.4 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of json might be problematic. Click here for more details.
- data/CHANGES +13 -2
- data/README +3 -2
- data/RUBY +58 -0
- data/Rakefile +4 -3
- data/VERSION +1 -1
- data/ext/json/ext/generator/unicode.c +1 -1
- data/ext/json/ext/parser/parser.c +146 -99
- data/ext/json/ext/parser/parser.rl +70 -16
- data/lib/json.rb +2 -3
- data/lib/json/common.rb +11 -2
- data/lib/json/editor.rb +1295 -1207
- data/lib/json/pure/parser.rb +35 -8
- data/lib/json/version.rb +1 -1
- data/tests/fixtures/{pass18.json → fail18.json} +0 -0
- data/tests/fixtures/{fail15.json → pass15.json} +0 -0
- data/tests/fixtures/{fail16.json → pass16.json} +0 -0
- data/tests/fixtures/{fail17.json → pass17.json} +0 -0
- data/tests/fixtures/{fail26.json → pass26.json} +0 -0
- data/tests/test_json.rb +19 -0
- data/tests/test_json_fixtures.rb +1 -1
- data/tools/fuzz.rb +1 -1
- metadata +8 -7
data/lib/json/pure/parser.rb
CHANGED
@@ -7,8 +7,9 @@ module JSON
|
|
7
7
|
class Parser < StringScanner
|
8
8
|
STRING = /" ((?:[^\x0-\x1f"\\] |
|
9
9
|
\\["\\\/bfnrt] |
|
10
|
-
\\u[0-9a-fA-F]{4}
|
11
|
-
|
10
|
+
\\u[0-9a-fA-F]{4} |
|
11
|
+
\\[\x20-\xff])*)
|
12
|
+
"/nx
|
12
13
|
INTEGER = /(-?0|-?[1-9]\d*)/
|
13
14
|
FLOAT = /(-?
|
14
15
|
(?:0|[1-9]\d*)
|
@@ -45,8 +46,20 @@ module JSON
|
|
45
46
|
UNPARSED = Object.new
|
46
47
|
|
47
48
|
# Creates a new JSON::Pure::Parser instance for the string _source_.
|
48
|
-
|
49
|
+
#
|
50
|
+
# It will be configured by the _opts_ hash. _opts_ can have the following
|
51
|
+
# keys:
|
52
|
+
# * *max_nesting*: The maximum depth of nesting allowed in the parsed data
|
53
|
+
# structures. Disable depth checking with :max_nesting => false.
|
54
|
+
def initialize(source, opts = {})
|
49
55
|
super
|
56
|
+
if !opts.key?(:max_nesting) # defaults to 19
|
57
|
+
@max_nesting = 19
|
58
|
+
elsif opts[:max_nesting]
|
59
|
+
@max_nesting = opts[:max_nesting]
|
60
|
+
else
|
61
|
+
@max_nesting = 0
|
62
|
+
end
|
50
63
|
@create_id = JSON.create_id
|
51
64
|
end
|
52
65
|
|
@@ -61,9 +74,11 @@ module JSON
|
|
61
74
|
case
|
62
75
|
when scan(OBJECT_OPEN)
|
63
76
|
obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
|
77
|
+
@current_nesting = 1
|
64
78
|
obj = parse_object
|
65
79
|
when scan(ARRAY_OPEN)
|
66
80
|
obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
|
81
|
+
@current_nesting = 1
|
67
82
|
obj = parse_array
|
68
83
|
when skip(IGNORE)
|
69
84
|
;
|
@@ -78,7 +93,8 @@ module JSON
|
|
78
93
|
private
|
79
94
|
|
80
95
|
# Unescape characters in strings.
|
81
|
-
UNESCAPE_MAP = {
|
96
|
+
UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
|
97
|
+
UNESCAPE_MAP.update({
|
82
98
|
?" => '"',
|
83
99
|
?\\ => '\\',
|
84
100
|
?/ => '/',
|
@@ -87,12 +103,13 @@ module JSON
|
|
87
103
|
?n => "\n",
|
88
104
|
?r => "\r",
|
89
105
|
?t => "\t",
|
90
|
-
|
106
|
+
?u => nil,
|
107
|
+
})
|
91
108
|
|
92
109
|
def parse_string
|
93
110
|
if scan(STRING)
|
94
111
|
return '' if self[1].empty?
|
95
|
-
self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))
|
112
|
+
self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n) do |c|
|
96
113
|
if u = UNESCAPE_MAP[c[1]]
|
97
114
|
u
|
98
115
|
else # \uXXXX
|
@@ -127,15 +144,23 @@ module JSON
|
|
127
144
|
when (string = parse_string) != UNPARSED
|
128
145
|
string
|
129
146
|
when scan(ARRAY_OPEN)
|
130
|
-
|
147
|
+
@current_nesting += 1
|
148
|
+
ary = parse_array
|
149
|
+
@current_nesting -= 1
|
150
|
+
ary
|
131
151
|
when scan(OBJECT_OPEN)
|
132
|
-
|
152
|
+
@current_nesting += 1
|
153
|
+
obj = parse_object
|
154
|
+
@current_nesting -= 1
|
155
|
+
obj
|
133
156
|
else
|
134
157
|
UNPARSED
|
135
158
|
end
|
136
159
|
end
|
137
160
|
|
138
161
|
def parse_array
|
162
|
+
raise NestingError, "nesting of #@current_nesting is to deep" if
|
163
|
+
@max_nesting.nonzero? && @current_nesting > @max_nesting
|
139
164
|
result = []
|
140
165
|
delim = false
|
141
166
|
until eos?
|
@@ -166,6 +191,8 @@ module JSON
|
|
166
191
|
end
|
167
192
|
|
168
193
|
def parse_object
|
194
|
+
raise NestingError, "nesting of #@current_nesting is to deep" if
|
195
|
+
@max_nesting.nonzero? && @current_nesting > @max_nesting
|
169
196
|
result = {}
|
170
197
|
delim = false
|
171
198
|
until eos?
|
data/lib/json/version.rb
CHANGED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/tests/test_json.rb
CHANGED
@@ -213,6 +213,10 @@ EOT
|
|
213
213
|
data = JSON.parse(json)
|
214
214
|
assert_equal ['"'], data
|
215
215
|
assert_equal json, JSON.unparse(data)
|
216
|
+
json = '["\\\'"]'
|
217
|
+
data = JSON.parse(json)
|
218
|
+
assert_equal ["'"], data
|
219
|
+
assert_equal '["\'"]', JSON.unparse(data)
|
216
220
|
end
|
217
221
|
|
218
222
|
def test_wrong_inputs
|
@@ -232,5 +236,20 @@ EOT
|
|
232
236
|
assert_raises(ParserError) { JSON.parse('[1.]') }
|
233
237
|
assert_raises(ParserError) { JSON.parse(' ') }
|
234
238
|
end
|
239
|
+
|
240
|
+
def test_nesting
|
241
|
+
to_deep = '[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]'
|
242
|
+
assert_raises(JSON::NestingError) { JSON.parse to_deep }
|
243
|
+
assert_raises(JSON::NestingError) { JSON.parser.new(to_deep).parse }
|
244
|
+
assert_raises(JSON::NestingError) { JSON.parse to_deep, :max_nesting => 19 }
|
245
|
+
ok = JSON.parse to_deep, :max_nesting => 20
|
246
|
+
assert_kind_of Array, ok
|
247
|
+
ok = JSON.parse to_deep, :max_nesting => nil
|
248
|
+
assert_kind_of Array, ok
|
249
|
+
ok = JSON.parse to_deep, :max_nesting => false
|
250
|
+
assert_kind_of Array, ok
|
251
|
+
ok = JSON.parse to_deep, :max_nesting => 0
|
252
|
+
assert_kind_of Array, ok
|
253
|
+
end
|
235
254
|
end
|
236
255
|
# vim: set et sw=2 ts=2:
|
data/tests/test_json_fixtures.rb
CHANGED
@@ -21,7 +21,7 @@ class TC_JSONFixtures < Test::Unit::TestCase
|
|
21
21
|
|
22
22
|
def test_failing
|
23
23
|
for (name, source) in @failed
|
24
|
-
assert_raises(JSON::ParserError,
|
24
|
+
assert_raises(JSON::ParserError, JSON::NestingError,
|
25
25
|
"Did not fail for fixture '#{name}'") do
|
26
26
|
JSON.parse(source)
|
27
27
|
end
|
data/tools/fuzz.rb
CHANGED
@@ -116,7 +116,7 @@ loop do
|
|
116
116
|
puts json.size
|
117
117
|
end
|
118
118
|
begin
|
119
|
-
o2 = JSON.parse(json)
|
119
|
+
o2 = JSON.parse(json, :max_nesting => false)
|
120
120
|
rescue JSON::ParserError => e
|
121
121
|
puts "Caught #{e.class}: #{e.message}\n#{e.backtrace * "\n"}"
|
122
122
|
puts "o1 = #{o1.inspect}", "json = #{json}", "json_str = #{json.inspect}"
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: json
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.0
|
7
|
-
date: 2007-
|
6
|
+
version: 1.1.0
|
7
|
+
date: 2007-06-04 00:00:00 +02:00
|
8
8
|
summary: A JSON implementation as a Ruby extension
|
9
9
|
require_paths:
|
10
10
|
- ext/json/ext
|
@@ -34,6 +34,7 @@ files:
|
|
34
34
|
- VERSION
|
35
35
|
- TODO
|
36
36
|
- tests
|
37
|
+
- RUBY
|
37
38
|
- GPL
|
38
39
|
- install.rb
|
39
40
|
- ext
|
@@ -55,12 +56,11 @@ files:
|
|
55
56
|
- tests/test_json_generate.rb
|
56
57
|
- tests/test_json_addition.rb
|
57
58
|
- tests/fixtures/fail27.json
|
59
|
+
- tests/fixtures/pass26.json
|
58
60
|
- tests/fixtures/fail22.json
|
59
|
-
- tests/fixtures/
|
60
|
-
- tests/fixtures/fail16.json
|
61
|
+
- tests/fixtures/pass17.json
|
61
62
|
- tests/fixtures/fail28.json
|
62
63
|
- tests/fixtures/fail25.json
|
63
|
-
- tests/fixtures/pass18.json
|
64
64
|
- tests/fixtures/fail9.json
|
65
65
|
- tests/fixtures/fail20.json
|
66
66
|
- tests/fixtures/fail24.json
|
@@ -68,6 +68,8 @@ files:
|
|
68
68
|
- tests/fixtures/fail4.json
|
69
69
|
- tests/fixtures/fail7.json
|
70
70
|
- tests/fixtures/fail10.json
|
71
|
+
- tests/fixtures/pass15.json
|
72
|
+
- tests/fixtures/fail18.json
|
71
73
|
- tests/fixtures/fail13.json
|
72
74
|
- tests/fixtures/fail6.json
|
73
75
|
- tests/fixtures/fail21.json
|
@@ -78,11 +80,10 @@ files:
|
|
78
80
|
- tests/fixtures/fail5.json
|
79
81
|
- tests/fixtures/pass1.json
|
80
82
|
- tests/fixtures/fail12.json
|
81
|
-
- tests/fixtures/fail15.json
|
82
83
|
- tests/fixtures/pass3.json
|
83
84
|
- tests/fixtures/fail8.json
|
84
|
-
- tests/fixtures/fail17.json
|
85
85
|
- tests/fixtures/fail19.json
|
86
|
+
- tests/fixtures/pass16.json
|
86
87
|
- tests/fixtures/pass2.json
|
87
88
|
- tests/fixtures/fail2.json
|
88
89
|
- ext/json
|