ox 2.9.3 → 2.9.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ed84d3d4fbc1ce7e736c41db72f0be81b54e647916ec7904d3ed8bde7a9f3c0
4
- data.tar.gz: d8b315fcbadfa83b886cf99ef1273da41511ce2633a2fae01ed9fb5f1a8ac872
3
+ metadata.gz: 9c220a3c8bc6e3606d936684b2cdde97146131cdee936c9a66bc8c4ce0473b90
4
+ data.tar.gz: 96e146a36eff4184918913f27cffb23a81de87835b14c4b30be612d13fb385b8
5
5
  SHA512:
6
- metadata.gz: b86eb6d808f3a3f0dd373082060c838cf829ca15f2d41d64df7a15f6014d4401019e45d39b564f1dade27f328c165792776692f361f4d95f955da1160c1db016
7
- data.tar.gz: a8262ff6dc805641118dd60691d80da5ac8bd23efd69274c1807feb94f3ddde1da1bfecbc538a2a62e06f02a242384629393fb42216875e57f5aebabd3e902b9
6
+ metadata.gz: 1b61e28ecced2336af416e61907c9f4b279c6f7b37df75a8d73a449fda4aac7ba62583255ba2b136f05286f69f840734d5bdd8573da5f11393106c3e6bd082c2
7
+ data.tar.gz: 703e1df77bb2da424be80c9f0491f57bf021ee312add658062c0c6fe736429fab3fe589a273cf32646ca331ec4e21c435fa51d4bfa2c8cedbc560f7e1b9f69ed
@@ -1,4 +1,8 @@
1
1
 
2
+ ## 2.9.4 - July 16, 2018
3
+
4
+ - Fixed issue with malformed object mode input.
5
+
2
6
  ## 2.9.3 - June 12, 2018
3
7
 
4
8
  - Handle `\0` in dumped strings better.
@@ -1270,6 +1270,7 @@ dump_obj_to_xml(VALUE obj, Options copts, Out out) {
1270
1270
  out->circ_cnt = 0;
1271
1271
  out->opts = copts;
1272
1272
  out->obj = obj;
1273
+ *out->cur = '\0';
1273
1274
  if (Yes == copts->circular) {
1274
1275
  ox_cache8_new(&out->circ_cache);
1275
1276
  }
@@ -24,7 +24,7 @@ static VALUE parse_xsd_time(const char *text, VALUE clas);
24
24
  static VALUE parse_double_time(const char *text, VALUE clas);
25
25
  static VALUE parse_regexp(const char *text);
26
26
 
27
- static VALUE get_var_sym_from_attrs(Attr a, void *encoding);
27
+ static ID get_var_sym_from_attrs(Attr a, void *encoding);
28
28
  static VALUE get_obj_from_attrs(Attr a, PInfo pi, VALUE base_class);
29
29
  static VALUE get_class_from_attrs(Attr a, PInfo pi, VALUE base_class);
30
30
  static VALUE classname2class(const char *name, PInfo pi, VALUE base_class);
@@ -76,7 +76,7 @@ str2sym(const char *str, void *encoding) {
76
76
  inline static ID
77
77
  name2var(const char *name, void *encoding) {
78
78
  VALUE *slot;
79
- ID var_id;
79
+ ID var_id = 0;
80
80
 
81
81
  if ('0' <= *name && *name <= '9') {
82
82
  var_id = INT2NUM(atoi(name));
@@ -194,7 +194,6 @@ parse_time(const char *text, VALUE clas) {
194
194
  Qnil == (t = parse_xsd_time(text, clas))) {
195
195
  VALUE args[1];
196
196
 
197
- /*printf("**** time parse\n"); */
198
197
  *args = rb_str_new2(text);
199
198
  t = rb_funcall2(ox_time_class, ox_parse_id, 1, args);
200
199
  }
@@ -236,14 +235,14 @@ classname2class(const char *name, PInfo pi, VALUE base_class) {
236
235
  return clas;
237
236
  }
238
237
 
239
- static VALUE
238
+ static ID
240
239
  get_var_sym_from_attrs(Attr a, void *encoding) {
241
240
  for (; 0 != a->name; a++) {
242
241
  if ('a' == *a->name && '\0' == *(a->name + 1)) {
243
242
  return name2var(a->value, encoding);
244
243
  }
245
244
  }
246
- return Qundef;
245
+ return 0;
247
246
  }
248
247
 
249
248
  static VALUE
@@ -544,7 +543,7 @@ add_text(PInfo pi, char *text, int closed) {
544
543
  break;
545
544
  case BigDecimalCode:
546
545
  #if HAS_BIGDECIMAL
547
- h->obj = rb_funcall(ox_bigdecimal_class, ox_new_id, 1, rb_str_new2(text));
546
+ h->obj = rb_funcall(rb_cObject, ox_bigdecimal_id, 1, rb_str_new2(text));
548
547
  #else
549
548
  h->obj = Qnil;
550
549
  #endif
@@ -646,7 +645,7 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
646
645
  break;
647
646
  case RawCode:
648
647
  if (hasChildren) {
649
- h->obj = ox_parse(pi->s, ox_gen_callbacks, &pi->s, pi->options, &pi->err);
648
+ h->obj = ox_parse(pi->s, pi->end - pi->s, ox_gen_callbacks, &pi->s, pi->options, &pi->err);
650
649
  if (0 != pi->circ_array) {
651
650
  circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
652
651
  }
@@ -730,6 +729,10 @@ end_element(PInfo pi, const char *ename) {
730
729
  /* special catch for empty strings */
731
730
  h->obj = rb_str_new2("");
732
731
  }
732
+ if (Qundef == h->obj) {
733
+ set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
734
+ return;
735
+ }
733
736
  pi->obj = h->obj;
734
737
  if (0 != ph) {
735
738
  switch (ph->type) {
@@ -739,11 +742,19 @@ end_element(PInfo pi, const char *ename) {
739
742
  case ExceptionCode:
740
743
  case ObjectCode:
741
744
  if (Qnil != ph->obj) {
745
+ if (0 == h->var) {
746
+ set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
747
+ return;
748
+ }
742
749
  rb_ivar_set(ph->obj, h->var, h->obj);
743
750
  }
744
751
  break;
745
752
  case StructCode:
746
753
  #if HAS_RSTRUCT
754
+ if (0 == h->var) {
755
+ set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
756
+ return;
757
+ }
747
758
  rb_struct_aset(ph->obj, h->var, h->obj);
748
759
  #else
749
760
  set_error(&pi->err, "Ruby structs not supported with this verion of Ruby", pi->str, pi->s);
@@ -776,7 +787,7 @@ end_element(PInfo pi, const char *ename) {
776
787
  Helper gh;
777
788
 
778
789
  helper_stack_pop(&pi->helpers);
779
- if (NULL == (gh = helper_stack_peek(&pi->helpers))) {
790
+ if (NULL == (gh = helper_stack_peek(&pi->helpers)) || Qundef == ph->obj || Qundef == h->obj) {
780
791
  set_error(&pi->err, "Corrupt parse stack, container is wrong type", pi->str, pi->s);
781
792
  return;
782
793
  }
@@ -795,11 +806,19 @@ end_element(PInfo pi, const char *ename) {
795
806
  return;
796
807
  #endif
797
808
  break;
798
- case RationalCode:
809
+ case RationalCode: {
810
+ if (Qundef == h->obj || RUBY_T_FIXNUM != rb_type(h->obj)) {
811
+ set_error(&pi->err, "Invalid object format", pi->str, pi->s);
812
+ return;
813
+ }
799
814
  #ifdef T_RATIONAL
800
815
  if (Qundef == ph->obj) {
801
816
  ph->obj = h->obj;
802
817
  } else {
818
+ if (Qundef == ph->obj || RUBY_T_FIXNUM != rb_type(h->obj)) {
819
+ set_error(&pi->err, "Corrupt parse stack, container is wrong type", pi->str, pi->s);
820
+ return;
821
+ }
803
822
  #ifdef RUBINIUS_RUBY
804
823
  ph->obj = rb_Rational(ph->obj, h->obj);
805
824
  #else
@@ -811,6 +830,7 @@ end_element(PInfo pi, const char *ename) {
811
830
  return;
812
831
  #endif
813
832
  break;
833
+ }
814
834
  default:
815
835
  set_error(&pi->err, "Corrupt parse stack, container is wrong type", pi->str, pi->s);
816
836
  return;
@@ -948,7 +968,7 @@ debug_stack(PInfo pi, const char *comment) {
948
968
 
949
969
  clas = rb_class2name(c);
950
970
  }
951
- if (Qundef != h->var) {
971
+ if (0 != h->var) {
952
972
  if (HashCode == h->type) {
953
973
  VALUE v;
954
974
 
@@ -39,6 +39,7 @@ ID ox_attr_value_id;
39
39
  ID ox_attributes_id;
40
40
  ID ox_attrs_done_id;
41
41
  ID ox_beg_id;
42
+ ID ox_bigdecimal_id;
42
43
  ID ox_cdata_id;
43
44
  ID ox_comment_id;
44
45
  ID ox_den_id;
@@ -645,7 +646,7 @@ to_obj(VALUE self, VALUE ruby_xml) {
645
646
  #if HAS_GC_GUARD
646
647
  rb_gc_disable();
647
648
  #endif
648
- obj = ox_parse(xml, ox_obj_callbacks, 0, &options, &err);
649
+ obj = ox_parse(xml, len - 1, ox_obj_callbacks, 0, &options, &err);
649
650
  if (SMALL_XML < len) {
650
651
  xfree(xml);
651
652
  }
@@ -686,7 +687,7 @@ to_gen(VALUE self, VALUE ruby_xml) {
686
687
  xml = ALLOCA_N(char, len);
687
688
  }
688
689
  memcpy(xml, x, len);
689
- obj = ox_parse(xml, ox_gen_callbacks, 0, &options, &err);
690
+ obj = ox_parse(xml, len - 1, ox_gen_callbacks, 0, &options, &err);
690
691
  if (SMALL_XML < len) {
691
692
  xfree(xml);
692
693
  }
@@ -697,7 +698,7 @@ to_gen(VALUE self, VALUE ruby_xml) {
697
698
  }
698
699
 
699
700
  static VALUE
700
- load(char *xml, int argc, VALUE *argv, VALUE self, VALUE encoding, Err err) {
701
+ load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, Err err) {
701
702
  VALUE obj;
702
703
  struct _Options options = ox_default_options;
703
704
 
@@ -838,29 +839,29 @@ load(char *xml, int argc, VALUE *argv, VALUE self, VALUE encoding, Err err) {
838
839
  #if HAS_GC_GUARD
839
840
  rb_gc_disable();
840
841
  #endif
841
- obj = ox_parse(xml, ox_obj_callbacks, 0, &options, err);
842
+ obj = ox_parse(xml, len, ox_obj_callbacks, 0, &options, err);
842
843
  #if HAS_GC_GUARD
843
844
  RB_GC_GUARD(obj);
844
845
  rb_gc_enable();
845
846
  #endif
846
847
  break;
847
848
  case GenMode:
848
- obj = ox_parse(xml, ox_gen_callbacks, 0, &options, err);
849
+ obj = ox_parse(xml, len, ox_gen_callbacks, 0, &options, err);
849
850
  break;
850
851
  case LimMode:
851
- obj = ox_parse(xml, ox_limited_callbacks, 0, &options, err);
852
+ obj = ox_parse(xml, len, ox_limited_callbacks, 0, &options, err);
852
853
  break;
853
854
  case HashMode:
854
- obj = ox_parse(xml, ox_hash_callbacks, 0, &options, err);
855
+ obj = ox_parse(xml, len, ox_hash_callbacks, 0, &options, err);
855
856
  break;
856
857
  case HashNoAttrMode:
857
- obj = ox_parse(xml, ox_hash_no_attrs_callbacks, 0, &options, err);
858
+ obj = ox_parse(xml, len, ox_hash_no_attrs_callbacks, 0, &options, err);
858
859
  break;
859
860
  case NoMode:
860
- obj = ox_parse(xml, ox_nomode_callbacks, 0, &options, err);
861
+ obj = ox_parse(xml, len, ox_nomode_callbacks, 0, &options, err);
861
862
  break;
862
863
  default:
863
- obj = ox_parse(xml, ox_gen_callbacks, 0, &options, err);
864
+ obj = ox_parse(xml, len, ox_gen_callbacks, 0, &options, err);
864
865
  break;
865
866
  }
866
867
  return obj;
@@ -920,7 +921,8 @@ load_str(int argc, VALUE *argv, VALUE self) {
920
921
  encoding = Qnil;
921
922
  #endif
922
923
  memcpy(xml, StringValuePtr(*argv), len);
923
- obj = load(xml, argc - 1, argv + 1, self, encoding, &err);
924
+ xml[len - 1] = '\0';
925
+ obj = load(xml, len - 1, argc - 1, argv + 1, self, encoding, &err);
924
926
  if (SMALL_XML < len) {
925
927
  xfree(xml);
926
928
  }
@@ -980,7 +982,7 @@ load_file(int argc, VALUE *argv, VALUE self) {
980
982
  obj = Qnil;
981
983
  } else {
982
984
  xml[len] = '\0';
983
- obj = load(xml, argc - 1, argv + 1, self, Qnil, &err);
985
+ obj = load(xml, len, argc - 1, argv + 1, self, Qnil, &err);
984
986
  }
985
987
  fclose(f);
986
988
  if (SMALL_XML < len) {
@@ -1376,6 +1378,7 @@ void Init_ox() {
1376
1378
  ox_attributes_id = rb_intern("@attributes");
1377
1379
  ox_attrs_done_id = rb_intern("attrs_done");
1378
1380
  ox_beg_id = rb_intern("@beg");
1381
+ ox_bigdecimal_id = rb_intern("BigDecimal");
1379
1382
  ox_cdata_id = rb_intern("cdata");
1380
1383
  ox_comment_id = rb_intern("comment");
1381
1384
  ox_den_id = rb_intern("@den");
@@ -156,17 +156,18 @@ typedef struct _Options {
156
156
  struct _PInfo {
157
157
  struct _HelperStack helpers;
158
158
  struct _Err err;
159
- char *str; /* buffer being read from */
160
- char *s; /* current position in buffer */
159
+ char *str; //buffer being read from
160
+ char *end; // end of original string
161
+ char *s; // current position in buffer
161
162
  VALUE obj;
162
163
  ParseCallbacks pcb;
163
164
  CircArray circ_array;
164
- unsigned long id; /* set for text types when cirs_array is set */
165
+ unsigned long id; //set for text types when cirs_array is set
165
166
  Options options;
166
- char last; /* last character read, rarely set */
167
+ char last; // last character read, rarely set
167
168
  };
168
169
 
169
- extern VALUE ox_parse(char *xml, ParseCallbacks pcb, char **endp, Options options, Err err);
170
+ extern VALUE ox_parse(char *xml, size_t len, ParseCallbacks pcb, char **endp, Options options, Err err);
170
171
  extern void _ox_raise_error(const char *msg, const char *xml, const char *current, const char* file, int line);
171
172
 
172
173
  extern void ox_sax_define(void);
@@ -190,6 +191,7 @@ extern ID ox_attr_value_id;
190
191
  extern ID ox_attrs_done_id;
191
192
  extern ID ox_attributes_id;
192
193
  extern ID ox_beg_id;
194
+ extern ID ox_bigdecimal_id;
193
195
  extern ID ox_cdata_id;
194
196
  extern ID ox_comment_id;
195
197
  extern ID ox_den_id;
@@ -108,7 +108,7 @@ mark_pi_cb(void *ptr) {
108
108
  }
109
109
 
110
110
  VALUE
111
- ox_parse(char *xml, ParseCallbacks pcb, char **endp, Options options, Err err) {
111
+ ox_parse(char *xml, size_t len, ParseCallbacks pcb, char **endp, Options options, Err err) {
112
112
  struct _PInfo pi;
113
113
  int body_read = 0;
114
114
  int block_given = rb_block_given_p();
@@ -128,6 +128,7 @@ ox_parse(char *xml, ParseCallbacks pcb, char **endp, Options options, Err err) {
128
128
 
129
129
  err_init(&pi.err);
130
130
  pi.str = xml;
131
+ pi.end = pi.str + len;
131
132
  pi.s = xml;
132
133
  pi.pcb = pcb;
133
134
  pi.obj = Qnil;
@@ -456,6 +457,9 @@ read_element(PInfo pi) {
456
457
  /* read attribute names until the close (/ or >) is reached */
457
458
  while (!done) {
458
459
  if ('\0' == c) {
460
+ if (pi->end <= pi->s) {
461
+ break;
462
+ }
459
463
  next_non_white(pi);
460
464
  c = *pi->s;
461
465
  }
@@ -485,6 +489,7 @@ read_element(PInfo pi) {
485
489
  hasChildren = 1;
486
490
  done = 1;
487
491
  pi->pcb->add_element(pi, ename, attrs.head, hasChildren);
492
+
488
493
  break;
489
494
  default:
490
495
  /* Attribute name so it's an element and the attribute will be */
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Ox
3
- # Current version of the module.
4
- VERSION = '2.9.3'
3
+ # Current version of the module.
4
+ VERSION = '2.9.4'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ox
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.3
4
+ version: 2.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-12 00:00:00.000000000 Z
11
+ date: 2018-07-16 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: "A fast XML parser and object serializer that uses only standard C lib.\n
14
14
  \ \nOptimized XML (Ox), as the name implies was written to provide speed