json_pure 1.0.4 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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_pure
|
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 in Ruby
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -32,6 +32,7 @@ files:
|
|
32
32
|
- VERSION
|
33
33
|
- TODO
|
34
34
|
- tests
|
35
|
+
- RUBY
|
35
36
|
- GPL
|
36
37
|
- install.rb
|
37
38
|
- ext
|
@@ -53,12 +54,11 @@ files:
|
|
53
54
|
- tests/test_json_generate.rb
|
54
55
|
- tests/test_json_addition.rb
|
55
56
|
- tests/fixtures/fail27.json
|
57
|
+
- tests/fixtures/pass26.json
|
56
58
|
- tests/fixtures/fail22.json
|
57
|
-
- tests/fixtures/
|
58
|
-
- tests/fixtures/fail16.json
|
59
|
+
- tests/fixtures/pass17.json
|
59
60
|
- tests/fixtures/fail28.json
|
60
61
|
- tests/fixtures/fail25.json
|
61
|
-
- tests/fixtures/pass18.json
|
62
62
|
- tests/fixtures/fail9.json
|
63
63
|
- tests/fixtures/fail20.json
|
64
64
|
- tests/fixtures/fail24.json
|
@@ -66,6 +66,8 @@ files:
|
|
66
66
|
- tests/fixtures/fail4.json
|
67
67
|
- tests/fixtures/fail7.json
|
68
68
|
- tests/fixtures/fail10.json
|
69
|
+
- tests/fixtures/pass15.json
|
70
|
+
- tests/fixtures/fail18.json
|
69
71
|
- tests/fixtures/fail13.json
|
70
72
|
- tests/fixtures/fail6.json
|
71
73
|
- tests/fixtures/fail21.json
|
@@ -76,11 +78,10 @@ files:
|
|
76
78
|
- tests/fixtures/fail5.json
|
77
79
|
- tests/fixtures/pass1.json
|
78
80
|
- tests/fixtures/fail12.json
|
79
|
-
- tests/fixtures/fail15.json
|
80
81
|
- tests/fixtures/pass3.json
|
81
82
|
- tests/fixtures/fail8.json
|
82
|
-
- tests/fixtures/fail17.json
|
83
83
|
- tests/fixtures/fail19.json
|
84
|
+
- tests/fixtures/pass16.json
|
84
85
|
- tests/fixtures/pass2.json
|
85
86
|
- tests/fixtures/fail2.json
|
86
87
|
- ext/json
|