oj 3.7.4 → 3.11.2
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.
- 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);
|