oj 2.6.1 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of oj might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 47818e1b552b974e400bd82db1723ecf930100ed
4
- data.tar.gz: 48f46104df400dab9f9b1c838b7247d68b34c1c3
3
+ metadata.gz: 874c4d47513efdd1f1a64da2ddfe403009f683bc
4
+ data.tar.gz: 16969c09038d314da516230b5ed45787cc05f4cd
5
5
  SHA512:
6
- metadata.gz: fa8d739990ecce865cf95bd363a6464b343cd29d6ab8af6a1bf19e3dd21029d8000f990084a03990822e3f7c88e3164476e7e2b9d8295b2d0e36a5b0dadf5194
7
- data.tar.gz: a02d4f7b1b07caee178e7ec726dedaa481c5c429777dc4be0f2ba9ed361aab57e040ad4ce1abd2e71d79836bad57702f32b180703ffae46e4e0f939e30c397c9
6
+ metadata.gz: 5192373bff2623463ab580cf32b54a45ba380e66a16d342de37b79655c94d6e4ef61180e9332023d6601bc7243ba3f1a594d3a6ad427f0ceb79e2211d070e7b1
7
+ data.tar.gz: 6457b838b18ad5b580b096db8f2ed5c474cc7a7841dd6c2fcde90360a2ec861c7ef0b33a63580339c0735a0f6822a75bdc35d88ed1b8cdd99360f5d85d7e645a
data/README.md CHANGED
@@ -26,11 +26,9 @@ Follow [@peterohler on Twitter](http://twitter.com/#!/peterohler) for announceme
26
26
 
27
27
  [![Build Status](https://secure.travis-ci.org/ohler55/oj.png?branch=master)](http://travis-ci.org/ohler55/oj)
28
28
 
29
- ### Current Release 2.6.1
29
+ ### Current Release 2.7.0
30
30
 
31
- - Set a limit on the maximum nesting depth to 1000. An exception is raised
32
- instead of a segfault unless a reduced stack is used which could trigger the
33
- segfault due to an out of memory condition.
31
+ - Added the push_key() method to the StringWriter and StreamWriter classes.
34
32
 
35
33
  [Older release notes](http://www.ohler.com/dev/oj_misc/release_notes.html).
36
34
 
data/ext/oj/dump.c CHANGED
@@ -2049,10 +2049,13 @@ maybe_comma(StrWriter sw) {
2049
2049
  }
2050
2050
 
2051
2051
  void
2052
- oj_str_writer_push_object(StrWriter sw, const char *key) {
2052
+ oj_str_writer_push_key(StrWriter sw, const char *key) {
2053
+ DumpType type = sw->types[sw->depth];
2053
2054
  long size;
2054
2055
 
2055
- key_check(sw, key);
2056
+ if (ObjectNew != type && ObjectType != type) {
2057
+ rb_raise(rb_eStandardError, "Can only push a key onto an Object.");
2058
+ }
2056
2059
  size = sw->depth * sw->out.indent + 3;
2057
2060
  if (sw->out.end - sw->out.cur <= (long)size) {
2058
2061
  grow(&sw->out, size);
@@ -2061,9 +2064,31 @@ oj_str_writer_push_object(StrWriter sw, const char *key) {
2061
2064
  if (0 < sw->depth) {
2062
2065
  fill_indent(&sw->out, sw->depth);
2063
2066
  }
2064
- if (0 != key) {
2065
- dump_cstr(key, strlen(key), 0, 0, &sw->out);
2066
- *sw->out.cur++ = ':';
2067
+ dump_cstr(key, strlen(key), 0, 0, &sw->out);
2068
+ *sw->out.cur++ = ':';
2069
+ sw->keyWritten = 1;
2070
+ }
2071
+
2072
+ void
2073
+ oj_str_writer_push_object(StrWriter sw, const char *key) {
2074
+ if (sw->keyWritten) {
2075
+ sw->keyWritten = 0;
2076
+ } else {
2077
+ long size;
2078
+
2079
+ key_check(sw, key);
2080
+ size = sw->depth * sw->out.indent + 3;
2081
+ if (sw->out.end - sw->out.cur <= (long)size) {
2082
+ grow(&sw->out, size);
2083
+ }
2084
+ maybe_comma(sw);
2085
+ if (0 < sw->depth) {
2086
+ fill_indent(&sw->out, sw->depth);
2087
+ }
2088
+ if (0 != key) {
2089
+ dump_cstr(key, strlen(key), 0, 0, &sw->out);
2090
+ *sw->out.cur++ = ':';
2091
+ }
2067
2092
  }
2068
2093
  *sw->out.cur++ = '{';
2069
2094
  push_type(sw, ObjectNew);
@@ -2071,20 +2096,24 @@ oj_str_writer_push_object(StrWriter sw, const char *key) {
2071
2096
 
2072
2097
  void
2073
2098
  oj_str_writer_push_array(StrWriter sw, const char *key) {
2074
- long size;
2099
+ if (sw->keyWritten) {
2100
+ sw->keyWritten = 0;
2101
+ } else {
2102
+ long size;
2075
2103
 
2076
- key_check(sw, key);
2077
- size = sw->depth * sw->out.indent + 3;
2078
- if (sw->out.end - sw->out.cur <= size) {
2079
- grow(&sw->out, size);
2080
- }
2081
- maybe_comma(sw);
2082
- if (0 < sw->depth) {
2083
- fill_indent(&sw->out, sw->depth);
2084
- }
2085
- if (0 != key) {
2086
- dump_cstr(key, strlen(key), 0, 0, &sw->out);
2087
- *sw->out.cur++ = ':';
2104
+ key_check(sw, key);
2105
+ size = sw->depth * sw->out.indent + 3;
2106
+ if (sw->out.end - sw->out.cur <= size) {
2107
+ grow(&sw->out, size);
2108
+ }
2109
+ maybe_comma(sw);
2110
+ if (0 < sw->depth) {
2111
+ fill_indent(&sw->out, sw->depth);
2112
+ }
2113
+ if (0 != key) {
2114
+ dump_cstr(key, strlen(key), 0, 0, &sw->out);
2115
+ *sw->out.cur++ = ':';
2116
+ }
2088
2117
  }
2089
2118
  *sw->out.cur++ = '[';
2090
2119
  push_type(sw, ArrayNew);
@@ -2092,40 +2121,48 @@ oj_str_writer_push_array(StrWriter sw, const char *key) {
2092
2121
 
2093
2122
  void
2094
2123
  oj_str_writer_push_value(StrWriter sw, VALUE val, const char *key) {
2095
- long size;
2124
+ if (sw->keyWritten) {
2125
+ sw->keyWritten = 0;
2126
+ } else {
2127
+ long size;
2096
2128
 
2097
- key_check(sw, key);
2098
- size = sw->depth * sw->out.indent + 3;
2099
- if (sw->out.end - sw->out.cur <= size) {
2100
- grow(&sw->out, size);
2101
- }
2102
- maybe_comma(sw);
2103
- if (0 < sw->depth) {
2104
- fill_indent(&sw->out, sw->depth);
2105
- }
2106
- if (0 != key) {
2107
- dump_cstr(key, strlen(key), 0, 0, &sw->out);
2108
- *sw->out.cur++ = ':';
2129
+ key_check(sw, key);
2130
+ size = sw->depth * sw->out.indent + 3;
2131
+ if (sw->out.end - sw->out.cur <= size) {
2132
+ grow(&sw->out, size);
2133
+ }
2134
+ maybe_comma(sw);
2135
+ if (0 < sw->depth) {
2136
+ fill_indent(&sw->out, sw->depth);
2137
+ }
2138
+ if (0 != key) {
2139
+ dump_cstr(key, strlen(key), 0, 0, &sw->out);
2140
+ *sw->out.cur++ = ':';
2141
+ }
2109
2142
  }
2110
2143
  dump_val(val, sw->depth, &sw->out);
2111
2144
  }
2112
2145
 
2113
2146
  void
2114
2147
  oj_str_writer_push_json(StrWriter sw, const char *json, const char *key) {
2115
- long size;
2148
+ if (sw->keyWritten) {
2149
+ sw->keyWritten = 0;
2150
+ } else {
2151
+ long size;
2116
2152
 
2117
- key_check(sw, key);
2118
- size = sw->depth * sw->out.indent + 3;
2119
- if (sw->out.end - sw->out.cur <= size) {
2120
- grow(&sw->out, size);
2121
- }
2122
- maybe_comma(sw);
2123
- if (0 < sw->depth) {
2124
- fill_indent(&sw->out, sw->depth);
2125
- }
2126
- if (0 != key) {
2127
- dump_cstr(key, strlen(key), 0, 0, &sw->out);
2128
- *sw->out.cur++ = ':';
2153
+ key_check(sw, key);
2154
+ size = sw->depth * sw->out.indent + 3;
2155
+ if (sw->out.end - sw->out.cur <= size) {
2156
+ grow(&sw->out, size);
2157
+ }
2158
+ maybe_comma(sw);
2159
+ if (0 < sw->depth) {
2160
+ fill_indent(&sw->out, sw->depth);
2161
+ }
2162
+ if (0 != key) {
2163
+ dump_cstr(key, strlen(key), 0, 0, &sw->out);
2164
+ *sw->out.cur++ = ':';
2165
+ }
2129
2166
  }
2130
2167
  dump_raw(json, strlen(json), &sw->out);
2131
2168
  }
@@ -2135,6 +2172,10 @@ oj_str_writer_pop(StrWriter sw) {
2135
2172
  long size;
2136
2173
  DumpType type = sw->types[sw->depth];
2137
2174
 
2175
+ if (sw->keyWritten) {
2176
+ sw->keyWritten = 0;
2177
+ rb_raise(rb_eStandardError, "Can not pop after writing a key but no value.");
2178
+ }
2138
2179
  sw->depth--;
2139
2180
  if (0 > sw->depth) {
2140
2181
  rb_raise(rb_eStandardError, "Can not pop with no open array or object.");
data/ext/oj/oj.c CHANGED
@@ -864,6 +864,8 @@ str_writer_init(StrWriter sw) {
864
864
  sw->types = ALLOC_N(char, 256);
865
865
  sw->types_end = sw->types + 256;
866
866
  *sw->types = '\0';
867
+ sw->keyWritten = 0;
868
+
867
869
  sw->out.buf = ALLOC_N(char, 4096);
868
870
  sw->out.end = sw->out.buf + 4086;
869
871
  sw->out.allocated = 1;
@@ -894,6 +896,23 @@ str_writer_new(int argc, VALUE *argv, VALUE self) {
894
896
  return Data_Wrap_Struct(oj_string_writer_class, 0, str_writer_free, sw);
895
897
  }
896
898
 
899
+ /* call-seq: push_key(key)
900
+ *
901
+ * Pushes a key onto the JSON document. The key will be used for the next push
902
+ * if currently in a JSON object and ignored otherwise. If a key is provided on
903
+ * the next push then that new key will be ignored.
904
+ * @param [String] key the key pending for the next push
905
+ */
906
+ static VALUE
907
+ str_writer_push_key(VALUE self, VALUE key) {
908
+ StrWriter sw = (StrWriter)DATA_PTR(self);
909
+
910
+ rb_check_type(key, T_STRING);
911
+ oj_str_writer_push_key(sw, StringValuePtr(key));
912
+
913
+ return Qnil;
914
+ }
915
+
897
916
  /* call-seq: push_object(key=nil)
898
917
  *
899
918
  * Pushes an object onto the JSON document. Future pushes will be to this object
@@ -1050,6 +1069,7 @@ str_writer_reset(VALUE self) {
1050
1069
 
1051
1070
  sw->depth = 0;
1052
1071
  *sw->types = '\0';
1072
+ sw->keyWritten = 0;
1053
1073
  sw->out.cur = sw->out.buf;
1054
1074
  *sw->out.cur = '\0';
1055
1075
 
@@ -1155,6 +1175,23 @@ stream_writer_new(int argc, VALUE *argv, VALUE self) {
1155
1175
  return Data_Wrap_Struct(oj_stream_writer_class, 0, stream_writer_free, sw);
1156
1176
  }
1157
1177
 
1178
+ /* call-seq: push_key(key)
1179
+ *
1180
+ * Pushes a key onto the JSON document. The key will be used for the next push
1181
+ * if currently in a JSON object and ignored otherwise. If a key is provided on
1182
+ * the next push then that new key will be ignored.
1183
+ * @param [String] key the key pending for the next push
1184
+ */
1185
+ static VALUE
1186
+ stream_writer_push_key(VALUE self, VALUE key) {
1187
+ StreamWriter sw = (StreamWriter)DATA_PTR(self);
1188
+
1189
+ rb_check_type(key, T_STRING);
1190
+ oj_str_writer_push_key(&sw->sw, StringValuePtr(key));
1191
+ stream_writer_write(sw);
1192
+ return Qnil;
1193
+ }
1194
+
1158
1195
  /* call-seq: push_object(key=nil)
1159
1196
  *
1160
1197
  * Pushes an object onto the JSON document. Future pushes will be to this object
@@ -1706,6 +1743,7 @@ void Init_oj() {
1706
1743
 
1707
1744
  oj_string_writer_class = rb_define_class_under(Oj, "StringWriter", rb_cObject);
1708
1745
  rb_define_module_function(oj_string_writer_class, "new", str_writer_new, -1);
1746
+ rb_define_method(oj_string_writer_class, "push_key", str_writer_push_key, 1);
1709
1747
  rb_define_method(oj_string_writer_class, "push_object", str_writer_push_object, -1);
1710
1748
  rb_define_method(oj_string_writer_class, "push_array", str_writer_push_array, -1);
1711
1749
  rb_define_method(oj_string_writer_class, "push_value", str_writer_push_value, -1);
@@ -1717,6 +1755,7 @@ void Init_oj() {
1717
1755
 
1718
1756
  oj_stream_writer_class = rb_define_class_under(Oj, "StreamWriter", rb_cObject);
1719
1757
  rb_define_module_function(oj_stream_writer_class, "new", stream_writer_new, -1);
1758
+ rb_define_method(oj_stream_writer_class, "push_key", stream_writer_push_key, 1);
1720
1759
  rb_define_method(oj_stream_writer_class, "push_object", stream_writer_push_object, -1);
1721
1760
  rb_define_method(oj_stream_writer_class, "push_array", stream_writer_push_array, -1);
1722
1761
  rb_define_method(oj_stream_writer_class, "push_value", stream_writer_push_value, -1);
data/ext/oj/oj.h CHANGED
@@ -162,6 +162,7 @@ typedef struct _StrWriter {
162
162
  int depth;
163
163
  char *types; // DumpType
164
164
  char *types_end;
165
+ int keyWritten;
165
166
  } *StrWriter;
166
167
 
167
168
  typedef struct _StreamWriter {
@@ -212,6 +213,7 @@ extern void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts);
212
213
  extern void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out);
213
214
  extern void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts);
214
215
 
216
+ extern void oj_str_writer_push_key(StrWriter sw, const char *key);
215
217
  extern void oj_str_writer_push_object(StrWriter sw, const char *key);
216
218
  extern void oj_str_writer_push_array(StrWriter sw, const char *key);
217
219
  extern void oj_str_writer_push_value(StrWriter sw, VALUE val, const char *key);
data/lib/oj/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Oj
3
3
  # Current version of the module.
4
- VERSION = '2.6.1'
4
+ VERSION = '2.7.0'
5
5
  end
data/test/test_writer.rb CHANGED
@@ -61,6 +61,24 @@ class OjWriter < ::Test::Unit::TestCase
61
61
  assert_equal('{"a1":{},"a2":{"b":{}},"a3":{}}', w.to_s)
62
62
  end
63
63
 
64
+ def test_string_writer_nested_key_object
65
+ w = Oj::StringWriter.new(:indent => 0)
66
+ w.push_object()
67
+ w.push_key('a1')
68
+ w.push_object()
69
+ w.pop()
70
+ w.push_key('a2')
71
+ w.push_object('x')
72
+ w.push_object('b')
73
+ w.pop()
74
+ w.pop()
75
+ w.push_key('a3')
76
+ w.push_object()
77
+ w.pop()
78
+ w.pop()
79
+ assert_equal('{"a1":{},"a2":{"b":{}},"a3":{}}', w.to_s)
80
+ end
81
+
64
82
  def test_string_writer_value_array
65
83
  w = Oj::StringWriter.new(:indent => 2)
66
84
  w.push_array()
@@ -117,6 +135,33 @@ class OjWriter < ::Test::Unit::TestCase
117
135
  end
118
136
 
119
137
  def test_string_writer_pop_excess
138
+ w = Oj::StringWriter.new(:indent => 0)
139
+ begin
140
+ w.push_object() {
141
+ w.push_key('key')
142
+ }
143
+ rescue Exception
144
+ assert(true)
145
+ return
146
+ end
147
+ assert(false, "*** expected an exception")
148
+ end
149
+
150
+ def test_string_writer_array_key
151
+ w = Oj::StringWriter.new(:indent => 0)
152
+ begin
153
+ w.push_array() {
154
+ w.push_key('key')
155
+ w.push_value(7)
156
+ }
157
+ rescue Exception
158
+ assert(true)
159
+ return
160
+ end
161
+ assert(false, "*** expected an exception")
162
+ end
163
+
164
+ def test_string_writer_pop_with_key
120
165
  w = Oj::StringWriter.new(:indent => 0)
121
166
  begin
122
167
  w.pop()
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: 2.6.1
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-21 00:00:00.000000000 Z
11
+ date: 2014-03-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: 'The fastest JSON parser and object serializer. '
14
14
  email: peter@ohler.com