oj 3.16.16 → 3.17.3
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/CHANGELOG.md +30 -0
- data/README.md +0 -16
- data/ext/oj/compat.c +3 -3
- data/ext/oj/custom.c +7 -2
- data/ext/oj/dump.c +113 -37
- data/ext/oj/dump.h +2 -0
- data/ext/oj/dump_compat.c +5 -0
- data/ext/oj/dump_object.c +5 -0
- data/ext/oj/dump_strict.c +13 -8
- data/ext/oj/fast.c +36 -16
- data/ext/oj/intern.c +1 -1
- data/ext/oj/mimic_json.c +3 -0
- data/ext/oj/oj.c +162 -1
- data/ext/oj/oj.h +55 -52
- data/ext/oj/parse.c +40 -12
- data/ext/oj/parser.c +112 -43
- data/ext/oj/rails.c +15 -15
- data/ext/oj/rxclass.c +1 -1
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/safe.c +230 -0
- data/ext/oj/safe.h +79 -0
- data/ext/oj/saj.c +10 -2
- data/ext/oj/simd.h +25 -0
- data/ext/oj/sparse.c +6 -3
- data/ext/oj/usual.c +18 -5
- data/ext/oj/wab.c +1 -1
- data/lib/oj/version.rb +1 -1
- metadata +4 -2
data/ext/oj/safe.c
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
|
|
2
|
+
#include "safe.h"
|
|
3
|
+
|
|
4
|
+
static VALUE max_hash_size_sym, max_array_size_sym, max_depth_sym, max_total_elements_sym, max_hash_size_error_class,
|
|
5
|
+
max_array_size_error_class, max_depth_error_class, max_total_elements_error_class;
|
|
6
|
+
|
|
7
|
+
static void check_object_size(safe_T safe) {
|
|
8
|
+
if (NIL_P(safe->max_hash_size)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
struct _usual usual = safe->usual;
|
|
13
|
+
Col current_object_location = usual.ctail - 1;
|
|
14
|
+
|
|
15
|
+
long int number_of_items_in_stack = usual.vtail - usual.vhead;
|
|
16
|
+
long int number_of_items_in_hash = (number_of_items_in_stack - current_object_location->vi - 1) / 2;
|
|
17
|
+
|
|
18
|
+
if (safe->max_hash_size > number_of_items_in_hash) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
rb_raise(max_hash_size_error_class, "Too many object items!");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static void check_array_size(safe_T safe) {
|
|
26
|
+
if (NIL_P(safe->max_array_size)) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
struct _usual usual = safe->usual;
|
|
31
|
+
Col current_object_location = usual.ctail - 1;
|
|
32
|
+
|
|
33
|
+
long int number_of_items_in_stack = usual.vtail - usual.vhead;
|
|
34
|
+
long int number_of_items_in_array = number_of_items_in_stack - current_object_location->vi - 1;
|
|
35
|
+
|
|
36
|
+
if (safe->max_array_size > number_of_items_in_array) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
rb_raise(max_array_size_error_class, "Too many array items!");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static void check_max_depth(safe_T safe, ojParser p) {
|
|
44
|
+
if (NIL_P(safe->max_depth) || safe->max_depth >= (p->depth + 1)) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
rb_raise(max_depth_error_class, "JSON is too deep!");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static void check_max_total_elements(safe_T safe) {
|
|
52
|
+
/*
|
|
53
|
+
* We check if `max_total_elements` is greater than `current_elements_count`
|
|
54
|
+
* (instead of greater than or equal) because top-level elements (e.g., [],
|
|
55
|
+
* null, true) are not counted. As a result, `current_elements_count`
|
|
56
|
+
* always holds one less than the actual total.
|
|
57
|
+
*/
|
|
58
|
+
if (NIL_P(safe->max_total_elements) || safe->max_total_elements > safe->current_elements_count) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
rb_raise(max_total_elements_error_class, "Too many elements!");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static void safe_start(ojParser p) {
|
|
66
|
+
safe_T safe = (safe_T)p->ctx;
|
|
67
|
+
|
|
68
|
+
safe->current_hash_size = 0;
|
|
69
|
+
safe->current_array_size = 0;
|
|
70
|
+
safe->current_elements_count = 0;
|
|
71
|
+
|
|
72
|
+
safe->delegated_start_func(p);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static void safe_open_object(ojParser p) {
|
|
76
|
+
safe_T safe = (safe_T)p->ctx;
|
|
77
|
+
|
|
78
|
+
safe->current_hash_size++;
|
|
79
|
+
safe->current_elements_count++;
|
|
80
|
+
|
|
81
|
+
check_array_size(safe);
|
|
82
|
+
check_max_depth(safe, p);
|
|
83
|
+
check_max_total_elements(safe);
|
|
84
|
+
|
|
85
|
+
safe->delegated_open_object_func(p);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static void safe_open_array(ojParser p) {
|
|
89
|
+
safe_T safe = (safe_T)p->ctx;
|
|
90
|
+
|
|
91
|
+
safe->current_array_size++;
|
|
92
|
+
safe->current_elements_count++;
|
|
93
|
+
|
|
94
|
+
check_array_size(safe);
|
|
95
|
+
check_max_depth(safe, p);
|
|
96
|
+
check_max_total_elements(safe);
|
|
97
|
+
|
|
98
|
+
safe->delegated_open_array_func(p);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
DEFINE_DELEGATED_FUNCTION(add_null);
|
|
102
|
+
DEFINE_DELEGATED_FUNCTION(add_true);
|
|
103
|
+
DEFINE_DELEGATED_FUNCTION(add_false);
|
|
104
|
+
DEFINE_DELEGATED_FUNCTION(add_int);
|
|
105
|
+
DEFINE_DELEGATED_FUNCTION(add_float);
|
|
106
|
+
DEFINE_DELEGATED_FUNCTION(add_big);
|
|
107
|
+
DEFINE_DELEGATED_FUNCTION(add_str);
|
|
108
|
+
|
|
109
|
+
static void safe_open_object_key(ojParser p) {
|
|
110
|
+
safe_T safe = (safe_T)p->ctx;
|
|
111
|
+
|
|
112
|
+
safe->current_hash_size++;
|
|
113
|
+
safe->current_elements_count += 2;
|
|
114
|
+
|
|
115
|
+
check_object_size(safe);
|
|
116
|
+
check_max_depth(safe, p);
|
|
117
|
+
check_max_total_elements(safe);
|
|
118
|
+
|
|
119
|
+
safe->delegated_open_object_key_func(p);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
static void safe_open_array_key(ojParser p) {
|
|
123
|
+
safe_T safe = (safe_T)p->ctx;
|
|
124
|
+
|
|
125
|
+
safe->current_array_size++;
|
|
126
|
+
safe->current_elements_count += 2;
|
|
127
|
+
|
|
128
|
+
check_object_size(safe);
|
|
129
|
+
check_max_depth(safe, p);
|
|
130
|
+
check_max_total_elements(safe);
|
|
131
|
+
|
|
132
|
+
safe->delegated_open_array_key_func(p);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
DEFINE_DELEGATED_OBJECT_FUNCTION(add_null);
|
|
136
|
+
DEFINE_DELEGATED_OBJECT_FUNCTION(add_true);
|
|
137
|
+
DEFINE_DELEGATED_OBJECT_FUNCTION(add_false);
|
|
138
|
+
DEFINE_DELEGATED_OBJECT_FUNCTION(add_int);
|
|
139
|
+
DEFINE_DELEGATED_OBJECT_FUNCTION(add_float);
|
|
140
|
+
DEFINE_DELEGATED_OBJECT_FUNCTION(add_big);
|
|
141
|
+
DEFINE_DELEGATED_OBJECT_FUNCTION(add_str);
|
|
142
|
+
|
|
143
|
+
void oj_init_safe_parser(ojParser p, safe_T safe, VALUE options) {
|
|
144
|
+
// Safe parser inherits all members of usual parser
|
|
145
|
+
oj_init_usual(p, &safe->usual);
|
|
146
|
+
|
|
147
|
+
safe->delegated_start_func = p->start;
|
|
148
|
+
p->start = safe_start;
|
|
149
|
+
|
|
150
|
+
Funcs f;
|
|
151
|
+
|
|
152
|
+
// Array parser functions
|
|
153
|
+
f = &p->funcs[ARRAY_FUN];
|
|
154
|
+
safe->delegated_open_object_func = f->open_object;
|
|
155
|
+
f->open_object = safe_open_object;
|
|
156
|
+
safe->delegated_open_array_func = f->open_array;
|
|
157
|
+
f->open_array = safe_open_array;
|
|
158
|
+
// The following overrides are done for counting objects
|
|
159
|
+
safe->delegated_add_null_func = f->add_null;
|
|
160
|
+
f->add_null = safe_add_null;
|
|
161
|
+
safe->delegated_add_true_func = f->add_true;
|
|
162
|
+
f->add_true = safe_add_true;
|
|
163
|
+
safe->delegated_add_false_func = f->add_false;
|
|
164
|
+
f->add_false = safe_add_false;
|
|
165
|
+
safe->delegated_add_int_func = f->add_int;
|
|
166
|
+
f->add_int = safe_add_int;
|
|
167
|
+
safe->delegated_add_float_func = f->add_float;
|
|
168
|
+
f->add_float = safe_add_float;
|
|
169
|
+
safe->delegated_add_big_func = f->add_big;
|
|
170
|
+
f->add_big = safe_add_big;
|
|
171
|
+
safe->delegated_add_str_func = f->add_str;
|
|
172
|
+
f->add_str = safe_add_str;
|
|
173
|
+
|
|
174
|
+
// Object parser functions
|
|
175
|
+
f = &p->funcs[OBJECT_FUN];
|
|
176
|
+
safe->delegated_open_object_key_func = f->open_object;
|
|
177
|
+
f->open_object = safe_open_object_key;
|
|
178
|
+
safe->delegated_open_array_key_func = f->open_array;
|
|
179
|
+
f->open_array = safe_open_array_key;
|
|
180
|
+
// The following overrides are done for counting objects
|
|
181
|
+
safe->delegated_add_null_key_func = f->add_null;
|
|
182
|
+
f->add_null = safe_add_null_key;
|
|
183
|
+
safe->delegated_add_true_key_func = f->add_true;
|
|
184
|
+
f->add_true = safe_add_true_key;
|
|
185
|
+
safe->delegated_add_false_key_func = f->add_false;
|
|
186
|
+
f->add_false = safe_add_false_key;
|
|
187
|
+
safe->delegated_add_int_key_func = f->add_int;
|
|
188
|
+
f->add_int = safe_add_int_key;
|
|
189
|
+
safe->delegated_add_float_key_func = f->add_float;
|
|
190
|
+
f->add_float = safe_add_float_key;
|
|
191
|
+
safe->delegated_add_big_key_func = f->add_big;
|
|
192
|
+
f->add_big = safe_add_big_key;
|
|
193
|
+
safe->delegated_add_str_key_func = f->add_str;
|
|
194
|
+
f->add_str = safe_add_str_key;
|
|
195
|
+
|
|
196
|
+
SET_CONFIG(max_hash_size);
|
|
197
|
+
SET_CONFIG(max_array_size);
|
|
198
|
+
SET_CONFIG(max_depth);
|
|
199
|
+
SET_CONFIG(max_total_elements);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
void oj_set_parser_safe(ojParser p, VALUE options) {
|
|
203
|
+
safe_T s = OJ_R_ALLOC(struct _safe_S);
|
|
204
|
+
|
|
205
|
+
oj_init_safe_parser(p, s, options);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
void oj_safe_init(VALUE parser_class) {
|
|
209
|
+
VALUE validation_error_class = rb_define_class_under(parser_class, "ValidationError", rb_eRuntimeError);
|
|
210
|
+
|
|
211
|
+
max_hash_size_error_class = rb_define_class_under(parser_class, "HashSizeError", validation_error_class);
|
|
212
|
+
max_array_size_error_class = rb_define_class_under(parser_class, "ArraySizeError", validation_error_class);
|
|
213
|
+
max_depth_error_class = rb_define_class_under(parser_class, "DepthError", validation_error_class);
|
|
214
|
+
max_total_elements_error_class = rb_define_class_under(parser_class, "TotalElementsError", validation_error_class);
|
|
215
|
+
|
|
216
|
+
rb_gc_register_address(&max_hash_size_error_class);
|
|
217
|
+
rb_gc_register_address(&max_array_size_error_class);
|
|
218
|
+
rb_gc_register_address(&max_depth_error_class);
|
|
219
|
+
rb_gc_register_address(&max_total_elements_error_class);
|
|
220
|
+
|
|
221
|
+
max_hash_size_sym = ID2SYM(rb_intern("max_hash_size"));
|
|
222
|
+
max_array_size_sym = ID2SYM(rb_intern("max_array_size"));
|
|
223
|
+
max_depth_sym = ID2SYM(rb_intern("max_depth"));
|
|
224
|
+
max_total_elements_sym = ID2SYM(rb_intern("max_total_elements"));
|
|
225
|
+
|
|
226
|
+
rb_gc_register_address(&max_hash_size_sym);
|
|
227
|
+
rb_gc_register_address(&max_array_size_sym);
|
|
228
|
+
rb_gc_register_address(&max_depth_sym);
|
|
229
|
+
rb_gc_register_address(&max_total_elements_sym);
|
|
230
|
+
}
|
data/ext/oj/safe.h
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#include <ruby.h>
|
|
2
|
+
|
|
3
|
+
#include "parser.h"
|
|
4
|
+
#include "usual.h"
|
|
5
|
+
|
|
6
|
+
#define SET_CONFIG(config_name) \
|
|
7
|
+
do { \
|
|
8
|
+
VALUE rb_##config_name = rb_hash_aref(options, config_name##_sym); \
|
|
9
|
+
\
|
|
10
|
+
if (RB_INTEGER_TYPE_P(rb_##config_name)) { \
|
|
11
|
+
safe->config_name = NUM2LONG(rb_##config_name); \
|
|
12
|
+
} else if (!NIL_P(rb_##config_name)) { \
|
|
13
|
+
rb_raise(rb_eArgError, "Incorrect value provided for `" #config_name "`"); \
|
|
14
|
+
} else { \
|
|
15
|
+
safe->config_name = Qnil; \
|
|
16
|
+
} \
|
|
17
|
+
} while (0);
|
|
18
|
+
|
|
19
|
+
#define DEFINE_DELEGATED_FUNCTION(function_name) \
|
|
20
|
+
static void safe_##function_name(ojParser p) { \
|
|
21
|
+
safe_T safe = (safe_T)p->ctx; \
|
|
22
|
+
\
|
|
23
|
+
safe->current_elements_count++; \
|
|
24
|
+
\
|
|
25
|
+
check_array_size(safe); \
|
|
26
|
+
check_max_total_elements(safe); \
|
|
27
|
+
\
|
|
28
|
+
safe->delegated_##function_name##_func(p); \
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
#define DEFINE_DELEGATED_OBJECT_FUNCTION(function_name) \
|
|
32
|
+
static void safe_##function_name##_key(ojParser p) { \
|
|
33
|
+
safe_T safe = (safe_T)p->ctx; \
|
|
34
|
+
\
|
|
35
|
+
safe->current_elements_count += 2; \
|
|
36
|
+
\
|
|
37
|
+
check_object_size(safe); \
|
|
38
|
+
check_max_total_elements(safe); \
|
|
39
|
+
\
|
|
40
|
+
safe->delegated_##function_name##_key_func(p); \
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
typedef struct _safe_S {
|
|
44
|
+
struct _usual usual;
|
|
45
|
+
|
|
46
|
+
long int max_hash_size;
|
|
47
|
+
long int max_array_size;
|
|
48
|
+
long int max_depth;
|
|
49
|
+
long int max_total_elements;
|
|
50
|
+
long int max_json_size_bytes;
|
|
51
|
+
|
|
52
|
+
long int current_hash_size;
|
|
53
|
+
long int current_array_size;
|
|
54
|
+
long int current_elements_count;
|
|
55
|
+
|
|
56
|
+
void (*delegated_start_func)(struct _ojParser *p);
|
|
57
|
+
|
|
58
|
+
// Array functions
|
|
59
|
+
void (*delegated_open_object_func)(struct _ojParser *p);
|
|
60
|
+
void (*delegated_open_array_func)(struct _ojParser *p);
|
|
61
|
+
void (*delegated_add_null_func)(struct _ojParser *p);
|
|
62
|
+
void (*delegated_add_true_func)(struct _ojParser *p);
|
|
63
|
+
void (*delegated_add_false_func)(struct _ojParser *p);
|
|
64
|
+
void (*delegated_add_int_func)(struct _ojParser *p);
|
|
65
|
+
void (*delegated_add_float_func)(struct _ojParser *p);
|
|
66
|
+
void (*delegated_add_big_func)(struct _ojParser *p);
|
|
67
|
+
void (*delegated_add_str_func)(struct _ojParser *p);
|
|
68
|
+
|
|
69
|
+
// Object functions
|
|
70
|
+
void (*delegated_open_object_key_func)(struct _ojParser *p);
|
|
71
|
+
void (*delegated_open_array_key_func)(struct _ojParser *p);
|
|
72
|
+
void (*delegated_add_null_key_func)(struct _ojParser *p);
|
|
73
|
+
void (*delegated_add_true_key_func)(struct _ojParser *p);
|
|
74
|
+
void (*delegated_add_false_key_func)(struct _ojParser *p);
|
|
75
|
+
void (*delegated_add_int_key_func)(struct _ojParser *p);
|
|
76
|
+
void (*delegated_add_float_key_func)(struct _ojParser *p);
|
|
77
|
+
void (*delegated_add_big_key_func)(struct _ojParser *p);
|
|
78
|
+
void (*delegated_add_str_key_func)(struct _ojParser *p);
|
|
79
|
+
} *safe_T;
|
data/ext/oj/saj.c
CHANGED
|
@@ -648,8 +648,16 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
|
648
648
|
len = lseek(fd, 0, SEEK_END);
|
|
649
649
|
lseek(fd, 0, SEEK_SET);
|
|
650
650
|
json = OJ_R_ALLOC_N(char, len + 1);
|
|
651
|
-
|
|
652
|
-
|
|
651
|
+
{
|
|
652
|
+
size_t total = 0;
|
|
653
|
+
|
|
654
|
+
while (total < len) {
|
|
655
|
+
cnt = read(fd, json + total, len - total);
|
|
656
|
+
if (cnt <= 0) {
|
|
657
|
+
rb_raise(rb_eIOError, "failed to read from IO Object.");
|
|
658
|
+
}
|
|
659
|
+
total += cnt;
|
|
660
|
+
}
|
|
653
661
|
}
|
|
654
662
|
json[len] = '\0';
|
|
655
663
|
#endif
|
data/ext/oj/simd.h
CHANGED
|
@@ -191,4 +191,29 @@ static inline OJ_TARGET_SSE42 __m128i vector_lookup_sse42(__m128i input, __m128i
|
|
|
191
191
|
|
|
192
192
|
#endif
|
|
193
193
|
|
|
194
|
+
#ifndef __has_builtin
|
|
195
|
+
#define __has_builtin(x) 0
|
|
196
|
+
#endif
|
|
197
|
+
|
|
198
|
+
#if __has_builtin(__builtin_memcpy)
|
|
199
|
+
#define HAVE_FAST_MEMCPY 1
|
|
200
|
+
|
|
201
|
+
inline static void fast_memcpy16(void *dest, const void *src, size_t n) {
|
|
202
|
+
char *d = (char *)dest;
|
|
203
|
+
char *s = (char *)src;
|
|
204
|
+
if (n >= 8) {
|
|
205
|
+
__builtin_memcpy(d, s, 8);
|
|
206
|
+
__builtin_memcpy(d + n - 8, s + n - 8, 8);
|
|
207
|
+
} else if (n >= 4) {
|
|
208
|
+
__builtin_memcpy(d, s, 4);
|
|
209
|
+
__builtin_memcpy(d + n - 4, s + n - 4, 4);
|
|
210
|
+
} else if (n >= 2) {
|
|
211
|
+
__builtin_memcpy(d, s, 2);
|
|
212
|
+
__builtin_memcpy(d + n - 2, s + n - 2, 2);
|
|
213
|
+
} else if (n >= 1) {
|
|
214
|
+
*d = *s;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
#endif
|
|
218
|
+
|
|
194
219
|
#endif /* OJ_SIMD_H */
|
data/ext/oj/sparse.c
CHANGED
|
@@ -399,6 +399,7 @@ static void read_num(ParseInfo pi) {
|
|
|
399
399
|
char c;
|
|
400
400
|
|
|
401
401
|
reader_protect(&pi->rd);
|
|
402
|
+
ni.pi = pi;
|
|
402
403
|
ni.i = 0;
|
|
403
404
|
ni.num = 0;
|
|
404
405
|
ni.div = 1;
|
|
@@ -415,7 +416,7 @@ static void read_num(ParseInfo pi) {
|
|
|
415
416
|
ni.bigdec_load = pi->options.compat_bigdec;
|
|
416
417
|
} else {
|
|
417
418
|
ni.no_big = (FloatDec == pi->options.bigdec_load || FastDec == pi->options.bigdec_load ||
|
|
418
|
-
|
|
419
|
+
RubyDec == pi->options.bigdec_load);
|
|
419
420
|
ni.bigdec_load = pi->options.bigdec_load;
|
|
420
421
|
}
|
|
421
422
|
|
|
@@ -549,6 +550,7 @@ static void read_nan(ParseInfo pi) {
|
|
|
549
550
|
struct _numInfo ni;
|
|
550
551
|
char c;
|
|
551
552
|
|
|
553
|
+
ni.pi = pi;
|
|
552
554
|
ni.str = pi->rd.str;
|
|
553
555
|
ni.i = 0;
|
|
554
556
|
ni.num = 0;
|
|
@@ -565,7 +567,7 @@ static void read_nan(ParseInfo pi) {
|
|
|
565
567
|
ni.bigdec_load = pi->options.compat_bigdec;
|
|
566
568
|
} else {
|
|
567
569
|
ni.no_big = (FloatDec == pi->options.bigdec_load || FastDec == pi->options.bigdec_load ||
|
|
568
|
-
|
|
570
|
+
RubyDec == pi->options.bigdec_load);
|
|
569
571
|
ni.bigdec_load = pi->options.bigdec_load;
|
|
570
572
|
}
|
|
571
573
|
|
|
@@ -745,6 +747,7 @@ void oj_sparse2(ParseInfo pi) {
|
|
|
745
747
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "expected NaN");
|
|
746
748
|
return;
|
|
747
749
|
}
|
|
750
|
+
ni.pi = pi;
|
|
748
751
|
ni.str = pi->rd.str;
|
|
749
752
|
ni.i = 0;
|
|
750
753
|
ni.num = 0;
|
|
@@ -761,7 +764,7 @@ void oj_sparse2(ParseInfo pi) {
|
|
|
761
764
|
ni.bigdec_load = pi->options.compat_bigdec;
|
|
762
765
|
} else {
|
|
763
766
|
ni.no_big = (FloatDec == pi->options.bigdec_load || FastDec == pi->options.bigdec_load ||
|
|
764
|
-
|
|
767
|
+
RubyDec == pi->options.bigdec_load);
|
|
765
768
|
ni.bigdec_load = pi->options.bigdec_load;
|
|
766
769
|
}
|
|
767
770
|
add_num_value(pi, &ni);
|
data/ext/oj/usual.c
CHANGED
|
@@ -63,7 +63,7 @@ static VALUE form_attr(const char *str, size_t len) {
|
|
|
63
63
|
memcpy(b + 1, str, len);
|
|
64
64
|
b[len + 1] = '\0';
|
|
65
65
|
|
|
66
|
-
id = rb_intern3(
|
|
66
|
+
id = rb_intern3(b, len + 1, oj_utf8_encoding);
|
|
67
67
|
OJ_R_FREE(b);
|
|
68
68
|
return id;
|
|
69
69
|
}
|
|
@@ -200,7 +200,10 @@ static void push_key(ojParser p) {
|
|
|
200
200
|
d->ktail = d->khead + pos;
|
|
201
201
|
d->kend = d->khead + cap;
|
|
202
202
|
}
|
|
203
|
-
|
|
203
|
+
if (32000 < klen) {
|
|
204
|
+
rb_raise(oj_json_parser_error_class, "Key too long. Keys are limited to 32,000 bytes.");
|
|
205
|
+
}
|
|
206
|
+
d->ktail->len = (int16_t)klen;
|
|
204
207
|
if (klen < sizeof(d->ktail->buf)) {
|
|
205
208
|
memcpy(d->ktail->buf, key, klen);
|
|
206
209
|
d->ktail->buf[klen] = '\0';
|
|
@@ -608,12 +611,16 @@ static void dfree(ojParser p) {
|
|
|
608
611
|
Usual d = (Usual)p->ctx;
|
|
609
612
|
|
|
610
613
|
cache_free(d->str_cache);
|
|
614
|
+
d->str_cache = NULL;
|
|
611
615
|
cache_free(d->attr_cache);
|
|
616
|
+
d->attr_cache = NULL;
|
|
612
617
|
if (NULL != d->sym_cache) {
|
|
613
618
|
cache_free(d->sym_cache);
|
|
619
|
+
d->sym_cache = NULL;
|
|
614
620
|
}
|
|
615
621
|
if (NULL != d->class_cache) {
|
|
616
622
|
cache_free(d->class_cache);
|
|
623
|
+
d->class_cache = NULL;
|
|
617
624
|
}
|
|
618
625
|
OJ_R_FREE(d->vhead);
|
|
619
626
|
OJ_R_FREE(d->chead);
|
|
@@ -640,6 +647,12 @@ static void mark(ojParser p) {
|
|
|
640
647
|
if (NULL != d->class_cache) {
|
|
641
648
|
cache_mark(d->class_cache);
|
|
642
649
|
}
|
|
650
|
+
if (Qnil != d->hash_class) {
|
|
651
|
+
rb_gc_mark(d->hash_class);
|
|
652
|
+
}
|
|
653
|
+
if (Qnil != d->array_class) {
|
|
654
|
+
rb_gc_mark(d->array_class);
|
|
655
|
+
}
|
|
643
656
|
for (vp = d->vhead; vp < d->vtail; vp++) {
|
|
644
657
|
if (Qundef != *vp) {
|
|
645
658
|
rb_gc_mark(*vp);
|
|
@@ -1050,10 +1063,10 @@ static VALUE opt_symbol_keys_set(ojParser p, VALUE value) {
|
|
|
1050
1063
|
if (NULL != d->sym_cache) {
|
|
1051
1064
|
cache_free(d->sym_cache);
|
|
1052
1065
|
d->sym_cache = NULL;
|
|
1066
|
+
d->key_cache = NULL;
|
|
1053
1067
|
}
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
}
|
|
1068
|
+
d->cache_keys = false;
|
|
1069
|
+
d->get_key = str_key;
|
|
1057
1070
|
}
|
|
1058
1071
|
return (NULL != d->sym_cache) ? Qtrue : Qfalse;
|
|
1059
1072
|
}
|
data/ext/oj/wab.c
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
// Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
|
|
20
20
|
#define OJ_INFINITY (1.0 / 0.0)
|
|
21
21
|
|
|
22
|
-
static char hex_chars[
|
|
22
|
+
static char hex_chars[257] = "\
|
|
23
23
|
................................\
|
|
24
24
|
................xxxxxxxxxx......\
|
|
25
25
|
.xxxxxx.........................\
|
data/lib/oj/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: oj
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.17.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter Ohler
|
|
@@ -158,6 +158,8 @@ files:
|
|
|
158
158
|
- ext/oj/resolve.h
|
|
159
159
|
- ext/oj/rxclass.c
|
|
160
160
|
- ext/oj/rxclass.h
|
|
161
|
+
- ext/oj/safe.c
|
|
162
|
+
- ext/oj/safe.h
|
|
161
163
|
- ext/oj/saj.c
|
|
162
164
|
- ext/oj/saj2.c
|
|
163
165
|
- ext/oj/saj2.h
|
|
@@ -229,7 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
229
231
|
- !ruby/object:Gem::Version
|
|
230
232
|
version: '0'
|
|
231
233
|
requirements: []
|
|
232
|
-
rubygems_version:
|
|
234
|
+
rubygems_version: 4.0.3
|
|
233
235
|
specification_version: 4
|
|
234
236
|
summary: A fast JSON parser and serializer.
|
|
235
237
|
test_files: []
|