ox 1.4.2 → 1.4.3
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 +3 -3
- data/ext/ox/ox.c +3 -3
- data/ext/ox/parse.c +54 -10
- data/ext/ox/sax.c +38 -11
- data/lib/ox/version.rb +1 -1
- data/test/bug3.rb +11 -13
- data/test/func.rb +18 -0
- data/test/sax_example.rb +37 -0
- data/test/sax_test.rb +2 -1
- metadata +30 -23
- data/test/big.rb +0 -24
- data/test/bug4.rb +0 -11
data/README.md
CHANGED
@@ -26,10 +26,10 @@ A fast XML parser and Object marshaller as a Ruby gem.
|
|
26
26
|
|
27
27
|
## <a name="release">Release Notes</a>
|
28
28
|
|
29
|
-
### Release 1.4.
|
29
|
+
### Release 1.4.3
|
30
30
|
|
31
|
-
-
|
32
|
-
-
|
31
|
+
- In tolerant mode attribute values can now be surrounded by single quotes.
|
32
|
+
- In tolerant mode attribute values can now be without quotes as long as they do not contain spaces and are followed by a white space character.
|
33
33
|
|
34
34
|
## <a name="description">Description</a>
|
35
35
|
|
data/ext/ox/ox.c
CHANGED
@@ -355,16 +355,16 @@ load(char *xml, int argc, VALUE *argv, VALUE self) {
|
|
355
355
|
obj = parse(xml, ox_obj_callbacks, 0, options.trace, options.effort);
|
356
356
|
break;
|
357
357
|
case GenMode:
|
358
|
-
obj = parse(xml, ox_gen_callbacks, 0, options.trace,
|
358
|
+
obj = parse(xml, ox_gen_callbacks, 0, options.trace, options.effort);
|
359
359
|
break;
|
360
360
|
case LimMode:
|
361
|
-
obj = parse(xml, ox_limited_callbacks, 0, options.trace,
|
361
|
+
obj = parse(xml, ox_limited_callbacks, 0, options.trace, options.effort);
|
362
362
|
break;
|
363
363
|
case NoMode:
|
364
364
|
obj = parse(xml, ox_nomode_callbacks, 0, options.trace, options.effort);
|
365
365
|
break;
|
366
366
|
default:
|
367
|
-
obj = parse(xml, ox_gen_callbacks, 0, options.trace,
|
367
|
+
obj = parse(xml, ox_gen_callbacks, 0, options.trace, options.effort);
|
368
368
|
break;
|
369
369
|
}
|
370
370
|
free(xml);
|
data/ext/ox/parse.c
CHANGED
@@ -78,6 +78,23 @@ next_non_white(PInfo pi) {
|
|
78
78
|
}
|
79
79
|
}
|
80
80
|
|
81
|
+
inline static void
|
82
|
+
next_white(PInfo pi) {
|
83
|
+
for (; 1; pi->s++) {
|
84
|
+
switch(*pi->s) {
|
85
|
+
case ' ':
|
86
|
+
case '\t':
|
87
|
+
case '\f':
|
88
|
+
case '\n':
|
89
|
+
case '\r':
|
90
|
+
case '\0':
|
91
|
+
return;
|
92
|
+
default:
|
93
|
+
break;
|
94
|
+
}
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
81
98
|
VALUE
|
82
99
|
parse(char *xml, ParseCallbacks pcb, char **endp, int trace, Effort effort) {
|
83
100
|
struct _PInfo pi;
|
@@ -599,26 +616,53 @@ read_cdata(PInfo pi) {
|
|
599
616
|
}
|
600
617
|
}
|
601
618
|
|
619
|
+
inline static void
|
620
|
+
next_non_token(PInfo pi) {
|
621
|
+
for (; 1; pi->s++) {
|
622
|
+
switch(*pi->s) {
|
623
|
+
case ' ':
|
624
|
+
case '\t':
|
625
|
+
case '\f':
|
626
|
+
case '\n':
|
627
|
+
case '\r':
|
628
|
+
case '/':
|
629
|
+
case '>':
|
630
|
+
return;
|
631
|
+
default:
|
632
|
+
break;
|
633
|
+
}
|
634
|
+
}
|
635
|
+
}
|
636
|
+
|
602
637
|
/* Assume the value starts immediately and goes until the quote character is
|
603
638
|
* reached again. Do not read the character after the terminating quote.
|
604
639
|
*/
|
605
640
|
static char*
|
606
641
|
read_quoted_value(PInfo pi) {
|
607
|
-
char *value;
|
642
|
+
char *value = 0;
|
608
643
|
|
609
|
-
if ('"'
|
644
|
+
if ('"' == *pi->s || ('\'' == *pi->s && StrictEffort != pi->effort)) {
|
645
|
+
char term = *pi->s;
|
646
|
+
|
647
|
+
pi->s++; // skip quote character
|
648
|
+
value = pi->s;
|
649
|
+
for (; *pi->s != term; pi->s++) {
|
650
|
+
if ('\0' == *pi->s) {
|
651
|
+
raise_error("invalid format, document not terminated", pi->str, pi->s);
|
652
|
+
}
|
653
|
+
}
|
654
|
+
*pi->s = '\0'; // terminate value
|
655
|
+
pi->s++; // move past quote
|
656
|
+
} else if (StrictEffort == pi->effort) {
|
610
657
|
raise_error("invalid format, expected a quote character", pi->str, pi->s);
|
611
|
-
}
|
612
|
-
|
613
|
-
|
614
|
-
for (; *pi->s != '"'; pi->s++) {
|
658
|
+
} else {
|
659
|
+
value = pi->s;
|
660
|
+
next_white(pi);
|
615
661
|
if ('\0' == *pi->s) {
|
616
662
|
raise_error("invalid format, document not terminated", pi->str, pi->s);
|
617
|
-
|
663
|
+
}
|
664
|
+
*pi->s++ = '\0'; // terminate value
|
618
665
|
}
|
619
|
-
*pi->s = '\0'; // terminate value
|
620
|
-
pi->s++; // move past quote
|
621
|
-
|
622
666
|
return value;
|
623
667
|
}
|
624
668
|
|
data/ext/ox/sax.c
CHANGED
@@ -131,6 +131,29 @@ next_non_white(SaxDrive dr) {
|
|
131
131
|
return '\0';
|
132
132
|
}
|
133
133
|
|
134
|
+
/* Starts by reading a character so it is safe to use with an empty or
|
135
|
+
* compacted buffer.
|
136
|
+
*/
|
137
|
+
inline static char
|
138
|
+
next_white(SaxDrive dr) {
|
139
|
+
char c;
|
140
|
+
|
141
|
+
while ('\0' != (c = sax_drive_get(dr))) {
|
142
|
+
switch(c) {
|
143
|
+
case ' ':
|
144
|
+
case '\t':
|
145
|
+
case '\f':
|
146
|
+
case '\n':
|
147
|
+
case '\r':
|
148
|
+
case '\0':
|
149
|
+
return c;
|
150
|
+
default:
|
151
|
+
break;
|
152
|
+
}
|
153
|
+
}
|
154
|
+
return '\0';
|
155
|
+
}
|
156
|
+
|
134
157
|
inline static int
|
135
158
|
is_white(char c) {
|
136
159
|
switch(c) {
|
@@ -727,19 +750,23 @@ read_quoted_value(SaxDrive dr) {
|
|
727
750
|
if (is_white(c)) {
|
728
751
|
c = next_non_white(dr);
|
729
752
|
}
|
730
|
-
if ('"'
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
753
|
+
if ('"' == c || '\'' == c) {
|
754
|
+
char term = c;
|
755
|
+
|
756
|
+
dr->str = dr->cur;
|
757
|
+
while (term != (c = sax_drive_get(dr))) {
|
758
|
+
if ('\0' == c) {
|
759
|
+
sax_drive_error(dr, "invalid format, quoted value not terminated", 1);
|
760
|
+
return -1;
|
761
|
+
}
|
739
762
|
}
|
740
|
-
}
|
763
|
+
} else {
|
764
|
+
dr->str = dr->cur - 1;
|
765
|
+
if ('\0' == (c = next_white(dr))) {
|
766
|
+
sax_drive_error(dr, "invalid format, attibute value not in quotes", 1);
|
767
|
+
}
|
768
|
+
}
|
741
769
|
*(dr->cur - 1) = '\0'; // terminate value
|
742
|
-
|
743
770
|
return 0;
|
744
771
|
}
|
745
772
|
|
data/lib/ox/version.rb
CHANGED
data/test/bug3.rb
CHANGED
@@ -3,21 +3,19 @@
|
|
3
3
|
$: << '../lib'
|
4
4
|
$: << '../ext'
|
5
5
|
|
6
|
-
if __FILE__ == $0
|
7
|
-
if (i = ARGV.index('-I'))
|
8
|
-
x,path = ARGV.slice!(i, 2)
|
9
|
-
$: << path
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
6
|
require 'ox'
|
14
7
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
8
|
+
def name_it()
|
9
|
+
begin
|
10
|
+
"x".foo
|
11
|
+
rescue Exception => e
|
12
|
+
#puts e.message
|
13
|
+
xml = Ox.dump(e, effort: :tolerant)
|
14
|
+
puts xml
|
15
|
+
o = Ox.load(xml, mode: :object)
|
16
|
+
puts o.message
|
17
|
+
puts Ox.dump(e)
|
20
18
|
end
|
21
19
|
end
|
22
20
|
|
23
|
-
|
21
|
+
name_it()
|
data/test/func.rb
CHANGED
@@ -222,6 +222,24 @@ class Func < ::Test::Unit::TestCase
|
|
222
222
|
assert_equal('html', doc.nodes[0].value)
|
223
223
|
end
|
224
224
|
|
225
|
+
def test_quote_value
|
226
|
+
xml = %{<top name="Pete"/>}
|
227
|
+
doc = Ox.parse(xml)
|
228
|
+
assert_equal('Pete', doc.attributes[:name])
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_single_quote
|
232
|
+
xml = %{<top name='Pete'/>}
|
233
|
+
doc = Ox.load(xml, :effort => :tolerant)
|
234
|
+
assert_equal('Pete', doc.attributes[:name])
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_no_quote
|
238
|
+
xml = %{<top name=Pete />}
|
239
|
+
doc = Ox.load(xml, :effort => :tolerant)
|
240
|
+
assert_equal('Pete', doc.attributes[:name])
|
241
|
+
end
|
242
|
+
|
225
243
|
def test_class
|
226
244
|
dump_and_load(Bag, false)
|
227
245
|
end
|
data/test/sax_example.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby -wW1
|
2
|
+
|
3
|
+
$: << '../lib'
|
4
|
+
$: << '../ext'
|
5
|
+
|
6
|
+
require 'stringio'
|
7
|
+
require 'ox'
|
8
|
+
|
9
|
+
class Sample < ::Ox::Sax
|
10
|
+
def start_element(name); puts "start: #{name}"; end
|
11
|
+
def end_element(name); puts "end: #{name}"; end
|
12
|
+
def attr(name, value); puts " #{name} => #{value}"; end
|
13
|
+
def text(value); puts "text #{value}"; end
|
14
|
+
end
|
15
|
+
|
16
|
+
io = StringIO.new(%{
|
17
|
+
<top name="sample">
|
18
|
+
<middle name="second">
|
19
|
+
<bottom name="third"/>
|
20
|
+
</middle>
|
21
|
+
</top>
|
22
|
+
})
|
23
|
+
|
24
|
+
handler = Sample.new()
|
25
|
+
Ox.sax_parse(handler, io)
|
26
|
+
|
27
|
+
# outputs
|
28
|
+
# start: top
|
29
|
+
# name => sample
|
30
|
+
# start: middle
|
31
|
+
# name => second
|
32
|
+
# start: bottom
|
33
|
+
# name => third
|
34
|
+
# end: bottom
|
35
|
+
# end: middle
|
36
|
+
# end: top
|
37
|
+
|
data/test/sax_test.rb
CHANGED
@@ -127,10 +127,11 @@ encoding = "UTF-8" ?>},
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def test_sax_element_attrs
|
130
|
-
parse_compare(%{<top x="57" y=
|
130
|
+
parse_compare(%{<top x="57" y='42' z=33 />},
|
131
131
|
[[:start_element, :top],
|
132
132
|
[:attr, :x, "57"],
|
133
133
|
[:attr, :y, "42"],
|
134
|
+
[:attr, :z, "33"],
|
134
135
|
[:end_element, :top]])
|
135
136
|
end
|
136
137
|
|
metadata
CHANGED
@@ -1,24 +1,28 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: ox
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.2
|
3
|
+
version: !ruby/object:Gem::Version
|
5
4
|
prerelease:
|
5
|
+
version: 1.4.3
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Peter Ohler
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
12
|
+
|
13
|
+
date: 2011-12-08 00:00:00 +09:00
|
14
|
+
default_executable:
|
13
15
|
dependencies: []
|
16
|
+
|
14
17
|
description: A fast XML parser and object serializer that uses only standard C lib.
|
15
18
|
email: peter@ohler.com
|
16
19
|
executables: []
|
17
|
-
|
20
|
+
|
21
|
+
extensions:
|
18
22
|
- ext/ox/extconf.rb
|
19
|
-
extra_rdoc_files:
|
23
|
+
extra_rdoc_files:
|
20
24
|
- README.md
|
21
|
-
files:
|
25
|
+
files:
|
22
26
|
- lib/ox/bag.rb
|
23
27
|
- lib/ox/cdata.rb
|
24
28
|
- lib/ox/comment.rb
|
@@ -47,11 +51,9 @@ files:
|
|
47
51
|
- ext/ox/parse.c
|
48
52
|
- ext/ox/sax.c
|
49
53
|
- test/bench.rb
|
50
|
-
- test/big.rb
|
51
54
|
- test/bug1.rb
|
52
55
|
- test/bug2.rb
|
53
56
|
- test/bug3.rb
|
54
|
-
- test/bug4.rb
|
55
57
|
- test/cache16_test.rb
|
56
58
|
- test/cache8_test.rb
|
57
59
|
- test/cache_test.rb
|
@@ -79,36 +81,41 @@ files:
|
|
79
81
|
- test/perf_sax.rb
|
80
82
|
- test/perf_write.rb
|
81
83
|
- test/sample.rb
|
84
|
+
- test/sax_example.rb
|
82
85
|
- test/sax_test.rb
|
83
86
|
- test/test.rb
|
84
87
|
- test/Sample.graffle
|
85
88
|
- LICENSE
|
86
89
|
- README.md
|
90
|
+
has_rdoc: true
|
87
91
|
homepage: https://github.com/ohler55/ox
|
88
92
|
licenses: []
|
93
|
+
|
89
94
|
post_install_message:
|
90
|
-
rdoc_options:
|
95
|
+
rdoc_options:
|
91
96
|
- --main
|
92
97
|
- README.md
|
93
|
-
require_paths:
|
98
|
+
require_paths:
|
94
99
|
- lib
|
95
100
|
- ext
|
96
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
102
|
none: false
|
98
|
-
requirements:
|
99
|
-
- -
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
version:
|
102
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: "0"
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
108
|
none: false
|
104
|
-
requirements:
|
105
|
-
- -
|
106
|
-
- !ruby/object:Gem::Version
|
107
|
-
version:
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: "0"
|
108
113
|
requirements: []
|
114
|
+
|
109
115
|
rubyforge_project: ox
|
110
|
-
rubygems_version: 1.
|
116
|
+
rubygems_version: 1.6.2
|
111
117
|
signing_key:
|
112
118
|
specification_version: 3
|
113
119
|
summary: A fast XML parser and object serializer.
|
114
120
|
test_files: []
|
121
|
+
|
data/test/big.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -wW1
|
2
|
-
|
3
|
-
$: << '../lib'
|
4
|
-
$: << '../ext'
|
5
|
-
|
6
|
-
if __FILE__ == $0
|
7
|
-
while (i = ARGV.index('-I'))
|
8
|
-
x,path = ARGV.slice!(i, 2)
|
9
|
-
$: << path
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
require 'ox'
|
14
|
-
|
15
|
-
def dump(cnt = 10000)
|
16
|
-
h = { }
|
17
|
-
cnt.times do |i|
|
18
|
-
h[i] = [i * 2, "this is #{i}"]
|
19
|
-
end
|
20
|
-
xml = Ox.dump(h)
|
21
|
-
puts "size: #{xml.size}"
|
22
|
-
end
|
23
|
-
|
24
|
-
dump(200000)
|