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 +4 -4
- data/CHANGELOG.md +4 -0
- data/ext/ox/dump.c +1 -0
- data/ext/ox/obj_load.c +30 -10
- data/ext/ox/ox.c +15 -12
- data/ext/ox/ox.h +7 -5
- data/ext/ox/parse.c +6 -1
- data/lib/ox/version.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c220a3c8bc6e3606d936684b2cdde97146131cdee936c9a66bc8c4ce0473b90
|
4
|
+
data.tar.gz: 96e146a36eff4184918913f27cffb23a81de87835b14c4b30be612d13fb385b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b61e28ecced2336af416e61907c9f4b279c6f7b37df75a8d73a449fda4aac7ba62583255ba2b136f05286f69f840734d5bdd8573da5f11393106c3e6bd082c2
|
7
|
+
data.tar.gz: 703e1df77bb2da424be80c9f0491f57bf021ee312add658062c0c6fe736429fab3fe589a273cf32646ca331ec4e21c435fa51d4bfa2c8cedbc560f7e1b9f69ed
|
data/CHANGELOG.md
CHANGED
data/ext/ox/dump.c
CHANGED
data/ext/ox/obj_load.c
CHANGED
@@ -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
|
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
|
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
|
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(
|
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 (
|
971
|
+
if (0 != h->var) {
|
952
972
|
if (HashCode == h->type) {
|
953
973
|
VALUE v;
|
954
974
|
|
data/ext/ox/ox.c
CHANGED
@@ -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
|
-
|
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");
|
data/ext/ox/ox.h
CHANGED
@@ -156,17 +156,18 @@ typedef struct _Options {
|
|
156
156
|
struct _PInfo {
|
157
157
|
struct _HelperStack helpers;
|
158
158
|
struct _Err err;
|
159
|
-
char *str;
|
160
|
-
char *
|
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;
|
165
|
+
unsigned long id; //set for text types when cirs_array is set
|
165
166
|
Options options;
|
166
|
-
char last;
|
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;
|
data/ext/ox/parse.c
CHANGED
@@ -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 */
|
data/lib/ox/version.rb
CHANGED
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.
|
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-
|
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
|