oj 3.7.4 → 3.11.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -4
- data/ext/oj/buf.h +6 -34
- data/ext/oj/cache8.c +3 -3
- data/ext/oj/cache8.h +5 -33
- data/ext/oj/circarray.c +5 -9
- data/ext/oj/circarray.h +5 -8
- data/ext/oj/code.c +3 -6
- data/ext/oj/code.h +7 -10
- data/ext/oj/compat.c +11 -14
- data/ext/oj/custom.c +108 -75
- data/ext/oj/dump.c +132 -92
- data/ext/oj/dump.h +6 -7
- data/ext/oj/dump_compat.c +37 -34
- data/ext/oj/dump_leaf.c +3 -6
- data/ext/oj/dump_object.c +23 -17
- data/ext/oj/dump_strict.c +7 -9
- data/ext/oj/encode.h +6 -32
- data/ext/oj/err.c +2 -5
- data/ext/oj/err.h +6 -34
- data/ext/oj/extconf.rb +6 -0
- data/ext/oj/fast.c +39 -56
- data/ext/oj/hash.c +11 -39
- data/ext/oj/hash.h +5 -33
- data/ext/oj/hash_test.c +3 -31
- data/ext/oj/mimic_json.c +65 -44
- data/ext/oj/object.c +38 -69
- data/ext/oj/odd.c +18 -17
- data/ext/oj/odd.h +6 -9
- data/ext/oj/oj.c +139 -93
- data/ext/oj/oj.h +43 -35
- data/ext/oj/parse.c +164 -60
- data/ext/oj/parse.h +30 -31
- data/ext/oj/rails.c +119 -83
- data/ext/oj/rails.h +4 -7
- data/ext/oj/reader.c +5 -8
- data/ext/oj/reader.h +7 -10
- data/ext/oj/resolve.c +4 -7
- data/ext/oj/resolve.h +4 -7
- data/ext/oj/rxclass.c +8 -11
- data/ext/oj/rxclass.h +8 -11
- data/ext/oj/saj.c +9 -12
- data/ext/oj/scp.c +4 -7
- data/ext/oj/sparse.c +67 -33
- data/ext/oj/stream_writer.c +16 -15
- data/ext/oj/strict.c +9 -12
- data/ext/oj/string_writer.c +27 -8
- data/ext/oj/trace.c +5 -8
- data/ext/oj/trace.h +9 -12
- data/ext/oj/util.c +136 -0
- data/ext/oj/util.h +19 -0
- data/ext/oj/val_stack.c +28 -36
- data/ext/oj/val_stack.h +19 -50
- data/ext/oj/wab.c +29 -29
- data/lib/oj.rb +0 -8
- data/lib/oj/json.rb +1 -1
- data/lib/oj/mimic.rb +46 -2
- data/lib/oj/version.rb +2 -2
- data/pages/Modes.md +47 -45
- data/pages/Options.md +43 -10
- data/pages/Rails.md +60 -21
- data/pages/Security.md +1 -1
- data/test/activesupport5/abstract_unit.rb +45 -0
- data/test/activesupport5/decoding_test.rb +68 -60
- data/test/activesupport5/encoding_test.rb +111 -96
- data/test/activesupport5/encoding_test_cases.rb +33 -25
- data/test/activesupport5/test_helper.rb +43 -21
- data/test/activesupport5/time_zone_test_helpers.rb +18 -3
- data/test/activesupport6/abstract_unit.rb +44 -0
- data/test/activesupport6/decoding_test.rb +133 -0
- data/test/activesupport6/encoding_test.rb +507 -0
- data/test/activesupport6/encoding_test_cases.rb +98 -0
- data/test/activesupport6/test_common.rb +17 -0
- data/test/activesupport6/test_helper.rb +163 -0
- data/test/activesupport6/time_zone_test_helpers.rb +39 -0
- data/test/bar.rb +24 -6
- data/test/baz.rb +16 -0
- data/test/foo.rb +26 -57
- data/test/helper.rb +10 -0
- data/test/json_gem/json_common_interface_test.rb +8 -3
- data/test/json_gem/json_generator_test.rb +15 -3
- data/test/json_gem/test_helper.rb +8 -0
- data/test/prec.rb +23 -0
- data/test/sample_json.rb +1 -1
- data/test/test_compat.rb +21 -10
- data/test/test_custom.rb +135 -8
- data/test/test_integer_range.rb +1 -2
- data/test/test_object.rb +35 -2
- data/test/test_rails.rb +35 -0
- data/test/test_strict.rb +24 -1
- data/test/test_various.rb +52 -63
- data/test/test_writer.rb +19 -2
- data/test/tests.rb +1 -0
- data/test/zoo.rb +13 -0
- metadata +100 -75
data/ext/oj/rails.h
CHANGED
@@ -1,10 +1,7 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2017, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2017 Peter Ohler. All rights reserved.
|
5
2
|
|
6
|
-
#ifndef
|
7
|
-
#define
|
3
|
+
#ifndef OJ_RAILS_H
|
4
|
+
#define OJ_RAILS_H
|
8
5
|
|
9
6
|
#include "dump.h"
|
10
7
|
|
@@ -18,4 +15,4 @@ extern bool oj_rails_float_opt;
|
|
18
15
|
extern VALUE oj_optimize_rails(VALUE self);
|
19
16
|
|
20
17
|
|
21
|
-
#endif /*
|
18
|
+
#endif /* OJ_RAILS_H */
|
data/ext/oj/reader.c
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2011, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
5
2
|
|
6
3
|
#include <stdlib.h>
|
7
4
|
#include <errno.h>
|
@@ -9,7 +6,7 @@
|
|
9
6
|
#include <strings.h>
|
10
7
|
#include <sys/types.h>
|
11
8
|
#if NEEDS_UIO
|
12
|
-
#include <sys/uio.h>
|
9
|
+
#include <sys/uio.h>
|
13
10
|
#endif
|
14
11
|
#include <unistd.h>
|
15
12
|
#include <time.h>
|
@@ -78,13 +75,13 @@ oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
|
|
78
75
|
reader->io = io;
|
79
76
|
} else if (to_s) {
|
80
77
|
volatile VALUE rstr = rb_funcall(io, oj_to_s_id, 0);
|
81
|
-
|
78
|
+
|
82
79
|
reader->read_func = 0;
|
83
80
|
reader->in_str = StringValuePtr(rstr);
|
84
81
|
reader->head = (char*)reader->in_str;
|
85
82
|
reader->tail = reader->head;
|
86
83
|
reader->read_end = reader->head + RSTRING_LEN(rstr);
|
87
|
-
} else {
|
84
|
+
} else {
|
88
85
|
rb_raise(rb_eArgError, "parser io argument must be a String or respond to readpartial() or read().\n");
|
89
86
|
}
|
90
87
|
}
|
@@ -107,7 +104,7 @@ oj_reader_read(Reader reader) {
|
|
107
104
|
if (0 >= shift) { /* no space left so allocate more */
|
108
105
|
const char *old = reader->head;
|
109
106
|
size_t size = reader->end - reader->head + BUF_PAD;
|
110
|
-
|
107
|
+
|
111
108
|
if (reader->head == reader->base) {
|
112
109
|
reader->head = ALLOC_N(char, size * 2);
|
113
110
|
memcpy((char*)reader->head, old, size);
|
data/ext/oj/reader.h
CHANGED
@@ -1,12 +1,9 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2011, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
5
2
|
|
6
|
-
#ifndef
|
7
|
-
#define
|
3
|
+
#ifndef OJ_READER_H
|
4
|
+
#define OJ_READER_H
|
8
5
|
|
9
|
-
typedef struct
|
6
|
+
typedef struct _reader {
|
10
7
|
char base[0x00001000];
|
11
8
|
char *head;
|
12
9
|
char *end;
|
@@ -18,7 +15,7 @@ typedef struct _Reader {
|
|
18
15
|
int line;
|
19
16
|
int col;
|
20
17
|
int free_head;
|
21
|
-
int (*read_func)(struct
|
18
|
+
int (*read_func)(struct _reader *reader);
|
22
19
|
union {
|
23
20
|
int fd;
|
24
21
|
VALUE io;
|
@@ -43,7 +40,7 @@ reader_get(Reader reader) {
|
|
43
40
|
}
|
44
41
|
reader->col++;
|
45
42
|
reader->pos++;
|
46
|
-
|
43
|
+
|
47
44
|
return *reader->tail++;
|
48
45
|
}
|
49
46
|
|
@@ -148,4 +145,4 @@ is_white(char c) {
|
|
148
145
|
return 0;
|
149
146
|
}
|
150
147
|
|
151
|
-
#endif /*
|
148
|
+
#endif /* OJ_READER_H */
|
data/ext/oj/resolve.c
CHANGED
@@ -1,12 +1,9 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2012, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2012 Peter Ohler. All rights reserved.
|
5
2
|
|
6
3
|
#include <stdlib.h>
|
7
4
|
#include <stdio.h>
|
8
5
|
#include <string.h>
|
9
|
-
#
|
6
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
10
7
|
#include <pthread.h>
|
11
8
|
#endif
|
12
9
|
|
@@ -75,7 +72,7 @@ oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE
|
|
75
72
|
if (No == pi->options.class_cache) {
|
76
73
|
return resolve_classpath(pi, name, len, auto_define, error_class);
|
77
74
|
}
|
78
|
-
#
|
75
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
79
76
|
pthread_mutex_lock(&oj_cache_mutex);
|
80
77
|
#else
|
81
78
|
rb_mutex_lock(oj_cache_mutex);
|
@@ -85,7 +82,7 @@ oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE
|
|
85
82
|
*slot = clas;
|
86
83
|
}
|
87
84
|
}
|
88
|
-
#
|
85
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
89
86
|
pthread_mutex_unlock(&oj_cache_mutex);
|
90
87
|
#else
|
91
88
|
rb_mutex_unlock(oj_cache_mutex);
|
data/ext/oj/resolve.h
CHANGED
@@ -1,14 +1,11 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2011, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
5
2
|
|
6
|
-
#ifndef
|
7
|
-
#define
|
3
|
+
#ifndef OJ_RESOLVE_H
|
4
|
+
#define OJ_RESOLVE_H
|
8
5
|
|
9
6
|
#include "ruby.h"
|
10
7
|
|
11
8
|
extern VALUE oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class);
|
12
9
|
extern VALUE oj_name2struct(ParseInfo pi, VALUE nameVal, VALUE error_class);
|
13
10
|
|
14
|
-
#endif /*
|
11
|
+
#endif /* OJ_RESOLVE_H */
|
data/ext/oj/rxclass.c
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2017, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2017 Peter Ohler. All rights reserved.
|
5
2
|
|
6
3
|
#include <sys/types.h>
|
7
4
|
#include <stdlib.h>
|
@@ -14,8 +11,8 @@
|
|
14
11
|
|
15
12
|
#include "rxclass.h"
|
16
13
|
|
17
|
-
typedef struct
|
18
|
-
struct
|
14
|
+
typedef struct _rxC {
|
15
|
+
struct _rxC *next;
|
19
16
|
VALUE rrx;
|
20
17
|
#if !IS_WINDOWS
|
21
18
|
regex_t rx;
|
@@ -48,9 +45,9 @@ oj_rxclass_cleanup(RxClass rc) {
|
|
48
45
|
|
49
46
|
void
|
50
47
|
oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas) {
|
51
|
-
RxC rxc = ALLOC_N(struct
|
48
|
+
RxC rxc = ALLOC_N(struct _rxC, 1);
|
52
49
|
|
53
|
-
memset(rxc, 0, sizeof(struct
|
50
|
+
memset(rxc, 0, sizeof(struct _rxC));
|
54
51
|
rxc->rrx = rx;
|
55
52
|
rxc->clas = clas;
|
56
53
|
if (NULL == rc->tail) {
|
@@ -73,7 +70,7 @@ oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
|
|
73
70
|
snprintf(rc->err, sizeof(rc->err), "expressions must be less than %lu characters", (unsigned long)sizeof(rxc->src));
|
74
71
|
return EINVAL;
|
75
72
|
}
|
76
|
-
rxc = ALLOC_N(struct
|
73
|
+
rxc = ALLOC_N(struct _rxC, 1);
|
77
74
|
rxc->next = 0;
|
78
75
|
rxc->clas = clas;
|
79
76
|
|
@@ -101,12 +98,12 @@ VALUE
|
|
101
98
|
oj_rxclass_match(RxClass rc, const char *str, int len) {
|
102
99
|
RxC rxc;
|
103
100
|
char buf[4096];
|
104
|
-
|
101
|
+
|
105
102
|
for (rxc = rc->head; NULL != rxc; rxc = rxc->next) {
|
106
103
|
if (Qnil != rxc->rrx) {
|
107
104
|
// Must use a valiabel for this to work.
|
108
105
|
volatile VALUE rstr = rb_str_new(str, len);
|
109
|
-
|
106
|
+
|
110
107
|
//if (Qtrue == rb_funcall(rxc->rrx, rb_intern("match?"), 1, rstr)) {
|
111
108
|
if (Qnil != rb_funcall(rxc->rrx, rb_intern("match"), 1, rstr)) {
|
112
109
|
return rxc->clas;
|
data/ext/oj/rxclass.h
CHANGED
@@ -1,19 +1,16 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2017, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2017 Peter Ohler. All rights reserved.
|
5
2
|
|
6
|
-
#ifndef
|
7
|
-
#define
|
3
|
+
#ifndef OJ_RXCLASS_H
|
4
|
+
#define OJ_RXCLASS_H
|
8
5
|
|
9
6
|
#include <stdbool.h>
|
10
7
|
#include "ruby.h"
|
11
8
|
|
12
|
-
struct
|
9
|
+
struct _rxC;
|
13
10
|
|
14
|
-
typedef struct
|
15
|
-
struct
|
16
|
-
struct
|
11
|
+
typedef struct _rxClass {
|
12
|
+
struct _rxC *head;
|
13
|
+
struct _rxC *tail;
|
17
14
|
char err[128];
|
18
15
|
} *RxClass;
|
19
16
|
|
@@ -24,4 +21,4 @@ extern VALUE oj_rxclass_match(RxClass rc, const char *str, int len);
|
|
24
21
|
extern void oj_rxclass_copy(RxClass src, RxClass dest);
|
25
22
|
extern void oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas);
|
26
23
|
|
27
|
-
#endif /*
|
24
|
+
#endif /* OJ_RXCLASS_H */
|
data/ext/oj/saj.c
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2012, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2012 Peter Ohler. All rights reserved.
|
5
2
|
|
6
3
|
#if !IS_WINDOWS
|
7
4
|
#include <sys/resource.h> /* for getrlimit() on linux */
|
@@ -19,7 +16,7 @@
|
|
19
16
|
#include "oj.h"
|
20
17
|
#include "encode.h"
|
21
18
|
|
22
|
-
typedef struct
|
19
|
+
typedef struct _parseInfo {
|
23
20
|
char *str; /* buffer being read from */
|
24
21
|
char *s; /* current position in buffer */
|
25
22
|
void *stack_min;
|
@@ -213,7 +210,7 @@ read_next(ParseInfo pi, const char *key) {
|
|
213
210
|
static void
|
214
211
|
read_hash(ParseInfo pi, const char *key) {
|
215
212
|
const char *ks;
|
216
|
-
|
213
|
+
|
217
214
|
if (pi->has_hash_start) {
|
218
215
|
call_no_value(pi->handler, oj_hash_start_id, key);
|
219
216
|
}
|
@@ -378,7 +375,7 @@ read_num(ParseInfo pi, const char *key) {
|
|
378
375
|
if (0 == e && 0 == a && 1 == div) {
|
379
376
|
if (big) {
|
380
377
|
char c = *pi->s;
|
381
|
-
|
378
|
+
|
382
379
|
*pi->s = '\0';
|
383
380
|
if (pi->has_add_value) {
|
384
381
|
call_add_value(pi->handler, rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)), key);
|
@@ -396,7 +393,7 @@ read_num(ParseInfo pi, const char *key) {
|
|
396
393
|
} else { /* decimal */
|
397
394
|
if (big) {
|
398
395
|
char c = *pi->s;
|
399
|
-
|
396
|
+
|
400
397
|
*pi->s = '\0';
|
401
398
|
if (pi->has_add_value) {
|
402
399
|
call_add_value(pi->handler, rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)), key);
|
@@ -541,7 +538,7 @@ read_quoted_value(ParseInfo pi) {
|
|
541
538
|
char *h = pi->s; /* head */
|
542
539
|
char *t = h; /* tail */
|
543
540
|
uint32_t code;
|
544
|
-
|
541
|
+
|
545
542
|
h++; /* skip quote character */
|
546
543
|
t++;
|
547
544
|
value = h;
|
@@ -605,7 +602,7 @@ read_quoted_value(ParseInfo pi) {
|
|
605
602
|
static void
|
606
603
|
saj_parse(VALUE handler, char *json) {
|
607
604
|
volatile VALUE obj = Qnil;
|
608
|
-
struct
|
605
|
+
struct _parseInfo pi;
|
609
606
|
|
610
607
|
if (0 == json) {
|
611
608
|
if (pi.has_error) {
|
@@ -626,7 +623,7 @@ saj_parse(VALUE handler, char *json) {
|
|
626
623
|
{
|
627
624
|
struct rlimit lim;
|
628
625
|
|
629
|
-
if (0 == getrlimit(RLIMIT_STACK, &lim)) {
|
626
|
+
if (0 == getrlimit(RLIMIT_STACK, &lim) && RLIM_INFINITY != lim.rlim_cur) {
|
630
627
|
pi.stack_min = (void*)((char*)&obj - (lim.rlim_cur / 4 * 3)); /* let 3/4ths of the stack be used only */
|
631
628
|
} else {
|
632
629
|
pi.stack_min = 0; /* indicates not to check stack limit */
|
@@ -679,7 +676,7 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
679
676
|
} else {
|
680
677
|
VALUE clas = rb_obj_class(input);
|
681
678
|
volatile VALUE s;
|
682
|
-
|
679
|
+
|
683
680
|
if (oj_stringio_class == clas) {
|
684
681
|
s = rb_funcall2(input, oj_string_id, 0, 0);
|
685
682
|
len = RSTRING_LEN(s) + 1;
|
data/ext/oj/scp.c
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2012, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2012 Peter Ohler. All rights reserved.
|
5
2
|
|
6
3
|
#include <stdlib.h>
|
7
4
|
#include <stdio.h>
|
@@ -36,7 +33,7 @@ noop_add_num(ParseInfo pi, NumInfo ni) {
|
|
36
33
|
}
|
37
34
|
|
38
35
|
static VALUE
|
39
|
-
noop_hash_key(
|
36
|
+
noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
40
37
|
return Qundef;
|
41
38
|
}
|
42
39
|
|
@@ -117,7 +114,7 @@ calc_hash_key(ParseInfo pi, Val kval) {
|
|
117
114
|
}
|
118
115
|
|
119
116
|
static VALUE
|
120
|
-
hash_key(
|
117
|
+
hash_key(ParseInfo pi, const char *key, size_t klen) {
|
121
118
|
return rb_funcall(pi->handler, oj_hash_key_id, 1, rb_str_new(key, klen));
|
122
119
|
}
|
123
120
|
|
@@ -159,7 +156,7 @@ array_append_value(ParseInfo pi, VALUE value) {
|
|
159
156
|
|
160
157
|
VALUE
|
161
158
|
oj_sc_parse(int argc, VALUE *argv, VALUE self) {
|
162
|
-
struct
|
159
|
+
struct _parseInfo pi;
|
163
160
|
VALUE input = argv[1];
|
164
161
|
|
165
162
|
parse_info_init(&pi);
|
data/ext/oj/sparse.c
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2013, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2013 Peter Ohler. All rights reserved.
|
5
2
|
|
6
3
|
#include <stdlib.h>
|
7
4
|
#include <stdio.h>
|
@@ -203,7 +200,7 @@ unicode_to_chars(ParseInfo pi, Buf buf, uint32_t code) {
|
|
203
200
|
// entered at backslash
|
204
201
|
static void
|
205
202
|
read_escaped_str(ParseInfo pi) {
|
206
|
-
struct
|
203
|
+
struct _buf buf;
|
207
204
|
char c;
|
208
205
|
uint32_t code;
|
209
206
|
Val parent = stack_peek(&pi->stack);
|
@@ -228,17 +225,6 @@ read_escaped_str(ParseInfo pi) {
|
|
228
225
|
case '"': buf_append(&buf, '"'); break;
|
229
226
|
case '/': buf_append(&buf, '/'); break;
|
230
227
|
case '\\': buf_append(&buf, '\\'); break;
|
231
|
-
case '\'':
|
232
|
-
// The json gem claims this is not an error despite the
|
233
|
-
// ECMA-404 indicating it is not valid.
|
234
|
-
if (CompatMode == pi->options.mode) {
|
235
|
-
buf_append(&buf, '\'');
|
236
|
-
} else {
|
237
|
-
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid escaped character");
|
238
|
-
buf_cleanup(&buf);
|
239
|
-
return;
|
240
|
-
}
|
241
|
-
break;
|
242
228
|
case 'u':
|
243
229
|
if (0 == (code = read_hex(pi)) && err_has(&pi->err)) {
|
244
230
|
buf_cleanup(&buf);
|
@@ -276,6 +262,12 @@ read_escaped_str(ParseInfo pi) {
|
|
276
262
|
}
|
277
263
|
break;
|
278
264
|
default:
|
265
|
+
// The json gem claims this is not an error despite the
|
266
|
+
// ECMA-404 indicating it is not valid.
|
267
|
+
if (CompatMode == pi->options.mode) {
|
268
|
+
buf_append(&buf, c);
|
269
|
+
break;
|
270
|
+
}
|
279
271
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid escaped character");
|
280
272
|
buf_cleanup(&buf);
|
281
273
|
return;
|
@@ -393,7 +385,7 @@ read_str(ParseInfo pi) {
|
|
393
385
|
|
394
386
|
static void
|
395
387
|
read_num(ParseInfo pi) {
|
396
|
-
struct
|
388
|
+
struct _numInfo ni;
|
397
389
|
char c;
|
398
390
|
|
399
391
|
reader_protect(&pi->rd);
|
@@ -407,8 +399,15 @@ read_num(ParseInfo pi) {
|
|
407
399
|
ni.infinity = 0;
|
408
400
|
ni.nan = 0;
|
409
401
|
ni.neg = 0;
|
410
|
-
ni.
|
411
|
-
|
402
|
+
ni.has_exp = 0;
|
403
|
+
if (CompatMode == pi->options.mode) {
|
404
|
+
ni.no_big = !pi->options.compat_bigdec;
|
405
|
+
ni.bigdec_load = pi->options.compat_bigdec;
|
406
|
+
} else {
|
407
|
+
ni.no_big = (FloatDec == pi->options.bigdec_load || FastDec == pi->options.bigdec_load || RubyDec == pi->options.bigdec_load);
|
408
|
+
ni.bigdec_load = pi->options.bigdec_load;
|
409
|
+
}
|
410
|
+
|
412
411
|
c = reader_get(&pi->rd);
|
413
412
|
if ('-' == c) {
|
414
413
|
c = reader_get(&pi->rd);
|
@@ -469,18 +468,26 @@ read_num(ParseInfo pi) {
|
|
469
468
|
if (0 < ni.num || 0 < ni.i) {
|
470
469
|
dec_cnt++;
|
471
470
|
}
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
471
|
+
if (INT64_MAX <= ni.div) {
|
472
|
+
if (!ni.no_big) {
|
473
|
+
ni.big = true;
|
474
|
+
}
|
475
|
+
} else {
|
476
|
+
ni.num = ni.num * 10 + d;
|
477
|
+
ni.div *= 10;
|
478
|
+
ni.di++;
|
479
|
+
if (INT64_MAX <= ni.div || DEC_MAX < dec_cnt) {
|
480
|
+
if (!ni.no_big) {
|
481
|
+
ni.big = true;
|
482
|
+
}
|
483
|
+
}
|
477
484
|
}
|
478
485
|
}
|
479
486
|
}
|
480
487
|
if ('e' == c || 'E' == c) {
|
481
488
|
int eneg = 0;
|
482
489
|
|
483
|
-
ni.
|
490
|
+
ni.has_exp = 1;
|
484
491
|
c = reader_get(&pi->rd);
|
485
492
|
if ('-' == c) {
|
486
493
|
c = reader_get(&pi->rd);
|
@@ -516,7 +523,11 @@ read_num(ParseInfo pi) {
|
|
516
523
|
ni.nan = 1;
|
517
524
|
}
|
518
525
|
}
|
519
|
-
if (
|
526
|
+
if (CompatMode == pi->options.mode) {
|
527
|
+
if (pi->options.compat_bigdec) {
|
528
|
+
ni.big = 1;
|
529
|
+
}
|
530
|
+
} else if (BigDec == pi->options.bigdec_load) {
|
520
531
|
ni.big = 1;
|
521
532
|
}
|
522
533
|
add_num_value(pi, &ni);
|
@@ -525,7 +536,7 @@ read_num(ParseInfo pi) {
|
|
525
536
|
|
526
537
|
static void
|
527
538
|
read_nan(ParseInfo pi) {
|
528
|
-
struct
|
539
|
+
struct _numInfo ni;
|
529
540
|
char c;
|
530
541
|
|
531
542
|
ni.str = pi->rd.str;
|
@@ -539,14 +550,24 @@ read_nan(ParseInfo pi) {
|
|
539
550
|
ni.infinity = 0;
|
540
551
|
ni.nan = 1;
|
541
552
|
ni.neg = 0;
|
542
|
-
|
553
|
+
if (CompatMode == pi->options.mode) {
|
554
|
+
ni.no_big = !pi->options.compat_bigdec;
|
555
|
+
ni.bigdec_load = pi->options.compat_bigdec;
|
556
|
+
} else {
|
557
|
+
ni.no_big = (FloatDec == pi->options.bigdec_load || FastDec == pi->options.bigdec_load || RubyDec == pi->options.bigdec_load);
|
558
|
+
ni.bigdec_load = pi->options.bigdec_load;
|
559
|
+
}
|
543
560
|
|
544
561
|
if ('a' != reader_get(&pi->rd) ||
|
545
562
|
('N' != (c = reader_get(&pi->rd)) && 'n' != c)) {
|
546
563
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
547
564
|
return;
|
548
565
|
}
|
549
|
-
if (
|
566
|
+
if (CompatMode == pi->options.mode) {
|
567
|
+
if (pi->options.compat_bigdec) {
|
568
|
+
ni.big = 1;
|
569
|
+
}
|
570
|
+
} else if (BigDec == pi->options.bigdec_load) {
|
550
571
|
ni.big = 1;
|
551
572
|
}
|
552
573
|
add_num_value(pi, &ni);
|
@@ -632,7 +653,7 @@ oj_sparse2(ParseInfo pi) {
|
|
632
653
|
while (1) {
|
633
654
|
if (0 < pi->max_depth && pi->max_depth <= pi->stack.tail - pi->stack.head - 1) {
|
634
655
|
VALUE err_clas = oj_get_json_err_class("NestingError");
|
635
|
-
|
656
|
+
|
636
657
|
oj_set_error_at(pi, err_clas, __FILE__, __LINE__, "Too deeply nested.");
|
637
658
|
pi->err_class = err_clas;
|
638
659
|
return;
|
@@ -718,7 +739,7 @@ oj_sparse2(ParseInfo pi) {
|
|
718
739
|
return;
|
719
740
|
}
|
720
741
|
} else if ('a' == c) {
|
721
|
-
struct
|
742
|
+
struct _numInfo ni;
|
722
743
|
|
723
744
|
c = reader_get(&pi->rd);
|
724
745
|
if ('N' != c && 'n' != c) {
|
@@ -736,7 +757,15 @@ oj_sparse2(ParseInfo pi) {
|
|
736
757
|
ni.infinity = 0;
|
737
758
|
ni.nan = 1;
|
738
759
|
ni.neg = 0;
|
739
|
-
|
760
|
+
if (CompatMode == pi->options.mode) {
|
761
|
+
ni.no_big = !pi->options.compat_bigdec;
|
762
|
+
ni.bigdec_load = pi->options.compat_bigdec;
|
763
|
+
} else {
|
764
|
+
ni.no_big = (FloatDec == pi->options.bigdec_load ||
|
765
|
+
FastDec == pi->options.bigdec_load ||
|
766
|
+
RubyDec == pi->options.bigdec_load);
|
767
|
+
ni.bigdec_load = pi->options.bigdec_load;
|
768
|
+
}
|
740
769
|
add_num_value(pi, &ni);
|
741
770
|
} else {
|
742
771
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid token");
|
@@ -773,6 +802,7 @@ oj_sparse2(ParseInfo pi) {
|
|
773
802
|
first = 0;
|
774
803
|
}
|
775
804
|
start = pi->rd.pos;
|
805
|
+
// TBD break if option set to allow that
|
776
806
|
}
|
777
807
|
}
|
778
808
|
}
|
@@ -890,7 +920,7 @@ CLEANUP:
|
|
890
920
|
if (Qnil != pi->err_class && 0 != pi->err_class) {
|
891
921
|
pi->err.clas = pi->err_class;
|
892
922
|
}
|
893
|
-
if (CompatMode == pi->options.mode) {
|
923
|
+
if (CompatMode == pi->options.mode && Yes != pi->options.safe) {
|
894
924
|
// The json gem requires the error message be UTF-8 encoded. In
|
895
925
|
// additional the complete JSON source should be returned but that
|
896
926
|
// is not possible without stored all the bytes read and reading
|
@@ -898,6 +928,10 @@ CLEANUP:
|
|
898
928
|
// idea.
|
899
929
|
VALUE args[] = { oj_encode(rb_str_new2(pi->err.msg)) };
|
900
930
|
|
931
|
+
if (pi->err.clas == oj_parse_error_class) {
|
932
|
+
// The error was an Oj::ParseError so change to a JSON::ParserError.
|
933
|
+
pi->err.clas = oj_json_parser_error_class;
|
934
|
+
}
|
901
935
|
rb_exc_raise(rb_class_new_instance(1, args, pi->err.clas));
|
902
936
|
} else {
|
903
937
|
oj_err_raise(&pi->err);
|