ox 1.2.10 → 1.2.11
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/ext/ox/parse.c +118 -1
- data/lib/ox/version.rb +1 -1
- data/test/func.rb +7 -0
- metadata +2 -2
data/ext/ox/parse.c
CHANGED
@@ -41,11 +41,13 @@ static void read_doctype(PInfo pi);
|
|
41
41
|
static void read_comment(PInfo pi);
|
42
42
|
static void read_element(PInfo pi);
|
43
43
|
static void read_text(PInfo pi);
|
44
|
+
//static void read_reduced_text(PInfo pi);
|
44
45
|
static void read_cdata(PInfo pi);
|
45
46
|
static char* read_name_token(PInfo pi);
|
46
47
|
static char* read_quoted_value(PInfo pi);
|
47
48
|
static int read_coded_char(PInfo pi);
|
48
49
|
static void next_non_white(PInfo pi);
|
50
|
+
static int collapse_special(char *str);
|
49
51
|
|
50
52
|
/* This XML parser is a single pass, destructive, callback parser. It is a
|
51
53
|
* single pass parse since it only make one pass over the characters in the
|
@@ -338,6 +340,11 @@ read_element(PInfo pi) {
|
|
338
340
|
// read value
|
339
341
|
next_non_white(pi);
|
340
342
|
ap->value = read_quoted_value(pi);
|
343
|
+
if (0 != strchr(ap->value, '&')) {
|
344
|
+
if (0 != collapse_special((char*)ap->value)) {
|
345
|
+
raise_error("invalid format, special character does not end with a semicolon", pi->str, pi->s);
|
346
|
+
}
|
347
|
+
}
|
341
348
|
ap++;
|
342
349
|
if (MAX_ATTRS <= (ap - attrs)) {
|
343
350
|
raise_error("too many attributes", pi->str, pi->s);
|
@@ -399,6 +406,8 @@ read_element(PInfo pi) {
|
|
399
406
|
pi->s = start;
|
400
407
|
//pi->s--;
|
401
408
|
read_text(pi);
|
409
|
+
//read_reduced_text(pi);
|
410
|
+
|
402
411
|
// to exit read_text with no errors the next character must be <
|
403
412
|
if ('/' == *(pi->s + 1) &&
|
404
413
|
0 == strncmp(ename, pi->s + 2, elen) &&
|
@@ -415,6 +424,63 @@ read_element(PInfo pi) {
|
|
415
424
|
|
416
425
|
static void
|
417
426
|
read_text(PInfo pi) {
|
427
|
+
char buf[MAX_TEXT_LEN];
|
428
|
+
char *b = buf;
|
429
|
+
char *alloc_buf = 0;
|
430
|
+
char *end = b + sizeof(buf) - 2;
|
431
|
+
char c;
|
432
|
+
int done = 0;
|
433
|
+
|
434
|
+
while (!done) {
|
435
|
+
c = *pi->s++;
|
436
|
+
switch(c) {
|
437
|
+
case '<':
|
438
|
+
done = 1;
|
439
|
+
pi->s--;
|
440
|
+
break;
|
441
|
+
case '\0':
|
442
|
+
raise_error("invalid format, document not terminated", pi->str, pi->s);
|
443
|
+
default:
|
444
|
+
if ('&' == c) {
|
445
|
+
c = read_coded_char(pi);
|
446
|
+
}
|
447
|
+
if (end <= b) {
|
448
|
+
unsigned long size;
|
449
|
+
|
450
|
+
if (0 == alloc_buf) {
|
451
|
+
size = sizeof(buf) * 2;
|
452
|
+
if (0 == (alloc_buf = (char*)malloc(size))) {
|
453
|
+
raise_error("text too long", pi->str, pi->s);
|
454
|
+
}
|
455
|
+
memcpy(alloc_buf, buf, b - buf);
|
456
|
+
b = alloc_buf + (b - buf);
|
457
|
+
} else {
|
458
|
+
unsigned long pos = b - alloc_buf;
|
459
|
+
|
460
|
+
size = (end - alloc_buf) * 2;
|
461
|
+
if (0 == (alloc_buf = (char*)realloc(alloc_buf, size))) {
|
462
|
+
raise_error("text too long", pi->str, pi->s);
|
463
|
+
}
|
464
|
+
b = alloc_buf + pos;
|
465
|
+
}
|
466
|
+
end = alloc_buf + size - 2;
|
467
|
+
}
|
468
|
+
*b++ = c;
|
469
|
+
break;
|
470
|
+
}
|
471
|
+
}
|
472
|
+
*b = '\0';
|
473
|
+
if (0 != alloc_buf) {
|
474
|
+
pi->pcb->add_text(pi, alloc_buf, ('/' == *(pi->s + 1)));
|
475
|
+
free(alloc_buf);
|
476
|
+
} else {
|
477
|
+
pi->pcb->add_text(pi, buf, ('/' == *(pi->s + 1)));
|
478
|
+
}
|
479
|
+
}
|
480
|
+
|
481
|
+
#if 0
|
482
|
+
static void
|
483
|
+
read_reduced_text(PInfo pi) {
|
418
484
|
char buf[MAX_TEXT_LEN];
|
419
485
|
char *b = buf;
|
420
486
|
char *alloc_buf = 0;
|
@@ -480,6 +546,7 @@ read_text(PInfo pi) {
|
|
480
546
|
pi->pcb->add_text(pi, buf, ('/' == *(pi->s + 1)));
|
481
547
|
}
|
482
548
|
}
|
549
|
+
#endif
|
483
550
|
|
484
551
|
static char*
|
485
552
|
read_name_token(PInfo pi) {
|
@@ -542,7 +609,7 @@ read_quoted_value(PInfo pi) {
|
|
542
609
|
for (; *pi->s != '"'; pi->s++) {
|
543
610
|
if ('\0' == *pi->s) {
|
544
611
|
raise_error("invalid format, document not terminated", pi->str, pi->s);
|
545
|
-
|
612
|
+
}
|
546
613
|
}
|
547
614
|
*pi->s = '\0'; // terminate value
|
548
615
|
pi->s++; // move past quote
|
@@ -599,3 +666,53 @@ read_coded_char(PInfo pi) {
|
|
599
666
|
return *pi->s;
|
600
667
|
}
|
601
668
|
|
669
|
+
static int
|
670
|
+
collapse_special(char *str) {
|
671
|
+
char *s = str;
|
672
|
+
char *b = str;
|
673
|
+
|
674
|
+
while ('\0' != *s) {
|
675
|
+
if ('&' == *s) {
|
676
|
+
int c;
|
677
|
+
char *end;
|
678
|
+
|
679
|
+
s++;
|
680
|
+
if ('#' == *s) {
|
681
|
+
c = (int)strtol(s, &end, 10);
|
682
|
+
if (';' != *end) {
|
683
|
+
return EDOM;
|
684
|
+
}
|
685
|
+
s = end + 1;
|
686
|
+
} else if (0 == strncasecmp(s, "lt;", 3)) {
|
687
|
+
c = '<';
|
688
|
+
s += 3;
|
689
|
+
} else if (0 == strncasecmp(s, "gt;", 3)) {
|
690
|
+
c = '>';
|
691
|
+
s += 3;
|
692
|
+
} else if (0 == strncasecmp(s, "amp;", 4)) {
|
693
|
+
c = '&';
|
694
|
+
s += 4;
|
695
|
+
} else if (0 == strncasecmp(s, "quot;", 5)) {
|
696
|
+
c = '"';
|
697
|
+
s += 5;
|
698
|
+
} else if (0 == strncasecmp(s, "apos;", 5)) {
|
699
|
+
c = '\'';
|
700
|
+
s += 5;
|
701
|
+
} else {
|
702
|
+
c = '?';
|
703
|
+
while (';' != *s++) {
|
704
|
+
if ('\0' == *s) {
|
705
|
+
return EDOM;
|
706
|
+
}
|
707
|
+
}
|
708
|
+
s++;
|
709
|
+
}
|
710
|
+
*b++ = (char)c;
|
711
|
+
} else {
|
712
|
+
*b++ = *s++;
|
713
|
+
}
|
714
|
+
}
|
715
|
+
*b = '\0';
|
716
|
+
|
717
|
+
return 0;
|
718
|
+
}
|
data/lib/ox/version.rb
CHANGED
data/test/func.rb
CHANGED
@@ -223,6 +223,13 @@ class Func < ::Test::Unit::TestCase
|
|
223
223
|
dump_and_load(s.new(2, 4, 10, 20), false)
|
224
224
|
end
|
225
225
|
|
226
|
+
def test_bad_format
|
227
|
+
xml = "<?xml version=\"1.0\"?>\n<tag>test</tagz>\n"
|
228
|
+
assert_raise(EncodingError) {
|
229
|
+
Ox.load(xml, :mode => :generic, :trace => 0)
|
230
|
+
}
|
231
|
+
end
|
232
|
+
|
226
233
|
def test_array_multi
|
227
234
|
dump_and_load([nil, true, false, 3, 'z', 7.9, 'a&b', :xyz, Time.now, (-1..7)], false)
|
228
235
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: ox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.2.
|
5
|
+
version: 1.2.11
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Peter Ohler
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-08-
|
13
|
+
date: 2011-08-30 00:00:00 +09:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|