oj 3.13.9 → 3.13.12

Sign up to get free protection for your applications and to get access to all the features.
data/ext/oj/oj.h CHANGED
@@ -39,6 +39,16 @@ enum st_retval { ST_CONTINUE = 0, ST_STOP = 1, ST_DELETE = 2, ST_CHECK };
39
39
  #define NINF_VAL "-3.0e14159265358979323846"
40
40
  #define NAN_VAL "3.3e14159265358979323846"
41
41
 
42
+ #if __STDC_VERSION__ >= 199901L
43
+ // To avoid using ruby_snprintf with C99.
44
+ #undef snprintf
45
+ #include <stdio.h>
46
+ #endif
47
+
48
+ // To avoid using ruby_nonempty_memcpy().
49
+ #undef memcpy
50
+ #include <string.h>
51
+
42
52
  typedef enum { Yes = 'y', No = 'n', NotSet = 0 } YesNo;
43
53
 
44
54
  typedef enum {
@@ -176,6 +186,7 @@ typedef struct _rOptTable {
176
186
  } * ROptTable;
177
187
 
178
188
  typedef struct _out {
189
+ char stack_buffer[4096];
179
190
  char * buf;
180
191
  char * end;
181
192
  char * cur;
@@ -265,8 +276,8 @@ extern void oj_str_writer_pop(StrWriter sw);
265
276
  extern void oj_str_writer_pop_all(StrWriter sw);
266
277
 
267
278
  extern void oj_init_doc(void);
268
- extern void oj_string_writer_init();
269
- extern void oj_stream_writer_init();
279
+ extern void oj_string_writer_init(void);
280
+ extern void oj_stream_writer_init(void);
270
281
  extern void oj_str_writer_init(StrWriter sw, int buf_size);
271
282
  extern VALUE oj_define_mimic_json(int argc, VALUE *argv, VALUE self);
272
283
  extern VALUE oj_mimic_generate(int argc, VALUE *argv, VALUE self);
@@ -282,6 +293,7 @@ extern VALUE oj_rails_encode(int argc, VALUE *argv, VALUE self);
282
293
  extern VALUE Oj;
283
294
  extern struct _options oj_default_options;
284
295
  extern rb_encoding * oj_utf8_encoding;
296
+ extern int oj_utf8_encoding_index;
285
297
 
286
298
  extern VALUE oj_bag_class;
287
299
  extern VALUE oj_bigdecimal_class;
@@ -364,6 +376,12 @@ extern bool oj_use_hash_alt;
364
376
  extern bool oj_use_array_alt;
365
377
  extern bool string_writer_optimized;
366
378
 
379
+ #define APPEND_CHARS(buffer, chars, size) \
380
+ { \
381
+ memcpy(buffer, chars, size); \
382
+ buffer += size; \
383
+ }
384
+
367
385
  #ifdef HAVE_PTHREAD_MUTEX_INIT
368
386
  extern pthread_mutex_t oj_cache_mutex;
369
387
  #else
data/ext/oj/parse.c CHANGED
@@ -972,9 +972,10 @@ static VALUE protect_parse(VALUE pip) {
972
972
  extern int oj_utf8_index;
973
973
 
974
974
  static void oj_pi_set_input_str(ParseInfo pi, volatile VALUE *inputp) {
975
- rb_encoding *enc = rb_enc_get(*inputp);
975
+ int idx = RB_ENCODING_GET(*inputp);
976
976
 
977
- if (oj_utf8_encoding != enc) {
977
+ if (oj_utf8_encoding_index != idx) {
978
+ rb_encoding *enc = rb_enc_from_index(idx);
978
979
  *inputp = rb_str_conv_enc(*inputp, enc, oj_utf8_encoding);
979
980
  }
980
981
  pi->json = RSTRING_PTR(*inputp);
data/ext/oj/parser.c CHANGED
@@ -11,8 +11,8 @@
11
11
  #define USE_THREAD_LIMIT 0
12
12
  // #define USE_THREAD_LIMIT 100000
13
13
  #define MAX_EXP 4932
14
- // max in the pow_map
15
- #define MAX_POW 400
14
+ // max in the pow_map which is the limit for double
15
+ #define MAX_POW 308
16
16
 
17
17
  #define MIN_SLEEP (1000000000LL / (double)CLOCKS_PER_SEC)
18
18
  // 9,223,372,036,854,775,807
@@ -385,7 +385,7 @@ static const byte hex_map[256] = "\
385
385
  ................................\
386
386
  ................................";
387
387
 
388
- static long double pow_map[401] = {
388
+ static long double pow_map[309] = {
389
389
  1.0L, 1.0e1L, 1.0e2L, 1.0e3L, 1.0e4L, 1.0e5L, 1.0e6L, 1.0e7L, 1.0e8L, 1.0e9L, 1.0e10L,
390
390
  1.0e11L, 1.0e12L, 1.0e13L, 1.0e14L, 1.0e15L, 1.0e16L, 1.0e17L, 1.0e18L, 1.0e19L, 1.0e20L, 1.0e21L,
391
391
  1.0e22L, 1.0e23L, 1.0e24L, 1.0e25L, 1.0e26L, 1.0e27L, 1.0e28L, 1.0e29L, 1.0e30L, 1.0e31L, 1.0e32L,
@@ -414,15 +414,7 @@ static long double pow_map[401] = {
414
414
  1.0e275L, 1.0e276L, 1.0e277L, 1.0e278L, 1.0e279L, 1.0e280L, 1.0e281L, 1.0e282L, 1.0e283L, 1.0e284L, 1.0e285L,
415
415
  1.0e286L, 1.0e287L, 1.0e288L, 1.0e289L, 1.0e290L, 1.0e291L, 1.0e292L, 1.0e293L, 1.0e294L, 1.0e295L, 1.0e296L,
416
416
  1.0e297L, 1.0e298L, 1.0e299L, 1.0e300L, 1.0e301L, 1.0e302L, 1.0e303L, 1.0e304L, 1.0e305L, 1.0e306L, 1.0e307L,
417
- 1.0e308L, 1.0e309L, 1.0e310L, 1.0e311L, 1.0e312L, 1.0e313L, 1.0e314L, 1.0e315L, 1.0e316L, 1.0e317L, 1.0e318L,
418
- 1.0e319L, 1.0e320L, 1.0e321L, 1.0e322L, 1.0e323L, 1.0e324L, 1.0e325L, 1.0e326L, 1.0e327L, 1.0e328L, 1.0e329L,
419
- 1.0e330L, 1.0e331L, 1.0e332L, 1.0e333L, 1.0e334L, 1.0e335L, 1.0e336L, 1.0e337L, 1.0e338L, 1.0e339L, 1.0e340L,
420
- 1.0e341L, 1.0e342L, 1.0e343L, 1.0e344L, 1.0e345L, 1.0e346L, 1.0e347L, 1.0e348L, 1.0e349L, 1.0e350L, 1.0e351L,
421
- 1.0e352L, 1.0e353L, 1.0e354L, 1.0e355L, 1.0e356L, 1.0e357L, 1.0e358L, 1.0e359L, 1.0e360L, 1.0e361L, 1.0e362L,
422
- 1.0e363L, 1.0e364L, 1.0e365L, 1.0e366L, 1.0e367L, 1.0e368L, 1.0e369L, 1.0e370L, 1.0e371L, 1.0e372L, 1.0e373L,
423
- 1.0e374L, 1.0e375L, 1.0e376L, 1.0e377L, 1.0e378L, 1.0e379L, 1.0e380L, 1.0e381L, 1.0e382L, 1.0e383L, 1.0e384L,
424
- 1.0e385L, 1.0e386L, 1.0e387L, 1.0e388L, 1.0e389L, 1.0e390L, 1.0e391L, 1.0e392L, 1.0e393L, 1.0e394L, 1.0e395L,
425
- 1.0e396L, 1.0e397L, 1.0e398L, 1.0e399L, 1.0e400L};
417
+ 1.0e308L};
426
418
 
427
419
  static VALUE parser_class;
428
420
 
@@ -1190,7 +1182,7 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
1190
1182
  p->map = value_map;
1191
1183
 
1192
1184
  if (argc < 1) {
1193
- oj_set_parser_validator(p);
1185
+ oj_set_parser_validator(p);
1194
1186
  } else {
1195
1187
  VALUE mode = argv[0];
1196
1188
 
@@ -1284,7 +1276,7 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
1284
1276
  */
1285
1277
  static VALUE parser_missing(int argc, VALUE *argv, VALUE self) {
1286
1278
  ojParser p = (ojParser)DATA_PTR(self);
1287
- const char * key = NULL;
1279
+ const char *key = NULL;
1288
1280
  volatile VALUE rkey = *argv;
1289
1281
  volatile VALUE rv = Qnil;
1290
1282
 
@@ -1515,8 +1507,11 @@ static VALUE parser_validate(VALUE self) {
1515
1507
  * isolates options to just the parser so that other parts of the code are not
1516
1508
  * forced to use the same options.
1517
1509
  */
1518
- void oj_parser_init() {
1510
+ void oj_parser_init(void) {
1519
1511
  parser_class = rb_define_class_under(Oj, "Parser", rb_cObject);
1512
+ rb_gc_register_address(&parser_class);
1513
+ rb_undef_alloc_func(parser_class);
1514
+
1520
1515
  rb_define_module_function(parser_class, "new", parser_new, -1);
1521
1516
  rb_define_method(parser_class, "parse", parser_parse, 1);
1522
1517
  rb_define_method(parser_class, "load", parser_load, 1);
data/ext/oj/rails.c CHANGED
@@ -157,7 +157,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
157
157
  assure_size(out, 2);
158
158
  *out->cur++ = '{';
159
159
  for (i = 0; i < cnt; i++) {
160
- volatile VALUE s = rb_sym2str(rb_ary_entry(ma, i));
160
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
161
161
 
162
162
  name = RSTRING_PTR(s);
163
163
  len = (int)RSTRING_LEN(s);
@@ -167,17 +167,14 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
167
167
  }
168
168
  fill_indent(out, d3);
169
169
  *out->cur++ = '"';
170
- memcpy(out->cur, name, len);
171
- out->cur += len;
170
+ APPEND_CHARS(out->cur, name, len);
172
171
  *out->cur++ = '"';
173
172
  if (0 < out->opts->dump_opts.before_size) {
174
- strcpy(out->cur, out->opts->dump_opts.before_sep);
175
- out->cur += out->opts->dump_opts.before_size;
173
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
176
174
  }
177
175
  *out->cur++ = ':';
178
176
  if (0 < out->opts->dump_opts.after_size) {
179
- strcpy(out->cur, out->opts->dump_opts.after_sep);
180
- out->cur += out->opts->dump_opts.after_size;
177
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
181
178
  }
182
179
  #ifdef RSTRUCT_LEN
183
180
  v = RSTRUCT_GET(obj, i);
@@ -330,12 +327,12 @@ static void dump_time(VALUE obj, int depth, Out out, bool as_ok) {
330
327
  sec = (long long)ts.tv_sec;
331
328
  nsec = ts.tv_nsec;
332
329
  } else {
333
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
334
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
330
+ sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
331
+ nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
335
332
  }
336
333
  #else
337
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
338
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
334
+ sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
335
+ nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
339
336
  #endif
340
337
  dump_sec_nano(obj, sec, nsec, out);
341
338
  }
@@ -345,9 +342,9 @@ static void dump_timewithzone(VALUE obj, int depth, Out out, bool as_ok) {
345
342
  long long nsec = 0;
346
343
 
347
344
  if (rb_respond_to(obj, oj_tv_nsec_id)) {
348
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
345
+ nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
349
346
  } else if (rb_respond_to(obj, oj_tv_usec_id)) {
350
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_usec_id, 0, 0)) * 1000;
347
+ nsec = NUM2LL(rb_funcall2(obj, oj_tv_usec_id, 0, 0)) * 1000;
351
348
  }
352
349
  dump_sec_nano(obj, sec, nsec, out);
353
350
  }
@@ -383,7 +380,7 @@ static StrLen columns_array(VALUE rcols, int *ccnt) {
383
380
  *ccnt = cnt;
384
381
  cols = ALLOC_N(struct _strLen, cnt);
385
382
  for (i = 0, cp = cols; i < cnt; i++, cp++) {
386
- v = rb_ary_entry(rcols, i);
383
+ v = RARRAY_AREF(rcols, i);
387
384
  if (T_STRING != rb_type(v)) {
388
385
  v = rb_funcall(v, oj_to_s_id, 0);
389
386
  }
@@ -405,14 +402,12 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
405
402
  assure_size(out, size);
406
403
  if (out->opts->dump_opts.use) {
407
404
  if (0 < out->opts->dump_opts.array_size) {
408
- strcpy(out->cur, out->opts->dump_opts.array_nl);
409
- out->cur += out->opts->dump_opts.array_size;
405
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
410
406
  }
411
407
  if (0 < out->opts->dump_opts.indent_size) {
412
408
  int i;
413
409
  for (i = d2; 0 < i; i--) {
414
- strcpy(out->cur, out->opts->dump_opts.indent_str);
415
- out->cur += out->opts->dump_opts.indent_size;
410
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
416
411
  }
417
412
  }
418
413
  } else {
@@ -420,7 +415,7 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
420
415
  }
421
416
  oj_dump_cstr(cols->str, cols->len, 0, 0, out);
422
417
  *out->cur++ = ':';
423
- dump_rails_val(rb_ary_entry(row, i), depth, out, true);
418
+ dump_rails_val(RARRAY_AREF(row, i), depth, out, true);
424
419
  if (i < ccnt - 1) {
425
420
  *out->cur++ = ',';
426
421
  }
@@ -429,15 +424,13 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
429
424
  assure_size(out, size);
430
425
  if (out->opts->dump_opts.use) {
431
426
  if (0 < out->opts->dump_opts.array_size) {
432
- strcpy(out->cur, out->opts->dump_opts.array_nl);
433
- out->cur += out->opts->dump_opts.array_size;
427
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
434
428
  }
435
429
  if (0 < out->opts->dump_opts.indent_size) {
436
430
  int i;
437
431
 
438
432
  for (i = depth; 0 < i; i--) {
439
- strcpy(out->cur, out->opts->dump_opts.indent_str);
440
- out->cur += out->opts->dump_opts.indent_size;
433
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
441
434
  }
442
435
  }
443
436
  } else {
@@ -477,20 +470,18 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
477
470
  assure_size(out, size);
478
471
  if (out->opts->dump_opts.use) {
479
472
  if (0 < out->opts->dump_opts.array_size) {
480
- strcpy(out->cur, out->opts->dump_opts.array_nl);
481
- out->cur += out->opts->dump_opts.array_size;
473
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
482
474
  }
483
475
  if (0 < out->opts->dump_opts.indent_size) {
484
476
  int i;
485
477
  for (i = d2; 0 < i; i--) {
486
- strcpy(out->cur, out->opts->dump_opts.indent_str);
487
- out->cur += out->opts->dump_opts.indent_size;
478
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
488
479
  }
489
480
  }
490
481
  } else {
491
482
  fill_indent(out, d2);
492
483
  }
493
- dump_row(rb_ary_entry(rows, i), cols, ccnt, d2, out);
484
+ dump_row(RARRAY_AREF(rows, i), cols, ccnt, d2, out);
494
485
  if (i < rcnt - 1) {
495
486
  *out->cur++ = ',';
496
487
  }
@@ -500,15 +491,13 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
500
491
  assure_size(out, size);
501
492
  if (out->opts->dump_opts.use) {
502
493
  if (0 < out->opts->dump_opts.array_size) {
503
- strcpy(out->cur, out->opts->dump_opts.array_nl);
504
- out->cur += out->opts->dump_opts.array_size;
494
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
505
495
  }
506
496
  if (0 < out->opts->dump_opts.indent_size) {
507
497
  int i;
508
498
 
509
499
  for (i = depth; 0 < i; i--) {
510
- strcpy(out->cur, out->opts->dump_opts.indent_str);
511
- out->cur += out->opts->dump_opts.indent_size;
500
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
512
501
  }
513
502
  }
514
503
  } else {
@@ -908,7 +897,6 @@ static VALUE protect_dump(VALUE ov) {
908
897
  }
909
898
 
910
899
  static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *argv) {
911
- char buf[4096];
912
900
  struct _out out;
913
901
  struct _options copts = *opts;
914
902
  volatile VALUE rstr = Qnil;
@@ -925,9 +913,9 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
925
913
  } else {
926
914
  copts.escape_mode = RailsEsc;
927
915
  }
928
- out.buf = buf;
929
- out.end = buf + sizeof(buf) - 10;
930
- out.allocated = false;
916
+
917
+ oj_out_init(&out);
918
+
931
919
  out.omit_nil = copts.dump_opts.omit_nil;
932
920
  out.caller = 0;
933
921
  out.cur = out.buf;
@@ -963,9 +951,9 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
963
951
  if (Yes == copts.circular) {
964
952
  oj_cache8_delete(out.circ_cache);
965
953
  }
966
- if (out.allocated) {
967
- xfree(out.buf);
968
- }
954
+
955
+ oj_out_free(&out);
956
+
969
957
  if (0 != line) {
970
958
  rb_jump_tag(line);
971
959
  }
@@ -1175,12 +1163,15 @@ oj_optimize_rails(VALUE self) {
1175
1163
  *
1176
1164
  * The Oj ActiveSupport compliant encoder.
1177
1165
  */
1178
- void oj_mimic_rails_init() {
1166
+ void oj_mimic_rails_init(void) {
1179
1167
  VALUE rails = rb_define_module_under(Oj, "Rails");
1180
1168
 
1181
1169
  rb_define_module_function(rails, "encode", rails_encode, -1);
1182
1170
 
1183
1171
  encoder_class = rb_define_class_under(rails, "Encoder", rb_cObject);
1172
+ rb_gc_register_address(&encoder_class);
1173
+ rb_undef_alloc_func(encoder_class);
1174
+
1184
1175
  rb_define_module_function(encoder_class, "new", encoder_new, -1);
1185
1176
  rb_define_module_function(rails, "optimize", rails_optimize, -1);
1186
1177
  rb_define_module_function(rails, "deoptimize", rails_deoptimize, -1);
@@ -1263,25 +1254,23 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
1263
1254
  } else {
1264
1255
  size = d2 * out->indent + 2;
1265
1256
  }
1257
+ assure_size(out, size * cnt);
1266
1258
  cnt--;
1267
1259
  for (i = 0; i <= cnt; i++) {
1268
- assure_size(out, size);
1269
1260
  if (out->opts->dump_opts.use) {
1270
1261
  if (0 < out->opts->dump_opts.array_size) {
1271
- strcpy(out->cur, out->opts->dump_opts.array_nl);
1272
- out->cur += out->opts->dump_opts.array_size;
1262
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
1273
1263
  }
1274
1264
  if (0 < out->opts->dump_opts.indent_size) {
1275
1265
  int i;
1276
1266
  for (i = d2; 0 < i; i--) {
1277
- strcpy(out->cur, out->opts->dump_opts.indent_str);
1278
- out->cur += out->opts->dump_opts.indent_size;
1267
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
1279
1268
  }
1280
1269
  }
1281
1270
  } else {
1282
1271
  fill_indent(out, d2);
1283
1272
  }
1284
- dump_rails_val(rb_ary_entry(a, i), d2, out, true);
1273
+ dump_rails_val(RARRAY_AREF(a, i), d2, out, true);
1285
1274
  if (i < cnt) {
1286
1275
  *out->cur++ = ',';
1287
1276
  }
@@ -1290,15 +1279,13 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
1290
1279
  assure_size(out, size);
1291
1280
  if (out->opts->dump_opts.use) {
1292
1281
  if (0 < out->opts->dump_opts.array_size) {
1293
- strcpy(out->cur, out->opts->dump_opts.array_nl);
1294
- out->cur += out->opts->dump_opts.array_size;
1282
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
1295
1283
  }
1296
1284
  if (0 < out->opts->dump_opts.indent_size) {
1297
1285
  int i;
1298
1286
 
1299
1287
  for (i = depth; 0 < i; i--) {
1300
- strcpy(out->cur, out->opts->dump_opts.indent_str);
1301
- out->cur += out->opts->dump_opts.indent_size;
1288
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
1302
1289
  }
1303
1290
  }
1304
1291
  } else {
@@ -1336,14 +1323,12 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
1336
1323
  size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
1337
1324
  assure_size(out, size);
1338
1325
  if (0 < out->opts->dump_opts.hash_size) {
1339
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
1340
- out->cur += out->opts->dump_opts.hash_size;
1326
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
1341
1327
  }
1342
1328
  if (0 < out->opts->dump_opts.indent_size) {
1343
1329
  int i;
1344
1330
  for (i = depth; 0 < i; i--) {
1345
- strcpy(out->cur, out->opts->dump_opts.indent_str);
1346
- out->cur += out->opts->dump_opts.indent_size;
1331
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
1347
1332
  }
1348
1333
  }
1349
1334
  if (rtype == T_STRING) {
@@ -1354,13 +1339,11 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
1354
1339
  size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
1355
1340
  assure_size(out, size);
1356
1341
  if (0 < out->opts->dump_opts.before_size) {
1357
- strcpy(out->cur, out->opts->dump_opts.before_sep);
1358
- out->cur += out->opts->dump_opts.before_size;
1342
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
1359
1343
  }
1360
1344
  *out->cur++ = ':';
1361
1345
  if (0 < out->opts->dump_opts.after_size) {
1362
- strcpy(out->cur, out->opts->dump_opts.after_sep);
1363
- out->cur += out->opts->dump_opts.after_size;
1346
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
1364
1347
  }
1365
1348
  }
1366
1349
  dump_rails_val(value, depth, out, true);
@@ -1403,15 +1386,13 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
1403
1386
  size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
1404
1387
  assure_size(out, size);
1405
1388
  if (0 < out->opts->dump_opts.hash_size) {
1406
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
1407
- out->cur += out->opts->dump_opts.hash_size;
1389
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
1408
1390
  }
1409
1391
  if (0 < out->opts->dump_opts.indent_size) {
1410
1392
  int i;
1411
1393
 
1412
1394
  for (i = depth; 0 < i; i--) {
1413
- strcpy(out->cur, out->opts->dump_opts.indent_str);
1414
- out->cur += out->opts->dump_opts.indent_size;
1395
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
1415
1396
  }
1416
1397
  }
1417
1398
  }
data/ext/oj/rails.h CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  #include "dump.h"
8
8
 
9
- extern void oj_mimic_rails_init();
9
+ extern void oj_mimic_rails_init(void);
10
10
  extern ROpt oj_rails_get_opt(ROptTable rot, VALUE clas);
11
11
 
12
12
  extern bool oj_rails_hash_opt;
data/ext/oj/reader.c CHANGED
@@ -6,9 +6,11 @@
6
6
  #include <stdlib.h>
7
7
  #include <strings.h>
8
8
  #include <sys/types.h>
9
+ #ifdef NEEDS_UIO
9
10
  #if NEEDS_UIO
10
11
  #include <sys/uio.h>
11
12
  #endif
13
+ #endif
12
14
  #include <time.h>
13
15
  #include <unistd.h>
14
16
 
data/ext/oj/saj.c CHANGED
@@ -210,10 +210,7 @@ static void read_hash(ParseInfo pi, const char *key) {
210
210
  pi->s++;
211
211
  } else {
212
212
  if (pi->has_error) {
213
- call_error("invalid format, expected , or } while in an object",
214
- pi,
215
- __FILE__,
216
- __LINE__);
213
+ call_error("invalid format, expected , or } while in an object", pi, __FILE__, __LINE__);
217
214
  }
218
215
  raise_error("invalid format, expected , or } while in an object", pi->str, pi->s);
219
216
  }
@@ -243,10 +240,7 @@ static void read_array(ParseInfo pi, const char *key) {
243
240
  break;
244
241
  } else {
245
242
  if (pi->has_error) {
246
- call_error("invalid format, expected , or ] while in an array",
247
- pi,
248
- __FILE__,
249
- __LINE__);
243
+ call_error("invalid format, expected , or ] while in an array", pi, __FILE__, __LINE__);
250
244
  }
251
245
  raise_error("invalid format, expected , or ] while in an array", pi->str, pi->s);
252
246
  }
@@ -276,7 +270,7 @@ static void read_str(ParseInfo pi, const char *key) {
276
270
  #endif
277
271
 
278
272
  static void read_num(ParseInfo pi, const char *key) {
279
- char * start = pi->s;
273
+ char *start = pi->s;
280
274
  int64_t n = 0;
281
275
  long a = 0;
282
276
  long div = 1;
@@ -351,9 +345,7 @@ static void read_num(ParseInfo pi, const char *key) {
351
345
 
352
346
  *pi->s = '\0';
353
347
  if (pi->has_add_value) {
354
- call_add_value(pi->handler,
355
- rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)),
356
- key);
348
+ call_add_value(pi->handler, rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)), key);
357
349
  }
358
350
  *pi->s = c;
359
351
  } else {
@@ -371,9 +363,7 @@ static void read_num(ParseInfo pi, const char *key) {
371
363
 
372
364
  *pi->s = '\0';
373
365
  if (pi->has_add_value) {
374
- call_add_value(pi->handler,
375
- rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)),
376
- key);
366
+ call_add_value(pi->handler, rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)), key);
377
367
  }
378
368
  *pi->s = c;
379
369
  } else {
@@ -505,9 +495,9 @@ static char *unicode_to_chars(ParseInfo pi, char *t, uint32_t code) {
505
495
  * reached again. Do not read the character after the terminating quote.
506
496
  */
507
497
  static char *read_quoted_value(ParseInfo pi) {
508
- char * value = 0;
509
- char * h = pi->s; /* head */
510
- char * t = h; /* tail */
498
+ char *value = 0;
499
+ char *h = pi->s; /* head */
500
+ char *t = h; /* tail */
511
501
  uint32_t code;
512
502
 
513
503
  h++; /* skip quote character */
@@ -588,15 +578,13 @@ static void saj_parse(VALUE handler, char *json) {
588
578
  pi.str = json;
589
579
  pi.s = json;
590
580
  #if IS_WINDOWS
591
- pi.stack_min = (void *)((char *)&obj -
592
- (512 * 1024)); /* assume a 1M stack and give half to ruby */
581
+ pi.stack_min = (void *)((char *)&obj - (512L * 1024L)); /* assume a 1M stack and give half to ruby */
593
582
  #else
594
583
  {
595
584
  struct rlimit lim;
596
585
 
597
586
  if (0 == getrlimit(RLIMIT_STACK, &lim) && RLIM_INFINITY != lim.rlim_cur) {
598
- pi.stack_min = (void *)((char *)&obj - (lim.rlim_cur / 4 *
599
- 3)); /* let 3/4ths of the stack be used only */
587
+ pi.stack_min = (void *)((char *)&obj - (lim.rlim_cur / 4 * 3)); /* let 3/4ths of the stack be used only */
600
588
  } else {
601
589
  pi.stack_min = 0; /* indicates not to check stack limit */
602
590
  }
@@ -633,7 +621,7 @@ static void saj_parse(VALUE handler, char *json) {
633
621
  */
634
622
  VALUE
635
623
  oj_saj_parse(int argc, VALUE *argv, VALUE self) {
636
- char * json = 0;
624
+ char *json = 0;
637
625
  size_t len = 0;
638
626
  VALUE input = argv[1];
639
627
 
@@ -315,8 +315,10 @@ static VALUE stream_writer_flush(VALUE self) {
315
315
  * will create that element in the JSON document and subsequent pushes will add
316
316
  * the elements to that array or object until a pop() is called.
317
317
  */
318
- void oj_stream_writer_init() {
318
+ void oj_stream_writer_init(void) {
319
319
  oj_stream_writer_class = rb_define_class_under(Oj, "StreamWriter", rb_cObject);
320
+ rb_gc_register_address(&oj_stream_writer_class);
321
+ rb_undef_alloc_func(oj_stream_writer_class);
320
322
  rb_define_module_function(oj_stream_writer_class, "new", stream_writer_new, -1);
321
323
  rb_define_method(oj_stream_writer_class, "push_key", stream_writer_push_key, 1);
322
324
  rb_define_method(oj_stream_writer_class, "push_object", stream_writer_push_object, -1);
@@ -53,10 +53,13 @@ void oj_str_writer_init(StrWriter sw, int buf_size) {
53
53
  } else if (buf_size < 1024) {
54
54
  buf_size = 1024;
55
55
  }
56
+ // Must be allocated. Using the out.stack_buffer results in double frees
57
+ // and I haven't figured out why yet.
56
58
  sw->out.buf = ALLOC_N(char, buf_size);
57
- sw->out.end = sw->out.buf + buf_size - 10;
58
- sw->out.allocated = true;
59
59
  sw->out.cur = sw->out.buf;
60
+ sw->out.end = sw->out.buf + buf_size - BUFFER_EXTRA;
61
+ sw->out.allocated = true;
62
+
60
63
  *sw->out.cur = '\0';
61
64
  sw->out.circ_cache = NULL;
62
65
  sw->out.circ_cnt = 0;
@@ -229,7 +232,9 @@ static void str_writer_free(void *ptr) {
229
232
  return;
230
233
  }
231
234
  sw = (StrWriter)ptr;
232
- xfree(sw->out.buf);
235
+
236
+ oj_out_free(&sw->out);
237
+
233
238
  xfree(sw->types);
234
239
  xfree(ptr);
235
240
  }
@@ -449,7 +454,7 @@ static VALUE str_writer_to_s(VALUE self) {
449
454
  * Returns the contents of the writer as a JSON element. If called from inside
450
455
  * an array or hash by Oj the raw buffer will be used othersize a more
451
456
  * inefficient parse of the contents and a return of the result is
452
- * completed. The parse uses the trict mode.
457
+ * completed. The parse uses the strict mode.
453
458
  *
454
459
  * *return* [_Hash_|_Array_|_String_|_Integer_|_Float_|_True_|_False_|_nil|)
455
460
  */
@@ -469,8 +474,10 @@ static VALUE str_writer_as_json(VALUE self) {
469
474
  * calling to_s() will return the JSON document. Note that calling to_s() before
470
475
  * construction is complete will return the document in it's current state.
471
476
  */
472
- void oj_string_writer_init() {
477
+ void oj_string_writer_init(void) {
473
478
  oj_string_writer_class = rb_define_class_under(Oj, "StringWriter", rb_cObject);
479
+ rb_gc_register_address(&oj_string_writer_class);
480
+ rb_undef_alloc_func(oj_string_writer_class);
474
481
  rb_define_module_function(oj_string_writer_class, "new", str_writer_new, -1);
475
482
  rb_define_method(oj_string_writer_class, "push_key", str_writer_push_key, 1);
476
483
  rb_define_method(oj_string_writer_class, "push_object", str_writer_push_object, -1);
data/ext/oj/wab.c CHANGED
@@ -35,7 +35,7 @@ static VALUE uri_http_clas = Qundef;
35
35
 
36
36
  ///// dump functions /////
37
37
 
38
- static VALUE resolve_wab_uuid_class() {
38
+ static VALUE resolve_wab_uuid_class(void) {
39
39
  if (Qundef == wab_uuid_clas) {
40
40
  volatile VALUE wab_module;
41
41
 
@@ -50,7 +50,7 @@ static VALUE resolve_wab_uuid_class() {
50
50
  return wab_uuid_clas;
51
51
  }
52
52
 
53
- static VALUE resolve_uri_class() {
53
+ static VALUE resolve_uri_class(void) {
54
54
  if (Qundef == uri_clas) {
55
55
  uri_clas = Qnil;
56
56
  if (rb_const_defined_at(rb_cObject, rb_intern("URI"))) {
@@ -60,7 +60,7 @@ static VALUE resolve_uri_class() {
60
60
  return uri_clas;
61
61
  }
62
62
 
63
- static VALUE resolve_uri_http_class() {
63
+ static VALUE resolve_uri_http_class(void) {
64
64
  if (Qundef == uri_http_clas) {
65
65
  volatile VALUE uri_module;
66
66
 
@@ -124,11 +124,11 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
124
124
  *out->cur++ = ']';
125
125
  } else {
126
126
  size = d2 * out->indent + 2;
127
+ assure_size(out, size * cnt);
127
128
  cnt--;
128
129
  for (i = 0; i <= cnt; i++) {
129
- assure_size(out, size);
130
130
  fill_indent(out, d2);
131
- oj_dump_wab_val(rb_ary_entry(a, i), d2, out);
131
+ oj_dump_wab_val(RARRAY_AREF(a, i), d2, out);
132
132
  if (i < cnt) {
133
133
  *out->cur++ = ',';
134
134
  }
@@ -201,12 +201,12 @@ static void dump_time(VALUE obj, Out out) {
201
201
  sec = ts.tv_sec;
202
202
  nsec = ts.tv_nsec;
203
203
  } else {
204
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
205
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
204
+ sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
205
+ nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
206
206
  }
207
207
  #else
208
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
209
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
208
+ sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
209
+ nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
210
210
  #endif
211
211
 
212
212
  assure_size(out, 36);