oj 2.14.6 → 2.15.0
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/README.md +17 -2
- data/ext/oj/dump.c +101 -34
- data/ext/oj/oj.c +37 -2
- data/ext/oj/oj.h +13 -0
- data/ext/oj/parse.c +23 -8
- data/ext/oj/parse.h +0 -1
- data/ext/oj/sparse.c +13 -2
- data/lib/oj/version.rb +1 -1
- data/test/bug.rb +50 -37
- data/test/perf1.rb +64 -0
- data/test/perf2.rb +76 -0
- data/test/perf_obj_old.rb +213 -0
- data/test/test_bigd.rb +63 -0
- data/test/{mod.rb → test_range.rb} +9 -6
- data/test/test_various.rb +22 -2
- metadata +56 -61
- checksums.yaml +0 -7
- data/test/bug2.rb +0 -10
- data/test/bug3.rb +0 -46
- data/test/bug_fast.rb +0 -32
- data/test/bug_load.rb +0 -24
- data/test/example.rb +0 -11
- data/test/io.rb +0 -48
- data/test/russian.rb +0 -18
- data/test/struct.rb +0 -29
- data/test/test_serializer.rb +0 -59
- data/test/write_timebars.rb +0 -31
data/README.md
CHANGED
@@ -157,11 +157,26 @@ Oj.default_options = {:mode => :compat }
|
|
157
157
|
* `:quirks_mode` [Boolean] Allow single JSON values instead of
|
158
158
|
documents, default is true (allow).
|
159
159
|
|
160
|
+
* `:nan` [:null|:huge|:word|:raise|:auto] How to dump Infinity, -Infinity, and
|
161
|
+
NaN in null, strict, and compat mode. :null places a null, :huge places a huge
|
162
|
+
number, :word places Infinity or NaN, :raise raises and exception, :auto uses
|
163
|
+
default for each mode which are :raise for :strict, :null for :null, and :word
|
164
|
+
for :compat. Default is :auto.
|
165
|
+
|
160
166
|
## Releases
|
161
167
|
|
162
|
-
**Release 2.
|
168
|
+
** Release 2.15.0**
|
169
|
+
|
170
|
+
- Fixed bug where encoded strings could be GCed.
|
171
|
+
|
172
|
+
- :nan option added for dumping Infinity, -Infinity, and NaN. This is an
|
173
|
+
edition to the API. The default value for the :non option is :auto which uses
|
174
|
+
the previous NaN handling on dumping of non-object modes.
|
175
|
+
|
176
|
+
**Release 2.14.7**
|
163
177
|
|
164
|
-
-
|
178
|
+
- Fixed bug where a comment before another JSON element caused an
|
179
|
+
error. Comments are not part of the spec but this keep support consistent.
|
165
180
|
|
166
181
|
[Older release notes](http://www.ohler.com/dev/oj_misc/release_notes.html).
|
167
182
|
|
data/ext/oj/dump.c
CHANGED
@@ -441,13 +441,17 @@ dump_bignum(VALUE obj, Out out) {
|
|
441
441
|
*out->cur = '\0';
|
442
442
|
}
|
443
443
|
|
444
|
+
static const char inf_val[] = INF_VAL;
|
445
|
+
static const char ninf_val[] = NINF_VAL;
|
446
|
+
static const char nan_val[] = NAN_VAL;
|
447
|
+
|
444
448
|
// Removed dependencies on math due to problems with CentOS 5.4.
|
445
449
|
static void
|
446
450
|
dump_float(VALUE obj, Out out) {
|
447
451
|
char buf[64];
|
448
452
|
char *b;
|
449
453
|
double d = rb_num2dbl(obj);
|
450
|
-
int cnt;
|
454
|
+
int cnt = 0;
|
451
455
|
|
452
456
|
if (0.0 == d) {
|
453
457
|
b = buf;
|
@@ -457,43 +461,106 @@ dump_float(VALUE obj, Out out) {
|
|
457
461
|
*b++ = '\0';
|
458
462
|
cnt = 3;
|
459
463
|
} else if (OJ_INFINITY == d) {
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
464
|
+
if (ObjectMode == out->opts->mode) {
|
465
|
+
strcpy(buf, inf_val);
|
466
|
+
cnt = sizeof(inf_val) - 1;
|
467
|
+
} else {
|
468
|
+
NanDump nd = out->opts->dump_opts.nan_dump;
|
469
|
+
|
470
|
+
if (AutoNan == nd) {
|
471
|
+
switch (out->opts->mode) {
|
472
|
+
case CompatMode: nd = WordNan; break;
|
473
|
+
case StrictMode: nd = RaiseNan; break;
|
474
|
+
case NullMode: nd = NullNan; break;
|
475
|
+
default: break;
|
476
|
+
}
|
477
|
+
}
|
478
|
+
switch (nd) {
|
479
|
+
case RaiseNan:
|
480
|
+
raise_strict(obj);
|
481
|
+
break;
|
482
|
+
case WordNan:
|
483
|
+
strcpy(buf, "Infinity");
|
484
|
+
cnt = 8;
|
485
|
+
break;
|
486
|
+
case NullNan:
|
487
|
+
strcpy(buf, "null");
|
488
|
+
cnt = 4;
|
489
|
+
break;
|
490
|
+
case HugeNan:
|
491
|
+
default:
|
492
|
+
strcpy(buf, inf_val);
|
493
|
+
cnt = sizeof(inf_val) - 1;
|
494
|
+
break;
|
495
|
+
}
|
471
496
|
}
|
472
497
|
} else if (-OJ_INFINITY == d) {
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
498
|
+
if (ObjectMode == out->opts->mode) {
|
499
|
+
strcpy(buf, ninf_val);
|
500
|
+
cnt = sizeof(ninf_val) - 1;
|
501
|
+
} else {
|
502
|
+
NanDump nd = out->opts->dump_opts.nan_dump;
|
503
|
+
|
504
|
+
if (AutoNan == nd) {
|
505
|
+
switch (out->opts->mode) {
|
506
|
+
case CompatMode: nd = WordNan; break;
|
507
|
+
case StrictMode: nd = RaiseNan; break;
|
508
|
+
case NullMode: nd = NullNan; break;
|
509
|
+
default: break;
|
510
|
+
}
|
511
|
+
}
|
512
|
+
switch (nd) {
|
513
|
+
case RaiseNan:
|
514
|
+
raise_strict(obj);
|
515
|
+
break;
|
516
|
+
case WordNan:
|
517
|
+
strcpy(buf, "-Infinity");
|
518
|
+
cnt = 9;
|
519
|
+
break;
|
520
|
+
case NullNan:
|
521
|
+
strcpy(buf, "null");
|
522
|
+
cnt = 4;
|
523
|
+
break;
|
524
|
+
case HugeNan:
|
525
|
+
default:
|
526
|
+
strcpy(buf, ninf_val);
|
527
|
+
cnt = sizeof(ninf_val) - 1;
|
528
|
+
break;
|
529
|
+
}
|
484
530
|
}
|
485
531
|
} else if (isnan(d)) {
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
532
|
+
if (ObjectMode == out->opts->mode) {
|
533
|
+
strcpy(buf, nan_val);
|
534
|
+
cnt = sizeof(nan_val) - 1;
|
535
|
+
} else {
|
536
|
+
NanDump nd = out->opts->dump_opts.nan_dump;
|
537
|
+
|
538
|
+
if (AutoNan == nd) {
|
539
|
+
switch (out->opts->mode) {
|
540
|
+
case CompatMode: nd = WordNan; break;
|
541
|
+
case StrictMode: nd = RaiseNan; break;
|
542
|
+
case NullMode: nd = NullNan; break;
|
543
|
+
default: break;
|
544
|
+
}
|
545
|
+
}
|
546
|
+
switch (nd) {
|
547
|
+
case RaiseNan:
|
548
|
+
raise_strict(obj);
|
549
|
+
break;
|
550
|
+
case WordNan:
|
551
|
+
strcpy(buf, "NaN");
|
552
|
+
cnt = 3;
|
553
|
+
break;
|
554
|
+
case NullNan:
|
555
|
+
strcpy(buf, "null");
|
556
|
+
cnt = 4;
|
557
|
+
break;
|
558
|
+
case HugeNan:
|
559
|
+
default:
|
560
|
+
strcpy(buf, nan_val);
|
561
|
+
cnt = sizeof(nan_val) - 1;
|
562
|
+
break;
|
563
|
+
}
|
497
564
|
}
|
498
565
|
} else if (d == (double)(long long int)d) {
|
499
566
|
cnt = snprintf(buf, sizeof(buf), "%.1f", d);
|
data/ext/oj/oj.c
CHANGED
@@ -120,15 +120,18 @@ static VALUE create_id_sym;
|
|
120
120
|
static VALUE escape_mode_sym;
|
121
121
|
static VALUE float_prec_sym;
|
122
122
|
static VALUE float_sym;
|
123
|
+
static VALUE huge_sym;
|
123
124
|
static VALUE indent_sym;
|
124
|
-
static VALUE json_sym;
|
125
125
|
static VALUE json_parser_error_class;
|
126
|
+
static VALUE json_sym;
|
126
127
|
static VALUE mode_sym;
|
128
|
+
static VALUE nan_sym;
|
127
129
|
static VALUE newline_sym;
|
128
130
|
static VALUE nilnil_sym;
|
129
131
|
static VALUE null_sym;
|
130
132
|
static VALUE object_sym;
|
131
133
|
static VALUE quirks_mode_sym;
|
134
|
+
static VALUE raise_sym;
|
132
135
|
static VALUE ruby_sym;
|
133
136
|
static VALUE sec_prec_sym;
|
134
137
|
static VALUE strict_sym;
|
@@ -137,6 +140,7 @@ static VALUE time_format_sym;
|
|
137
140
|
static VALUE unix_sym;
|
138
141
|
static VALUE unix_zone_sym;
|
139
142
|
static VALUE use_to_json_sym;
|
143
|
+
static VALUE word_sym;
|
140
144
|
static VALUE xmlschema_sym;
|
141
145
|
static VALUE xss_safe_sym;
|
142
146
|
|
@@ -194,6 +198,7 @@ struct _Options oj_default_options = {
|
|
194
198
|
0, // after_size
|
195
199
|
0, // hash_size
|
196
200
|
0, // array_size
|
201
|
+
AutoNan,// nan_dump
|
197
202
|
}
|
198
203
|
};
|
199
204
|
|
@@ -224,6 +229,7 @@ static VALUE define_mimic_json(int argc, VALUE *argv, VALUE self);
|
|
224
229
|
* - space_before: [String|nil] String to use before the colon separator in JSON object fields
|
225
230
|
* - object_nl: [String|nil] String to use after a JSON object field value
|
226
231
|
* - array_nl: [String|nil] String to use after a JSON array value
|
232
|
+
* - nan: [:null|:huge|:word|:raise|:auto] how to dump Infinity and NaN in null, strict, and compat mode. :null places a null, :huge places a huge number, :word places Infinity or NaN, :raise raises and exception, :auto uses default for each mode.
|
227
233
|
* @return [Hash] all current option settings.
|
228
234
|
*/
|
229
235
|
static VALUE
|
@@ -279,6 +285,14 @@ get_def_opts(VALUE self) {
|
|
279
285
|
rb_hash_aset(opts, object_nl_sym, (0 == oj_default_options.dump_opts.hash_size) ? Qnil : rb_str_new2(oj_default_options.dump_opts.hash_nl));
|
280
286
|
rb_hash_aset(opts, array_nl_sym, (0 == oj_default_options.dump_opts.array_size) ? Qnil : rb_str_new2(oj_default_options.dump_opts.array_nl));
|
281
287
|
|
288
|
+
switch (oj_default_options.dump_opts.nan_dump) {
|
289
|
+
case NullNan: rb_hash_aset(opts, nan_sym, null_sym); break;
|
290
|
+
case RaiseNan: rb_hash_aset(opts, nan_sym, raise_sym); break;
|
291
|
+
case WordNan: rb_hash_aset(opts, nan_sym, word_sym); break;
|
292
|
+
case HugeNan: rb_hash_aset(opts, nan_sym, huge_sym); break;
|
293
|
+
case AutoNan:
|
294
|
+
default: rb_hash_aset(opts, nan_sym, auto_sym); break;
|
295
|
+
}
|
282
296
|
return opts;
|
283
297
|
}
|
284
298
|
|
@@ -321,6 +335,7 @@ get_def_opts(VALUE self) {
|
|
321
335
|
* @param [String|nil] :space_before String to use before the colon separator in JSON object fields
|
322
336
|
* @param [String|nil] :object_nl String to use after a JSON object field value
|
323
337
|
* @param [String|nil] :array_nl String to use after a JSON array value
|
338
|
+
* @param [:null|:huge|:word|:raise] :nan how to dump Infinity and NaN in null, strict, and compat mode. :null places a null, :huge places a huge number, :word places Infinity or NaN, :raise raises and exception, :auto uses default for each mode.
|
324
339
|
* @return [nil]
|
325
340
|
*/
|
326
341
|
static VALUE
|
@@ -546,6 +561,21 @@ oj_parse_options(VALUE ropts, Options copts) {
|
|
546
561
|
copts->dump_opts.array_size = (uint8_t)len;
|
547
562
|
}
|
548
563
|
}
|
564
|
+
if (Qnil != (v = rb_hash_lookup(ropts, nan_sym))) {
|
565
|
+
if (null_sym == v) {
|
566
|
+
copts->dump_opts.nan_dump = NullNan;
|
567
|
+
} else if (huge_sym == v) {
|
568
|
+
copts->dump_opts.nan_dump = HugeNan;
|
569
|
+
} else if (word_sym == v) {
|
570
|
+
copts->dump_opts.nan_dump = WordNan;
|
571
|
+
} else if (raise_sym == v) {
|
572
|
+
copts->dump_opts.nan_dump = RaiseNan;
|
573
|
+
} else if (auto_sym == v) {
|
574
|
+
copts->dump_opts.nan_dump = AutoNan;
|
575
|
+
} else {
|
576
|
+
rb_raise(rb_eArgError, ":nan must be :null, :huge, :word, :raise, or :auto.");
|
577
|
+
}
|
578
|
+
}
|
549
579
|
copts->dump_opts.use = (0 < copts->dump_opts.indent_size ||
|
550
580
|
0 < copts->dump_opts.after_size ||
|
551
581
|
0 < copts->dump_opts.before_size ||
|
@@ -1832,6 +1862,7 @@ static struct _Options mimic_object_to_json_options = {
|
|
1832
1862
|
0, // after_size
|
1833
1863
|
0, // hash_size
|
1834
1864
|
0, // array_size
|
1865
|
+
AutoNan,// nan_dump
|
1835
1866
|
}
|
1836
1867
|
};
|
1837
1868
|
|
@@ -2120,11 +2151,11 @@ void Init_oj() {
|
|
2120
2151
|
json_parser_error_class = Qnil; // replaced if mimic is called
|
2121
2152
|
|
2122
2153
|
allow_gc_sym = ID2SYM(rb_intern("allow_gc")); rb_gc_register_address(&allow_gc_sym);
|
2154
|
+
array_nl_sym = ID2SYM(rb_intern("array_nl")); rb_gc_register_address(&array_nl_sym);
|
2123
2155
|
ascii_only_sym = ID2SYM(rb_intern("ascii_only")); rb_gc_register_address(&ascii_only_sym);
|
2124
2156
|
ascii_sym = ID2SYM(rb_intern("ascii")); rb_gc_register_address(&ascii_sym);
|
2125
2157
|
auto_define_sym = ID2SYM(rb_intern("auto_define")); rb_gc_register_address(&auto_define_sym);
|
2126
2158
|
auto_sym = ID2SYM(rb_intern("auto")); rb_gc_register_address(&auto_sym);
|
2127
|
-
array_nl_sym = ID2SYM(rb_intern("array_nl")); rb_gc_register_address(&array_nl_sym);
|
2128
2159
|
bigdecimal_as_decimal_sym = ID2SYM(rb_intern("bigdecimal_as_decimal"));rb_gc_register_address(&bigdecimal_as_decimal_sym);
|
2129
2160
|
bigdecimal_load_sym = ID2SYM(rb_intern("bigdecimal_load"));rb_gc_register_address(&bigdecimal_load_sym);
|
2130
2161
|
bigdecimal_sym = ID2SYM(rb_intern("bigdecimal")); rb_gc_register_address(&bigdecimal_sym);
|
@@ -2135,15 +2166,18 @@ void Init_oj() {
|
|
2135
2166
|
escape_mode_sym = ID2SYM(rb_intern("escape_mode")); rb_gc_register_address(&escape_mode_sym);
|
2136
2167
|
float_prec_sym = ID2SYM(rb_intern("float_precision"));rb_gc_register_address(&float_prec_sym);
|
2137
2168
|
float_sym = ID2SYM(rb_intern("float")); rb_gc_register_address(&float_sym);
|
2169
|
+
huge_sym = ID2SYM(rb_intern("huge")); rb_gc_register_address(&huge_sym);
|
2138
2170
|
indent_sym = ID2SYM(rb_intern("indent")); rb_gc_register_address(&indent_sym);
|
2139
2171
|
json_sym = ID2SYM(rb_intern("json")); rb_gc_register_address(&json_sym);
|
2140
2172
|
mode_sym = ID2SYM(rb_intern("mode")); rb_gc_register_address(&mode_sym);
|
2173
|
+
nan_sym = ID2SYM(rb_intern("nan")); rb_gc_register_address(&nan_sym);
|
2141
2174
|
newline_sym = ID2SYM(rb_intern("newline")); rb_gc_register_address(&newline_sym);
|
2142
2175
|
nilnil_sym = ID2SYM(rb_intern("nilnil")); rb_gc_register_address(&nilnil_sym);
|
2143
2176
|
null_sym = ID2SYM(rb_intern("null")); rb_gc_register_address(&null_sym);
|
2144
2177
|
object_nl_sym = ID2SYM(rb_intern("object_nl")); rb_gc_register_address(&object_nl_sym);
|
2145
2178
|
object_sym = ID2SYM(rb_intern("object")); rb_gc_register_address(&object_sym);
|
2146
2179
|
quirks_mode_sym = ID2SYM(rb_intern("quirks_mode")); rb_gc_register_address(&quirks_mode_sym);
|
2180
|
+
raise_sym = ID2SYM(rb_intern("raise")); rb_gc_register_address(&raise_sym);
|
2147
2181
|
ruby_sym = ID2SYM(rb_intern("ruby")); rb_gc_register_address(&ruby_sym);
|
2148
2182
|
sec_prec_sym = ID2SYM(rb_intern("second_precision"));rb_gc_register_address(&sec_prec_sym);
|
2149
2183
|
space_before_sym = ID2SYM(rb_intern("space_before"));rb_gc_register_address(&space_before_sym);
|
@@ -2154,6 +2188,7 @@ void Init_oj() {
|
|
2154
2188
|
unix_sym = ID2SYM(rb_intern("unix")); rb_gc_register_address(&unix_sym);
|
2155
2189
|
unix_zone_sym = ID2SYM(rb_intern("unix_zone")); rb_gc_register_address(&unix_zone_sym);
|
2156
2190
|
use_to_json_sym = ID2SYM(rb_intern("use_to_json")); rb_gc_register_address(&use_to_json_sym);
|
2191
|
+
word_sym = ID2SYM(rb_intern("word")); rb_gc_register_address(&word_sym);
|
2157
2192
|
xmlschema_sym = ID2SYM(rb_intern("xmlschema")); rb_gc_register_address(&xmlschema_sym);
|
2158
2193
|
xss_safe_sym = ID2SYM(rb_intern("xss_safe")); rb_gc_register_address(&xss_safe_sym);
|
2159
2194
|
|
data/ext/oj/oj.h
CHANGED
@@ -68,6 +68,10 @@ enum st_retval {ST_CONTINUE = 0, ST_STOP = 1, ST_DELETE = 2, ST_CHECK};
|
|
68
68
|
|
69
69
|
#include "err.h"
|
70
70
|
|
71
|
+
#define INF_VAL "3.0e14159265358979323846"
|
72
|
+
#define NINF_VAL "-3.0e14159265358979323846"
|
73
|
+
#define NAN_VAL "3.3e14159265358979323846"
|
74
|
+
|
71
75
|
typedef enum {
|
72
76
|
Yes = 'y',
|
73
77
|
No = 'n',
|
@@ -108,6 +112,14 @@ typedef enum {
|
|
108
112
|
ObjectType = 'o',
|
109
113
|
} DumpType;
|
110
114
|
|
115
|
+
typedef enum {
|
116
|
+
AutoNan = 'a',
|
117
|
+
NullNan = 'n',
|
118
|
+
HugeNan = 'h',
|
119
|
+
WordNan = 'w',
|
120
|
+
RaiseNan = 'r',
|
121
|
+
} NanDump;
|
122
|
+
|
111
123
|
typedef enum {
|
112
124
|
STRING_IO = 'c',
|
113
125
|
STREAM_IO = 's',
|
@@ -126,6 +138,7 @@ typedef struct _DumpOpts {
|
|
126
138
|
uint8_t after_size;
|
127
139
|
uint8_t hash_size;
|
128
140
|
uint8_t array_size;
|
141
|
+
char nan_dump; // NanDump
|
129
142
|
} *DumpOpts;
|
130
143
|
|
131
144
|
typedef struct _Options {
|
data/ext/oj/parse.c
CHANGED
@@ -481,6 +481,17 @@ read_num(ParseInfo pi) {
|
|
481
481
|
}
|
482
482
|
ni.len = pi->cur - ni.str;
|
483
483
|
}
|
484
|
+
// Check for special reserved values for Infinity and NaN.
|
485
|
+
if (ni.big) {
|
486
|
+
if (0 == strcasecmp(INF_VAL, ni.str)) {
|
487
|
+
ni.infinity = 1;
|
488
|
+
} else if (0 == strcasecmp(NINF_VAL, ni.str)) {
|
489
|
+
ni.infinity = 1;
|
490
|
+
ni.neg = 1;
|
491
|
+
} else if (0 == strcasecmp(NAN_VAL, ni.str)) {
|
492
|
+
ni.nan = 1;
|
493
|
+
}
|
494
|
+
}
|
484
495
|
if (BigDec == pi->options.bigdec_load) {
|
485
496
|
ni.big = 1;
|
486
497
|
}
|
@@ -644,6 +655,9 @@ oj_parse2(ParseInfo pi) {
|
|
644
655
|
break;
|
645
656
|
case '/':
|
646
657
|
skip_comment(pi);
|
658
|
+
if (first) {
|
659
|
+
continue;
|
660
|
+
}
|
647
661
|
break;
|
648
662
|
case '\0':
|
649
663
|
pi->cur--;
|
@@ -772,17 +786,18 @@ protect_parse(VALUE pip) {
|
|
772
786
|
}
|
773
787
|
|
774
788
|
extern int oj_utf8_index;
|
775
|
-
|
776
|
-
|
789
|
+
|
790
|
+
static void
|
791
|
+
oj_pi_set_input_str(ParseInfo pi, volatile VALUE *inputp) {
|
777
792
|
#if HAS_ENCODING_SUPPORT
|
778
|
-
rb_encoding *enc = rb_to_encoding(rb_obj_encoding(
|
793
|
+
rb_encoding *enc = rb_to_encoding(rb_obj_encoding(*inputp));
|
779
794
|
|
780
795
|
if (rb_utf8_encoding() != enc) {
|
781
|
-
|
796
|
+
*inputp = rb_str_conv_enc(*inputp, enc, rb_utf8_encoding());
|
782
797
|
}
|
783
798
|
#endif
|
784
|
-
pi->json = rb_string_value_ptr((VALUE*)
|
785
|
-
pi->end = pi->json + RSTRING_LEN(
|
799
|
+
pi->json = rb_string_value_ptr((VALUE*)inputp);
|
800
|
+
pi->end = pi->json + RSTRING_LEN(*inputp);
|
786
801
|
}
|
787
802
|
|
788
803
|
VALUE
|
@@ -811,7 +826,7 @@ oj_pi_parse(int argc, VALUE *argv, ParseInfo pi, char *json, size_t len, int yie
|
|
811
826
|
pi->end = json + len;
|
812
827
|
free_json = 1;
|
813
828
|
} else if (T_STRING == rb_type(input)) {
|
814
|
-
oj_pi_set_input_str(pi, input);
|
829
|
+
oj_pi_set_input_str(pi, &input);
|
815
830
|
} else if (Qnil == input && Yes == pi->options.nilnil) {
|
816
831
|
return Qnil;
|
817
832
|
} else {
|
@@ -820,7 +835,7 @@ oj_pi_parse(int argc, VALUE *argv, ParseInfo pi, char *json, size_t len, int yie
|
|
820
835
|
|
821
836
|
if (oj_stringio_class == clas) {
|
822
837
|
s = rb_funcall2(input, oj_string_id, 0, 0);
|
823
|
-
oj_pi_set_input_str(pi, s);
|
838
|
+
oj_pi_set_input_str(pi, &s);
|
824
839
|
#if !IS_WINDOWS
|
825
840
|
} else if (rb_cFile == clas && 0 == FIX2INT(rb_funcall(input, oj_pos_id, 0))) {
|
826
841
|
int fd = FIX2INT(rb_funcall(input, oj_fileno_id, 0));
|
data/ext/oj/parse.h
CHANGED
@@ -93,7 +93,6 @@ typedef struct _ParseInfo {
|
|
93
93
|
|
94
94
|
extern void oj_parse2(ParseInfo pi);
|
95
95
|
extern void oj_set_error_at(ParseInfo pi, VALUE err_clas, const char* file, int line, const char *format, ...);
|
96
|
-
extern void oj_pi_set_input_str(ParseInfo pi, volatile VALUE input);
|
97
96
|
extern VALUE oj_pi_parse(int argc, VALUE *argv, ParseInfo pi, char *json, size_t len, int yieldOk);
|
98
97
|
extern VALUE oj_num_as_value(NumInfo ni);
|
99
98
|
|
data/ext/oj/sparse.c
CHANGED
@@ -487,11 +487,22 @@ read_num(ParseInfo pi) {
|
|
487
487
|
reader_backup(&pi->rd);
|
488
488
|
}
|
489
489
|
}
|
490
|
+
ni.str = pi->rd.str;
|
491
|
+
ni.len = pi->rd.tail - pi->rd.str;
|
492
|
+
// Check for special reserved values for Infinity and NaN.
|
493
|
+
if (ni.big) {
|
494
|
+
if (0 == strcasecmp(INF_VAL, ni.str)) {
|
495
|
+
ni.infinity = 1;
|
496
|
+
} else if (0 == strcasecmp(NINF_VAL, ni.str)) {
|
497
|
+
ni.infinity = 1;
|
498
|
+
ni.neg = 1;
|
499
|
+
} else if (0 == strcasecmp(NAN_VAL, ni.str)) {
|
500
|
+
ni.nan = 1;
|
501
|
+
}
|
502
|
+
}
|
490
503
|
if (BigDec == pi->options.bigdec_load) {
|
491
504
|
ni.big = 1;
|
492
505
|
}
|
493
|
-
ni.str = pi->rd.str;
|
494
|
-
ni.len = pi->rd.tail - pi->rd.str;
|
495
506
|
add_num_value(pi, &ni);
|
496
507
|
reader_release(&pi->rd);
|
497
508
|
}
|