oj 3.13.23 → 3.14.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/CHANGELOG.md +16 -0
- data/README.md +2 -1
- data/ext/oj/buf.h +6 -5
- data/ext/oj/cache.c +11 -10
- data/ext/oj/cache8.c +3 -2
- data/ext/oj/circarray.c +6 -5
- data/ext/oj/compat.c +12 -31
- data/ext/oj/custom.c +16 -31
- data/ext/oj/dump.c +10 -13
- data/ext/oj/dump_compat.c +9 -19
- data/ext/oj/dump_object.c +8 -13
- data/ext/oj/dump_strict.c +8 -18
- data/ext/oj/extconf.rb +10 -2
- data/ext/oj/fast.c +31 -47
- data/ext/oj/intern.c +7 -5
- data/ext/oj/mem.c +324 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +3 -2
- data/ext/oj/object.c +9 -13
- data/ext/oj/odd.c +7 -6
- data/ext/oj/oj.c +12 -5
- data/ext/oj/oj.h +6 -0
- data/ext/oj/parse.c +18 -13
- data/ext/oj/parser.c +7 -7
- data/ext/oj/rails.c +19 -28
- data/ext/oj/reader.c +4 -3
- data/ext/oj/reader.h +3 -1
- data/ext/oj/rxclass.c +5 -4
- data/ext/oj/saj.c +6 -5
- data/ext/oj/saj2.c +10 -5
- data/ext/oj/sparse.c +5 -4
- data/ext/oj/stream_writer.c +5 -4
- data/ext/oj/strict.c +4 -12
- data/ext/oj/string_writer.c +7 -6
- data/ext/oj/trace.h +16 -0
- data/ext/oj/usual.c +28 -27
- data/ext/oj/val_stack.h +4 -3
- data/ext/oj/wab.c +9 -21
- data/lib/oj/version.rb +1 -1
- data/pages/InstallOptions.md +20 -0
- data/test/foo.rb +46 -65
- data/test/perf_parser.rb +1 -0
- data/test/test_compat.rb +9 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 35277d429b423f078c9c259bc2f7d8fd5714f55bb67def193b2b58c1352f3d11
|
4
|
+
data.tar.gz: 337ca936375237d94a5e6a6ece01abd28ce367119fbb72b53dc41c3248c9e136
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e41c8ef241150e82943a92becc0ca0ec501d3ea9f9a2729abcb2529f2f5ac4360bb0a7684d46fd2357c0edb81d9347b5a6228129536c24157df5b0a788a4fc22
|
7
|
+
data.tar.gz: 6b69fcd20fe9956826865a8fafbca921ae0d9d39f43fbb3aa713b8411381852bcbfa16f7b3a3557e0c24e0545fb0a82c120c93c24bcd81ea8616b89fb6db2b47
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 3.14.2 - 2023-02-10
|
4
|
+
|
5
|
+
- Fixed check for \0 in strings.
|
6
|
+
|
7
|
+
## 3.14.1 - 2023-02-01
|
8
|
+
|
9
|
+
- Fixed issue with uninitialized handler for Oj::Parser::Saj.
|
10
|
+
|
11
|
+
- Fixed hang on unterminated string with a \0 byte in parse.c.
|
12
|
+
|
13
|
+
## 3.14.0 - 2023-01-30
|
14
|
+
|
15
|
+
- Tracing is now a compile time option giving a 15 to 20% performance boost.
|
16
|
+
|
17
|
+
- Some cleanup in teh fast parser.
|
18
|
+
|
3
19
|
## 3.13.23 - 2022-11-06
|
4
20
|
|
5
21
|
- Fixed issue with Oj::Parser extension regarding GC timeing.
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# [](http://www.ohler.com/oj) gem
|
2
2
|
|
3
|
-
[](https://github.com/ohler55/oj/actions/workflows/CI.yml)
|
4
4
|

|
5
5
|

|
6
6
|
[](https://dependabot.com/compatibility-score.html?dependency-name=oj&package-manager=bundler&version-scheme=semver)
|
@@ -70,6 +70,7 @@ links.
|
|
70
70
|
- [{file:Compatibility.md}](pages/Compatibility.md) lists current compatibility with Rubys and Rails.
|
71
71
|
- [{file:Advanced.md}](pages/Advanced.md) for fast parser and marshalling features.
|
72
72
|
- [{file:Security.md}](pages/Security.md) for security considerations.
|
73
|
+
- [{file:InstallOptions.md}](pages/InstallOptions.md) for install option.
|
73
74
|
|
74
75
|
## Releases
|
75
76
|
|
data/ext/oj/buf.h
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
#define OJ_BUF_H
|
6
6
|
|
7
7
|
#include "ruby.h"
|
8
|
+
#include "mem.h"
|
8
9
|
|
9
10
|
typedef struct _buf {
|
10
11
|
char *head;
|
@@ -25,7 +26,7 @@ inline static void buf_reset(Buf buf) {
|
|
25
26
|
|
26
27
|
inline static void buf_cleanup(Buf buf) {
|
27
28
|
if (buf->base != buf->head) {
|
28
|
-
|
29
|
+
OJ_R_FREE(buf->head);
|
29
30
|
}
|
30
31
|
}
|
31
32
|
|
@@ -49,10 +50,10 @@ inline static void buf_append_string(Buf buf, const char *s, size_t slen) {
|
|
49
50
|
size_t new_len = len + slen + len / 2;
|
50
51
|
|
51
52
|
if (buf->base == buf->head) {
|
52
|
-
buf->head =
|
53
|
+
buf->head = OJ_R_ALLOC_N(char, new_len);
|
53
54
|
memcpy(buf->head, buf->base, len);
|
54
55
|
} else {
|
55
|
-
|
56
|
+
OJ_R_REALLOC_N(buf->head, char, new_len);
|
56
57
|
}
|
57
58
|
buf->tail = buf->head + toff;
|
58
59
|
buf->end = buf->head + new_len - 1;
|
@@ -68,10 +69,10 @@ inline static void buf_append(Buf buf, char c) {
|
|
68
69
|
size_t new_len = len + len / 2;
|
69
70
|
|
70
71
|
if (buf->base == buf->head) {
|
71
|
-
buf->head =
|
72
|
+
buf->head = OJ_R_ALLOC_N(char, new_len);
|
72
73
|
memcpy(buf->head, buf->base, len);
|
73
74
|
} else {
|
74
|
-
|
75
|
+
OJ_R_REALLOC_N(buf->head, char, new_len);
|
75
76
|
}
|
76
77
|
buf->tail = buf->head + toff;
|
77
78
|
buf->end = buf->head + new_len - 1;
|
data/ext/oj/cache.c
CHANGED
@@ -6,6 +6,7 @@
|
|
6
6
|
#endif
|
7
7
|
#include <stdlib.h>
|
8
8
|
|
9
|
+
#include "mem.h"
|
9
10
|
#include "cache.h"
|
10
11
|
|
11
12
|
// The stdlib calloc, realloc, and free are used instead of the Ruby ALLOC,
|
@@ -100,7 +101,7 @@ static void rehash(Cache c) {
|
|
100
101
|
osize = c->size;
|
101
102
|
c->size = osize * 4;
|
102
103
|
c->mask = c->size - 1;
|
103
|
-
c->slots =
|
104
|
+
c->slots = OJ_REALLOC((void *)c->slots, sizeof(Slot) * c->size);
|
104
105
|
memset((Slot *)c->slots + osize, 0, sizeof(Slot) * osize * 3);
|
105
106
|
end = (Slot *)c->slots + osize;
|
106
107
|
for (sp = (Slot *)c->slots; sp < end; sp++) {
|
@@ -128,7 +129,7 @@ static VALUE lockless_intern(Cache c, const char *key, size_t len) {
|
|
128
129
|
while (REUSE_MAX < c->rcnt) {
|
129
130
|
if (NULL != (b = c->reuse)) {
|
130
131
|
c->reuse = b->next;
|
131
|
-
|
132
|
+
OJ_FREE(b);
|
132
133
|
c->rcnt--;
|
133
134
|
} else {
|
134
135
|
// An accounting error occured somewhere so correct it.
|
@@ -143,7 +144,7 @@ static VALUE lockless_intern(Cache c, const char *key, size_t len) {
|
|
143
144
|
}
|
144
145
|
rkey = c->form(key, len);
|
145
146
|
if (NULL == (b = c->reuse)) {
|
146
|
-
b =
|
147
|
+
b = OJ_CALLOC(1, sizeof(struct _slot));
|
147
148
|
} else {
|
148
149
|
c->reuse = b->next;
|
149
150
|
c->rcnt--;
|
@@ -174,7 +175,7 @@ static VALUE locking_intern(Cache c, const char *key, size_t len) {
|
|
174
175
|
while (REUSE_MAX < c->rcnt) {
|
175
176
|
if (NULL != (b = c->reuse)) {
|
176
177
|
c->reuse = b->next;
|
177
|
-
|
178
|
+
OJ_FREE(b);
|
178
179
|
c->rcnt--;
|
179
180
|
} else {
|
180
181
|
// An accounting error occured somewhere so correct it.
|
@@ -200,7 +201,7 @@ static VALUE locking_intern(Cache c, const char *key, size_t len) {
|
|
200
201
|
}
|
201
202
|
CACHE_UNLOCK(c);
|
202
203
|
if (NULL == b) {
|
203
|
-
b =
|
204
|
+
b = OJ_CALLOC(1, sizeof(struct _slot));
|
204
205
|
}
|
205
206
|
rkey = c->form(key, len);
|
206
207
|
b->hash = h;
|
@@ -228,7 +229,7 @@ static VALUE locking_intern(Cache c, const char *key, size_t len) {
|
|
228
229
|
}
|
229
230
|
|
230
231
|
Cache cache_create(size_t size, VALUE (*form)(const char *str, size_t len), bool mark, bool locking) {
|
231
|
-
Cache c =
|
232
|
+
Cache c = OJ_CALLOC(1, sizeof(struct _cache));
|
232
233
|
int shift = 0;
|
233
234
|
|
234
235
|
for (; REHASH_LIMIT < size; size /= 2, shift++) {
|
@@ -243,7 +244,7 @@ Cache cache_create(size_t size, VALUE (*form)(const char *str, size_t len), bool
|
|
243
244
|
#endif
|
244
245
|
c->size = 1 << shift;
|
245
246
|
c->mask = c->size - 1;
|
246
|
-
c->slots =
|
247
|
+
c->slots = OJ_CALLOC(c->size, sizeof(Slot));
|
247
248
|
c->form = form;
|
248
249
|
c->xrate = 1; // low
|
249
250
|
c->mark = mark;
|
@@ -268,11 +269,11 @@ void cache_free(Cache c) {
|
|
268
269
|
|
269
270
|
for (s = c->slots[i]; NULL != s; s = next) {
|
270
271
|
next = s->next;
|
271
|
-
|
272
|
+
OJ_FREE(s);
|
272
273
|
}
|
273
274
|
}
|
274
|
-
|
275
|
-
|
275
|
+
OJ_FREE((void *)c->slots);
|
276
|
+
OJ_FREE(c);
|
276
277
|
}
|
277
278
|
|
278
279
|
void cache_mark(Cache c) {
|
data/ext/oj/cache8.c
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
#include <stdlib.h>
|
10
10
|
#include <string.h>
|
11
11
|
|
12
|
+
#include "mem.h"
|
12
13
|
#include "ruby.h"
|
13
14
|
|
14
15
|
#define BITS 4
|
@@ -32,7 +33,7 @@ void oj_cache8_new(Cache8 *cache) {
|
|
32
33
|
Bucket *b;
|
33
34
|
int i;
|
34
35
|
|
35
|
-
*cache =
|
36
|
+
*cache = OJ_R_ALLOC(struct _cache8);
|
36
37
|
for (i = SLOT_CNT, b = (*cache)->buckets; 0 < i; i--, b++) {
|
37
38
|
b->value = 0;
|
38
39
|
}
|
@@ -51,7 +52,7 @@ static void cache8_delete(Cache8 cache, int depth) {
|
|
51
52
|
}
|
52
53
|
}
|
53
54
|
}
|
54
|
-
|
55
|
+
OJ_R_FREE(cache);
|
55
56
|
}
|
56
57
|
|
57
58
|
slot_t oj_cache8_get(Cache8 cache, sid_t key, slot_t **slot) {
|
data/ext/oj/circarray.c
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
// Copyright (c) 2012 Peter Ohler. All rights reserved.
|
2
2
|
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
3
3
|
|
4
|
+
#include "mem.h"
|
4
5
|
#include "circarray.h"
|
5
6
|
|
6
7
|
CircArray oj_circ_array_new(void) {
|
7
8
|
CircArray ca;
|
8
9
|
|
9
|
-
if (0 == (ca =
|
10
|
+
if (0 == (ca = OJ_R_ALLOC(struct _circArray))) {
|
10
11
|
rb_raise(rb_eNoMemError, "not enough memory\n");
|
11
12
|
}
|
12
13
|
ca->objs = ca->obj_array;
|
@@ -18,9 +19,9 @@ CircArray oj_circ_array_new(void) {
|
|
18
19
|
|
19
20
|
void oj_circ_array_free(CircArray ca) {
|
20
21
|
if (ca->objs != ca->obj_array) {
|
21
|
-
|
22
|
+
OJ_R_FREE(ca->objs);
|
22
23
|
}
|
23
|
-
|
24
|
+
OJ_R_FREE(ca);
|
24
25
|
}
|
25
26
|
|
26
27
|
void oj_circ_array_set(CircArray ca, VALUE obj, unsigned long id) {
|
@@ -31,12 +32,12 @@ void oj_circ_array_set(CircArray ca, VALUE obj, unsigned long id) {
|
|
31
32
|
unsigned long cnt = id + 512;
|
32
33
|
|
33
34
|
if (ca->objs == ca->obj_array) {
|
34
|
-
if (0 == (ca->objs =
|
35
|
+
if (0 == (ca->objs = OJ_R_ALLOC_N(VALUE, cnt))) {
|
35
36
|
rb_raise(rb_eNoMemError, "not enough memory\n");
|
36
37
|
}
|
37
38
|
memcpy(ca->objs, ca->obj_array, sizeof(VALUE) * ca->cnt);
|
38
39
|
} else {
|
39
|
-
|
40
|
+
OJ_R_REALLOC_N(ca->objs, VALUE, cnt);
|
40
41
|
}
|
41
42
|
ca->size = cnt;
|
42
43
|
}
|
data/ext/oj/compat.c
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
#include <stdio.h>
|
5
5
|
|
6
|
+
#include "mem.h"
|
6
7
|
#include "encode.h"
|
7
8
|
#include "err.h"
|
8
9
|
#include "intern.h"
|
@@ -54,9 +55,7 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
|
|
54
55
|
} else {
|
55
56
|
rb_hash_aset(parent->val, rkey, rstr);
|
56
57
|
}
|
57
|
-
|
58
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
|
59
|
-
}
|
58
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rstr);
|
60
59
|
}
|
61
60
|
}
|
62
61
|
|
@@ -68,9 +67,7 @@ static VALUE start_hash(ParseInfo pi) {
|
|
68
67
|
} else {
|
69
68
|
h = rb_hash_new();
|
70
69
|
}
|
71
|
-
|
72
|
-
oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
|
73
|
-
}
|
70
|
+
TRACE_PARSE_IN(pi->options.trace, "start_hash", pi);
|
74
71
|
return h;
|
75
72
|
}
|
76
73
|
|
@@ -89,13 +86,11 @@ static void end_hash(struct _parseInfo *pi) {
|
|
89
86
|
}
|
90
87
|
}
|
91
88
|
if (0 != parent->classname) {
|
92
|
-
|
89
|
+
OJ_R_FREE((char *)parent->classname);
|
93
90
|
parent->classname = 0;
|
94
91
|
}
|
95
92
|
}
|
96
|
-
|
97
|
-
oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
|
98
|
-
}
|
93
|
+
TRACE_PARSE_HASH_END(pi->options.trace, pi);
|
99
94
|
}
|
100
95
|
|
101
96
|
static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
@@ -110,16 +105,12 @@ static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig
|
|
110
105
|
}
|
111
106
|
}
|
112
107
|
pi->stack.head->val = rstr;
|
113
|
-
|
114
|
-
oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, rstr);
|
115
|
-
}
|
108
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, rstr);
|
116
109
|
}
|
117
110
|
|
118
111
|
static void add_num(ParseInfo pi, NumInfo ni) {
|
119
112
|
pi->stack.head->val = oj_num_as_value(ni);
|
120
|
-
|
121
|
-
oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, pi->stack.head->val);
|
122
|
-
}
|
113
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, pi->stack.head->val);
|
123
114
|
}
|
124
115
|
|
125
116
|
static void hash_set_num(struct _parseInfo *pi, Val parent, NumInfo ni) {
|
@@ -138,9 +129,7 @@ static void hash_set_num(struct _parseInfo *pi, Val parent, NumInfo ni) {
|
|
138
129
|
} else {
|
139
130
|
rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), rval);
|
140
131
|
}
|
141
|
-
|
142
|
-
oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, rval);
|
143
|
-
}
|
132
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_number", pi, rval);
|
144
133
|
}
|
145
134
|
|
146
135
|
static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
|
@@ -157,18 +146,14 @@ static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
|
|
157
146
|
} else {
|
158
147
|
rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), value);
|
159
148
|
}
|
160
|
-
|
161
|
-
oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
|
162
|
-
}
|
149
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, value);
|
163
150
|
}
|
164
151
|
|
165
152
|
static VALUE start_array(ParseInfo pi) {
|
166
153
|
if (Qnil != pi->options.array_class) {
|
167
154
|
return rb_class_new_instance(0, NULL, pi->options.array_class);
|
168
155
|
}
|
169
|
-
|
170
|
-
oj_trace_parse_in("start_array", pi, __FILE__, __LINE__);
|
171
|
-
}
|
156
|
+
TRACE_PARSE_IN(pi->options.trace, "start_array", pi);
|
172
157
|
return rb_ary_new();
|
173
158
|
}
|
174
159
|
|
@@ -184,9 +169,7 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
|
|
184
169
|
} else {
|
185
170
|
rb_ary_push(parent->val, rval);
|
186
171
|
}
|
187
|
-
|
188
|
-
oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
|
189
|
-
}
|
172
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
|
190
173
|
}
|
191
174
|
|
192
175
|
static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
@@ -201,9 +184,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
|
|
201
184
|
}
|
202
185
|
}
|
203
186
|
rb_ary_push(stack_peek(&pi->stack)->val, rstr);
|
204
|
-
|
205
|
-
oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
|
206
|
-
}
|
187
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rstr);
|
207
188
|
}
|
208
189
|
|
209
190
|
void oj_set_compat_callbacks(ParseInfo pi) {
|
data/ext/oj/custom.c
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#include <stdint.h>
|
5
5
|
#include <stdio.h>
|
6
6
|
|
7
|
+
#include "mem.h"
|
7
8
|
#include "code.h"
|
8
9
|
#include "dump.h"
|
9
10
|
#include "encode.h"
|
@@ -24,20 +25,20 @@ static void dump_obj_str(VALUE obj, int depth, Out out) {
|
|
24
25
|
{"s", 1, Qnil},
|
25
26
|
{NULL, 0, Qnil},
|
26
27
|
};
|
27
|
-
attrs->value =
|
28
|
+
attrs->value = oj_safe_string_convert(obj);
|
28
29
|
|
29
30
|
oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
|
30
31
|
}
|
31
32
|
|
32
33
|
static void dump_obj_as_str(VALUE obj, int depth, Out out) {
|
33
|
-
volatile VALUE rstr =
|
34
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
34
35
|
const char *str = RSTRING_PTR(rstr);
|
35
36
|
|
36
37
|
oj_dump_cstr(str, RSTRING_LEN(rstr), 0, 0, out);
|
37
38
|
}
|
38
39
|
|
39
40
|
static void bigdecimal_dump(VALUE obj, int depth, Out out) {
|
40
|
-
volatile VALUE rstr =
|
41
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
41
42
|
const char *str = RSTRING_PTR(rstr);
|
42
43
|
int len = (int)RSTRING_LEN(rstr);
|
43
44
|
|
@@ -305,7 +306,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
305
306
|
switch (rb_type(key)) {
|
306
307
|
case T_STRING: oj_dump_str(key, 0, out, false); break;
|
307
308
|
case T_SYMBOL: oj_dump_sym(key, 0, out, false); break;
|
308
|
-
default: oj_dump_str(
|
309
|
+
default: oj_dump_str(oj_safe_string_convert(key), 0, out, false); break;
|
309
310
|
}
|
310
311
|
if (!out->opts->dump_opts.use) {
|
311
312
|
*out->cur++ = ':';
|
@@ -437,7 +438,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
437
438
|
ID i;
|
438
439
|
|
439
440
|
if (sizeof(nbuf) <= nlen) {
|
440
|
-
if (NULL == (n2 =
|
441
|
+
if (NULL == (n2 = OJ_STRDUP(name))) {
|
441
442
|
rb_raise(rb_eNoMemError, "for attribute name.");
|
442
443
|
}
|
443
444
|
} else {
|
@@ -454,7 +455,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
454
455
|
i = rb_intern(n);
|
455
456
|
v = rb_funcall(v, i, 0);
|
456
457
|
if (nbuf != n2) {
|
457
|
-
|
458
|
+
OJ_FREE(n2);
|
458
459
|
}
|
459
460
|
}
|
460
461
|
fill_indent(out, d2);
|
@@ -479,17 +480,13 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
|
|
479
480
|
const char *s;
|
480
481
|
int len;
|
481
482
|
|
482
|
-
|
483
|
-
oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
484
|
-
}
|
483
|
+
TRACE(out->opts->trace, "to_json", obj, depth + 1, TraceRubyIn);
|
485
484
|
if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
|
486
485
|
rs = rb_funcall(obj, oj_to_json_id, 0);
|
487
486
|
} else {
|
488
487
|
rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
|
489
488
|
}
|
490
|
-
|
491
|
-
oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
492
|
-
}
|
489
|
+
TRACE(out->opts->trace, "to_json", obj, depth + 1, TraceRubyOut);
|
493
490
|
s = RSTRING_PTR(rs);
|
494
491
|
len = (int)RSTRING_LEN(rs);
|
495
492
|
|
@@ -499,9 +496,7 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
|
|
499
496
|
} else if (Yes == out->opts->as_json && rb_respond_to(obj, oj_as_json_id)) {
|
500
497
|
volatile VALUE aj;
|
501
498
|
|
502
|
-
|
503
|
-
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
504
|
-
}
|
499
|
+
TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyIn);
|
505
500
|
// Some classes elect to not take an options argument so check the arity
|
506
501
|
// of as_json.
|
507
502
|
if (0 == rb_obj_method_arity(obj, oj_as_json_id)) {
|
@@ -509,12 +504,10 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
|
|
509
504
|
} else {
|
510
505
|
aj = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
511
506
|
}
|
512
|
-
|
513
|
-
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
514
|
-
}
|
507
|
+
TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyOut);
|
515
508
|
// Catch the obvious brain damaged recursive dumping.
|
516
509
|
if (aj == obj) {
|
517
|
-
volatile VALUE rstr =
|
510
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
518
511
|
|
519
512
|
oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), false, false, out);
|
520
513
|
} else {
|
@@ -876,9 +869,7 @@ static DumpFunc custom_funcs[] = {
|
|
876
869
|
void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
|
877
870
|
int type = rb_type(obj);
|
878
871
|
|
879
|
-
|
880
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
881
|
-
}
|
872
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
|
882
873
|
if (MAX_DEPTH < depth) {
|
883
874
|
rb_raise(rb_eNoMemError, "Too deeply nested.\n");
|
884
875
|
}
|
@@ -887,16 +878,12 @@ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
887
878
|
|
888
879
|
if (NULL != f) {
|
889
880
|
f(obj, depth, out, true);
|
890
|
-
|
891
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
892
|
-
}
|
881
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
|
893
882
|
return;
|
894
883
|
}
|
895
884
|
}
|
896
885
|
oj_dump_nil(Qnil, depth, out, false);
|
897
|
-
|
898
|
-
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
899
|
-
}
|
886
|
+
TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
|
900
887
|
}
|
901
888
|
|
902
889
|
///// load functions /////
|
@@ -969,9 +956,7 @@ static void end_hash(struct _parseInfo *pi) {
|
|
969
956
|
}
|
970
957
|
parent->clas = Qundef;
|
971
958
|
}
|
972
|
-
|
973
|
-
oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
|
974
|
-
}
|
959
|
+
TRACE_PARSE_HASH_END(pi->options.trace, pi);
|
975
960
|
}
|
976
961
|
|
977
962
|
static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
|
data/ext/oj/dump.c
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
#include <poll.h>
|
15
15
|
#endif
|
16
16
|
|
17
|
+
#include "mem.h"
|
17
18
|
#include "cache8.h"
|
18
19
|
#include "odd.h"
|
19
20
|
#include "oj.h"
|
@@ -463,7 +464,7 @@ void oj_dump_time(VALUE obj, Out out, int withZone) {
|
|
463
464
|
}
|
464
465
|
|
465
466
|
void oj_dump_ruby_time(VALUE obj, Out out) {
|
466
|
-
volatile VALUE rstr =
|
467
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
467
468
|
|
468
469
|
oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
|
469
470
|
}
|
@@ -736,13 +737,9 @@ void oj_dump_raw_json(VALUE obj, int depth, Out out) {
|
|
736
737
|
} else {
|
737
738
|
volatile VALUE jv;
|
738
739
|
|
739
|
-
|
740
|
-
oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
741
|
-
}
|
740
|
+
TRACE(out->opts->trace, "raw_json", obj, depth + 1, TraceRubyIn);
|
742
741
|
jv = rb_funcall(obj, oj_raw_json_id, 2, RB_INT2NUM(depth), RB_INT2NUM(out->indent));
|
743
|
-
|
744
|
-
oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
745
|
-
}
|
742
|
+
TRACE(out->opts->trace, "raw_json", obj, depth + 1, TraceRubyOut);
|
746
743
|
oj_dump_raw(RSTRING_PTR(jv), (size_t)RSTRING_LEN(jv), out);
|
747
744
|
}
|
748
745
|
}
|
@@ -932,7 +929,7 @@ void oj_dump_class(VALUE obj, int depth, Out out, bool as_ok) {
|
|
932
929
|
}
|
933
930
|
|
934
931
|
void oj_dump_obj_to_s(VALUE obj, Out out) {
|
935
|
-
volatile VALUE rstr =
|
932
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
936
933
|
|
937
934
|
oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
|
938
935
|
}
|
@@ -952,7 +949,7 @@ void oj_out_init(Out out) {
|
|
952
949
|
|
953
950
|
void oj_out_free(Out out) {
|
954
951
|
if (out->allocated) {
|
955
|
-
|
952
|
+
OJ_R_FREE(out->buf); // TBD
|
956
953
|
}
|
957
954
|
}
|
958
955
|
|
@@ -966,9 +963,9 @@ void oj_grow_out(Out out, size_t len) {
|
|
966
963
|
size += len;
|
967
964
|
}
|
968
965
|
if (out->allocated) {
|
969
|
-
|
966
|
+
OJ_R_REALLOC_N(buf, char, (size + BUFFER_EXTRA));
|
970
967
|
} else {
|
971
|
-
buf =
|
968
|
+
buf = OJ_R_ALLOC_N(char, (size + BUFFER_EXTRA));
|
972
969
|
out->allocated = true;
|
973
970
|
memcpy(buf, out->buf, out->end - out->buf + BUFFER_EXTRA);
|
974
971
|
}
|
@@ -1173,7 +1170,7 @@ void oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1173
1170
|
} else if (d == (double)(long long int)d) {
|
1174
1171
|
cnt = snprintf(buf, sizeof(buf), "%.1f", d);
|
1175
1172
|
} else if (0 == out->opts->float_prec) {
|
1176
|
-
volatile VALUE rstr =
|
1173
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
1177
1174
|
|
1178
1175
|
cnt = (int)RSTRING_LEN(rstr);
|
1179
1176
|
if ((int)sizeof(buf) <= cnt) {
|
@@ -1195,7 +1192,7 @@ int oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char
|
|
1195
1192
|
// Round off issues at 16 significant digits so check for obvious ones of
|
1196
1193
|
// 0001 and 9999.
|
1197
1194
|
if (17 <= cnt && (0 == strcmp("0001", buf + cnt - 4) || 0 == strcmp("9999", buf + cnt - 4))) {
|
1198
|
-
volatile VALUE rstr =
|
1195
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
1199
1196
|
|
1200
1197
|
strcpy(buf, RSTRING_PTR(rstr));
|
1201
1198
|
cnt = (int)RSTRING_LEN(rstr);
|
data/ext/oj/dump_compat.c
CHANGED
@@ -109,17 +109,13 @@ dump_to_json(VALUE obj, Out out) {
|
|
109
109
|
const char *s;
|
110
110
|
int len;
|
111
111
|
|
112
|
-
|
113
|
-
oj_trace("to_json", obj, __FILE__, __LINE__, 0, TraceRubyIn);
|
114
|
-
}
|
112
|
+
TRACE(out->opts->trace, "to_json", obj, 0, TraceRubyIn);
|
115
113
|
if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
|
116
114
|
rs = rb_funcall(obj, oj_to_json_id, 0);
|
117
115
|
} else {
|
118
116
|
rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
|
119
117
|
}
|
120
|
-
|
121
|
-
oj_trace("to_json", obj, __FILE__, __LINE__, 0, TraceRubyOut);
|
122
|
-
}
|
118
|
+
TRACE(out->opts->trace, "to_json", obj, 0, TraceRubyOut);
|
123
119
|
|
124
120
|
s = RSTRING_PTR(rs);
|
125
121
|
len = (int)RSTRING_LEN(rs);
|
@@ -299,7 +295,7 @@ datetime_alt(VALUE obj, int depth, Out out) {
|
|
299
295
|
attrs[3].value = rb_funcall(obj, hour_id, 0);
|
300
296
|
attrs[4].value = rb_funcall(obj, min_id, 0);
|
301
297
|
attrs[5].value = rb_funcall(obj, sec_id, 0);
|
302
|
-
attrs[6].value =
|
298
|
+
attrs[6].value = oj_safe_string_convert(rb_funcall(obj, offset_id, 0));
|
303
299
|
attrs[7].value = rb_funcall(obj, start_id, 0);
|
304
300
|
|
305
301
|
oj_code_attrs(obj, attrs, depth, out, true);
|
@@ -606,7 +602,7 @@ dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
606
602
|
} else if (oj_rails_float_opt) {
|
607
603
|
cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, "%0.16g");
|
608
604
|
} else {
|
609
|
-
volatile VALUE rstr =
|
605
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
610
606
|
|
611
607
|
strcpy(buf, RSTRING_PTR(rstr));
|
612
608
|
cnt = (int)RSTRING_LEN(rstr);
|
@@ -648,7 +644,7 @@ hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
648
644
|
break;
|
649
645
|
default:
|
650
646
|
/*rb_raise(rb_eTypeError, "In :compat mode all Hash keys must be Strings or Symbols, not %s.\n", rb_class2name(rb_obj_class(key)));*/
|
651
|
-
oj_dump_str(
|
647
|
+
oj_dump_str(oj_safe_string_convert(key), 0, out, false);
|
652
648
|
break;
|
653
649
|
}
|
654
650
|
if (!out->opts->dump_opts.use) {
|
@@ -833,7 +829,7 @@ dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
833
829
|
if (use_bignum_alt) {
|
834
830
|
rs = rb_big2str(obj, 10);
|
835
831
|
} else {
|
836
|
-
rs =
|
832
|
+
rs = oj_safe_string_convert(obj);
|
837
833
|
}
|
838
834
|
rb_check_type(rs, T_STRING);
|
839
835
|
cnt = (int)RSTRING_LEN(rs);
|
@@ -893,9 +889,7 @@ void
|
|
893
889
|
oj_dump_compat_val(VALUE obj, int depth, Out out, bool as_ok) {
|
894
890
|
int type = rb_type(obj);
|
895
891
|
|
896
|
-
|
897
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
898
|
-
}
|
892
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
|
899
893
|
if (out->opts->dump_opts.max_depth <= depth) {
|
900
894
|
// When JSON.dump is called then an ArgumentError is expected and the
|
901
895
|
// limit is the depth inclusive. If JSON.generate is called then a
|
@@ -918,14 +912,10 @@ oj_dump_compat_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
918
912
|
|
919
913
|
if (NULL != f) {
|
920
914
|
f(obj, depth, out, as_ok);
|
921
|
-
|
922
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
923
|
-
}
|
915
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
|
924
916
|
return;
|
925
917
|
}
|
926
918
|
}
|
927
919
|
oj_dump_nil(Qnil, depth, out, false);
|
928
|
-
|
929
|
-
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
930
|
-
}
|
920
|
+
TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
|
931
921
|
}
|