oj 3.7.5 → 3.7.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/oj/buf.h +4 -4
- data/ext/oj/cache8.c +3 -3
- data/ext/oj/cache8.h +4 -4
- data/ext/oj/circarray.c +1 -1
- data/ext/oj/circarray.h +4 -4
- data/ext/oj/code.h +6 -6
- data/ext/oj/compat.c +5 -5
- data/ext/oj/custom.c +15 -13
- data/ext/oj/dump.c +15 -5
- data/ext/oj/dump.h +3 -3
- data/ext/oj/dump_compat.c +15 -11
- data/ext/oj/dump_leaf.c +1 -1
- data/ext/oj/dump_object.c +4 -2
- data/ext/oj/encode.h +3 -3
- data/ext/oj/err.c +1 -1
- data/ext/oj/err.h +5 -5
- data/ext/oj/fast.c +14 -14
- data/ext/oj/hash.c +7 -7
- data/ext/oj/hash.h +4 -4
- data/ext/oj/hash_test.c +2 -2
- data/ext/oj/mimic_json.c +9 -9
- data/ext/oj/object.c +3 -3
- data/ext/oj/odd.c +12 -8
- data/ext/oj/odd.h +5 -5
- data/ext/oj/oj.c +14 -12
- data/ext/oj/oj.h +23 -23
- data/ext/oj/parse.c +3 -3
- data/ext/oj/parse.h +26 -26
- data/ext/oj/rails.c +27 -23
- data/ext/oj/rails.h +3 -3
- data/ext/oj/reader.h +5 -5
- data/ext/oj/resolve.h +3 -3
- data/ext/oj/rxclass.c +5 -5
- data/ext/oj/rxclass.h +7 -7
- data/ext/oj/saj.c +2 -2
- data/ext/oj/scp.c +3 -3
- data/ext/oj/sparse.c +4 -4
- data/ext/oj/stream_writer.c +1 -1
- data/ext/oj/strict.c +6 -6
- data/ext/oj/string_writer.c +1 -1
- data/ext/oj/trace.h +8 -8
- data/ext/oj/val_stack.c +8 -2
- data/ext/oj/val_stack.h +9 -9
- data/ext/oj/wab.c +11 -7
- data/lib/oj/version.rb +1 -1
- data/test/bug.rb +51 -0
- data/test/bug2.rb +10 -0
- data/test/bug3.rb +46 -0
- data/test/bug_fast.rb +32 -0
- data/test/bug_load.rb +24 -0
- data/test/crash.rb +111 -0
- data/test/example.rb +11 -0
- data/test/foo.rb +4 -29
- data/test/io.rb +48 -0
- data/test/isolated/test_mimic_rails_datetime.rb +27 -0
- data/test/mem.rb +12 -27
- data/test/mod.rb +16 -0
- data/test/omit.rb +20 -0
- data/test/rails.rb +50 -0
- data/test/rails_datetime_test.rb +24 -0
- data/test/russian.rb +18 -0
- data/test/struct.rb +29 -0
- data/test/test_serializer.rb +59 -0
- data/test/write_timebars.rb +31 -0
- data/test/x_test.rb +185 -0
- metadata +102 -68
- data/test/big.rb +0 -15
data/ext/oj/rxclass.c
CHANGED
@@ -14,8 +14,8 @@
|
|
14
14
|
|
15
15
|
#include "rxclass.h"
|
16
16
|
|
17
|
-
typedef struct
|
18
|
-
struct
|
17
|
+
typedef struct _rxC {
|
18
|
+
struct _rxC *next;
|
19
19
|
VALUE rrx;
|
20
20
|
#if !IS_WINDOWS
|
21
21
|
regex_t rx;
|
@@ -48,9 +48,9 @@ oj_rxclass_cleanup(RxClass rc) {
|
|
48
48
|
|
49
49
|
void
|
50
50
|
oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas) {
|
51
|
-
RxC rxc = ALLOC_N(struct
|
51
|
+
RxC rxc = ALLOC_N(struct _rxC, 1);
|
52
52
|
|
53
|
-
memset(rxc, 0, sizeof(struct
|
53
|
+
memset(rxc, 0, sizeof(struct _rxC));
|
54
54
|
rxc->rrx = rx;
|
55
55
|
rxc->clas = clas;
|
56
56
|
if (NULL == rc->tail) {
|
@@ -73,7 +73,7 @@ oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
|
|
73
73
|
snprintf(rc->err, sizeof(rc->err), "expressions must be less than %lu characters", (unsigned long)sizeof(rxc->src));
|
74
74
|
return EINVAL;
|
75
75
|
}
|
76
|
-
rxc = ALLOC_N(struct
|
76
|
+
rxc = ALLOC_N(struct _rxC, 1);
|
77
77
|
rxc->next = 0;
|
78
78
|
rxc->clas = clas;
|
79
79
|
|
data/ext/oj/rxclass.h
CHANGED
@@ -3,17 +3,17 @@
|
|
3
3
|
* All rights reserved.
|
4
4
|
*/
|
5
5
|
|
6
|
-
#ifndef
|
7
|
-
#define
|
6
|
+
#ifndef OJ_RXCLASS_H
|
7
|
+
#define OJ_RXCLASS_H
|
8
8
|
|
9
9
|
#include <stdbool.h>
|
10
10
|
#include "ruby.h"
|
11
11
|
|
12
|
-
struct
|
12
|
+
struct _rxC;
|
13
13
|
|
14
|
-
typedef struct
|
15
|
-
struct
|
16
|
-
struct
|
14
|
+
typedef struct _rxClass {
|
15
|
+
struct _rxC *head;
|
16
|
+
struct _rxC *tail;
|
17
17
|
char err[128];
|
18
18
|
} *RxClass;
|
19
19
|
|
@@ -24,4 +24,4 @@ extern VALUE oj_rxclass_match(RxClass rc, const char *str, int len);
|
|
24
24
|
extern void oj_rxclass_copy(RxClass src, RxClass dest);
|
25
25
|
extern void oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas);
|
26
26
|
|
27
|
-
#endif /*
|
27
|
+
#endif /* OJ_RXCLASS_H */
|
data/ext/oj/saj.c
CHANGED
@@ -19,7 +19,7 @@
|
|
19
19
|
#include "oj.h"
|
20
20
|
#include "encode.h"
|
21
21
|
|
22
|
-
typedef struct
|
22
|
+
typedef struct _parseInfo {
|
23
23
|
char *str; /* buffer being read from */
|
24
24
|
char *s; /* current position in buffer */
|
25
25
|
void *stack_min;
|
@@ -605,7 +605,7 @@ read_quoted_value(ParseInfo pi) {
|
|
605
605
|
static void
|
606
606
|
saj_parse(VALUE handler, char *json) {
|
607
607
|
volatile VALUE obj = Qnil;
|
608
|
-
struct
|
608
|
+
struct _parseInfo pi;
|
609
609
|
|
610
610
|
if (0 == json) {
|
611
611
|
if (pi.has_error) {
|
data/ext/oj/scp.c
CHANGED
@@ -36,7 +36,7 @@ noop_add_num(ParseInfo pi, NumInfo ni) {
|
|
36
36
|
}
|
37
37
|
|
38
38
|
static VALUE
|
39
|
-
noop_hash_key(
|
39
|
+
noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
40
40
|
return Qundef;
|
41
41
|
}
|
42
42
|
|
@@ -117,7 +117,7 @@ calc_hash_key(ParseInfo pi, Val kval) {
|
|
117
117
|
}
|
118
118
|
|
119
119
|
static VALUE
|
120
|
-
hash_key(
|
120
|
+
hash_key(ParseInfo pi, const char *key, size_t klen) {
|
121
121
|
return rb_funcall(pi->handler, oj_hash_key_id, 1, rb_str_new(key, klen));
|
122
122
|
}
|
123
123
|
|
@@ -159,7 +159,7 @@ array_append_value(ParseInfo pi, VALUE value) {
|
|
159
159
|
|
160
160
|
VALUE
|
161
161
|
oj_sc_parse(int argc, VALUE *argv, VALUE self) {
|
162
|
-
struct
|
162
|
+
struct _parseInfo pi;
|
163
163
|
VALUE input = argv[1];
|
164
164
|
|
165
165
|
parse_info_init(&pi);
|
data/ext/oj/sparse.c
CHANGED
@@ -203,7 +203,7 @@ unicode_to_chars(ParseInfo pi, Buf buf, uint32_t code) {
|
|
203
203
|
// entered at backslash
|
204
204
|
static void
|
205
205
|
read_escaped_str(ParseInfo pi) {
|
206
|
-
struct
|
206
|
+
struct _buf buf;
|
207
207
|
char c;
|
208
208
|
uint32_t code;
|
209
209
|
Val parent = stack_peek(&pi->stack);
|
@@ -393,7 +393,7 @@ read_str(ParseInfo pi) {
|
|
393
393
|
|
394
394
|
static void
|
395
395
|
read_num(ParseInfo pi) {
|
396
|
-
struct
|
396
|
+
struct _numInfo ni;
|
397
397
|
char c;
|
398
398
|
|
399
399
|
reader_protect(&pi->rd);
|
@@ -525,7 +525,7 @@ read_num(ParseInfo pi) {
|
|
525
525
|
|
526
526
|
static void
|
527
527
|
read_nan(ParseInfo pi) {
|
528
|
-
struct
|
528
|
+
struct _numInfo ni;
|
529
529
|
char c;
|
530
530
|
|
531
531
|
ni.str = pi->rd.str;
|
@@ -718,7 +718,7 @@ oj_sparse2(ParseInfo pi) {
|
|
718
718
|
return;
|
719
719
|
}
|
720
720
|
} else if ('a' == c) {
|
721
|
-
struct
|
721
|
+
struct _numInfo ni;
|
722
722
|
|
723
723
|
c = reader_get(&pi->rd);
|
724
724
|
if ('N' != c && 'n' != c) {
|
data/ext/oj/stream_writer.c
CHANGED
@@ -94,7 +94,7 @@ stream_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
94
94
|
} else {
|
95
95
|
rb_raise(rb_eArgError, "expected an IO Object.");
|
96
96
|
}
|
97
|
-
sw = ALLOC(struct
|
97
|
+
sw = ALLOC(struct _streamWriter);
|
98
98
|
if (2 == argc && T_HASH == rb_type(argv[1])) {
|
99
99
|
volatile VALUE v;
|
100
100
|
int buf_size = 0;
|
data/ext/oj/strict.c
CHANGED
@@ -15,21 +15,21 @@
|
|
15
15
|
#include "trace.h"
|
16
16
|
|
17
17
|
static void
|
18
|
-
hash_end(
|
18
|
+
hash_end(ParseInfo pi) {
|
19
19
|
if (Yes == pi->options.trace) {
|
20
20
|
oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
|
21
21
|
}
|
22
22
|
}
|
23
23
|
|
24
24
|
static void
|
25
|
-
array_end(
|
25
|
+
array_end(ParseInfo pi) {
|
26
26
|
if (Yes == pi->options.trace) {
|
27
27
|
oj_trace_parse_array_end(pi, __FILE__, __LINE__);
|
28
28
|
}
|
29
29
|
}
|
30
30
|
|
31
31
|
static VALUE
|
32
|
-
noop_hash_key(
|
32
|
+
noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
33
33
|
return Qundef;
|
34
34
|
}
|
35
35
|
|
@@ -100,7 +100,7 @@ hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len, const char
|
|
100
100
|
}
|
101
101
|
|
102
102
|
static void
|
103
|
-
hash_set_num(
|
103
|
+
hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
|
104
104
|
volatile VALUE v;
|
105
105
|
|
106
106
|
if (ni->infinity || ni->nan) {
|
@@ -183,7 +183,7 @@ oj_set_strict_callbacks(ParseInfo pi) {
|
|
183
183
|
|
184
184
|
VALUE
|
185
185
|
oj_strict_parse(int argc, VALUE *argv, VALUE self) {
|
186
|
-
struct
|
186
|
+
struct _parseInfo pi;
|
187
187
|
|
188
188
|
parse_info_init(&pi);
|
189
189
|
pi.options = oj_default_options;
|
@@ -200,7 +200,7 @@ oj_strict_parse(int argc, VALUE *argv, VALUE self) {
|
|
200
200
|
|
201
201
|
VALUE
|
202
202
|
oj_strict_parse_cstr(int argc, VALUE *argv, char *json, size_t len) {
|
203
|
-
struct
|
203
|
+
struct _parseInfo pi;
|
204
204
|
|
205
205
|
parse_info_init(&pi);
|
206
206
|
pi.options = oj_default_options;
|
data/ext/oj/string_writer.c
CHANGED
@@ -272,7 +272,7 @@ str_writer_free(void *ptr) {
|
|
272
272
|
*/
|
273
273
|
static VALUE
|
274
274
|
str_writer_new(int argc, VALUE *argv, VALUE self) {
|
275
|
-
StrWriter sw = ALLOC(struct
|
275
|
+
StrWriter sw = ALLOC(struct _strWriter);
|
276
276
|
|
277
277
|
oj_str_writer_init(sw, 0);
|
278
278
|
if (1 == argc) {
|
data/ext/oj/trace.h
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
* All rights reserved.
|
4
4
|
*/
|
5
5
|
|
6
|
-
#ifndef
|
7
|
-
#define
|
6
|
+
#ifndef OJ_TRACE_H
|
7
|
+
#define OJ_TRACE_H
|
8
8
|
|
9
9
|
#include <stdbool.h>
|
10
10
|
#include <ruby.h>
|
@@ -17,12 +17,12 @@ typedef enum {
|
|
17
17
|
TraceRubyOut = '<',
|
18
18
|
} TraceWhere;
|
19
19
|
|
20
|
-
struct
|
20
|
+
struct _parseInfo;
|
21
21
|
|
22
22
|
extern void oj_trace(const char *func, VALUE obj, const char *file, int line, int depth, TraceWhere where);
|
23
|
-
extern void oj_trace_parse_in(const char *func, struct
|
24
|
-
extern void oj_trace_parse_call(const char *func, struct
|
25
|
-
extern void oj_trace_parse_hash_end(struct
|
26
|
-
extern void oj_trace_parse_array_end(struct
|
23
|
+
extern void oj_trace_parse_in(const char *func, struct _parseInfo *pi, const char *file, int line);
|
24
|
+
extern void oj_trace_parse_call(const char *func, struct _parseInfo *pi, const char *file, int line, VALUE obj);
|
25
|
+
extern void oj_trace_parse_hash_end(struct _parseInfo *pi, const char *file, int line);
|
26
|
+
extern void oj_trace_parse_array_end(struct _parseInfo *pi, const char *file, int line);
|
27
27
|
|
28
|
-
#endif /*
|
28
|
+
#endif /* OJ_TRACE_H */
|
data/ext/oj/val_stack.c
CHANGED
@@ -28,6 +28,8 @@
|
|
28
28
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
29
|
*/
|
30
30
|
|
31
|
+
#include <string.h>
|
32
|
+
|
31
33
|
#include "oj.h"
|
32
34
|
#include "val_stack.h"
|
33
35
|
|
@@ -63,12 +65,16 @@ mark(void *ptr) {
|
|
63
65
|
VALUE
|
64
66
|
oj_stack_init(ValStack stack) {
|
65
67
|
#if HAVE_LIBPTHREAD
|
66
|
-
|
68
|
+
int err;
|
69
|
+
|
70
|
+
if (0 != (err = pthread_mutex_init(&stack->mutex, 0))) {
|
71
|
+
rb_raise(rb_eException, "failed to initialize a mutex. %s", strerror(err));
|
72
|
+
}
|
67
73
|
#else
|
68
74
|
stack->mutex = rb_mutex_new();
|
69
75
|
#endif
|
70
76
|
stack->head = stack->base;
|
71
|
-
stack->end = stack->base + sizeof(stack->base) / sizeof(struct
|
77
|
+
stack->end = stack->base + sizeof(stack->base) / sizeof(struct _val);
|
72
78
|
stack->tail = stack->head;
|
73
79
|
stack->head->val = Qundef;
|
74
80
|
stack->head->key = 0;
|
data/ext/oj/val_stack.h
CHANGED
@@ -28,8 +28,8 @@
|
|
28
28
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
29
|
*/
|
30
30
|
|
31
|
-
#ifndef
|
32
|
-
#define
|
31
|
+
#ifndef OJ_VAL_STACK_H
|
32
|
+
#define OJ_VAL_STACK_H
|
33
33
|
|
34
34
|
#include "ruby.h"
|
35
35
|
#include "odd.h"
|
@@ -52,7 +52,7 @@ typedef enum {
|
|
52
52
|
NEXT_HASH_COMMA = 'n',
|
53
53
|
} ValNext;
|
54
54
|
|
55
|
-
typedef struct
|
55
|
+
typedef struct _val {
|
56
56
|
volatile VALUE val;
|
57
57
|
const char *key;
|
58
58
|
char karray[32];
|
@@ -71,8 +71,8 @@ typedef struct _Val {
|
|
71
71
|
char kalloc;
|
72
72
|
} *Val;
|
73
73
|
|
74
|
-
typedef struct
|
75
|
-
struct
|
74
|
+
typedef struct _valStack {
|
75
|
+
struct _val base[STACK_INC];
|
76
76
|
Val head; // current stack
|
77
77
|
Val end; // stack end
|
78
78
|
Val tail; // pointer to one past last element name on stack
|
@@ -109,10 +109,10 @@ stack_push(ValStack stack, VALUE val, ValNext next) {
|
|
109
109
|
// A realloc can trigger a GC so make sure it happens outside the lock
|
110
110
|
// but lock before changing pointers.
|
111
111
|
if (stack->base == stack->head) {
|
112
|
-
head = ALLOC_N(struct
|
113
|
-
memcpy(head, stack->base, sizeof(struct
|
112
|
+
head = ALLOC_N(struct _val, len + STACK_INC);
|
113
|
+
memcpy(head, stack->base, sizeof(struct _val) * len);
|
114
114
|
} else {
|
115
|
-
REALLOC_N(head, struct
|
115
|
+
REALLOC_N(head, struct _val, len + STACK_INC);
|
116
116
|
}
|
117
117
|
#if HAVE_LIBPTHREAD
|
118
118
|
pthread_mutex_lock(&stack->mutex);
|
@@ -185,4 +185,4 @@ stack_pop(ValStack stack) {
|
|
185
185
|
|
186
186
|
extern const char* oj_stack_next_string(ValNext n);
|
187
187
|
|
188
|
-
#endif /*
|
188
|
+
#endif /* OJ_VAL_STACK_H */
|
data/ext/oj/wab.c
CHANGED
@@ -200,10 +200,14 @@ dump_time(VALUE obj, Out out) {
|
|
200
200
|
long long nsec;
|
201
201
|
|
202
202
|
#ifdef HAVE_RB_TIME_TIMESPEC
|
203
|
-
{
|
203
|
+
if (16 <= sizeof(struct timespec)) {
|
204
204
|
struct timespec ts = rb_time_timespec(obj);
|
205
|
+
|
205
206
|
sec = ts.tv_sec;
|
206
207
|
nsec = ts.tv_nsec;
|
208
|
+
} else {
|
209
|
+
sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
210
|
+
nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
207
211
|
}
|
208
212
|
#else
|
209
213
|
sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
@@ -291,21 +295,21 @@ oj_dump_wab_val(VALUE obj, int depth, Out out) {
|
|
291
295
|
///// load functions /////
|
292
296
|
|
293
297
|
static void
|
294
|
-
hash_end(
|
298
|
+
hash_end(ParseInfo pi) {
|
295
299
|
if (Yes == pi->options.trace) {
|
296
300
|
oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
|
297
301
|
}
|
298
302
|
}
|
299
303
|
|
300
304
|
static void
|
301
|
-
array_end(
|
305
|
+
array_end(ParseInfo pi) {
|
302
306
|
if (Yes == pi->options.trace) {
|
303
307
|
oj_trace_parse_array_end(pi, __FILE__, __LINE__);
|
304
308
|
}
|
305
309
|
}
|
306
310
|
|
307
311
|
static VALUE
|
308
|
-
noop_hash_key(
|
312
|
+
noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
309
313
|
return Qundef;
|
310
314
|
}
|
311
315
|
|
@@ -516,7 +520,7 @@ hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len, const char
|
|
516
520
|
}
|
517
521
|
|
518
522
|
static void
|
519
|
-
hash_set_num(
|
523
|
+
hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
|
520
524
|
volatile VALUE rval = Qnil;
|
521
525
|
|
522
526
|
if (ni->infinity || ni->nan) {
|
@@ -598,7 +602,7 @@ oj_set_wab_callbacks(ParseInfo pi) {
|
|
598
602
|
|
599
603
|
VALUE
|
600
604
|
oj_wab_parse(int argc, VALUE *argv, VALUE self) {
|
601
|
-
struct
|
605
|
+
struct _parseInfo pi;
|
602
606
|
|
603
607
|
parse_info_init(&pi);
|
604
608
|
pi.options = oj_default_options;
|
@@ -615,7 +619,7 @@ oj_wab_parse(int argc, VALUE *argv, VALUE self) {
|
|
615
619
|
|
616
620
|
VALUE
|
617
621
|
oj_wab_parse_cstr(int argc, VALUE *argv, char *json, size_t len) {
|
618
|
-
struct
|
622
|
+
struct _parseInfo pi;
|
619
623
|
|
620
624
|
parse_info_init(&pi);
|
621
625
|
pi.options = oj_default_options;
|
data/lib/oj/version.rb
CHANGED
data/test/bug.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
$: << File.dirname(__FILE__)
|
5
|
+
|
6
|
+
require 'helper'
|
7
|
+
|
8
|
+
class Handler
|
9
|
+
def initialize
|
10
|
+
@state = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def hash_start
|
14
|
+
@state << {}
|
15
|
+
@state.last
|
16
|
+
end
|
17
|
+
|
18
|
+
def hash_end
|
19
|
+
@state.pop
|
20
|
+
end
|
21
|
+
|
22
|
+
def hash_set(h,k,v)
|
23
|
+
h.store(k,v)
|
24
|
+
end
|
25
|
+
|
26
|
+
def array_start
|
27
|
+
@state << []
|
28
|
+
@state.last
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def array_end
|
33
|
+
@state.pop
|
34
|
+
end
|
35
|
+
|
36
|
+
def array_append(a,v)
|
37
|
+
a << v
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_value(v)
|
41
|
+
p v
|
42
|
+
end
|
43
|
+
|
44
|
+
def error(message, line, column); p "ERROR: #{message}" end
|
45
|
+
end
|
46
|
+
|
47
|
+
$handler = Handler.new
|
48
|
+
|
49
|
+
IO.popen("cat tst") { |p| puts Oj.sc_parse($handler, p) }
|
50
|
+
|
51
|
+
#File.open('tst', 'r') { |file| Oj.sc_parse($handler, file) }
|