oj 3.17.1 → 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 +8 -0
- data/ext/oj/compat.c +3 -3
- data/ext/oj/custom.c +2 -2
- data/ext/oj/fast.c +17 -4
- data/ext/oj/intern.c +1 -1
- data/ext/oj/oj.c +6 -1
- data/ext/oj/parse.c +2 -2
- data/ext/oj/parser.c +15 -2
- data/ext/oj/rxclass.c +1 -1
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/safe.c +1 -0
- data/ext/oj/usual.c +18 -5
- data/lib/oj/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e7458dcdf494ef6b1b283ca86d51fba0b3102ecf5cec13f43682878c01708c80
|
|
4
|
+
data.tar.gz: ab8099b8b275aa5acab45a012bbc96ef0c860e041be2c4ae7d6f7cd331da1755
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 60d445fd27bbea120359c21d0c1b0ac1d4fbbd678c8fd28efe620706d382a2f0cc434645967c9bac0b6d08d1065fe99dc4b15e2623d98ca0e15a61eb591a993b
|
|
7
|
+
data.tar.gz: b7736fd3a7b27f98ef3e4df05464000849403ff33a3f82ecd6d8c51b40d0c2753d23ed14c078eb26506d504de991e35ebe68e5703225c80aab6ebbd28b7a80dc
|
data/CHANGELOG.md
CHANGED
data/ext/oj/compat.c
CHANGED
|
@@ -27,7 +27,7 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
|
|
|
27
27
|
volatile VALUE rkey = oj_calc_hash_key(pi, kval);
|
|
28
28
|
|
|
29
29
|
if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
|
|
30
|
-
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str,
|
|
30
|
+
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, len);
|
|
31
31
|
|
|
32
32
|
if (Qnil != clas) {
|
|
33
33
|
rstr = rb_funcall(clas, oj_json_create_id, 1, rstr);
|
|
@@ -84,7 +84,7 @@ static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig
|
|
|
84
84
|
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
|
85
85
|
|
|
86
86
|
if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
|
|
87
|
-
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str,
|
|
87
|
+
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, len);
|
|
88
88
|
|
|
89
89
|
if (Qnil != clas) {
|
|
90
90
|
pi->stack.head->val = rb_funcall(clas, oj_json_create_id, 1, rstr);
|
|
@@ -155,7 +155,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
|
|
|
155
155
|
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
|
156
156
|
|
|
157
157
|
if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
|
|
158
|
-
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str,
|
|
158
|
+
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, len);
|
|
159
159
|
|
|
160
160
|
if (Qnil != clas) {
|
|
161
161
|
rb_ary_push(stack_peek(&pi->stack)->val, rb_funcall(clas, oj_json_create_id, 1, rstr));
|
data/ext/oj/custom.c
CHANGED
|
@@ -915,7 +915,7 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
|
|
|
915
915
|
volatile VALUE rkey = oj_calc_hash_key(pi, kval);
|
|
916
916
|
|
|
917
917
|
if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
|
|
918
|
-
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str,
|
|
918
|
+
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, len);
|
|
919
919
|
|
|
920
920
|
if (Qnil != clas) {
|
|
921
921
|
rstr = rb_funcall(clas, oj_json_create_id, 1, rstr);
|
|
@@ -1020,7 +1020,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
|
|
|
1020
1020
|
volatile VALUE rstr = rb_utf8_str_new(str, len);
|
|
1021
1021
|
|
|
1022
1022
|
if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
|
|
1023
|
-
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str,
|
|
1023
|
+
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, len);
|
|
1024
1024
|
|
|
1025
1025
|
if (Qnil != clas) {
|
|
1026
1026
|
rb_ary_push(stack_peek(&pi->stack)->val, rb_funcall(clas, oj_json_create_id, 1, rstr));
|
data/ext/oj/fast.c
CHANGED
|
@@ -80,7 +80,7 @@ static void each_leaf(Doc doc, VALUE self);
|
|
|
80
80
|
static int move_step(Doc doc, const char *path, int loc);
|
|
81
81
|
static Leaf get_doc_leaf(Doc doc, const char *path);
|
|
82
82
|
static Leaf get_leaf(Leaf *stack, Leaf *lp, const char *path);
|
|
83
|
-
static void each_value(Doc doc, Leaf leaf);
|
|
83
|
+
static void each_value(Doc doc, Leaf leaf, VALUE self);
|
|
84
84
|
|
|
85
85
|
VALUE oj_doc_class = Qundef;
|
|
86
86
|
|
|
@@ -957,6 +957,9 @@ static void each_leaf(Doc doc, VALUE self) {
|
|
|
957
957
|
}
|
|
958
958
|
} else {
|
|
959
959
|
rb_yield(self);
|
|
960
|
+
if (NULL == DATA_PTR(self)) {
|
|
961
|
+
rb_raise(rb_eIOError, "Document closed.");
|
|
962
|
+
}
|
|
960
963
|
}
|
|
961
964
|
}
|
|
962
965
|
|
|
@@ -1050,19 +1053,22 @@ static int move_step(Doc doc, const char *path, int loc) {
|
|
|
1050
1053
|
return loc;
|
|
1051
1054
|
}
|
|
1052
1055
|
|
|
1053
|
-
static void each_value(Doc doc, Leaf leaf) {
|
|
1056
|
+
static void each_value(Doc doc, Leaf leaf, VALUE self) {
|
|
1054
1057
|
if (COL_VAL == leaf->value_type) {
|
|
1055
1058
|
if (0 != leaf->elements) {
|
|
1056
1059
|
Leaf first = leaf->elements->next;
|
|
1057
1060
|
Leaf e = first;
|
|
1058
1061
|
|
|
1059
1062
|
do {
|
|
1060
|
-
each_value(doc, e);
|
|
1063
|
+
each_value(doc, e, self);
|
|
1061
1064
|
e = e->next;
|
|
1062
1065
|
} while (e != first);
|
|
1063
1066
|
}
|
|
1064
1067
|
} else {
|
|
1065
1068
|
rb_yield(leaf_value(doc, leaf));
|
|
1069
|
+
if (NULL == DATA_PTR(self)) {
|
|
1070
|
+
rb_raise(rb_eIOError, "Document closed.");
|
|
1071
|
+
}
|
|
1066
1072
|
}
|
|
1067
1073
|
}
|
|
1068
1074
|
|
|
@@ -1498,12 +1504,19 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
|
|
|
1498
1504
|
Leaf first = (*doc->where)->elements->next;
|
|
1499
1505
|
Leaf e = first;
|
|
1500
1506
|
|
|
1507
|
+
if (MAX_STACK <= (doc->where + 1) - doc->where_path) {
|
|
1508
|
+
rb_raise(rb_const_get_at(Oj, rb_intern("DepthError")), "Path too deep. Limit is %d levels.", MAX_STACK);
|
|
1509
|
+
}
|
|
1501
1510
|
doc->where++;
|
|
1502
1511
|
do {
|
|
1503
1512
|
*doc->where = e;
|
|
1504
1513
|
rb_yield(self);
|
|
1514
|
+
if (NULL == DATA_PTR(self)) {
|
|
1515
|
+
rb_raise(rb_eIOError, "Document closed.");
|
|
1516
|
+
}
|
|
1505
1517
|
e = e->next;
|
|
1506
1518
|
} while (e != first);
|
|
1519
|
+
doc->where--;
|
|
1507
1520
|
}
|
|
1508
1521
|
if (0 < wlen) {
|
|
1509
1522
|
memcpy(doc->where_path, save_path, sizeof(Leaf) * (wlen + 1));
|
|
@@ -1547,7 +1560,7 @@ static VALUE doc_each_value(int argc, VALUE *argv, VALUE self) {
|
|
|
1547
1560
|
path = StringValuePtr(*argv);
|
|
1548
1561
|
}
|
|
1549
1562
|
if (0 != (leaf = get_doc_leaf(doc, path))) {
|
|
1550
|
-
each_value(doc, leaf);
|
|
1563
|
+
each_value(doc, leaf, self);
|
|
1551
1564
|
}
|
|
1552
1565
|
}
|
|
1553
1566
|
return Qnil;
|
data/ext/oj/intern.c
CHANGED
data/ext/oj/oj.c
CHANGED
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
#include "rails.h"
|
|
21
21
|
#include "simd.h"
|
|
22
22
|
|
|
23
|
+
#define MAX_INDENT 16
|
|
24
|
+
|
|
23
25
|
typedef struct _yesNoOpt {
|
|
24
26
|
VALUE sym;
|
|
25
27
|
char *attr;
|
|
@@ -766,7 +768,10 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
|
766
768
|
case T_FIXNUM:
|
|
767
769
|
copts->dump_opts.indent_size = 0;
|
|
768
770
|
*copts->dump_opts.indent_str = '\0';
|
|
769
|
-
|
|
771
|
+
if (MAX_INDENT < FIX2INT(v)) {
|
|
772
|
+
rb_raise(rb_eArgError, "indent is limited to %d characters.", MAX_INDENT);
|
|
773
|
+
}
|
|
774
|
+
copts->indent = FIX2INT(v);
|
|
770
775
|
break;
|
|
771
776
|
case T_STRING:
|
|
772
777
|
if (sizeof(copts->dump_opts.indent_str) <= (len = RSTRING_LEN(v))) {
|
data/ext/oj/parse.c
CHANGED
|
@@ -394,7 +394,7 @@ void oj_scanner_init(void) {
|
|
|
394
394
|
static void read_escaped_str(ParseInfo pi, const char *start) {
|
|
395
395
|
struct _buf buf;
|
|
396
396
|
const char *s;
|
|
397
|
-
|
|
397
|
+
size_t cnt = pi->cur - start;
|
|
398
398
|
uint32_t code;
|
|
399
399
|
Val parent = stack_peek(&pi->stack);
|
|
400
400
|
|
|
@@ -669,7 +669,7 @@ static void read_num(ParseInfo pi) {
|
|
|
669
669
|
// A trailing . is not a valid decimal but if encountered allow it
|
|
670
670
|
// except when mimicking the JSON gem or in strict mode.
|
|
671
671
|
if (StrictMode == pi->options.mode || CompatMode == pi->options.mode) {
|
|
672
|
-
|
|
672
|
+
size_t pos = pi->cur - ni.str;
|
|
673
673
|
|
|
674
674
|
if (1 == pos || (2 == pos && ni.neg)) {
|
|
675
675
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number");
|
data/ext/oj/parser.c
CHANGED
|
@@ -674,6 +674,10 @@ static void parse(ojParser p, const byte *json, bool more) {
|
|
|
674
674
|
p->cur = b - json;
|
|
675
675
|
p->funcs[p->stack[p->depth]].open_object(p);
|
|
676
676
|
p->depth++;
|
|
677
|
+
if ((int)sizeof(p->stack) <= p->depth) {
|
|
678
|
+
parse_error(p, "too deeply nested");
|
|
679
|
+
break;
|
|
680
|
+
}
|
|
677
681
|
p->stack[p->depth] = OBJECT_FUN;
|
|
678
682
|
p->map = key1_map;
|
|
679
683
|
break;
|
|
@@ -696,6 +700,10 @@ static void parse(ojParser p, const byte *json, bool more) {
|
|
|
696
700
|
p->cur = b - json;
|
|
697
701
|
p->funcs[p->stack[p->depth]].open_array(p);
|
|
698
702
|
p->depth++;
|
|
703
|
+
if ((int)sizeof(p->stack) <= p->depth) {
|
|
704
|
+
parse_error(p, "too deeply nested");
|
|
705
|
+
break;
|
|
706
|
+
}
|
|
699
707
|
p->stack[p->depth] = ARRAY_FUN;
|
|
700
708
|
p->map = value_map;
|
|
701
709
|
break;
|
|
@@ -1399,14 +1407,19 @@ static void validate_document_end(ojParser p) {
|
|
|
1399
1407
|
*/
|
|
1400
1408
|
static VALUE parser_parse(VALUE self, VALUE json) {
|
|
1401
1409
|
ojParser p;
|
|
1402
|
-
|
|
1410
|
+
int frozen = OBJ_FROZEN(json);
|
|
1411
|
+
const byte *ptr;
|
|
1412
|
+
|
|
1413
|
+
if (!frozen) {
|
|
1414
|
+
rb_str_freeze(json);
|
|
1415
|
+
}
|
|
1416
|
+
ptr = (const byte *)StringValuePtr(json);
|
|
1403
1417
|
|
|
1404
1418
|
TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);
|
|
1405
1419
|
|
|
1406
1420
|
parser_reset(p);
|
|
1407
1421
|
p->start(p);
|
|
1408
1422
|
parse(p, ptr, false);
|
|
1409
|
-
|
|
1410
1423
|
validate_document_end(p);
|
|
1411
1424
|
|
|
1412
1425
|
return p->result(p);
|
data/ext/oj/rxclass.c
CHANGED
data/ext/oj/rxclass.h
CHANGED
|
@@ -19,7 +19,7 @@ typedef struct _rxClass {
|
|
|
19
19
|
extern void oj_rxclass_init(RxClass rc);
|
|
20
20
|
extern void oj_rxclass_cleanup(RxClass rc);
|
|
21
21
|
extern int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas);
|
|
22
|
-
extern VALUE oj_rxclass_match(RxClass rc, const char *str,
|
|
22
|
+
extern VALUE oj_rxclass_match(RxClass rc, const char *str, size_t len);
|
|
23
23
|
extern void oj_rxclass_copy(RxClass src, RxClass dest);
|
|
24
24
|
extern void oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas);
|
|
25
25
|
|
data/ext/oj/safe.c
CHANGED
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/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.17.
|
|
4
|
+
version: 3.17.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter Ohler
|
|
@@ -231,7 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
231
231
|
- !ruby/object:Gem::Version
|
|
232
232
|
version: '0'
|
|
233
233
|
requirements: []
|
|
234
|
-
rubygems_version: 4.0.
|
|
234
|
+
rubygems_version: 4.0.3
|
|
235
235
|
specification_version: 4
|
|
236
236
|
summary: A fast JSON parser and serializer.
|
|
237
237
|
test_files: []
|