ox 1.8.6 → 1.8.7

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

Potentially problematic release.


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

data/README.md CHANGED
@@ -34,6 +34,14 @@ A fast XML parser and Object marshaller as a Ruby gem.
34
34
 
35
35
  ## <a name="release">Release Notes</a>
36
36
 
37
+ ### Release 1.8.7
38
+
39
+ - Added a correct check for element open and close names.
40
+
41
+ - Changed raised Exceptions to customer classes that inherit from StandardError.
42
+
43
+ - Fixed a few minor bugs.
44
+
37
45
  ### Release 1.8.6
38
46
 
39
47
  - Removed broken check for matching start and end element names in SAX mode. The names are still included in the
data/ext/ox/cache.c CHANGED
@@ -46,8 +46,8 @@ struct _Cache {
46
46
  static void slot_print(Cache cache, unsigned int depth);
47
47
 
48
48
  static char* dupstr(const char *s) {
49
- size_t len = strlen(s);
50
- char *d = ALLOC_N(char, len + 1);
49
+ size_t len = strlen(s) + 1;
50
+ char *d = ALLOC_N(char, len);
51
51
 
52
52
  memcpy(d, s, len);
53
53
 
@@ -63,7 +63,7 @@ ox_cache_new(Cache *cache) {
63
63
  }
64
64
 
65
65
  VALUE
66
- ox_cache_get(Cache cache, const char *key, VALUE **slot) {
66
+ ox_cache_get(Cache cache, const char *key, VALUE **slot, char **keyp) {
67
67
  unsigned char *k = (unsigned char*)key;
68
68
  Cache *cp;
69
69
 
@@ -107,7 +107,9 @@ ox_cache_get(Cache cache, const char *key, VALUE **slot) {
107
107
  }
108
108
  }
109
109
  *slot = &cache->value;
110
-
110
+ if (0 != keyp) {
111
+ *keyp = cache->key;
112
+ }
111
113
  return cache->value;
112
114
  }
113
115
 
data/ext/ox/cache.h CHANGED
@@ -37,7 +37,7 @@ typedef struct _Cache *Cache;
37
37
 
38
38
  extern void ox_cache_new(Cache *cache);
39
39
 
40
- extern VALUE ox_cache_get(Cache cache, const char *key, VALUE **slot);
40
+ extern VALUE ox_cache_get(Cache cache, const char *key, VALUE **slot, char **keyp);
41
41
 
42
42
  extern void ox_cache_print(Cache cache);
43
43
 
data/ext/ox/cache_test.c CHANGED
@@ -49,7 +49,7 @@ ox_cache_test() {
49
49
 
50
50
  ox_cache_new(&c);
51
51
  for (d = data; 0 != *d; d++) {
52
- v = ox_cache_get(c, *d, &slot);
52
+ v = ox_cache_get(c, *d, &slot, 0);
53
53
  if (Qundef == v) {
54
54
  if (0 == slot) {
55
55
  /*printf("*** failed to get a slot for %s\n", *d); */
data/ext/ox/gen_load.c CHANGED
@@ -326,7 +326,7 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
326
326
  VALUE *slot;
327
327
 
328
328
  if (Yes == pi->options->sym_keys) {
329
- if (Qundef == (sym = ox_cache_get(ox_symbol_cache, attrs->name, &slot))) {
329
+ if (Qundef == (sym = ox_cache_get(ox_symbol_cache, attrs->name, &slot, 0))) {
330
330
  #if HAS_ENCODING_SUPPORT
331
331
  if (0 != pi->options->rb_enc) {
332
332
  VALUE rstr = rb_str_new2(attrs->name);
@@ -438,7 +438,7 @@ add_instruct(PInfo pi, const char *name, Attr attrs, const char *content) {
438
438
  VALUE *slot;
439
439
 
440
440
  if (Yes == pi->options->sym_keys) {
441
- if (Qundef == (sym = ox_cache_get(ox_symbol_cache, attrs->name, &slot))) {
441
+ if (Qundef == (sym = ox_cache_get(ox_symbol_cache, attrs->name, &slot, 0))) {
442
442
  #if HAS_ENCODING_SUPPORT
443
443
  if (0 != pi->options->rb_enc) {
444
444
  VALUE rstr = rb_str_new2(attrs->name);
data/ext/ox/obj_load.c CHANGED
@@ -104,7 +104,7 @@ name2var(const char *name, void *encoding) {
104
104
 
105
105
  if ('0' <= *name && *name <= '9') {
106
106
  var_id = INT2NUM(atoi(name));
107
- } else if (Qundef == (var_id = ox_cache_get(ox_attr_cache, name, &slot))) {
107
+ } else if (Qundef == (var_id = ox_cache_get(ox_attr_cache, name, &slot, 0))) {
108
108
  #ifdef HAVE_RUBY_ENCODING_H
109
109
  if (0 != encoding) {
110
110
  VALUE rstr = rb_str_new2(name);
@@ -226,7 +226,7 @@ classname2class(const char *name, PInfo pi, VALUE base_class) {
226
226
  VALUE *slot;
227
227
  VALUE clas;
228
228
 
229
- if (Qundef == (clas = ox_cache_get(ox_class_cache, name, &slot))) {
229
+ if (Qundef == (clas = ox_cache_get(ox_class_cache, name, &slot, 0))) {
230
230
  char class_name[1024];
231
231
  char *s;
232
232
  const char *n = name;
@@ -483,7 +483,7 @@ add_text(PInfo pi, char *text, int closed) {
483
483
  VALUE sym;
484
484
  VALUE *slot;
485
485
 
486
- if (Qundef == (sym = ox_cache_get(ox_symbol_cache, text, &slot))) {
486
+ if (Qundef == (sym = ox_cache_get(ox_symbol_cache, text, &slot, 0))) {
487
487
  sym = str2sym(text, (void*)pi->options->rb_enc);
488
488
  *slot = sym;
489
489
  }
@@ -532,7 +532,7 @@ add_text(PInfo pi, char *text, int closed) {
532
532
  char *str = ALLOCA_N(char, str_size + 1);
533
533
 
534
534
  from_base64(text, (uchar*)str);
535
- if (Qundef == (sym = ox_cache_get(ox_symbol_cache, str, &slot))) {
535
+ if (Qundef == (sym = ox_cache_get(ox_symbol_cache, str, &slot, 0))) {
536
536
  sym = str2sym(str, (void*)pi->options->rb_enc);
537
537
  *slot = sym;
538
538
  }
data/ext/ox/ox.c CHANGED
@@ -95,6 +95,7 @@ VALUE ox_encoding_sym;
95
95
  VALUE ox_empty_string;
96
96
  VALUE ox_zero_fixnum;
97
97
 
98
+ VALUE ox_arg_error_class;
98
99
  VALUE ox_bag_clas;
99
100
  VALUE ox_cdata_clas;
100
101
  VALUE ox_comment_clas;
@@ -103,6 +104,7 @@ VALUE ox_doctype_clas;
103
104
  VALUE ox_document_clas;
104
105
  VALUE ox_element_clas;
105
106
  VALUE ox_instruct_clas;
107
+ VALUE ox_parse_error_class;
106
108
  VALUE ox_stringio_class;
107
109
  VALUE ox_struct_class;
108
110
  VALUE ox_time_class;
@@ -175,7 +177,7 @@ defuse_bom(char *xml, Options options) {
175
177
  options->rb_enc = ox_utf8_encoding;
176
178
  xml += 3;
177
179
  } else {
178
- rb_raise(rb_eArgError, "Invalid BOM in XML string.\n");
180
+ rb_raise(ox_parse_error_class, "Invalid BOM in XML string.\n");
179
181
  }
180
182
  break;
181
183
  #if 0
@@ -184,7 +186,7 @@ defuse_bom(char *xml, Options options) {
184
186
  options->rb_enc = ox_utf16be_encoding;
185
187
  xml += 2;
186
188
  } else {
187
- rb_raise(rb_eArgError, "Invalid BOM in XML string.\n");
189
+ rb_raise(ox_parse_error_class, "Invalid BOM in XML string.\n");
188
190
  }
189
191
  break;
190
192
  case 0xFF: /* UTF-16LE or UTF-32LE */
@@ -197,7 +199,7 @@ defuse_bom(char *xml, Options options) {
197
199
  xml += 2;
198
200
  }
199
201
  } else {
200
- rb_raise(rb_eArgError, "Invalid BOM in XML string.\n");
202
+ rb_raise(ox_parse_error_class, "Invalid BOM in XML string.\n");
201
203
  }
202
204
  break;
203
205
  case 0x00: /* UTF-32BE */
@@ -205,7 +207,7 @@ defuse_bom(char *xml, Options options) {
205
207
  options->rb_enc = ox_utf32be_encoding;
206
208
  xml += 4;
207
209
  } else {
208
- rb_raise(rb_eArgError, "Invalid BOM in XML string.\n");
210
+ rb_raise(ox_parse_error_class, "Invalid BOM in XML string.\n");
209
211
  }
210
212
  break;
211
213
  #endif
@@ -332,7 +334,7 @@ set_def_opts(VALUE self, VALUE opts) {
332
334
  } else if (limited_sym == v) {
333
335
  ox_default_options.mode = LimMode;
334
336
  } else {
335
- rb_raise(rb_eArgError, ":mode must be :object, :generic, :limited, or nil.\n");
337
+ rb_raise(ox_parse_error_class, ":mode must be :object, :generic, :limited, or nil.\n");
336
338
  }
337
339
 
338
340
  v = rb_hash_aref(opts, effort_sym);
@@ -345,7 +347,7 @@ set_def_opts(VALUE self, VALUE opts) {
345
347
  } else if (auto_define_sym == v) {
346
348
  ox_default_options.effort = AutoEffort;
347
349
  } else {
348
- rb_raise(rb_eArgError, ":effort must be :strict, :tolerant, :auto_define, or nil.\n");
350
+ rb_raise(ox_parse_error_class, ":effort must be :strict, :tolerant, :auto_define, or nil.\n");
349
351
  }
350
352
  for (o = ynos; 0 != o->attr; o++) {
351
353
  v = rb_hash_lookup(opts, o->sym);
@@ -356,7 +358,7 @@ set_def_opts(VALUE self, VALUE opts) {
356
358
  } else if (Qfalse == v) {
357
359
  *o->attr = No;
358
360
  } else {
359
- rb_raise(rb_eArgError, "%s must be true or false.\n", rb_id2name(SYM2ID(o->sym)));
361
+ rb_raise(ox_parse_error_class, "%s must be true or false.\n", rb_id2name(SYM2ID(o->sym)));
360
362
  }
361
363
  }
362
364
  return Qnil;
@@ -446,7 +448,7 @@ load(char *xml, int argc, VALUE *argv, VALUE self, VALUE encoding) {
446
448
  } else if (limited_sym == v) {
447
449
  options.mode = LimMode;
448
450
  } else {
449
- rb_raise(rb_eArgError, ":mode must be :generic, :object, or :limited.\n");
451
+ rb_raise(ox_parse_error_class, ":mode must be :generic, :object, or :limited.\n");
450
452
  }
451
453
  }
452
454
  if (Qnil != (v = rb_hash_lookup(h, effort_sym))) {
@@ -457,7 +459,7 @@ load(char *xml, int argc, VALUE *argv, VALUE self, VALUE encoding) {
457
459
  } else if (strict_sym == v) {
458
460
  options.effort = StrictEffort;
459
461
  } else {
460
- rb_raise(rb_eArgError, ":effort must be :strict, :tolerant, or :auto_define.\n");
462
+ rb_raise(ox_parse_error_class, ":effort must be :strict, :tolerant, or :auto_define.\n");
461
463
  }
462
464
  }
463
465
  if (Qnil != (v = rb_hash_lookup(h, trace_sym))) {
@@ -625,7 +627,7 @@ sax_parse(int argc, VALUE *argv, VALUE self) {
625
627
  int convert = 0;
626
628
 
627
629
  if (argc < 2) {
628
- rb_raise(rb_eArgError, "Wrong number of arguments to sax_parse.\n");
630
+ rb_raise(ox_parse_error_class, "Wrong number of arguments to sax_parse.\n");
629
631
  }
630
632
  if (3 <= argc && rb_cHash == rb_obj_class(argv[2])) {
631
633
  VALUE h = argv[2];
@@ -657,19 +659,19 @@ parse_dump_options(VALUE ropts, Options copts) {
657
659
 
658
660
  if (Qnil != (v = rb_hash_lookup(ropts, indent_sym))) {
659
661
  if (rb_cFixnum != rb_obj_class(v)) {
660
- rb_raise(rb_eArgError, ":indent must be a Fixnum.\n");
662
+ rb_raise(ox_parse_error_class, ":indent must be a Fixnum.\n");
661
663
  }
662
664
  copts->indent = NUM2INT(v);
663
665
  }
664
666
  if (Qnil != (v = rb_hash_lookup(ropts, trace_sym))) {
665
667
  if (rb_cFixnum != rb_obj_class(v)) {
666
- rb_raise(rb_eArgError, ":trace must be a Fixnum.\n");
668
+ rb_raise(ox_parse_error_class, ":trace must be a Fixnum.\n");
667
669
  }
668
670
  copts->trace = NUM2INT(v);
669
671
  }
670
672
  if (Qnil != (v = rb_hash_lookup(ropts, ox_encoding_sym))) {
671
673
  if (rb_cString != rb_obj_class(v)) {
672
- rb_raise(rb_eArgError, ":encoding must be a String.\n");
674
+ rb_raise(ox_parse_error_class, ":encoding must be a String.\n");
673
675
  }
674
676
  strncpy(copts->encoding, StringValuePtr(v), sizeof(copts->encoding) - 1);
675
677
  }
@@ -681,7 +683,7 @@ parse_dump_options(VALUE ropts, Options copts) {
681
683
  } else if (strict_sym == v) {
682
684
  copts->effort = StrictEffort;
683
685
  } else {
684
- rb_raise(rb_eArgError, ":effort must be :strict, :tolerant, or :auto_define.\n");
686
+ rb_raise(ox_parse_error_class, ":effort must be :strict, :tolerant, or :auto_define.\n");
685
687
  }
686
688
  }
687
689
  for (o = ynos; 0 != o->attr; o++) {
@@ -693,7 +695,7 @@ parse_dump_options(VALUE ropts, Options copts) {
693
695
  } else if (rb_cFalseClass == c) {
694
696
  *o->attr = No;
695
697
  } else {
696
- rb_raise(rb_eArgError, "%s must be true or false.\n", rb_id2name(SYM2ID(o->sym)));
698
+ rb_raise(ox_parse_error_class, "%s must be true or false.\n", rb_id2name(SYM2ID(o->sym)));
697
699
  }
698
700
  }
699
701
  }
@@ -846,6 +848,8 @@ void Init_ox() {
846
848
 
847
849
  ox_time_class = rb_const_get(rb_cObject, rb_intern("Time"));
848
850
  ox_date_class = rb_const_get(rb_cObject, rb_intern("Date"));
851
+ ox_parse_error_class = rb_const_get_at(Ox, rb_intern("ParseError"));
852
+ ox_arg_error_class = rb_const_get_at(Ox, rb_intern("ArgError"));
849
853
  ox_struct_class = rb_const_get(rb_cObject, rb_intern("Struct"));
850
854
  ox_stringio_class = rb_const_get(rb_cObject, rb_intern("StringIO"));
851
855
 
@@ -910,5 +914,5 @@ _ox_raise_error(const char *msg, const char *xml, const char *current, const cha
910
914
  xline++;
911
915
  }
912
916
  }
913
- rb_raise(rb_eSyntaxError, "%s at line %d, column %d [%s:%d]\n", msg, xline, col, file, line);
917
+ rb_raise(ox_parse_error_class, "%s at line %d, column %d [%s:%d]\n", msg, xline, col, file, line);
914
918
  }
data/ext/ox/ox.h CHANGED
@@ -272,12 +272,14 @@ extern VALUE ox_utf8_encoding;
272
272
  extern void *ox_utf8_encoding;
273
273
  #endif
274
274
 
275
+ extern VALUE ox_arg_error_class;
275
276
  extern VALUE ox_date_class;
276
277
  extern VALUE ox_empty_string;
277
278
  extern VALUE ox_encoding_sym;
279
+ extern VALUE ox_parse_error_class;
280
+ extern VALUE ox_stringio_class;
278
281
  extern VALUE ox_struct_class;
279
282
  extern VALUE ox_time_class;
280
- extern VALUE ox_stringio_class;
281
283
  extern VALUE ox_zero_fixnum;
282
284
 
283
285
  extern VALUE ox_document_clas;
data/ext/ox/sax.c CHANGED
@@ -202,11 +202,11 @@ is_white(char c) {
202
202
  }
203
203
 
204
204
  inline static VALUE
205
- str2sym(const char *str, SaxDrive dr) {
205
+ str2sym(const char *str, SaxDrive dr, char **strp) {
206
206
  VALUE *slot;
207
207
  VALUE sym;
208
208
 
209
- if (Qundef == (sym = ox_cache_get(ox_symbol_cache, str, &slot))) {
209
+ if (Qundef == (sym = ox_cache_get(ox_symbol_cache, str, &slot, strp))) {
210
210
  #if HAS_ENCODING_SUPPORT
211
211
  if (0 != dr->encoding) {
212
212
  VALUE rstr = rb_str_new2(str);
@@ -312,7 +312,7 @@ sax_drive_init(SaxDrive dr, VALUE handler, VALUE io, int convert) {
312
312
  }
313
313
  #endif
314
314
  } else {
315
- rb_raise(rb_eArgError, "sax_parser io argument must respond to readpartial() or read().\n");
315
+ rb_raise(ox_arg_error_class, "sax_parser io argument must respond to readpartial() or read().\n");
316
316
  }
317
317
  dr->buf = dr->base_buf;
318
318
  *dr->buf = '\0';
@@ -427,7 +427,7 @@ sax_drive_error(SaxDrive dr, const char *msg, int critical) {
427
427
  rb_funcall2(dr->handler, ox_error_id, 3, args);
428
428
  } else if (critical) {
429
429
  sax_drive_cleanup(dr);
430
- rb_raise(rb_eSyntaxError, "%s at line %d, column %d\n", msg, dr->line, dr->col);
430
+ rb_raise(ox_parse_error_class, "%s at line %d, column %d\n", msg, dr->line, dr->col);
431
431
  }
432
432
  }
433
433
 
@@ -748,17 +748,16 @@ read_comment(SaxDrive dr) {
748
748
  */
749
749
  static int
750
750
  read_element(SaxDrive dr) {
751
+ char *ename = 0;
751
752
  VALUE name = Qnil;
752
753
  const char *err;
753
754
  char c;
754
- char *ename = 0;
755
755
  int closed;
756
756
 
757
757
  if ('\0' == (c = read_name_token(dr))) {
758
758
  return -1;
759
759
  }
760
- ename = dr->str;
761
- name = str2sym(dr->str, dr);
760
+ name = str2sym(dr->str, dr, &ename);
762
761
  if (dr->has_start_element) {
763
762
  VALUE args[1];
764
763
 
@@ -794,7 +793,11 @@ read_element(SaxDrive dr) {
794
793
  if (0 != read_children(dr, 0)) {
795
794
  return -1;
796
795
  }
797
- /* no check of matching start and end as it would require coping the name */
796
+ if (0 != ename && 0 != strcmp(ename, dr->str)) {
797
+ //printf("*** ename: %s close: %s\n", ename, dr->str);
798
+ sax_drive_error(dr, "invalid format, element start and end names do not match", 1);
799
+ return -1;
800
+ }
798
801
  if (0 != dr->has_end_element) {
799
802
  VALUE args[1];
800
803
 
@@ -872,7 +875,7 @@ read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml) {
872
875
  }
873
876
  /* TBD use symbol cache */
874
877
  if (dr->has_attr || dr->has_attr_value) {
875
- name = str2sym(dr->str, dr);
878
+ name = str2sym(dr->str, dr, 0);
876
879
  }
877
880
  if (is_white(c)) {
878
881
  c = next_non_white(dr);
@@ -1275,7 +1278,7 @@ sax_value_as_sym(VALUE self) {
1275
1278
  if ('\0' == *dr->str) {
1276
1279
  return Qnil;
1277
1280
  }
1278
- return str2sym(dr->str, dr);
1281
+ return str2sym(dr->str, dr, 0);
1279
1282
  }
1280
1283
 
1281
1284
  static VALUE
@@ -1308,7 +1311,7 @@ sax_value_as_i(VALUE self) {
1308
1311
  if ('0' <= *s && *s <= '9') {
1309
1312
  n = n * 10 + (*s - '0');
1310
1313
  } else {
1311
- rb_raise(rb_eArgError, "Not a valid Fixnum.\n");
1314
+ rb_raise(ox_arg_error_class, "Not a valid Fixnum.\n");
1312
1315
  }
1313
1316
  }
1314
1317
  if (neg) {
data/lib/ox.rb CHANGED
@@ -87,7 +87,7 @@ module Ox
87
87
  end
88
88
 
89
89
  require 'ox/version'
90
- require 'ox/invalidpath'
90
+ require 'ox/error'
91
91
  require 'ox/hasattrs'
92
92
  require 'ox/node'
93
93
  require 'ox/comment'
data/lib/ox/error.rb ADDED
@@ -0,0 +1,22 @@
1
+
2
+ module Ox
3
+
4
+ class Error < StandardError
5
+ end # Error
6
+
7
+ # An Exception that is raised as a result of a parse error while parsing a XML document.
8
+ class ParseError < Error
9
+ end # ParseError
10
+
11
+ # An Exception that is raised as a result of an invalid argument.
12
+ class ArgError < Error
13
+ end # ArgError
14
+
15
+ # An Exception raised if a path is not valid.
16
+ class InvalidPath < Error
17
+ def initialize(path)
18
+ super("#{path.join('/')} is not a valid location.")
19
+ end
20
+ end # InvalidPath
21
+
22
+ end # Ox
data/lib/ox/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Ox
3
3
  # Current version of the module.
4
- VERSION = '1.8.6'
4
+ VERSION = '1.8.7'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ox
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.6
4
+ version: 1.8.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-07 00:00:00.000000000 Z
12
+ date: 2013-02-08 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! "A fast XML parser and object serializer that uses only standard C
15
15
  lib.\n \nOptimized XML (Ox), as the name implies was written to provide
@@ -29,9 +29,9 @@ files:
29
29
  - lib/ox/doctype.rb
30
30
  - lib/ox/document.rb
31
31
  - lib/ox/element.rb
32
+ - lib/ox/error.rb
32
33
  - lib/ox/hasattrs.rb
33
34
  - lib/ox/instruct.rb
34
- - lib/ox/invalidpath.rb
35
35
  - lib/ox/node.rb
36
36
  - lib/ox/sax.rb
37
37
  - lib/ox/version.rb
@@ -1,10 +0,0 @@
1
- module Ox
2
-
3
- #
4
- class InvalidPath < Exception
5
- def initialize(path)
6
- super("#{path.join('/')} is not a valid location.")
7
- end
8
-
9
- end # InvalidPath
10
- end # Ox