nokogiri 1.6.8.rc3-java → 1.6.8.1-java

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

Potentially problematic release.


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

Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -3
  3. data/CHANGELOG.rdoc +41 -5
  4. data/CONTRIBUTING.md +1 -1
  5. data/Gemfile +7 -8
  6. data/Manifest.txt +1 -1
  7. data/README.md +0 -3
  8. data/Rakefile +10 -12
  9. data/build_all +1 -1
  10. data/dependencies.yml +29 -4
  11. data/ext/java/nokogiri/XmlAttr.java +3 -1
  12. data/ext/java/nokogiri/XmlDocumentFragment.java +0 -14
  13. data/ext/java/nokogiri/XmlNode.java +74 -58
  14. data/ext/java/nokogiri/internals/NokogiriHelpers.java +7 -7
  15. data/ext/java/nokogiri/internals/SaveContextVisitor.java +5 -1
  16. data/ext/nokogiri/extconf.rb +89 -33
  17. data/ext/nokogiri/xml_node.c +22 -9
  18. data/ext/nokogiri/xml_reader.c +0 -13
  19. data/ext/nokogiri/xml_sax_parser.c +7 -7
  20. data/lib/nokogiri.rb +11 -7
  21. data/lib/nokogiri/html/document.rb +4 -2
  22. data/lib/nokogiri/nokogiri.jar +0 -0
  23. data/lib/nokogiri/version.rb +1 -1
  24. data/lib/nokogiri/xml/document.rb +1 -1
  25. data/lib/nokogiri/xml/parse_options.rb +22 -0
  26. data/tasks/test.rb +5 -0
  27. data/test/html/test_document.rb +26 -0
  28. data/test/html/test_document_encoding.rb +5 -0
  29. data/test/html/test_document_fragment.rb +5 -0
  30. data/test/test_encoding_handler.rb +2 -0
  31. data/test/test_xslt_transforms.rb +33 -0
  32. data/test/xml/sax/test_parser.rb +15 -7
  33. data/test/xml/test_document_encoding.rb +5 -0
  34. data/test/xml/test_document_fragment.rb +12 -0
  35. data/test/xml/test_node_attributes.rb +6 -0
  36. data/test/xml/test_node_reparenting.rb +193 -18
  37. data/test/xml/test_reader.rb +589 -0
  38. data/test/xml/test_unparented_node.rb +13 -0
  39. data/test_all +33 -42
  40. metadata +63 -66
  41. data/test/test_reader.rb +0 -577
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1a5e58bb62530c4c55b141723a110e00128ff051
4
- data.tar.gz: 7102867999ccfaf4220369ffa366ca0cbc28b5ac
3
+ metadata.gz: 851e5661ef0fc4070c2305cc3b6f70187b48966c
4
+ data.tar.gz: 113797bd7cbf2ffe3df45f178b14c7b891639108
5
5
  SHA512:
6
- metadata.gz: 2c647157a41f0e818d30359b07b1a2d365a8cb71efa3f42426f841d86476b9691a1d06dbb75572a138f0da9b1e930d41047c0a1850c1661175cd23488156ae9d
7
- data.tar.gz: 86559f6d4d4eb562ab8589b3411187b595711d40c5dcedccea46a24546dbe2a6a0e918a421ad66af43dbbd0bf3fa65f0caefc2b1d9747b7bb6f2cb043cc3996c
6
+ metadata.gz: ff8deb5980f4fd7b6f14dad2d4f1e6d916a6e67bf341b813d030e81d9b2b7e9b7383d17e92a6cd642cda6c3f687b949d00f59e74ee7f9c870c5637c9c681c402
7
+ data.tar.gz: 35575f378e879b96d02f1d029a383066d1182f9df98061ac7df7d1df01085a2a7c00af6f00afa93fda55c4d181907a44164d5bc5e129cf0b3be9e5f658cacbff
@@ -10,8 +10,9 @@ rvm:
10
10
  - 2.2.3
11
11
  - 2.3.0
12
12
  - jruby-19mode
13
- - jruby-1.7.23
13
+ - jruby
14
14
  - jruby-9.0.4.0
15
+ - jruby-head
15
16
  - rbx-19mode
16
17
  - rbx-2
17
18
 
@@ -24,13 +25,14 @@ matrix:
24
25
  # https://github.com/travis-ci/travis-ci/issues/5361
25
26
  - os: osx
26
27
  rvm: 2.3.0
28
+ - rvm: jruby-head
27
29
  exclude:
28
30
  - os: osx
29
31
  rvm: ruby-1.9.2
30
32
  - os: osx
31
33
  rvm: jruby-19mode
32
34
  - os: osx
33
- rvm: jruby-1.7.23
35
+ rvm: jruby
34
36
  - os: osx
35
37
  rvm: jruby-9.0.4.0
36
38
  - os: osx
@@ -42,7 +44,7 @@ notifications:
42
44
  irc:
43
45
  channels:
44
46
  - "chat.freenode.net#nokogiri"
45
- on_success: change
47
+ on_success: always
46
48
  on_failure: always
47
49
  template:
48
50
  - "%{repository} (%{branch}:%{commit} by %{author}): %{message} (%{build_url})"
@@ -1,10 +1,37 @@
1
- === 1.6.8 / unreleased
1
+ === 1.6.8.1 / 2016-10-03
2
2
 
3
- ==== Security Note
3
+ ==== Dependency License Notes
4
+
5
+ Removes required dependency on the `pkg-config` gem. This dependency
6
+ was introduced in v1.6.8 and, because it's distributed under LGPL, was
7
+ objectionable to many Nokogiri users (#1488, #1496).
8
+
9
+ This version makes `pkg-config` an optional dependency. If it's
10
+ installed, it's used; but otherwise Nokogiri will attempt to work
11
+ around its absence.
12
+
13
+
14
+ === 1.6.8 / 2016-06-06
15
+
16
+ ==== Security Notes
17
+
18
+ [MRI] Bundled libxml2 is upgraded to 2.9.4, which fixes many security issues. Many of these had previously been patched in the vendored libxml 2.9.2 in the 1.6.7.x branch, but some are newer.
19
+
20
+ See these libxml2 email posts for more:
21
+
22
+ * https://mail.gnome.org/archives/xml/2015-November/msg00012.html
23
+ * https://mail.gnome.org/archives/xml/2016-May/msg00023.html
24
+
25
+ For a more detailed analysis, you may care to read Canonical's take on these security issues:
26
+
27
+ * http://www.ubuntu.com/usn/usn-2994-1
28
+
29
+
30
+ [MRI] Bundled libxslt is upgraded to 1.1.29, which fixes a security issue as well as many long-known outstanding bugs, some features, some portability improvements, and general cleanup.
31
+
32
+ See this libxslt email post for more:
4
33
 
5
- * (MRI) Bundled Libxml2 is upgraded to 2.9.3, which fixes a series of security issues.
6
- These security issues had been patched in the vendored libxml 2.9.2 in the 1.6.7.x branch.
7
- See https://mail.gnome.org/archives/xml/2015-November/msg00012.html for more.
34
+ * https://mail.gnome.org/archives/xslt/2016-May/msg00004.html
8
35
 
9
36
 
10
37
  ==== Features
@@ -16,19 +43,28 @@ Several changes were made to improve performance:
16
43
  * Use Symbol#to_proc where we weren't previously. (#1296) (Thanks, Bruno Sutic!)
17
44
  * XML::DTD#each uses implicit block calls. (Thanks, @glaucocustodio!)
18
45
  * Fall back to the `pkg-config` gem if we're having trouble finding the system libxml2. This should help many FreeBSD users. (#1417)
46
+ * Set document encoding appropriately even on blank document. (#1043) (Thanks, @batter!)
19
47
 
20
48
 
21
49
  ==== Bug Fixes
22
50
 
51
+ * [JRuby] fix slow add_child (#692)
23
52
  * [JRuby] fix load errors when deploying to JRuby/Torquebox (#1114) (Thanks, @atambo and @jvshahid!)
24
53
  * [JRuby] fix NPE when inspecting nodes returned by NodeSet#drop (#1042) (Thanks, @mkristian!)
25
54
  * [JRuby] fix nil attriubte node's namespace in reader (#1327) (Thanks, @codekitchen!)
26
55
  * [JRuby] fix Nokogiri munging unicode characters that require more than 2 bytes (#1113) (Thanks, @mkristian!)
56
+ * [JRuby] allow unlinking an unparented node (#1112, #1152) (Thanks, @esse!)
57
+ * [JRuby] allow Fragment parsing on a frozen string (#444, #1077)
58
+ * [JRuby] HTML `style` tags are no longer encoded (#1316) (Thanks, @tbeauvais!)
27
59
  * [MRI] fix assertion failure while accessing attribute node's namespace in reader (#843) (Thanks, @2potatocakes!)
28
60
  * [MRI] fix issue with GCing namespace nodes returned in an xpath query. (#1155)
29
61
  * [MRI] Ensure C strings are null-terminated. (#1381)
30
62
  * [MRI] Ensure Rubygems is loaded before using mini_portile2 at installation. (#1393, #1411) (Thanks, @JonRowe!)
31
63
  * [MRI] Handling another edge case where the `libxml-ruby` gem's global callbacks were smashing the heap. (#1426). (Thanks to @bbergstrom for providing an isolated test case!)
64
+ * [MRI] Ensure encodings are passed to Sax::Parser xmldecl callback. (#844)
65
+ * [MRI] Ensure default ns prefix is applied correctly when reparenting nodes to another document. (#391) (Thanks, @ylecuyer!)
66
+ * [MRI] Ensure Reader handles non-existent attributes as expected. (#1254) (Thanks, @ccutrer!)
67
+ * [MRI] Cleanup around namespace handling when reparenting nodes. (#1332, #1333, #1444) (Thanks, @cuttrer and @bradleybeddoes!)
32
68
  * unescape special characters in CSS queries (#1303) (Thanks, @twalpole!)
33
69
  * consistently handle empty documents (#1349)
34
70
  * Update to mini_portile2 2.1.0 to address whitespace-handling during patching. (#1402)
@@ -1,4 +1,4 @@
1
- # Issue and Pull Request Guidlines
1
+ # Issue and Pull Request Guidelines
2
2
 
3
3
  Thank you for getting involved in making Nokogiri better!
4
4
 
data/Gemfile CHANGED
@@ -5,19 +5,18 @@
5
5
  source "https://rubygems.org/"
6
6
 
7
7
  gem "mini_portile2", "~>2.1.0"
8
- gem "pkg-config", "~>1.1.7"
9
8
 
10
9
  gem "rdoc", "~>4.0", :group => [:development, :test]
11
- gem "hoe-bundler", ">=1.1", :group => [:development, :test]
10
+ gem "hoe-bundler", "~>1.2.0", :group => [:development, :test]
12
11
  gem "hoe-debugging", "~>1.2.1", :group => [:development, :test]
13
- gem "hoe-gemspec", ">=1.0", :group => [:development, :test]
14
- gem "hoe-git", ">=1.4", :group => [:development, :test]
15
- gem "minitest", "~>2.2.2", :group => [:development, :test]
16
- gem "rake", ">=0.9", :group => [:development, :test]
12
+ gem "hoe-gemspec", "~>1.0.0", :group => [:development, :test]
13
+ gem "hoe-git", "~>1.6.0", :group => [:development, :test]
14
+ gem "minitest", "~>5.8.4", :group => [:development, :test]
15
+ gem "rake", "~>10.5.0", :group => [:development, :test]
17
16
  gem "rake-compiler", "~>0.9.2", :group => [:development, :test]
18
17
  gem "rake-compiler-dock", "~>0.5.1", :group => [:development, :test]
19
- gem "racc", ">=1.4.6", :group => [:development, :test], :platform => :ruby
20
- gem "rexical", ">=1.0.5", :group => [:development, :test], :platform => :ruby
18
+ gem "racc", "~>1.4.14", :group => [:development, :test], :platform => :ruby
19
+ gem "rexical", "~>1.0.5", :group => [:development, :test], :platform => :ruby
21
20
  gem "hoe", "~>3.14", :group => [:development, :test]
22
21
 
23
22
  # vim: syntax=ruby
@@ -319,7 +319,6 @@ test/test_css_cache.rb
319
319
  test/test_encoding_handler.rb
320
320
  test/test_memory_leak.rb
321
321
  test/test_nokogiri.rb
322
- test/test_reader.rb
323
322
  test/test_soap4r_sax.rb
324
323
  test/test_xslt_transforms.rb
325
324
  test/xml/node/test_save_options.rb
@@ -351,6 +350,7 @@ test/xml/test_node_reparenting.rb
351
350
  test/xml/test_node_set.rb
352
351
  test/xml/test_parse_options.rb
353
352
  test/xml/test_processing_instruction.rb
353
+ test/xml/test_reader.rb
354
354
  test/xml/test_reader_encoding.rb
355
355
  test/xml/test_relax_ng.rb
356
356
  test/xml/test_schema.rb
data/README.md CHANGED
@@ -22,9 +22,6 @@ Nokogiri (鋸) is an HTML, XML, SAX, and Reader parser. Among
22
22
  Nokogiri's many features is the ability to search documents via XPath
23
23
  or CSS3 selectors.
24
24
 
25
- XML is like violence - if it doesn’t solve your problems, you are not
26
- using enough of it.
27
-
28
25
 
29
26
  ## Features
30
27
 
data/Rakefile CHANGED
@@ -8,7 +8,6 @@ Hoe.plugin :debugging
8
8
  Hoe.plugin :git
9
9
  Hoe.plugin :gemspec
10
10
  Hoe.plugin :bundler
11
- Hoe.add_include_dirs '.'
12
11
 
13
12
  GENERATED_PARSER = "lib/nokogiri/css/parser.rb"
14
13
  GENERATED_TOKENIZER = "lib/nokogiri/css/tokenizer.rb"
@@ -129,21 +128,20 @@ HOE = Hoe.spec 'nokogiri' do
129
128
  unless java?
130
129
  self.extra_deps += [
131
130
  ["mini_portile2", "~> 2.1.0"], # keep version in sync with extconf.rb
132
- ["pkg-config", "~> 1.1.7"], # keep version in sync with extconf.rb
133
131
  ]
134
132
  end
135
133
 
136
134
  self.extra_dev_deps += [
137
- ["hoe-bundler", ">= 1.1"],
135
+ ["hoe-bundler", "~> 1.2.0"],
138
136
  ["hoe-debugging", "~> 1.2.1"],
139
- ["hoe-gemspec", ">= 1.0"],
140
- ["hoe-git", ">= 1.4"],
141
- ["minitest", "~> 2.2.2"],
142
- ["rake", ">= 0.9"],
137
+ ["hoe-gemspec", "~> 1.0.0"],
138
+ ["hoe-git", "~> 1.6.0"],
139
+ ["minitest", "~> 5.8.4"],
140
+ ["rake", "~> 10.5.0"],
143
141
  ["rake-compiler", "~> 0.9.2"],
144
142
  ["rake-compiler-dock", "~> 0.5.1"],
145
- ["racc", ">= 1.4.6"],
146
- ["rexical", ">= 1.0.5"]
143
+ ["racc", "~> 1.4.14"],
144
+ ["rexical", "~> 1.0.5"]
147
145
  ]
148
146
 
149
147
  if java?
@@ -207,7 +205,7 @@ else
207
205
 
208
206
  task gem_build_path do
209
207
  %w[libxml2 libxslt].each do |lib|
210
- version = dependencies[lib]
208
+ version = dependencies[lib]["version"]
211
209
  archive = File.join("ports", "archives", "#{lib}-#{version}.tar.gz")
212
210
  add_file_to_gem archive
213
211
  patchesdir = File.join("patches", lib)
@@ -232,7 +230,7 @@ else
232
230
  ext.cross_platform = CROSS_RUBIES.map(&:platform).uniq
233
231
  ext.cross_config_options << "--enable-cross-build"
234
232
  ext.cross_compiling do |spec|
235
- libs = dependencies.map { |name, version| "#{name}-#{version}" }.join(', ')
233
+ libs = dependencies.map { |name, dep| "#{name}-#{dep["version"]}" }.join(', ')
236
234
 
237
235
  spec.required_ruby_version = [
238
236
  '>= 1.9.2',
@@ -293,7 +291,7 @@ task :debug do
293
291
  ENV['CFLAGS'] += " -DDEBUG"
294
292
  end
295
293
 
296
- require 'tasks/test'
294
+ require File.join File.dirname(__FILE__), 'tasks/test'
297
295
 
298
296
  task :java_debug do
299
297
  ENV['JRUBY_OPTS'] = "#{ENV['JRUBY_OPTS']} --debug --dev"
data/build_all CHANGED
@@ -16,7 +16,7 @@ else
16
16
  fi
17
17
 
18
18
  set -o errexit
19
- set -x
19
+ #set -x
20
20
 
21
21
  rm -rf tmp pkg
22
22
  bundle exec rake clean clobber
@@ -1,4 +1,29 @@
1
- libxml2: "2.9.3"
2
- libxslt: "1.1.28"
3
- zlib: "1.2.8"
4
- libiconv: "1.14"
1
+ libxml2:
2
+ version: "2.9.4"
3
+ md5: "ae249165c173b1ff386ee8ad676815f5" # manually confirmed via `gpg --verify`
4
+ # gpg: Signature made Mon 23 May 2016 04:02:13 AM EDT using DSA key ID DE95BC1F
5
+ # gpg: Good signature from "Daniel Veillard (Red Hat work email) <veillard@redhat.com>"
6
+ # gpg: aka "Daniel Veillard <Daniel.Veillard@w3.org>"
7
+ # gpg: WARNING: This key is not certified with a trusted signature!
8
+ # gpg: There is no indication that the signature belongs to the owner.
9
+ # Primary key fingerprint: C744 15BA 7C9C 7F78 F02E 1DC3 4606 B8A5 DE95 BC1F
10
+
11
+ libxslt:
12
+ version: "1.1.29"
13
+ md5: "a129d3c44c022de3b9dcf6d6f288d72e"
14
+ # gpg: Signature made Mon 23 May 2016 09:58:52 PM EDT using DSA key ID DE95BC1F
15
+ # gpg: Good signature from "Daniel Veillard (Red Hat work email) <veillard@redhat.com>"
16
+ # gpg: aka "Daniel Veillard <Daniel.Veillard@w3.org>"
17
+ # gpg: WARNING: This key is not certified with a trusted signature!
18
+ # gpg: There is no indication that the signature belongs to the owner.
19
+ # Primary key fingerprint: C744 15BA 7C9C 7F78 F02E 1DC3 4606 B8A5 DE95 BC1F
20
+
21
+ zlib:
22
+ version: "1.2.8"
23
+ md5: "44d667c142d7cda120332623eab69f40"
24
+
25
+ libiconv:
26
+ version: "1.14"
27
+ md5: "e34509b1623cec449dfeb73d7ce9c6c6"
28
+ # gpg: Signature made Sun 07 Aug 2011 01:58:18 PM EDT using DSA key ID F059B1D1
29
+ # gpg: BAD signature from "Bruno Haible (Open Source Development) <bruno@clisp.org>"
@@ -164,7 +164,9 @@ public class XmlAttr extends XmlNode{
164
164
  protected IRubyObject getNodeName(ThreadContext context) {
165
165
  if (name != null) return name;
166
166
  String attrName = ((Attr)node).getName();
167
- if (!(doc instanceof HtmlDocument)) attrName = NokogiriHelpers.getLocalPart(attrName);
167
+ if (!(doc instanceof HtmlDocument) && node.getNamespaceURI() != null) {
168
+ attrName = NokogiriHelpers.getLocalPart(attrName);
169
+ }
168
170
  return attrName == null ? context.getRuntime().getNil() : RubyString.newString(context.getRuntime(), attrName);
169
171
  }
170
172
 
@@ -54,7 +54,6 @@ import org.jruby.javasupport.util.RuntimeHelpers;
54
54
  import org.jruby.runtime.ThreadContext;
55
55
  import org.jruby.runtime.builtin.IRubyObject;
56
56
  import org.w3c.dom.Attr;
57
- import org.w3c.dom.Document;
58
57
  import org.w3c.dom.NamedNodeMap;
59
58
 
60
59
  /**
@@ -90,7 +89,6 @@ public class XmlDocumentFragment extends XmlNode {
90
89
 
91
90
  // make wellformed fragment, ignore invalid namespace, or add appropriate namespace to parse
92
91
  if (args.length > 1 && args[1] instanceof RubyString) {
93
- args[1] = trim(context, doc, (RubyString)args[1]);
94
92
  if (XmlDocumentFragment.isTag((RubyString)args[1])) {
95
93
  args[1] = RubyString.newString(context.getRuntime(), addNamespaceDeclIfNeeded(doc, rubyStringToString(args[1])));
96
94
  }
@@ -107,18 +105,6 @@ public class XmlDocumentFragment extends XmlNode {
107
105
  RuntimeHelpers.invoke(context, fragment, "initialize", args);
108
106
  return fragment;
109
107
  }
110
-
111
- private static IRubyObject trim(ThreadContext context, XmlDocument xmlDocument, RubyString str) {
112
- // checks whether schema is given. if exists, allows whitespace processing to a parser
113
- Document document = (Document)xmlDocument.node;
114
- if (document.getDoctype() != null) return str;
115
- // strips trailing \n off forcefully
116
- // not to return new object in case of no chomp needed, chomp! is used here.
117
- IRubyObject result;
118
- if (context.getRuntime().is1_9()) result = str.chomp_bang19(context);
119
- else result = str.chomp_bang(context);
120
- return result.isNil() ? str : result;
121
- }
122
108
 
123
109
  private static boolean isTag(RubyString ruby_string) {
124
110
  String str = rubyStringToString(ruby_string);
@@ -333,15 +333,11 @@ public class XmlNode extends RubyObject {
333
333
  Element element = null;
334
334
  String node_name = rubyStringToString(name);
335
335
  String prefix = NokogiriHelpers.getPrefix(node_name);
336
- if (prefix == null) {
337
- element = document.createElement(node_name);
338
- } else {
339
- String namespace_uri = null;
340
- if (document.getDocumentElement() != null) {
341
- namespace_uri = document.getDocumentElement().lookupNamespaceURI(prefix);
342
- }
343
- element = document.createElementNS(namespace_uri, node_name);
336
+ String namespace_uri = null;
337
+ if (document.getDocumentElement() != null) {
338
+ namespace_uri = document.getDocumentElement().lookupNamespaceURI(prefix);
344
339
  }
340
+ element = document.createElementNS(namespace_uri, node_name);
345
341
  setNode(context, element);
346
342
  }
347
343
 
@@ -454,57 +450,77 @@ public class XmlNode extends RubyObject {
454
450
  public void post_add_child(ThreadContext context, XmlNode current, XmlNode child) {
455
451
  }
456
452
 
453
+ /**
454
+ * This method should be called after a node has been adopted in a new
455
+ * document. This method will ensure that the node is renamed with the
456
+ * appriopriate NS uri. First the prefix of the node is extracted, then is
457
+ * used to lookup the namespace uri in the new document starting at the
458
+ * current node and traversing the ancestors. If the namespace uri wasn't
459
+ * empty (or null) all children and the node has attributes and/or children
460
+ * then the algorithm is recursively applied to the children.
461
+ */
457
462
  public void relink_namespace(ThreadContext context) {
458
- if (node instanceof Element) {
459
- clearCachedNode(node);
460
- Element e = (Element) node;
461
- String prefix = e.getPrefix();
462
- String currentNS = e.getNamespaceURI();
463
- if (prefix == null && currentNS == null) {
464
- prefix = NokogiriHelpers.getPrefix(e.getNodeName());
465
- } else if (currentNS != null) {
466
- prefix = e.lookupPrefix(currentNS);
467
- }
468
- e.getOwnerDocument().setStrictErrorChecking(false);
469
- String nsURI = e.lookupNamespaceURI(prefix);
470
- this.node = NokogiriHelpers.renameNode(e, nsURI, e.getNodeName());
471
-
472
- if (e.hasAttributes()) {
473
- NamedNodeMap attrs = e.getAttributes();
474
-
475
- for (int i = 0; i < attrs.getLength(); i++) {
476
- Attr attr = (Attr) attrs.item(i);
477
- String nsUri = "";
478
- String attrPrefix = attr.getPrefix();
479
- if (attrPrefix == null) {
480
- attrPrefix = NokogiriHelpers.getPrefix(attr.getNodeName());
481
- }
482
- String nodeName = attr.getNodeName();
483
- if ("xml".equals(attrPrefix)) {
484
- nsUri = "http://www.w3.org/XML/1998/namespace";
485
- } else if ("xmlns".equals(attrPrefix) || nodeName.equals("xmlns")) {
486
- nsUri = "http://www.w3.org/2000/xmlns/";
487
- } else {
488
- nsUri = attr.lookupNamespaceURI(attrPrefix);
489
- }
463
+ if (!(node instanceof Element)) {
464
+ return;
465
+ }
490
466
 
491
- if (nsUri == e.getNamespaceURI()) {
492
- nsUri = null;
493
- }
467
+ // TODO: this feels kind of weird, why are we clearing the XmlNode
468
+ // cache here !!!
469
+ clearCachedNode(node);
470
+ Element e = (Element) node;
494
471
 
495
- if (!(nsUri == null || "".equals(nsUri) || "http://www.w3.org/XML/1998/namespace".equals(nsUri))) {
496
- XmlNamespace.createFromAttr(context.getRuntime(), attr);
497
- }
498
- clearCachedNode(attr);
499
- NokogiriHelpers.renameNode(attr, nsUri, nodeName);
472
+ // disable error checking to prevent lines like the following
473
+ // from throwing a `NAMESPACE_ERR' exception:
474
+ // Nokogiri::XML::DocumentFragment.parse("<o:div>a</o:div>")
475
+ // since the `o' prefix isn't defined anywhere.
476
+ e.getOwnerDocument().setStrictErrorChecking(false);
477
+
478
+ String prefix = e.getPrefix();
479
+ String nsURI = e.lookupNamespaceURI(prefix);
480
+ this.node = NokogiriHelpers.renameNode(e, nsURI, e.getNodeName());
481
+
482
+ if (nsURI == null || nsURI == "") {
483
+ return;
484
+ }
485
+
486
+ if (e.hasAttributes()) {
487
+ NamedNodeMap attrs = e.getAttributes();
488
+
489
+ for (int i = 0; i < attrs.getLength(); i++) {
490
+ Attr attr = (Attr) attrs.item(i);
491
+ String nsUri = "";
492
+ String attrPrefix = attr.getPrefix();
493
+ if (attrPrefix == null) {
494
+ attrPrefix = NokogiriHelpers.getPrefix(attr.getNodeName());
495
+ }
496
+ String nodeName = attr.getNodeName();
497
+ if ("xml".equals(attrPrefix)) {
498
+ nsUri = "http://www.w3.org/XML/1998/namespace";
499
+ } else if ("xmlns".equals(attrPrefix) || nodeName.equals("xmlns")) {
500
+ nsUri = "http://www.w3.org/2000/xmlns/";
501
+ } else {
502
+ nsUri = attr.lookupNamespaceURI(attrPrefix);
503
+ }
504
+
505
+ if (nsUri == e.getNamespaceURI()) {
506
+ nsUri = null;
500
507
  }
501
- }
502
508
 
503
- if (this.node.hasChildNodes()) {
504
- XmlNodeSet nodeSet = (XmlNodeSet)(children(context));
505
- nodeSet.relink_namespace(context);
509
+ if (!(nsUri == null || "".equals(nsUri) || "http://www.w3.org/XML/1998/namespace".equals(nsUri))) {
510
+ // Create a new namespace object and add it to the document
511
+ // namespace cache.
512
+ // TODO: why do we need the namespace cache ?
513
+ XmlNamespace.createFromAttr(context.getRuntime(), attr);
514
+ }
515
+ clearCachedNode(attr);
516
+ NokogiriHelpers.renameNode(attr, nsUri, nodeName);
506
517
  }
507
518
  }
519
+
520
+ if (this.node.hasChildNodes()) {
521
+ XmlNodeSet nodeSet = (XmlNodeSet)(children(context));
522
+ nodeSet.relink_namespace(context);
523
+ }
508
524
  }
509
525
 
510
526
  // Users might extend XmlNode. This method works for such a case.
@@ -605,6 +621,7 @@ public class XmlNode extends RubyObject {
605
621
 
606
622
  NokogiriNamespaceCache nsCache = NokogiriHelpers.getNamespaceCacheFormNode(node);
607
623
  XmlNamespace cachedNamespace = nsCache.get(prefixString, hrefString);
624
+
608
625
  if (cachedNamespace != null) return cachedNamespace;
609
626
 
610
627
  Node namespaceOwner;
@@ -615,12 +632,14 @@ public class XmlNode extends RubyObject {
615
632
  final String uri = "http://www.w3.org/2000/xmlns/";
616
633
  String qName =
617
634
  prefix.isNil() ? "xmlns" : "xmlns:" + prefixString;
635
+
618
636
  element.setAttributeNS(uri, qName, hrefString);
619
637
  }
620
638
  else if (node.getNodeType() == Node.ATTRIBUTE_NODE) namespaceOwner = ((Attr)node).getOwnerElement();
621
639
  else namespaceOwner = node.getParentNode();
622
640
  XmlNamespace ns = XmlNamespace.createFromPrefixAndHref(namespaceOwner, prefix, href);
623
641
  if (node != namespaceOwner) {
642
+
624
643
  this.node = NokogiriHelpers.renameNode(node, ns.getHref(), ns.getPrefix() + ":" + node.getLocalName());
625
644
  }
626
645
  updateNodeNamespaceIfNecessary(context, ns);
@@ -1323,7 +1342,7 @@ public class XmlNode extends RubyObject {
1323
1342
  } else if (prefix.equals("xmlns")) {
1324
1343
  uri = "http://www.w3.org/2000/xmlns/";
1325
1344
  } else {
1326
- uri = findNamespaceHref(context, prefix);
1345
+ uri = node.lookupNamespaceURI(prefix);
1327
1346
  }
1328
1347
  }
1329
1348
 
@@ -1413,13 +1432,10 @@ public class XmlNode extends RubyObject {
1413
1432
 
1414
1433
  @JRubyMethod(name = {"unlink", "remove"})
1415
1434
  public IRubyObject unlink(ThreadContext context) {
1416
- if(node.getParentNode() == null) {
1417
- throw context.getRuntime().newRuntimeError("TYPE: " + node.getNodeType()+ " PARENT NULL");
1418
- } else {
1435
+ if (node.getParentNode() != null) {
1419
1436
  clearXpathContext(node.getParentNode());
1420
1437
  node.getParentNode().removeChild(node);
1421
1438
  }
1422
-
1423
1439
  return this;
1424
1440
  }
1425
1441
 
@@ -1582,7 +1598,7 @@ public class XmlNode extends RubyObject {
1582
1598
  ((XmlDocument) this).resetNamespaceCache(context);
1583
1599
  }
1584
1600
 
1585
- relink_namespace(context);
1601
+ other.relink_namespace(context);
1586
1602
  // post_add_child(context, this, other);
1587
1603
 
1588
1604
  return nodeOrTags;