oj 3.0.7 → 3.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/oj/dump.c +46 -3
- data/ext/oj/dump_compat.c +7 -2
- data/ext/oj/mimic_json.c +1 -1
- data/ext/oj/oj.c +1 -1
- data/ext/oj/rails.c +10 -5
- data/ext/oj/rails.h +1 -0
- data/lib/oj/version.rb +1 -1
- data/pages/Rails.md +14 -0
- data/test/test_compat.rb +18 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a944529c2d9fc9f12e3be88cb7edd568e3c32de9
|
4
|
+
data.tar.gz: d40180c12d6ae9ee8e50fa13bbe49374674e5eb3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a46eb91148fd3200c0226d38a7ad9bff977a037a0ebd93ddcda9b082f515e2561e815c01694c58ec17af7d9be9f83075a4f630c35b077c862b1de048173f1627
|
7
|
+
data.tar.gz: af1bfff262e48d2f46282b5314247a98ea919fbb17f8b653fca03736f93944f61e1fba25b00df894020372ae0f3b1e3bddd2732c3be65dfe2c17bec6140d77e2
|
data/ext/oj/dump.c
CHANGED
@@ -157,11 +157,15 @@ inline static size_t
|
|
157
157
|
hixss_friendly_size(const uint8_t *str, size_t len) {
|
158
158
|
size_t size = 0;
|
159
159
|
size_t i = len;
|
160
|
-
|
160
|
+
bool check = false;
|
161
|
+
|
161
162
|
for (; 0 < i; str++, i--) {
|
162
163
|
size += hixss_friendly_chars[*str];
|
164
|
+
if (0 != (0x80 & *str)) {
|
165
|
+
check = true;
|
166
|
+
}
|
163
167
|
}
|
164
|
-
return size - len * (size_t)'0';
|
168
|
+
return size - len * (size_t)'0' + check;
|
165
169
|
}
|
166
170
|
|
167
171
|
inline static size_t
|
@@ -279,6 +283,34 @@ dump_unicode(const char *str, const char *end, Out out) {
|
|
279
283
|
return str - 1;
|
280
284
|
}
|
281
285
|
|
286
|
+
static const char*
|
287
|
+
check_unicode(const char *str, const char *end) {
|
288
|
+
uint8_t b = *(uint8_t*)str;
|
289
|
+
int cnt;
|
290
|
+
|
291
|
+
if (0xC0 == (0xE0 & b)) {
|
292
|
+
cnt = 1;
|
293
|
+
} else if (0xE0 == (0xF0 & b)) {
|
294
|
+
cnt = 2;
|
295
|
+
} else if (0xF0 == (0xF8 & b)) {
|
296
|
+
cnt = 3;
|
297
|
+
} else if (0xF8 == (0xFC & b)) {
|
298
|
+
cnt = 4;
|
299
|
+
} else if (0xFC == (0xFE & b)) {
|
300
|
+
cnt = 5;
|
301
|
+
} else {
|
302
|
+
rb_raise(oj_json_generator_error_class, "Invalid Unicode");
|
303
|
+
}
|
304
|
+
str++;
|
305
|
+
for (; 0 < cnt; cnt--, str++) {
|
306
|
+
b = *(uint8_t*)str;
|
307
|
+
if (end <= str || 0x80 != (0xC0 & b)) {
|
308
|
+
rb_raise(oj_json_generator_error_class, "Invalid Unicode");
|
309
|
+
}
|
310
|
+
}
|
311
|
+
return str;
|
312
|
+
}
|
313
|
+
|
282
314
|
// Returns 0 if not using circular references, -1 if no further writing is
|
283
315
|
// needed (duplicate), and a positive value if the object was added to the
|
284
316
|
// cache.
|
@@ -707,6 +739,7 @@ oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
|
|
707
739
|
*out->cur++ = '"';
|
708
740
|
} else {
|
709
741
|
const char *end = str + cnt;
|
742
|
+
const char *check_start = str;
|
710
743
|
|
711
744
|
if (is_sym) {
|
712
745
|
*out->cur++ = ':';
|
@@ -714,6 +747,15 @@ oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
|
|
714
747
|
for (; str < end; str++) {
|
715
748
|
switch (cmap[(uint8_t)*str]) {
|
716
749
|
case '1':
|
750
|
+
if (JXEsc == out->opts->escape_mode && check_start <= str) {
|
751
|
+
if (0 != (0x80 & (uint8_t)*str)) {
|
752
|
+
if (0xC0 == (0xC0 & (uint8_t)*str)) {
|
753
|
+
check_start = check_unicode(str, end);
|
754
|
+
} else {
|
755
|
+
rb_raise(oj_json_generator_error_class, "Invalid Unicode");
|
756
|
+
}
|
757
|
+
}
|
758
|
+
}
|
717
759
|
*out->cur++ = *str;
|
718
760
|
break;
|
719
761
|
case '2':
|
@@ -734,6 +776,7 @@ oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
|
|
734
776
|
str = dump_unicode(str, end, out);
|
735
777
|
} else {
|
736
778
|
*out->cur++ = *str;
|
779
|
+
check_start = str + 3;
|
737
780
|
}
|
738
781
|
break;
|
739
782
|
}
|
@@ -773,7 +816,7 @@ oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
|
|
773
816
|
break;
|
774
817
|
case 2:
|
775
818
|
if (0xE0 != (0xF0 & c)) {
|
776
|
-
rb_raise(oj_json_generator_error_class, "Partial character in string.
|
819
|
+
rb_raise(oj_json_generator_error_class, "Partial character in string.");
|
777
820
|
}
|
778
821
|
break;
|
779
822
|
case 3:
|
data/ext/oj/dump_compat.c
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
|
6
6
|
#include "code.h"
|
7
7
|
#include "dump.h"
|
8
|
+
#include "rails.h"
|
8
9
|
|
9
10
|
// Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
|
10
11
|
#define OJ_INFINITY (1.0/0.0)
|
@@ -612,9 +613,13 @@ dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
612
613
|
} else if (d == (double)(long long int)d) {
|
613
614
|
//cnt = snprintf(buf, sizeof(buf), "%.1Lf", (long double)d);
|
614
615
|
cnt = snprintf(buf, sizeof(buf), "%.1f", d);
|
615
|
-
} else {
|
616
|
-
//cnt = snprintf(buf, sizeof(buf), "%0.16Lg", (long double)d);
|
616
|
+
} else if (oj_rails_float_opt) {
|
617
617
|
cnt = snprintf(buf, sizeof(buf), "%0.16g", d);
|
618
|
+
} else {
|
619
|
+
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
|
620
|
+
|
621
|
+
strcpy(buf, rb_string_value_ptr((VALUE*)&rstr));
|
622
|
+
cnt = RSTRING_LEN(rstr);
|
618
623
|
}
|
619
624
|
assure_size(out, cnt);
|
620
625
|
for (b = buf; '\0' != *b; b++) {
|
data/ext/oj/mimic_json.c
CHANGED
data/ext/oj/oj.c
CHANGED
@@ -1000,6 +1000,7 @@ to_json(int argc, VALUE *argv, VALUE self) {
|
|
1000
1000
|
if (1 > argc) {
|
1001
1001
|
rb_raise(rb_eArgError, "wrong number of arguments (0 for 1).");
|
1002
1002
|
}
|
1003
|
+
copts.escape_mode = JXEsc;
|
1003
1004
|
copts.dump_opts.nan_dump = false;
|
1004
1005
|
if (2 == argc) {
|
1005
1006
|
oj_parse_mimic_dump_options(argv[1], &copts);
|
@@ -1600,4 +1601,3 @@ Init_oj() {
|
|
1600
1601
|
#endif
|
1601
1602
|
oj_init_doc();
|
1602
1603
|
}
|
1603
|
-
|
data/ext/oj/rails.c
CHANGED
@@ -19,6 +19,7 @@ typedef struct _Encoder {
|
|
19
19
|
|
20
20
|
bool oj_rails_hash_opt = false;
|
21
21
|
bool oj_rails_array_opt = false;
|
22
|
+
bool oj_rails_float_opt = false;
|
22
23
|
|
23
24
|
static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok);
|
24
25
|
|
@@ -187,7 +188,6 @@ dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
187
188
|
*out->cur = '\0';
|
188
189
|
}
|
189
190
|
|
190
|
-
|
191
191
|
static ID to_a_id = 0;
|
192
192
|
|
193
193
|
static void
|
@@ -484,11 +484,12 @@ optimize(int argc, VALUE *argv, ROptTable rot, bool on) {
|
|
484
484
|
oj_rails_hash_opt = on;
|
485
485
|
} else if (rb_cArray == *argv) {
|
486
486
|
oj_rails_array_opt = on;
|
487
|
+
} else if (rb_cFloat == *argv) {
|
488
|
+
oj_rails_float_opt = on;
|
487
489
|
} else if (NULL != (ro = oj_rails_get_opt(rot, *argv)) ||
|
488
490
|
NULL != (ro = create_opt(rot, *argv))) {
|
489
491
|
ro->on = on;
|
490
492
|
}
|
491
|
-
// TBD recurse if there are subclasses
|
492
493
|
}
|
493
494
|
}
|
494
495
|
|
@@ -936,8 +937,13 @@ dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
936
937
|
cnt = 4;
|
937
938
|
} else if (d == (double)(long long int)d) {
|
938
939
|
cnt = snprintf(buf, sizeof(buf), "%.1f", d);
|
939
|
-
} else {
|
940
|
+
} else if (oj_rails_float_opt) {
|
940
941
|
cnt = snprintf(buf, sizeof(buf), "%0.16g", d);
|
942
|
+
} else {
|
943
|
+
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
|
944
|
+
|
945
|
+
strcpy(buf, rb_string_value_ptr((VALUE*)&rstr));
|
946
|
+
cnt = RSTRING_LEN(rstr);
|
941
947
|
}
|
942
948
|
}
|
943
949
|
assure_size(out, cnt);
|
@@ -1091,8 +1097,7 @@ dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1091
1097
|
return;
|
1092
1098
|
}
|
1093
1099
|
}
|
1094
|
-
|
1095
|
-
if (0 < out->argc && as_ok && rb_respond_to(obj, oj_as_json_id)) {
|
1100
|
+
if ((!oj_rails_hash_opt || 0 < out->argc) && as_ok && rb_respond_to(obj, oj_as_json_id)) {
|
1096
1101
|
dump_as_json(obj, depth, out, false);
|
1097
1102
|
return;
|
1098
1103
|
}
|
data/ext/oj/rails.h
CHANGED
data/lib/oj/version.rb
CHANGED
data/pages/Rails.md
CHANGED
@@ -61,6 +61,7 @@ Oj::Rails.optimize is called with no arguments are:
|
|
61
61
|
|
62
62
|
* Array
|
63
63
|
* BigDecimal
|
64
|
+
* Float
|
64
65
|
* Hash
|
65
66
|
* Range
|
66
67
|
* Regexp
|
@@ -72,3 +73,16 @@ Oj::Rails.optimize is called with no arguments are:
|
|
72
73
|
|
73
74
|
The ActiveSupport decoder is the JSON.parse() method. Calling the
|
74
75
|
Oj::Rails.set_decoder() method replaces that method with the Oj equivelant.
|
76
|
+
|
77
|
+
### Notes:
|
78
|
+
|
79
|
+
1. Optimized Floats set the significant digits to 16. This is different than
|
80
|
+
Ruby which is used by the json gem and by Rails. Ruby varies the
|
81
|
+
significant digits which can be either 16 or 17 depending on the value.
|
82
|
+
|
83
|
+
2. Optimized Hashs do not collapse keys that become the same in the output. As
|
84
|
+
an example, a non-String object that has a to_s() method will become the
|
85
|
+
return value of the to_s() method in the output without checking to see if
|
86
|
+
that has already been used. This could occur is a mix of String and Symbols
|
87
|
+
are used as keys or if a other non-String objects such as Numerics are mixed
|
88
|
+
with numbers as Strings.
|
data/test/test_compat.rb
CHANGED
@@ -283,7 +283,6 @@ class CompatJuice < Minitest::Test
|
|
283
283
|
end
|
284
284
|
x = Oj.load('Infinity', :mode => :compat)
|
285
285
|
assert_equal('Infinity', x.to_s)
|
286
|
-
|
287
286
|
end
|
288
287
|
|
289
288
|
# Time
|
@@ -461,6 +460,24 @@ class CompatJuice < Minitest::Test
|
|
461
460
|
assert_equal(%|{"args":"[{:max_nesting=>40}]"}|, json)
|
462
461
|
end
|
463
462
|
|
463
|
+
def test_bad_unicode
|
464
|
+
begin
|
465
|
+
Oj.to_json("\xE4xy")
|
466
|
+
fail()
|
467
|
+
rescue Exception
|
468
|
+
assert(true)
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
def test_bad_unicode_start
|
473
|
+
begin
|
474
|
+
Oj.to_json("\x8abc")
|
475
|
+
fail()
|
476
|
+
rescue Exception
|
477
|
+
assert(true)
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
464
481
|
def dump_and_load(obj, trace=false)
|
465
482
|
json = Oj.dump(obj)
|
466
483
|
puts json if trace
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-05-
|
11
|
+
date: 2017-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|