libxml-ruby 2.6.0 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,16 +1,10 @@
1
1
  #ifndef __RXML_WRITER__
2
- # define __RXML_WRITER__
2
+ #define __RXML_WRITER__
3
3
 
4
- # include <libxml/xmlversion.h>
5
-
6
- # ifdef LIBXML_WRITER_ENABLED
7
-
8
- # include <libxml/xmlwriter.h>
4
+ #ifdef LIBXML_WRITER_ENABLED
5
+ #include <libxml/xmlwriter.h>
6
+ #endif
9
7
 
10
8
  extern VALUE cXMLWriter;
11
-
12
9
  void rxml_init_writer(void);
13
-
14
- # endif /* LIBXML_WRITER_ENABLED */
15
-
16
- #endif /* __RXML_WRITER__ */
10
+ #endif
@@ -59,9 +59,10 @@ VALUE rxml_xpath_object_wrap(xmlDocPtr xdoc, xmlXPathObjectPtr xpop)
59
59
  {
60
60
  int i;
61
61
  rxml_xpath_object *rxpop = ALLOC(rxml_xpath_object);
62
+ /* Make sure Ruby's GC can find the array in the stack */
63
+ VALUE nsnodes = rb_ary_new();
62
64
  rxpop->xdoc =xdoc;
63
65
  rxpop->xpop = xpop;
64
- rxpop->nsnodes = rb_ary_new();
65
66
 
66
67
  /* Find all the extra namespace nodes and wrap them. */
67
68
  if (xpop->nodesetval && xpop->nodesetval->nodeNr)
@@ -83,11 +84,12 @@ VALUE rxml_xpath_object_wrap(xmlDocPtr xdoc, xmlXPathObjectPtr xpop)
83
84
  namespace nodes will not be freed */
84
85
  ns = rxml_namespace_wrap((xmlNsPtr)xnode);
85
86
  RDATA(ns)->dfree = (RUBY_DATA_FUNC)rxml_xpath_namespace_free;
86
- rb_ary_push(rxpop->nsnodes, ns);
87
+ rb_ary_push(nsnodes, ns);
87
88
  }
88
89
  }
89
90
  }
90
91
 
92
+ rxpop->nsnodes = nsnodes;
91
93
  return Data_Wrap_Struct(cXMLXPathObject, rxml_xpath_object_mark, rxml_xpath_object_free, rxpop);
92
94
  }
93
95
 
@@ -52,6 +52,8 @@ module LibXML
52
52
  self.int2 == other.int2 and
53
53
  self.ctxt == other.ctxt and
54
54
  self.node == other.node
55
+ rescue
56
+ false
55
57
  end
56
58
 
57
59
  def level_to_s
@@ -90,4 +92,4 @@ module LibXML
90
92
  end
91
93
  end
92
94
 
93
- LibXML::XML::Error.set_handler(&LibXML::XML::Error::VERBOSE_HANDLER)
95
+ LibXML::XML::Error.set_handler(&LibXML::XML::Error::VERBOSE_HANDLER)
@@ -0,0 +1,9 @@
1
+ require './test_helper'
2
+
3
+ 1000000.times do
4
+ doc = XML::Document.string('<foo><bar/><baz/></foo>')
5
+ #puts doc.root
6
+ node = doc.root.first.remove!
7
+ doc.root.last.next = node
8
+ node = nil
9
+ end
@@ -63,6 +63,10 @@ class TestDtd < Test::Unit::TestCase
63
63
  assert(@doc.validate(dtd))
64
64
  end
65
65
 
66
+ def test_node_type
67
+ assert_equal(XML::Node::DTD_NODE, dtd.node_type)
68
+ end
69
+
66
70
  def test_invalid
67
71
  new_node = XML::Node.new('invalid', 'this will mess up validation')
68
72
  @doc.root << new_node
@@ -30,7 +30,7 @@ class HTMLParserTest < Test::Unit::TestCase
30
30
  XML::HTMLParser.file(nil)
31
31
  end
32
32
 
33
- assert_equal("can't convert nil into String", error.to_s)
33
+ assert_match(/nil into String/, error.to_s)
34
34
  end
35
35
 
36
36
  def test_io
@@ -150,4 +150,4 @@ class HTMLParserTest < Test::Unit::TestCase
150
150
  doc = XML::HTMLParser.file('model/ruby-lang.html').parse
151
151
  end
152
152
  end
153
- end
153
+ end
@@ -59,7 +59,7 @@ class TestParser < Test::Unit::TestCase
59
59
  XML::Parser.file(nil)
60
60
  end
61
61
 
62
- assert_equal("can't convert nil into String", error.to_s)
62
+ assert_match(/nil into String/, error.to_s)
63
63
  end
64
64
 
65
65
  def test_file_encoding
@@ -353,4 +353,29 @@ class TestParser < Test::Unit::TestCase
353
353
  assert_instance_of(XML::Document, doc)
354
354
  assert_instance_of(XML::Parser::Context, parser.context)
355
355
  end
356
- end
356
+
357
+ def test_errors_from_background_thread
358
+ errors = []
359
+ background_errors = []
360
+
361
+ begin
362
+ XML::Error.set_handler do |error|
363
+ errors << error
364
+ end
365
+ parser = XML::Parser.string("<moo>")
366
+
367
+ thread = Thread.new do
368
+ XML::Error.set_handler do |error|
369
+ background_errors << error
370
+ end
371
+ parser.parse rescue nil
372
+ end
373
+ thread.join
374
+ ensure
375
+ XML::Error.set_handler(&XML::Error::QUIET_HANDLER)
376
+ end
377
+
378
+ assert_equal(errors.size, 0)
379
+ assert_equal(background_errors.size, 1)
380
+ end
381
+ end
@@ -0,0 +1,384 @@
1
+ # encoding: UTF-8
2
+
3
+ require './test_helper'
4
+ require 'test/unit'
5
+ require 'stringio'
6
+
7
+ class TestParser < Test::Unit::TestCase
8
+ def setup
9
+ XML::Error.set_handler(&XML::Error::QUIET_HANDLER)
10
+ end
11
+
12
+ def teardown
13
+ GC.start
14
+ GC.start
15
+ GC.start
16
+ end
17
+
18
+ # ----- Sources -------
19
+ def test_document
20
+ file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.utf-8.xml'))
21
+ parser = XML::Parser.file(file)
22
+ doc = parser.parse
23
+
24
+ parser = XML::Parser.document(doc)
25
+
26
+ doc = parser.parse
27
+
28
+ assert_instance_of(XML::Document, doc)
29
+ assert_instance_of(XML::Parser::Context, parser.context)
30
+ end
31
+
32
+ def test_nil_document
33
+ error = assert_raise(TypeError) do
34
+ XML::Parser.document(nil)
35
+ end
36
+
37
+ assert_equal("Must pass an XML::Document object", error.to_s)
38
+ end
39
+
40
+ def test_file
41
+ file = File.expand_path(File.join(File.dirname(__FILE__), 'model/rubynet.xml'))
42
+
43
+ parser = XML::Parser.file(file)
44
+ doc = parser.parse
45
+ assert_instance_of(XML::Document, doc)
46
+ assert_instance_of(XML::Parser::Context, parser.context)
47
+ end
48
+
49
+ def test_noexistent_file
50
+ error = assert_raise(XML::Error) do
51
+ XML::Parser.file('i_dont_exist.xml')
52
+ end
53
+
54
+ assert_equal('Warning: failed to load external entity "i_dont_exist.xml".', error.to_s)
55
+ end
56
+
57
+ def test_nil_file
58
+ error = assert_raise(TypeError) do
59
+ XML::Parser.file(nil)
60
+ end
61
+
62
+ assert_match(/nil into String/, error.to_s)
63
+ end
64
+
65
+ def test_file_encoding
66
+ file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.utf-8.xml'))
67
+ parser = XML::Parser.file(file, :encoding => XML::Encoding::ISO_8859_1)
68
+
69
+ error = assert_raise(XML::Error) do
70
+ doc = parser.parse
71
+ end
72
+
73
+ assert(error.to_s.match(/Fatal error: Extra content at the end of the document/))
74
+
75
+ parser = XML::Parser.file(file, :encoding => XML::Encoding::UTF_8)
76
+ doc = parser.parse
77
+ assert_not_nil(doc)
78
+ end
79
+
80
+ def test_file_base_uri
81
+ file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.utf-8.xml'))
82
+
83
+ parser = XML::Parser.file(file)
84
+ doc = parser.parse
85
+ assert(doc.child.base_uri.match(/test\/model\/bands.utf-8.xml/))
86
+
87
+ parser = XML::Parser.file(file, :base_uri => "http://libxml.org")
88
+ doc = parser.parse
89
+ assert(doc.child.base_uri.match(/test\/model\/bands.utf-8.xml/))
90
+ end
91
+
92
+ def test_io
93
+ File.open(File.join(File.dirname(__FILE__), 'model/rubynet.xml')) do |io|
94
+ parser = XML::Parser.io(io)
95
+ assert_instance_of(XML::Parser, parser)
96
+
97
+ doc = parser.parse
98
+ assert_instance_of(XML::Document, doc)
99
+ assert_instance_of(XML::Parser::Context, parser.context)
100
+ end
101
+ end
102
+
103
+ def test_io_gc
104
+ # Test that the reader keeps a reference
105
+ # to the io object
106
+ file = File.open(File.join(File.dirname(__FILE__), 'model/rubynet.xml'))
107
+ parser = XML::Parser.io(file)
108
+ file = nil
109
+ GC.start
110
+ assert(parser.parse)
111
+ end
112
+
113
+ def test_nil_io
114
+ error = assert_raise(TypeError) do
115
+ XML::Parser.io(nil)
116
+ end
117
+
118
+ assert_equal("Must pass in an IO object", error.to_s)
119
+ end
120
+
121
+ def test_string_io
122
+ data = File.read(File.join(File.dirname(__FILE__), 'model/rubynet.xml'))
123
+ string_io = StringIO.new(data)
124
+ parser = XML::Parser.io(string_io)
125
+
126
+ doc = parser.parse
127
+ assert_instance_of(XML::Document, doc)
128
+ assert_instance_of(XML::Parser::Context, parser.context)
129
+ end
130
+
131
+ def test_string_io_thread
132
+ thread = Thread.new do
133
+ data = File.read(File.join(File.dirname(__FILE__), 'model/rubynet.xml'))
134
+ string_io = StringIO.new(data)
135
+ parser = XML::Parser.io(string_io)
136
+
137
+ doc = parser.parse
138
+ assert_instance_of(XML::Document, doc)
139
+ assert_instance_of(XML::Parser::Context, parser.context)
140
+ end
141
+
142
+ thread.join
143
+ assert(true)
144
+ end
145
+
146
+ def test_string
147
+ str = '<ruby_array uga="booga" foo="bar"><fixnum>one</fixnum><fixnum>two</fixnum></ruby_array>'
148
+
149
+ parser = XML::Parser.string(str)
150
+ assert_instance_of(XML::Parser, parser)
151
+
152
+ doc = parser.parse
153
+ assert_instance_of(XML::Document, doc)
154
+ assert_instance_of(XML::Parser::Context, parser.context)
155
+ end
156
+
157
+ def test_nil_string
158
+ error = assert_raise(TypeError) do
159
+ XML::Parser.string(nil)
160
+ end
161
+
162
+ assert_equal("wrong argument type nil (expected String)", error.to_s)
163
+ end
164
+
165
+ def test_string_options
166
+ xml = <<-EOS
167
+ <!DOCTYPE foo [<!ENTITY foo 'bar'>]>
168
+ <test>
169
+ <cdata><![CDATA[something]]></cdata>
170
+ <entity>&foo;</entity>
171
+ </test>
172
+ EOS
173
+
174
+ XML::default_substitute_entities = false
175
+
176
+ # Parse normally
177
+ parser = XML::Parser.string(xml)
178
+ doc = parser.parse
179
+ assert_nil(doc.child.base_uri)
180
+
181
+ # Cdata section should be cdata nodes
182
+ node = doc.find_first('/test/cdata').child
183
+ assert_equal(XML::Node::CDATA_SECTION_NODE, node.node_type)
184
+
185
+ # Entities should not be subtituted
186
+ node = doc.find_first('/test/entity')
187
+ assert_equal('&foo;', node.child.to_s)
188
+
189
+ # Parse with options
190
+ parser = XML::Parser.string(xml, :base_uri => 'http://libxml.rubyforge.org',
191
+ :options => XML::Parser::Options::NOCDATA | XML::Parser::Options::NOENT)
192
+ doc = parser.parse
193
+ assert_equal(doc.child.base_uri, 'http://libxml.rubyforge.org')
194
+
195
+ # Cdata section should be text nodes
196
+ node = doc.find_first('/test/cdata').child
197
+ assert_equal(XML::Node::TEXT_NODE, node.node_type)
198
+
199
+ # Entities should be subtituted
200
+ node = doc.find_first('/test/entity')
201
+ assert_equal('bar', node.child.to_s)
202
+ end
203
+
204
+ def test_string_encoding
205
+ # ISO_8859_1:
206
+ # ö - f6 in hex, \366 in octal
207
+ # ü - fc in hex, \374 in octal
208
+
209
+ xml = <<-EOS
210
+ <bands>
211
+ <metal>m\366tley_cr\374e</metal>
212
+ </bands>
213
+ EOS
214
+
215
+ # Parse as UTF_8
216
+ parser = XML::Parser.string(xml, :encoding => XML::Encoding::UTF_8)
217
+
218
+ error = assert_raise(XML::Error) do
219
+ doc = parser.parse
220
+ end
221
+
222
+ assert_equal("Fatal error: Input is not proper UTF-8, indicate encoding !\nBytes: 0xF6 0x74 0x6C 0x65 at :2.",
223
+ error.to_s)
224
+
225
+ # Parse as ISO_8859_1:
226
+ parser = XML::Parser.string(xml, :encoding => XML::Encoding::ISO_8859_1)
227
+ doc = parser.parse
228
+ node = doc.find_first('//metal')
229
+ if defined?(Encoding)
230
+ assert_equal(Encoding::UTF_8, node.content.encoding)
231
+ assert_equal("m\303\266tley_cr\303\274e", node.content)
232
+ else
233
+ assert_equal("m\303\266tley_cr\303\274e", node.content)
234
+ end
235
+ end
236
+
237
+ def test_fd_gc
238
+ # Test opening # of documents up to the file limit for the OS.
239
+ # Ideally it should run until libxml emits a warning,
240
+ # thereby knowing we've done a GC sweep. For the time being,
241
+ # re-open the same doc `limit descriptors` times.
242
+ # If we make it to the end, then we've succeeded,
243
+ # otherwise an exception will be thrown.
244
+ XML::Error.set_handler {|error|}
245
+
246
+ max_fd = if RUBY_PLATFORM.match(/mswin32|mingw/i)
247
+ 500
248
+ else
249
+ (`ulimit -n`.chomp.to_i) + 1
250
+ end
251
+
252
+ file = File.join(File.dirname(__FILE__), 'model/rubynet.xml')
253
+ max_fd.times do
254
+ XML::Parser.file(file).parse
255
+ end
256
+ XML::Error.reset_handler {|error|}
257
+ end
258
+
259
+ def test_open_many_files
260
+ 1000.times do
261
+ doc = XML::Parser.file('model/atom.xml').parse
262
+ end
263
+ end
264
+
265
+ # ----- Errors ------
266
+ def test_error
267
+ error = assert_raise(XML::Error) do
268
+ XML::Parser.string('<foo><bar/></foz>').parse
269
+ end
270
+
271
+ assert_not_nil(error)
272
+ assert_kind_of(XML::Error, error)
273
+ assert_equal("Fatal error: Opening and ending tag mismatch: foo line 1 and foz at :1.", error.message)
274
+ assert_equal(XML::Error::PARSER, error.domain)
275
+ assert_equal(XML::Error::TAG_NAME_MISMATCH, error.code)
276
+ assert_equal(XML::Error::FATAL, error.level)
277
+ assert_nil(error.file)
278
+ assert_equal(1, error.line)
279
+ assert_equal('foo', error.str1)
280
+ assert_equal('foz', error.str2)
281
+ assert_nil(error.str3)
282
+ assert_equal(1, error.int1)
283
+ assert_equal(20, error.int2)
284
+ assert_nil(error.node)
285
+ end
286
+
287
+ def test_bad_xml
288
+ parser = XML::Parser.string('<ruby_array uga="booga" foo="bar"<fixnum>one</fixnum><fixnum>two</fixnum></ruby_array>')
289
+ error = assert_raise(XML::Error) do
290
+ assert_not_nil(parser.parse)
291
+ end
292
+
293
+ assert_not_nil(error)
294
+ assert_kind_of(XML::Error, error)
295
+ assert_equal("Fatal error: Extra content at the end of the document at :1.", error.message)
296
+ assert_equal(XML::Error::PARSER, error.domain)
297
+ assert_equal(XML::Error::DOCUMENT_END, error.code)
298
+ assert_equal(XML::Error::FATAL, error.level)
299
+ assert_nil(error.file)
300
+ assert_equal(1, error.line)
301
+ assert_nil(error.str1)
302
+ assert_nil(error.str2)
303
+ assert_nil(error.str3)
304
+ assert_equal(0, error.int1)
305
+ assert_equal(20, error.int2)
306
+ assert_nil(error.node)
307
+ end
308
+
309
+ # Deprecated methods
310
+ def test_document_deprecated
311
+ file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.utf-8.xml'))
312
+ parser = XML::Parser.file(file)
313
+ doc = parser.parse
314
+
315
+ parser = XML::Parser.new
316
+ parser.document = doc
317
+ doc = parser.parse
318
+
319
+ assert_instance_of(XML::Document, doc)
320
+ assert_instance_of(XML::Parser::Context, parser.context)
321
+ end
322
+
323
+ def test_file_deprecated
324
+ file = File.expand_path(File.join(File.dirname(__FILE__), 'model/rubynet.xml'))
325
+
326
+ parser = XML::Parser.new
327
+ parser.file = file
328
+ doc = parser.parse
329
+ assert_instance_of(XML::Document, doc)
330
+ assert_instance_of(XML::Parser::Context, parser.context)
331
+ end
332
+
333
+ def test_io_deprecated
334
+ File.open(File.join(File.dirname(__FILE__), 'model/rubynet.xml')) do |io|
335
+ parser = XML::Parser.new
336
+ assert_instance_of(XML::Parser, parser)
337
+ parser.io = io
338
+
339
+ doc = parser.parse
340
+ assert_instance_of(XML::Document, doc)
341
+ assert_instance_of(XML::Parser::Context, parser.context)
342
+ end
343
+ end
344
+
345
+ def test_string_deprecated
346
+ str = '<ruby_array uga="booga" foo="bar"><fixnum>one</fixnum><fixnum>two</fixnum></ruby_array>'
347
+
348
+ parser = XML::Parser.new
349
+ parser.string = str
350
+ assert_instance_of(XML::Parser, parser)
351
+
352
+ doc = parser.parse
353
+ assert_instance_of(XML::Document, doc)
354
+ assert_instance_of(XML::Parser::Context, parser.context)
355
+ end
356
+ <<<<<<< HEAD
357
+ =======
358
+
359
+ def test_errors_from_background_thread
360
+ errors = []
361
+ background_errors = []
362
+
363
+ begin
364
+ XML::Error.set_handler do |error|
365
+ errors << error
366
+ end
367
+ parser = XML::Parser.string("<moo>")
368
+
369
+ thread = Thread.new do
370
+ XML::Error.set_handler do |error|
371
+ background_errors << error
372
+ end
373
+ parser.parse rescue nil
374
+ end
375
+ thread.join
376
+ ensure
377
+ XML::Error.set_handler(&XML::Error::QUIET_HANDLER)
378
+ end
379
+
380
+ assert_equal(errors.size, 0)
381
+ assert_equal(background_errors.size, 1)
382
+ end
383
+ >>>>>>> a1cd317d43c1c1f23551545e431452508720668d
384
+ end