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.
data/ext/oj/parser.c CHANGED
@@ -75,7 +75,7 @@ enum {
75
75
 
76
76
  /*
77
77
  0123456789abcdef0123456789abcdef */
78
- static const char value_map[257] = "\
78
+ static const char value_map[258] = "\
79
79
  X........ab..a..................\
80
80
  a.i..........f..ghhhhhhhhh......\
81
81
  ...........................k.m..\
@@ -85,7 +85,7 @@ a.i..........f..ghhhhhhhhh......\
85
85
  ................................\
86
86
  ................................v";
87
87
 
88
- static const char null_map[257] = "\
88
+ static const char null_map[258] = "\
89
89
  ................................\
90
90
  ............o...................\
91
91
  ................................\
@@ -95,7 +95,7 @@ static const char null_map[257] = "\
95
95
  ................................\
96
96
  ................................N";
97
97
 
98
- static const char true_map[257] = "\
98
+ static const char true_map[258] = "\
99
99
  ................................\
100
100
  ............o...................\
101
101
  ................................\
@@ -105,7 +105,7 @@ static const char true_map[257] = "\
105
105
  ................................\
106
106
  ................................T";
107
107
 
108
- static const char false_map[257] = "\
108
+ static const char false_map[258] = "\
109
109
  ................................\
110
110
  ............o...................\
111
111
  ................................\
@@ -115,7 +115,7 @@ static const char false_map[257] = "\
115
115
  ................................\
116
116
  ................................F";
117
117
 
118
- static const char comma_map[257] = "\
118
+ static const char comma_map[258] = "\
119
119
  .........ab..a..................\
120
120
  a.i..........f..ghhhhhhhhh......\
121
121
  ...........................k....\
@@ -125,7 +125,7 @@ a.i..........f..ghhhhhhhhh......\
125
125
  ................................\
126
126
  ................................,";
127
127
 
128
- static const char after_map[257] = "\
128
+ static const char after_map[258] = "\
129
129
  X........ab..a..................\
130
130
  a...........o...................\
131
131
  .............................m..\
@@ -135,7 +135,7 @@ a...........o...................\
135
135
  ................................\
136
136
  ................................a";
137
137
 
138
- static const char key1_map[257] = "\
138
+ static const char key1_map[258] = "\
139
139
  .........ab..a..................\
140
140
  a.p.............................\
141
141
  ................................\
@@ -145,7 +145,7 @@ a.p.............................\
145
145
  ................................\
146
146
  ................................K";
147
147
 
148
- static const char key_map[257] = "\
148
+ static const char key_map[258] = "\
149
149
  .........ab..a..................\
150
150
  a.p.............................\
151
151
  ................................\
@@ -155,7 +155,7 @@ a.p.............................\
155
155
  ................................\
156
156
  ................................k";
157
157
 
158
- static const char colon_map[257] = "\
158
+ static const char colon_map[258] = "\
159
159
  .........ab..a..................\
160
160
  a.........................q.....\
161
161
  ................................\
@@ -165,7 +165,7 @@ a.........................q.....\
165
165
  ................................\
166
166
  ................................:";
167
167
 
168
- static const char neg_map[257] = "\
168
+ static const char neg_map[258] = "\
169
169
  ................................\
170
170
  ................O---------......\
171
171
  ................................\
@@ -175,7 +175,7 @@ static const char neg_map[257] = "\
175
175
  ................................\
176
176
  ................................-";
177
177
 
178
- static const char zero_map[257] = "\
178
+ static const char zero_map[258] = "\
179
179
  .........rs..r..................\
180
180
  r...........u.t.................\
181
181
  .............................H..\
@@ -185,7 +185,7 @@ r...........u.t.................\
185
185
  ................................\
186
186
  ................................0";
187
187
 
188
- static const char digit_map[257] = "\
188
+ static const char digit_map[258] = "\
189
189
  .........rs..r..................\
190
190
  r...........u.t.NNNNNNNNNN......\
191
191
  .....w.......................H..\
@@ -195,7 +195,7 @@ r...........u.t.NNNNNNNNNN......\
195
195
  ................................\
196
196
  ................................d";
197
197
 
198
- static const char dot_map[257] = "\
198
+ static const char dot_map[258] = "\
199
199
  ................................\
200
200
  ................vvvvvvvvvv......\
201
201
  ................................\
@@ -205,7 +205,7 @@ static const char dot_map[257] = "\
205
205
  ................................\
206
206
  .................................";
207
207
 
208
- static const char frac_map[257] = "\
208
+ static const char frac_map[258] = "\
209
209
  .........rs..r..................\
210
210
  r...........u...vvvvvvvvvv......\
211
211
  .....w.......................H..\
@@ -215,7 +215,7 @@ r...........u...vvvvvvvvvv......\
215
215
  ................................\
216
216
  ................................f";
217
217
 
218
- static const char exp_sign_map[257] = "\
218
+ static const char exp_sign_map[258] = "\
219
219
  ................................\
220
220
  ...........x.x..yyyyyyyyyy......\
221
221
  ................................\
@@ -225,7 +225,7 @@ static const char exp_sign_map[257] = "\
225
225
  ................................\
226
226
  ................................x";
227
227
 
228
- static const char exp_zero_map[257] = "\
228
+ static const char exp_zero_map[258] = "\
229
229
  ................................\
230
230
  ................yyyyyyyyyy......\
231
231
  ................................\
@@ -235,7 +235,7 @@ static const char exp_zero_map[257] = "\
235
235
  ................................\
236
236
  ................................z";
237
237
 
238
- static const char exp_map[257] = "\
238
+ static const char exp_map[258] = "\
239
239
  .........rs..r..................\
240
240
  r...........u...yyyyyyyyyy......\
241
241
  .............................H..\
@@ -245,7 +245,7 @@ r...........u...yyyyyyyyyy......\
245
245
  ................................\
246
246
  ................................X";
247
247
 
248
- static const char big_digit_map[257] = "\
248
+ static const char big_digit_map[258] = "\
249
249
  .........rs..r..................\
250
250
  r...........u.D.CCCCCCCCCC......\
251
251
  .....J.......................H..\
@@ -255,7 +255,7 @@ r...........u.D.CCCCCCCCCC......\
255
255
  ................................\
256
256
  ................................D";
257
257
 
258
- static const char big_dot_map[257] = "\
258
+ static const char big_dot_map[258] = "\
259
259
  ................................\
260
260
  ................IIIIIIIIII......\
261
261
  ................................\
@@ -265,7 +265,7 @@ static const char big_dot_map[257] = "\
265
265
  ................................\
266
266
  ................................o";
267
267
 
268
- static const char big_frac_map[257] = "\
268
+ static const char big_frac_map[258] = "\
269
269
  .........rs..r..................\
270
270
  r...........u...IIIIIIIIII......\
271
271
  .....J.......................H..\
@@ -275,7 +275,7 @@ r...........u...IIIIIIIIII......\
275
275
  ................................\
276
276
  ................................g";
277
277
 
278
- static const char big_exp_sign_map[257] = "\
278
+ static const char big_exp_sign_map[258] = "\
279
279
  ................................\
280
280
  ...........K.K..LLLLLLLLLL......\
281
281
  ................................\
@@ -285,7 +285,7 @@ static const char big_exp_sign_map[257] = "\
285
285
  ................................\
286
286
  ................................B";
287
287
 
288
- static const char big_exp_zero_map[257] = "\
288
+ static const char big_exp_zero_map[258] = "\
289
289
  ................................\
290
290
  ................LLLLLLLLLL......\
291
291
  ................................\
@@ -295,7 +295,7 @@ static const char big_exp_zero_map[257] = "\
295
295
  ................................\
296
296
  ................................Z";
297
297
 
298
- static const char big_exp_map[257] = "\
298
+ static const char big_exp_map[258] = "\
299
299
  .........rs..r..................\
300
300
  r...........u...LLLLLLLLLL......\
301
301
  .............................H..\
@@ -305,7 +305,7 @@ r...........u...LLLLLLLLLL......\
305
305
  ................................\
306
306
  ................................Y";
307
307
 
308
- static const char string_map[257] = "\
308
+ static const char string_map[258] = "\
309
309
  ................................\
310
310
  RRzRRRRRRRRRRRRRRRRRRRRRRRRRRRRR\
311
311
  RRRRRRRRRRRRRRRRRRRRRRRRRRRRARRR\
@@ -315,7 +315,7 @@ RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR\
315
315
  MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\
316
316
  PPPPPPPPPPPPPPPPQQQQQQQQ........s";
317
317
 
318
- static const char esc_map[257] = "\
318
+ static const char esc_map[258] = "\
319
319
  ................................\
320
320
  ..B............B................\
321
321
  ............................B...\
@@ -325,7 +325,7 @@ static const char esc_map[257] = "\
325
325
  ................................\
326
326
  ................................~";
327
327
 
328
- static const char esc_byte_map[257] = "\
328
+ static const char esc_byte_map[258] = "\
329
329
  ................................\
330
330
  ..\"............/................\
331
331
  ............................\\...\
@@ -335,7 +335,7 @@ static const char esc_byte_map[257] = "\
335
335
  ................................\
336
336
  ................................b";
337
337
 
338
- static const char u_map[257] = "\
338
+ static const char u_map[258] = "\
339
339
  ................................\
340
340
  ................EEEEEEEEEE......\
341
341
  .EEEEEE.........................\
@@ -345,7 +345,7 @@ static const char u_map[257] = "\
345
345
  ................................\
346
346
  ................................u";
347
347
 
348
- static const char utf_map[257] = "\
348
+ static const char utf_map[258] = "\
349
349
  ................................\
350
350
  ................................\
351
351
  ................................\
@@ -355,7 +355,7 @@ SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS\
355
355
  ................................\
356
356
  ................................8";
357
357
 
358
- static const char space_map[257] = "\
358
+ static const char space_map[258] = "\
359
359
  .........ab..a..................\
360
360
  a...............................\
361
361
  ................................\
@@ -365,7 +365,7 @@ a...............................\
365
365
  ................................\
366
366
  ................................S";
367
367
 
368
- static const char trail_map[257] = "\
368
+ static const char trail_map[258] = "\
369
369
  .........ab..a..................\
370
370
  a...............................\
371
371
  ................................\
@@ -375,7 +375,7 @@ a...............................\
375
375
  ................................\
376
376
  ................................R";
377
377
 
378
- static const byte hex_map[256] = "\
378
+ static const byte hex_map[257] = "\
379
379
  ................................\
380
380
  ................\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09......\
381
381
  .\x0a\x0b\x0c\x0d\x0e\x0f.........................\
@@ -594,7 +594,7 @@ static void big_change(ojParser p) {
594
594
  }
595
595
  }
596
596
 
597
- static void parse(ojParser p, const byte *json) {
597
+ static void parse(ojParser p, const byte *json, bool more) {
598
598
  const byte *start;
599
599
  const byte *b = json;
600
600
  int i;
@@ -635,6 +635,9 @@ static void parse(ojParser p, const byte *json) {
635
635
  if ('"' == *b) {
636
636
  p->map = colon_map;
637
637
  break;
638
+ } else if ('\0' == *b && !more) {
639
+ parse_error(p, "quoted string not terminated");
640
+ break;
638
641
  }
639
642
  b--;
640
643
  p->map = string_map;
@@ -659,6 +662,9 @@ static void parse(ojParser p, const byte *json) {
659
662
  p->funcs[p->stack[p->depth]].add_str(p);
660
663
  p->map = (0 == p->depth) ? value_map : after_map;
661
664
  break;
665
+ } else if ('\0' == *b && !more) {
666
+ parse_error(p, "quoted string not terminated");
667
+ break;
662
668
  }
663
669
  b--;
664
670
  p->map = string_map;
@@ -668,6 +674,10 @@ static void parse(ojParser p, const byte *json) {
668
674
  p->cur = b - json;
669
675
  p->funcs[p->stack[p->depth]].open_object(p);
670
676
  p->depth++;
677
+ if ((int)sizeof(p->stack) <= p->depth) {
678
+ parse_error(p, "too deeply nested");
679
+ break;
680
+ }
671
681
  p->stack[p->depth] = OBJECT_FUN;
672
682
  p->map = key1_map;
673
683
  break;
@@ -690,6 +700,10 @@ static void parse(ojParser p, const byte *json) {
690
700
  p->cur = b - json;
691
701
  p->funcs[p->stack[p->depth]].open_array(p);
692
702
  p->depth++;
703
+ if ((int)sizeof(p->stack) <= p->depth) {
704
+ parse_error(p, "too deeply nested");
705
+ break;
706
+ }
693
707
  p->stack[p->depth] = ARRAY_FUN;
694
708
  p->map = value_map;
695
709
  break;
@@ -1176,6 +1190,8 @@ extern void oj_set_parser_validator(ojParser p);
1176
1190
  extern void oj_set_parser_saj(ojParser p);
1177
1191
  extern void oj_set_parser_usual(ojParser p);
1178
1192
  extern void oj_set_parser_debug(ojParser p);
1193
+ extern void oj_set_parser_safe(ojParser p, VALUE options);
1194
+ extern void oj_safe_init(VALUE parser_class);
1179
1195
 
1180
1196
  static int opt_cb(VALUE rkey, VALUE value, VALUE ptr) {
1181
1197
  ojParser p = (ojParser)ptr;
@@ -1354,6 +1370,34 @@ static VALUE parser_missing(int argc, VALUE *argv, VALUE self) {
1354
1370
  return p->option(p, key, rv);
1355
1371
  }
1356
1372
 
1373
+ static void validate_primitives_are_complete(ojParser p) {
1374
+ if (0 >= p->ri) {
1375
+ return;
1376
+ }
1377
+
1378
+ switch (p->map[256]) {
1379
+ case 'N': parse_error(p, "expected null"); break;
1380
+ case 'F': parse_error(p, "expected false"); break;
1381
+ case 'T': parse_error(p, "expected true"); break;
1382
+ }
1383
+ }
1384
+
1385
+ static void validate_non_primitives_are_complete(ojParser p) {
1386
+ if (0 >= p->depth) {
1387
+ return;
1388
+ }
1389
+ if (OBJECT_FUN == p->stack[p->depth]) {
1390
+ parse_error(p, "Object is not closed");
1391
+ } else {
1392
+ parse_error(p, "Array is not closed");
1393
+ }
1394
+ }
1395
+
1396
+ static void validate_document_end(ojParser p) {
1397
+ validate_primitives_are_complete(p);
1398
+ validate_non_primitives_are_complete(p);
1399
+ }
1400
+
1357
1401
  /* Document-method: parse(json)
1358
1402
  * call-seq: parse(json)
1359
1403
  *
@@ -1363,21 +1407,21 @@ static VALUE parser_missing(int argc, VALUE *argv, VALUE self) {
1363
1407
  */
1364
1408
  static VALUE parser_parse(VALUE self, VALUE json) {
1365
1409
  ojParser p;
1366
- const byte *ptr = (const byte *)StringValuePtr(json);
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);
1367
1417
 
1368
1418
  TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);
1369
1419
 
1370
1420
  parser_reset(p);
1371
1421
  p->start(p);
1372
- parse(p, ptr);
1422
+ parse(p, ptr, false);
1423
+ validate_document_end(p);
1373
1424
 
1374
- if (0 < p->depth) {
1375
- if (OBJECT_FUN == p->stack[p->depth]) {
1376
- parse_error(p, "Object is not closed");
1377
- } else {
1378
- parse_error(p, "Array is not closed");
1379
- }
1380
- }
1381
1425
  return p->result(p);
1382
1426
  }
1383
1427
 
@@ -1396,7 +1440,7 @@ static VALUE load(VALUE self) {
1396
1440
  while (true) {
1397
1441
  rb_funcall(p->reader, oj_readpartial_id, 2, INT2NUM(16385), rbuf);
1398
1442
  if (0 < RSTRING_LEN(rbuf)) {
1399
- parse(p, (byte *)StringValuePtr(rbuf));
1443
+ parse(p, (byte *)StringValuePtr(rbuf), true);
1400
1444
  }
1401
1445
  if (Qtrue == rb_funcall(p->reader, oj_eofq_id, 0)) {
1402
1446
  if (0 < p->depth) {
@@ -1466,7 +1510,7 @@ static VALUE parser_file(VALUE self, VALUE filename) {
1466
1510
  while (true) {
1467
1511
  if (0 < (rsize = read(fd, buf, size))) {
1468
1512
  buf[rsize] = '\0';
1469
- parse(p, buf);
1513
+ parse(p, buf, true);
1470
1514
  }
1471
1515
  if (rsize <= 0) {
1472
1516
  if (0 != rsize) {
@@ -1577,6 +1621,28 @@ static VALUE parser_validate(VALUE self) {
1577
1621
  return validate_parser;
1578
1622
  }
1579
1623
 
1624
+ static VALUE parser_safe(int argc, VALUE *argv, VALUE self) {
1625
+ VALUE options;
1626
+
1627
+ if (1 == argc) {
1628
+ options = argv[0];
1629
+
1630
+ Check_Type(options, T_HASH);
1631
+ } else {
1632
+ options = rb_hash_new();
1633
+ }
1634
+
1635
+ ojParser p = OJ_R_ALLOC(struct _ojParser);
1636
+
1637
+ memset(p, 0, sizeof(struct _ojParser));
1638
+ buf_init(&p->key);
1639
+ buf_init(&p->buf);
1640
+ p->map = value_map;
1641
+ oj_set_parser_safe(p, options);
1642
+
1643
+ return TypedData_Wrap_Struct(parser_class, &oj_parser_type, p);
1644
+ }
1645
+
1580
1646
  /* Document-class: Oj::Parser
1581
1647
  *
1582
1648
  * A reusable parser that makes use of named delegates to determine the
@@ -1604,4 +1670,7 @@ void oj_parser_init(void) {
1604
1670
  rb_define_module_function(parser_class, "usual", parser_usual, 0);
1605
1671
  rb_define_module_function(parser_class, "saj", parser_saj, 0);
1606
1672
  rb_define_module_function(parser_class, "validate", parser_validate, 0);
1673
+ rb_define_module_function(parser_class, "safe", parser_safe, -1);
1674
+
1675
+ oj_safe_init(parser_class);
1607
1676
  }
data/ext/oj/rails.c CHANGED
@@ -920,7 +920,7 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
920
920
  if (Yes == copts.circular) {
921
921
  oj_cache8_new(&out.circ_cache);
922
922
  }
923
- // dump_rails_val(*argv, 0, &out, true);
923
+
924
924
  rb_protect(protect_dump, (VALUE)&oo, &line);
925
925
 
926
926
  if (0 == line) {
@@ -1219,8 +1219,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
1219
1219
  return;
1220
1220
  }
1221
1221
  }
1222
- // if (!oj_rails_array_opt && as_ok && 0 < out->argc && rb_respond_to(a, oj_as_json_id)) {
1223
- if (as_ok && 0 < out->argc && rb_respond_to(a, oj_as_json_id)) {
1222
+ if (!oj_rails_array_opt && as_ok && rb_respond_to(a, oj_as_json_id)) {
1224
1223
  dump_as_json(a, depth, out, false);
1225
1224
  return;
1226
1225
  }
@@ -1287,18 +1286,19 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
1287
1286
  if (out->omit_nil && Qnil == value) {
1288
1287
  return ST_CONTINUE;
1289
1288
  }
1290
- if (rtype != T_STRING && rtype != T_SYMBOL) {
1291
- key = oj_safe_string_convert(key);
1292
- rtype = rb_type(key);
1289
+ if (NULL != out->opts->dump_opts.only || NULL != out->opts->dump_opts.except) {
1290
+ if (oj_key_skip(key, out->opts->dump_opts.only, out->opts->dump_opts.except)) {
1291
+ return ST_CONTINUE;
1292
+ }
1293
1293
  }
1294
1294
  if (!out->opts->dump_opts.use) {
1295
1295
  size = depth * out->indent + 1;
1296
1296
  assure_size(out, size);
1297
1297
  fill_indent(out, depth);
1298
- if (rtype == T_STRING) {
1299
- oj_dump_str(key, 0, out, false);
1300
- } else {
1301
- oj_dump_sym(key, 0, out, false);
1298
+ switch (rtype) {
1299
+ case T_STRING: oj_dump_str(key, 0, out, false); break;
1300
+ case T_SYMBOL: oj_dump_sym(key, 0, out, false); break;
1301
+ default: oj_dump_str(oj_safe_string_convert(key), 0, out, false); break;
1302
1302
  }
1303
1303
  *out->cur++ = ':';
1304
1304
  } else {
@@ -1313,10 +1313,10 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
1313
1313
  APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
1314
1314
  }
1315
1315
  }
1316
- if (rtype == T_STRING) {
1317
- oj_dump_str(key, 0, out, false);
1318
- } else {
1319
- oj_dump_sym(key, 0, out, false);
1316
+ switch (rtype) {
1317
+ case T_STRING: oj_dump_str(key, 0, out, false); break;
1318
+ case T_SYMBOL: oj_dump_sym(key, 0, out, false); break;
1319
+ default: oj_dump_str(oj_safe_string_convert(key), 0, out, false); break;
1320
1320
  }
1321
1321
  size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
1322
1322
  assure_size(out, size);
@@ -1345,7 +1345,7 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
1345
1345
  return;
1346
1346
  }
1347
1347
  }
1348
- if ((!oj_rails_hash_opt || 0 < out->argc) && as_ok && rb_respond_to(obj, oj_as_json_id)) {
1348
+ if (!oj_rails_hash_opt && as_ok && rb_respond_to(obj, oj_as_json_id)) {
1349
1349
  dump_as_json(obj, depth, out, false);
1350
1350
  return;
1351
1351
  }
data/ext/oj/rxclass.c CHANGED
@@ -96,7 +96,7 @@ int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
96
96
  }
97
97
 
98
98
  VALUE
99
- oj_rxclass_match(RxClass rc, const char *str, int len) {
99
+ oj_rxclass_match(RxClass rc, const char *str, size_t len) {
100
100
  RxC rxc;
101
101
  char buf[4096];
102
102
 
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, int len);
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