oj 3.0.7 → 3.0.8
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/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
|