json 1.1.2 → 1.1.3
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 +10 -0
- data/Rakefile +5 -7
- data/VERSION +1 -1
- data/benchmarks/benchmark_generator.rb +0 -0
- data/benchmarks/benchmark_parser.rb +0 -0
- data/benchmarks/benchmark_rails.rb +0 -0
- data/bin/edit_json.rb +0 -1
- data/bin/prettify_json.rb +1 -0
- data/data/index.html +5 -4
- data/ext/json/ext/generator/extconf.rb +1 -1
- data/ext/json/ext/generator/generator.c +3 -4
- data/ext/json/ext/generator/unicode.c +0 -2
- data/ext/json/ext/parser/extconf.rb +1 -1
- data/ext/json/ext/parser/parser.c +315 -309
- data/ext/json/ext/parser/parser.rl +27 -28
- data/ext/json/ext/parser/unicode.c +0 -2
- data/install.rb +0 -0
- data/lib/json/add/core.rb +20 -5
- data/lib/json/common.rb +5 -5
- data/lib/json/editor.rb +0 -1
- data/lib/json/pure/generator.rb +1 -1
- data/lib/json/pure/parser.rb +1 -1
- data/lib/json/version.rb +1 -1
- data/tests/runner.rb +0 -1
- data/tests/test_json.rb +0 -1
- data/tests/test_json_addition.rb +24 -7
- data/tests/test_json_fixtures.rb +0 -0
- data/tests/test_json_generate.rb +0 -0
- data/tests/test_json_rails.rb +6 -2
- data/tests/test_json_unicode.rb +0 -0
- data/tools/fuzz.rb +10 -2
- data/tools/server.rb +0 -0
- metadata +44 -37
@@ -1,5 +1,3 @@
|
|
1
|
-
/* vim: set cin et sw=4 ts=4: */
|
2
|
-
|
3
1
|
#include "ruby.h"
|
4
2
|
#include "re.h"
|
5
3
|
#include "st.h"
|
@@ -75,7 +73,7 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
75
73
|
VALUE v = Qnil;
|
76
74
|
char *np = JSON_parse_value(json, fpc, pe, &v);
|
77
75
|
if (np == NULL) {
|
78
|
-
fbreak;
|
76
|
+
fhold; fbreak;
|
79
77
|
} else {
|
80
78
|
rb_hash_aset(*result, last_name, v);
|
81
79
|
fexec np;
|
@@ -84,10 +82,10 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
84
82
|
|
85
83
|
action parse_name {
|
86
84
|
char *np = JSON_parse_string(json, fpc, pe, &last_name);
|
87
|
-
if (np == NULL) fbreak; else fexec np;
|
85
|
+
if (np == NULL) { fhold; fbreak; } else fexec np;
|
88
86
|
}
|
89
87
|
|
90
|
-
action exit { fbreak; }
|
88
|
+
action exit { fhold; fbreak; }
|
91
89
|
|
92
90
|
a_pair = ignore* begin_name >parse_name
|
93
91
|
ignore* name_separator ignore*
|
@@ -147,19 +145,19 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
147
145
|
if (json->allow_nan) {
|
148
146
|
*result = CNaN;
|
149
147
|
} else {
|
150
|
-
rb_raise(eParserError, "unexpected token at '%s'", p - 2);
|
148
|
+
rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
|
151
149
|
}
|
152
150
|
}
|
153
151
|
action parse_infinity {
|
154
152
|
if (json->allow_nan) {
|
155
153
|
*result = CInfinity;
|
156
154
|
} else {
|
157
|
-
rb_raise(eParserError, "unexpected token at '%s'", p - 8);
|
155
|
+
rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
|
158
156
|
}
|
159
157
|
}
|
160
158
|
action parse_string {
|
161
159
|
char *np = JSON_parse_string(json, fpc, pe, result);
|
162
|
-
if (np == NULL) fbreak; else fexec np;
|
160
|
+
if (np == NULL) { fhold; fbreak; } else fexec np;
|
163
161
|
}
|
164
162
|
|
165
163
|
action parse_number {
|
@@ -168,35 +166,35 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
168
166
|
if (json->allow_nan) {
|
169
167
|
*result = CMinusInfinity;
|
170
168
|
fexec p + 10;
|
171
|
-
fbreak;
|
169
|
+
fhold; fbreak;
|
172
170
|
} else {
|
173
|
-
rb_raise(eParserError, "unexpected token at '%s'", p);
|
171
|
+
rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
174
172
|
}
|
175
173
|
}
|
176
174
|
np = JSON_parse_float(json, fpc, pe, result);
|
177
175
|
if (np != NULL) fexec np;
|
178
176
|
np = JSON_parse_integer(json, fpc, pe, result);
|
179
177
|
if (np != NULL) fexec np;
|
180
|
-
fbreak;
|
178
|
+
fhold; fbreak;
|
181
179
|
}
|
182
180
|
|
183
181
|
action parse_array {
|
184
182
|
char *np;
|
185
|
-
json->current_nesting
|
183
|
+
json->current_nesting++;
|
186
184
|
np = JSON_parse_array(json, fpc, pe, result);
|
187
|
-
json->current_nesting
|
188
|
-
if (np == NULL) fbreak; else fexec np;
|
185
|
+
json->current_nesting--;
|
186
|
+
if (np == NULL) { fhold; fbreak; } else fexec np;
|
189
187
|
}
|
190
188
|
|
191
189
|
action parse_object {
|
192
190
|
char *np;
|
193
|
-
json->current_nesting
|
191
|
+
json->current_nesting++;
|
194
192
|
np = JSON_parse_object(json, fpc, pe, result);
|
195
|
-
json->current_nesting
|
196
|
-
if (np == NULL) fbreak; else fexec np;
|
193
|
+
json->current_nesting--;
|
194
|
+
if (np == NULL) { fhold; fbreak; } else fexec np;
|
197
195
|
}
|
198
196
|
|
199
|
-
action exit { fbreak; }
|
197
|
+
action exit { fhold; fbreak; }
|
200
198
|
|
201
199
|
main := (
|
202
200
|
Vnull @parse_null |
|
@@ -230,7 +228,7 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
230
228
|
|
231
229
|
write data;
|
232
230
|
|
233
|
-
action exit { fbreak; }
|
231
|
+
action exit { fhold; fbreak; }
|
234
232
|
|
235
233
|
main := '-'? ('0' | [1-9][0-9]*) (^[0-9] @exit);
|
236
234
|
}%%
|
@@ -258,7 +256,7 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
|
|
258
256
|
|
259
257
|
write data;
|
260
258
|
|
261
|
-
action exit { fbreak; }
|
259
|
+
action exit { fhold; fbreak; }
|
262
260
|
|
263
261
|
main := '-'? (
|
264
262
|
(('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?)
|
@@ -294,14 +292,14 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
294
292
|
VALUE v = Qnil;
|
295
293
|
char *np = JSON_parse_value(json, fpc, pe, &v);
|
296
294
|
if (np == NULL) {
|
297
|
-
fbreak;
|
295
|
+
fhold; fbreak;
|
298
296
|
} else {
|
299
297
|
rb_ary_push(*result, v);
|
300
298
|
fexec np;
|
301
299
|
}
|
302
300
|
}
|
303
301
|
|
304
|
-
action exit { fbreak; }
|
302
|
+
action exit { fhold; fbreak; }
|
305
303
|
|
306
304
|
next_element = value_separator ignore* begin_value >parse_value;
|
307
305
|
|
@@ -326,7 +324,7 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
326
324
|
if(cs >= JSON_array_first_final) {
|
327
325
|
return p + 1;
|
328
326
|
} else {
|
329
|
-
rb_raise(eParserError, "unexpected token at '%s'", p);
|
327
|
+
rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
330
328
|
}
|
331
329
|
}
|
332
330
|
|
@@ -394,10 +392,10 @@ static VALUE json_string_unescape(char *p, char *pe)
|
|
394
392
|
|
395
393
|
action parse_string {
|
396
394
|
*result = json_string_unescape(json->memo + 1, p);
|
397
|
-
if (NIL_P(*result)) fbreak; else fexec p + 1;
|
395
|
+
if (NIL_P(*result)) { fhold; fbreak; } else fexec p + 1;
|
398
396
|
}
|
399
397
|
|
400
|
-
action exit { fbreak; }
|
398
|
+
action exit { fhold; fbreak; }
|
401
399
|
|
402
400
|
main := '"' ((^(["\\] | 0..0x1f) | '\\'["\\/bfnrt] | '\\u'[0-9a-fA-F]{4} | '\\'^(["\\/bfnrtu]|0..0x1f))* %parse_string) '"' @exit;
|
403
401
|
}%%
|
@@ -430,14 +428,14 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
430
428
|
char *np;
|
431
429
|
json->current_nesting = 1;
|
432
430
|
np = JSON_parse_object(json, fpc, pe, &result);
|
433
|
-
if (np == NULL) fbreak; else fexec np;
|
431
|
+
if (np == NULL) { fhold; fbreak; } else fexec np;
|
434
432
|
}
|
435
433
|
|
436
434
|
action parse_array {
|
437
435
|
char *np;
|
438
436
|
json->current_nesting = 1;
|
439
437
|
np = JSON_parse_array(json, fpc, pe, &result);
|
440
|
-
if (np == NULL) fbreak; else fexec np;
|
438
|
+
if (np == NULL) { fhold; fbreak; } else fexec np;
|
441
439
|
}
|
442
440
|
|
443
441
|
main := ignore* (
|
@@ -573,7 +571,7 @@ static VALUE cParser_parse(VALUE self)
|
|
573
571
|
if (cs >= JSON_first_final && p == pe) {
|
574
572
|
return result;
|
575
573
|
} else {
|
576
|
-
rb_raise(eParserError, "unexpected token at '%s'", p);
|
574
|
+
rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
577
575
|
}
|
578
576
|
}
|
579
577
|
|
@@ -615,6 +613,7 @@ static VALUE cParser_source(VALUE self)
|
|
615
613
|
|
616
614
|
void Init_parser()
|
617
615
|
{
|
616
|
+
rb_require("json/common");
|
618
617
|
mJSON = rb_define_module("JSON");
|
619
618
|
mExt = rb_define_module_under(mJSON, "Ext");
|
620
619
|
cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
|
data/install.rb
CHANGED
File without changes
|
data/lib/json/add/core.rb
CHANGED
@@ -9,14 +9,21 @@ require 'date'
|
|
9
9
|
|
10
10
|
class Time
|
11
11
|
def self.json_create(object)
|
12
|
-
|
12
|
+
if usec = object.delete('u') # used to be tv_usec -> tv_nsec
|
13
|
+
object['n'] = usec * 1000
|
14
|
+
end
|
15
|
+
if respond_to?(:tv_nsec)
|
16
|
+
at(*object.values_at('s', 'n'))
|
17
|
+
else
|
18
|
+
at(object['s'], object['n'] / 1000)
|
19
|
+
end
|
13
20
|
end
|
14
21
|
|
15
22
|
def to_json(*args)
|
16
23
|
{
|
17
24
|
'json_class' => self.class.name,
|
18
25
|
's' => tv_sec,
|
19
|
-
'
|
26
|
+
'n' => respond_to?(:tv_nsec) ? tv_nsec : tv_usec * 1000
|
20
27
|
}.to_json(*args)
|
21
28
|
end
|
22
29
|
end
|
@@ -26,13 +33,15 @@ class Date
|
|
26
33
|
civil(*object.values_at('y', 'm', 'd', 'sg'))
|
27
34
|
end
|
28
35
|
|
36
|
+
alias start sg unless method_defined?(:start)
|
37
|
+
|
29
38
|
def to_json(*args)
|
30
39
|
{
|
31
40
|
'json_class' => self.class.name,
|
32
41
|
'y' => year,
|
33
42
|
'm' => month,
|
34
43
|
'd' => day,
|
35
|
-
'sg' =>
|
44
|
+
'sg' => start,
|
36
45
|
}.to_json(*args)
|
37
46
|
end
|
38
47
|
end
|
@@ -41,11 +50,17 @@ class DateTime
|
|
41
50
|
def self.json_create(object)
|
42
51
|
args = object.values_at('y', 'm', 'd', 'H', 'M', 'S')
|
43
52
|
of_a, of_b = object['of'].split('/')
|
44
|
-
|
53
|
+
if of_b and of_b != '0'
|
54
|
+
args << Rational(of_a.to_i, of_b.to_i)
|
55
|
+
else
|
56
|
+
args << of_a
|
57
|
+
end
|
45
58
|
args << object['sg']
|
46
59
|
civil(*args)
|
47
60
|
end
|
48
61
|
|
62
|
+
alias start sg unless method_defined?(:start)
|
63
|
+
|
49
64
|
def to_json(*args)
|
50
65
|
{
|
51
66
|
'json_class' => self.class.name,
|
@@ -56,7 +71,7 @@ class DateTime
|
|
56
71
|
'M' => min,
|
57
72
|
'S' => sec,
|
58
73
|
'of' => offset.to_s,
|
59
|
-
'sg' =>
|
74
|
+
'sg' => start,
|
60
75
|
}.to_json(*args)
|
61
76
|
end
|
62
77
|
end
|
data/lib/json/common.rb
CHANGED
@@ -2,7 +2,7 @@ require 'json/version'
|
|
2
2
|
|
3
3
|
module JSON
|
4
4
|
class << self
|
5
|
-
# If _object_ is string
|
5
|
+
# If _object_ is string-like parse the string and return the parsed result
|
6
6
|
# as a Ruby data structure. Otherwise generate a JSON text from the Ruby
|
7
7
|
# data structure object and return it.
|
8
8
|
#
|
@@ -184,7 +184,8 @@ module JSON
|
|
184
184
|
end
|
185
185
|
|
186
186
|
# :stopdoc:
|
187
|
-
# I want to deprecate these later, so I'll first be silent about them, and
|
187
|
+
# I want to deprecate these later, so I'll first be silent about them, and
|
188
|
+
# later delete them.
|
188
189
|
alias unparse generate
|
189
190
|
module_function :unparse
|
190
191
|
# :startdoc:
|
@@ -238,7 +239,7 @@ module JSON
|
|
238
239
|
# :startdoc:
|
239
240
|
|
240
241
|
# Load a ruby data structure from a JSON _source_ and return it. A source can
|
241
|
-
# either be a string
|
242
|
+
# either be a string-like object, an IO like object, or an object responding
|
242
243
|
# to the read method. If _proc_ was given, it will be called with any nested
|
243
244
|
# Ruby object as an argument recursively in depth first order.
|
244
245
|
#
|
@@ -327,7 +328,7 @@ module ::Kernel
|
|
327
328
|
nil
|
328
329
|
end
|
329
330
|
|
330
|
-
# If _object_ is string
|
331
|
+
# If _object_ is string-like parse the string and return the parsed result as
|
331
332
|
# a Ruby data structure. Otherwise generate a JSON text from the Ruby data
|
332
333
|
# structure object and return it.
|
333
334
|
#
|
@@ -351,4 +352,3 @@ class ::Class
|
|
351
352
|
respond_to?(:json_create)
|
352
353
|
end
|
353
354
|
end
|
354
|
-
# vim: set et sw=2 ts=2:
|
data/lib/json/editor.rb
CHANGED
data/lib/json/pure/generator.rb
CHANGED
@@ -40,7 +40,7 @@ module JSON
|
|
40
40
|
# Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
|
41
41
|
# UTF16 big endian characters as \u????, and return it.
|
42
42
|
def utf8_to_json(string) # :nodoc:
|
43
|
-
string = string.gsub(/["\\\/\x0-\x1f]/) {
|
43
|
+
string = string.gsub(/["\\\/\x0-\x1f]/) { MAP[$&] }
|
44
44
|
string.gsub!(/(
|
45
45
|
(?:
|
46
46
|
[\xc2-\xdf][\x80-\xbf] |
|
data/lib/json/pure/parser.rb
CHANGED
data/lib/json/version.rb
CHANGED
data/tests/runner.rb
CHANGED
data/tests/test_json.rb
CHANGED
data/tests/test_json_addition.rb
CHANGED
@@ -31,6 +31,10 @@ class TC_JSONAddition < Test::Unit::TestCase
|
|
31
31
|
end
|
32
32
|
|
33
33
|
class B
|
34
|
+
def self.json_creatable?
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
34
38
|
def to_json(*args)
|
35
39
|
{
|
36
40
|
'json_class' => self.class.name,
|
@@ -78,14 +82,14 @@ class TC_JSONAddition < Test::Unit::TestCase
|
|
78
82
|
)
|
79
83
|
end
|
80
84
|
|
81
|
-
def
|
85
|
+
def test_extended_json_fail1
|
82
86
|
b = B.new
|
83
87
|
assert !B.json_creatable?
|
84
88
|
json = generate(b)
|
85
|
-
assert_equal({
|
89
|
+
assert_equal({ "json_class"=>"TC_JSONAddition::B" }, JSON.parse(json))
|
86
90
|
end
|
87
91
|
|
88
|
-
def
|
92
|
+
def test_extended_json_fail2
|
89
93
|
c = C.new
|
90
94
|
assert !C.json_creatable?
|
91
95
|
json = generate(c)
|
@@ -112,6 +116,8 @@ EOT
|
|
112
116
|
assert_equal raw, raw_again
|
113
117
|
end
|
114
118
|
|
119
|
+
MyJsonStruct = Struct.new 'MyJsonStruct', :foo, :bar
|
120
|
+
|
115
121
|
def test_core
|
116
122
|
t = Time.now
|
117
123
|
assert_equal t, JSON(JSON(t))
|
@@ -123,8 +129,7 @@ EOT
|
|
123
129
|
assert_equal 1...10, JSON(JSON(1...10))
|
124
130
|
assert_equal "a".."c", JSON(JSON("a".."c"))
|
125
131
|
assert_equal "a"..."c", JSON(JSON("a"..."c"))
|
126
|
-
|
127
|
-
s = struct.new 4711, 'foot'
|
132
|
+
s = MyJsonStruct.new 4711, 'foot'
|
128
133
|
assert_equal s, JSON(JSON(s))
|
129
134
|
struct = Struct.new :foo, :bar
|
130
135
|
s = struct.new 4711, 'foot'
|
@@ -138,7 +143,19 @@ EOT
|
|
138
143
|
assert_equal e.message, e_again.message
|
139
144
|
assert_equal e.backtrace, e_again.backtrace
|
140
145
|
end
|
141
|
-
assert_equal
|
142
|
-
assert_equal
|
146
|
+
assert_equal(/foo/, JSON(JSON(/foo/)))
|
147
|
+
assert_equal(/foo/i, JSON(JSON(/foo/i)))
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_utc_datetime
|
151
|
+
now = Time.now
|
152
|
+
d = DateTime.parse(now.to_s) # usual case
|
153
|
+
assert d, JSON.parse(d.to_json)
|
154
|
+
d = DateTime.parse(now.utc.to_s) # of = 0
|
155
|
+
assert d, JSON.parse(d.to_json)
|
156
|
+
d = DateTime.civil(2008, 6, 17, 11, 48, 32, 1) # of = 1 / 12 => 1/12
|
157
|
+
assert d, JSON.parse(d.to_json)
|
158
|
+
d = DateTime.civil(2008, 6, 17, 11, 48, 32, 12) # of = 12 / 12 => 12
|
159
|
+
assert d, JSON.parse(d.to_json)
|
143
160
|
end
|
144
161
|
end
|
data/tests/test_json_fixtures.rb
CHANGED
File without changes
|
data/tests/test_json_generate.rb
CHANGED
File without changes
|
data/tests/test_json_rails.rb
CHANGED
@@ -31,6 +31,10 @@ class TC_JSONRails < Test::Unit::TestCase
|
|
31
31
|
end
|
32
32
|
|
33
33
|
class B
|
34
|
+
def self.json_creatable?
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
34
38
|
def to_json(*args)
|
35
39
|
{
|
36
40
|
'json_class' => self.class.name,
|
@@ -74,14 +78,14 @@ class TC_JSONRails < Test::Unit::TestCase
|
|
74
78
|
)
|
75
79
|
end
|
76
80
|
|
77
|
-
def
|
81
|
+
def test_extended_json_fail1
|
78
82
|
b = B.new
|
79
83
|
assert !B.json_creatable?
|
80
84
|
json = generate(b)
|
81
85
|
assert_equal({ 'json_class' => B.name }, JSON.parse(json))
|
82
86
|
end
|
83
87
|
|
84
|
-
def
|
88
|
+
def test_extended_json_fail2
|
85
89
|
c = C.new # with rails addition all objects are theoretically creatable
|
86
90
|
assert C.json_creatable?
|
87
91
|
json = generate(c)
|
data/tests/test_json_unicode.rb
CHANGED
File without changes
|