nokogiri-backport 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (239) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/LICENSE-DEPENDENCIES.md +1682 -0
  4. data/LICENSE.md +9 -0
  5. data/README.md +272 -0
  6. data/bin/nokogiri +118 -0
  7. data/dependencies.yml +74 -0
  8. data/ext/java/nokogiri/EncodingHandler.java +124 -0
  9. data/ext/java/nokogiri/HtmlDocument.java +178 -0
  10. data/ext/java/nokogiri/HtmlElementDescription.java +148 -0
  11. data/ext/java/nokogiri/HtmlEntityLookup.java +79 -0
  12. data/ext/java/nokogiri/HtmlSaxParserContext.java +282 -0
  13. data/ext/java/nokogiri/HtmlSaxPushParser.java +222 -0
  14. data/ext/java/nokogiri/NokogiriService.java +597 -0
  15. data/ext/java/nokogiri/XmlAttr.java +162 -0
  16. data/ext/java/nokogiri/XmlAttributeDecl.java +129 -0
  17. data/ext/java/nokogiri/XmlCdata.java +82 -0
  18. data/ext/java/nokogiri/XmlComment.java +97 -0
  19. data/ext/java/nokogiri/XmlDocument.java +633 -0
  20. data/ext/java/nokogiri/XmlDocumentFragment.java +185 -0
  21. data/ext/java/nokogiri/XmlDtd.java +481 -0
  22. data/ext/java/nokogiri/XmlElement.java +68 -0
  23. data/ext/java/nokogiri/XmlElementContent.java +382 -0
  24. data/ext/java/nokogiri/XmlElementDecl.java +147 -0
  25. data/ext/java/nokogiri/XmlEntityDecl.java +157 -0
  26. data/ext/java/nokogiri/XmlEntityReference.java +101 -0
  27. data/ext/java/nokogiri/XmlNamespace.java +199 -0
  28. data/ext/java/nokogiri/XmlNode.java +1684 -0
  29. data/ext/java/nokogiri/XmlNodeSet.java +434 -0
  30. data/ext/java/nokogiri/XmlProcessingInstruction.java +100 -0
  31. data/ext/java/nokogiri/XmlReader.java +531 -0
  32. data/ext/java/nokogiri/XmlRelaxng.java +151 -0
  33. data/ext/java/nokogiri/XmlSaxParserContext.java +374 -0
  34. data/ext/java/nokogiri/XmlSaxPushParser.java +286 -0
  35. data/ext/java/nokogiri/XmlSchema.java +388 -0
  36. data/ext/java/nokogiri/XmlSyntaxError.java +138 -0
  37. data/ext/java/nokogiri/XmlText.java +110 -0
  38. data/ext/java/nokogiri/XmlXpathContext.java +301 -0
  39. data/ext/java/nokogiri/XsltStylesheet.java +347 -0
  40. data/ext/java/nokogiri/internals/ClosedStreamException.java +10 -0
  41. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +252 -0
  42. data/ext/java/nokogiri/internals/IgnoreSchemaErrorsErrorHandler.java +20 -0
  43. data/ext/java/nokogiri/internals/NokogiriBlockingQueueInputStream.java +151 -0
  44. data/ext/java/nokogiri/internals/NokogiriDomParser.java +116 -0
  45. data/ext/java/nokogiri/internals/NokogiriEntityResolver.java +121 -0
  46. data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +69 -0
  47. data/ext/java/nokogiri/internals/NokogiriHandler.java +327 -0
  48. data/ext/java/nokogiri/internals/NokogiriHelpers.java +734 -0
  49. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +217 -0
  50. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +127 -0
  51. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +100 -0
  52. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +121 -0
  53. data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +78 -0
  54. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +180 -0
  55. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +72 -0
  56. data/ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java +60 -0
  57. data/ext/java/nokogiri/internals/NokogiriXsltErrorListener.java +87 -0
  58. data/ext/java/nokogiri/internals/ParserContext.java +259 -0
  59. data/ext/java/nokogiri/internals/ReaderNode.java +488 -0
  60. data/ext/java/nokogiri/internals/SaveContextVisitor.java +778 -0
  61. data/ext/java/nokogiri/internals/SchemaErrorHandler.java +73 -0
  62. data/ext/java/nokogiri/internals/XalanDTMManagerPatch.java +168 -0
  63. data/ext/java/nokogiri/internals/XmlDeclHandler.java +42 -0
  64. data/ext/java/nokogiri/internals/XmlDomParserContext.java +274 -0
  65. data/ext/java/nokogiri/internals/XmlSaxParser.java +65 -0
  66. data/ext/java/nokogiri/internals/c14n/AttrCompare.java +119 -0
  67. data/ext/java/nokogiri/internals/c14n/C14nHelper.java +159 -0
  68. data/ext/java/nokogiri/internals/c14n/CanonicalFilter.java +37 -0
  69. data/ext/java/nokogiri/internals/c14n/CanonicalizationException.java +93 -0
  70. data/ext/java/nokogiri/internals/c14n/Canonicalizer.java +252 -0
  71. data/ext/java/nokogiri/internals/c14n/Canonicalizer11.java +639 -0
  72. data/ext/java/nokogiri/internals/c14n/Canonicalizer11_OmitComments.java +38 -0
  73. data/ext/java/nokogiri/internals/c14n/Canonicalizer11_WithComments.java +38 -0
  74. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315.java +367 -0
  75. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315Excl.java +295 -0
  76. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclOmitComments.java +40 -0
  77. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclWithComments.java +44 -0
  78. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315OmitComments.java +44 -0
  79. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315WithComments.java +43 -0
  80. data/ext/java/nokogiri/internals/c14n/CanonicalizerBase.java +630 -0
  81. data/ext/java/nokogiri/internals/c14n/CanonicalizerPhysical.java +173 -0
  82. data/ext/java/nokogiri/internals/c14n/CanonicalizerSpi.java +76 -0
  83. data/ext/java/nokogiri/internals/c14n/Constants.java +42 -0
  84. data/ext/java/nokogiri/internals/c14n/ElementProxy.java +293 -0
  85. data/ext/java/nokogiri/internals/c14n/HelperNodeList.java +93 -0
  86. data/ext/java/nokogiri/internals/c14n/IgnoreAllErrorHandler.java +79 -0
  87. data/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java +166 -0
  88. data/ext/java/nokogiri/internals/c14n/InvalidCanonicalizerException.java +76 -0
  89. data/ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java +402 -0
  90. data/ext/java/nokogiri/internals/c14n/NodeFilter.java +51 -0
  91. data/ext/java/nokogiri/internals/c14n/UtfHelpper.java +179 -0
  92. data/ext/java/nokogiri/internals/c14n/XMLUtils.java +507 -0
  93. data/ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java +1745 -0
  94. data/ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java +685 -0
  95. data/ext/nokogiri/depend +477 -0
  96. data/ext/nokogiri/extconf.rb +836 -0
  97. data/ext/nokogiri/html_document.c +171 -0
  98. data/ext/nokogiri/html_document.h +10 -0
  99. data/ext/nokogiri/html_element_description.c +279 -0
  100. data/ext/nokogiri/html_element_description.h +10 -0
  101. data/ext/nokogiri/html_entity_lookup.c +32 -0
  102. data/ext/nokogiri/html_entity_lookup.h +8 -0
  103. data/ext/nokogiri/html_sax_parser_context.c +116 -0
  104. data/ext/nokogiri/html_sax_parser_context.h +11 -0
  105. data/ext/nokogiri/html_sax_push_parser.c +87 -0
  106. data/ext/nokogiri/html_sax_push_parser.h +9 -0
  107. data/ext/nokogiri/nokogiri.c +135 -0
  108. data/ext/nokogiri/nokogiri.h +130 -0
  109. data/ext/nokogiri/xml_attr.c +103 -0
  110. data/ext/nokogiri/xml_attr.h +9 -0
  111. data/ext/nokogiri/xml_attribute_decl.c +70 -0
  112. data/ext/nokogiri/xml_attribute_decl.h +9 -0
  113. data/ext/nokogiri/xml_cdata.c +62 -0
  114. data/ext/nokogiri/xml_cdata.h +9 -0
  115. data/ext/nokogiri/xml_comment.c +69 -0
  116. data/ext/nokogiri/xml_comment.h +9 -0
  117. data/ext/nokogiri/xml_document.c +622 -0
  118. data/ext/nokogiri/xml_document.h +23 -0
  119. data/ext/nokogiri/xml_document_fragment.c +48 -0
  120. data/ext/nokogiri/xml_document_fragment.h +10 -0
  121. data/ext/nokogiri/xml_dtd.c +202 -0
  122. data/ext/nokogiri/xml_dtd.h +10 -0
  123. data/ext/nokogiri/xml_element_content.c +123 -0
  124. data/ext/nokogiri/xml_element_content.h +10 -0
  125. data/ext/nokogiri/xml_element_decl.c +69 -0
  126. data/ext/nokogiri/xml_element_decl.h +9 -0
  127. data/ext/nokogiri/xml_encoding_handler.c +79 -0
  128. data/ext/nokogiri/xml_encoding_handler.h +8 -0
  129. data/ext/nokogiri/xml_entity_decl.c +110 -0
  130. data/ext/nokogiri/xml_entity_decl.h +10 -0
  131. data/ext/nokogiri/xml_entity_reference.c +52 -0
  132. data/ext/nokogiri/xml_entity_reference.h +9 -0
  133. data/ext/nokogiri/xml_io.c +63 -0
  134. data/ext/nokogiri/xml_io.h +11 -0
  135. data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
  136. data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
  137. data/ext/nokogiri/xml_namespace.c +111 -0
  138. data/ext/nokogiri/xml_namespace.h +14 -0
  139. data/ext/nokogiri/xml_node.c +1773 -0
  140. data/ext/nokogiri/xml_node.h +13 -0
  141. data/ext/nokogiri/xml_node_set.c +486 -0
  142. data/ext/nokogiri/xml_node_set.h +12 -0
  143. data/ext/nokogiri/xml_processing_instruction.c +56 -0
  144. data/ext/nokogiri/xml_processing_instruction.h +9 -0
  145. data/ext/nokogiri/xml_reader.c +657 -0
  146. data/ext/nokogiri/xml_reader.h +10 -0
  147. data/ext/nokogiri/xml_relax_ng.c +179 -0
  148. data/ext/nokogiri/xml_relax_ng.h +9 -0
  149. data/ext/nokogiri/xml_sax_parser.c +305 -0
  150. data/ext/nokogiri/xml_sax_parser.h +39 -0
  151. data/ext/nokogiri/xml_sax_parser_context.c +262 -0
  152. data/ext/nokogiri/xml_sax_parser_context.h +10 -0
  153. data/ext/nokogiri/xml_sax_push_parser.c +159 -0
  154. data/ext/nokogiri/xml_sax_push_parser.h +9 -0
  155. data/ext/nokogiri/xml_schema.c +276 -0
  156. data/ext/nokogiri/xml_schema.h +9 -0
  157. data/ext/nokogiri/xml_syntax_error.c +64 -0
  158. data/ext/nokogiri/xml_syntax_error.h +13 -0
  159. data/ext/nokogiri/xml_text.c +52 -0
  160. data/ext/nokogiri/xml_text.h +9 -0
  161. data/ext/nokogiri/xml_xpath_context.c +374 -0
  162. data/ext/nokogiri/xml_xpath_context.h +10 -0
  163. data/ext/nokogiri/xslt_stylesheet.c +263 -0
  164. data/ext/nokogiri/xslt_stylesheet.h +14 -0
  165. data/lib/isorelax.jar +0 -0
  166. data/lib/jing.jar +0 -0
  167. data/lib/nekodtd.jar +0 -0
  168. data/lib/nekohtml.jar +0 -0
  169. data/lib/nokogiri/css/node.rb +53 -0
  170. data/lib/nokogiri/css/parser.rb +751 -0
  171. data/lib/nokogiri/css/parser.y +272 -0
  172. data/lib/nokogiri/css/parser_extras.rb +94 -0
  173. data/lib/nokogiri/css/syntax_error.rb +8 -0
  174. data/lib/nokogiri/css/tokenizer.rb +154 -0
  175. data/lib/nokogiri/css/tokenizer.rex +55 -0
  176. data/lib/nokogiri/css/xpath_visitor.rb +260 -0
  177. data/lib/nokogiri/css.rb +28 -0
  178. data/lib/nokogiri/decorators/slop.rb +43 -0
  179. data/lib/nokogiri/html/builder.rb +36 -0
  180. data/lib/nokogiri/html/document.rb +322 -0
  181. data/lib/nokogiri/html/document_fragment.rb +50 -0
  182. data/lib/nokogiri/html/element_description.rb +24 -0
  183. data/lib/nokogiri/html/element_description_defaults.rb +672 -0
  184. data/lib/nokogiri/html/entity_lookup.rb +14 -0
  185. data/lib/nokogiri/html/sax/parser.rb +63 -0
  186. data/lib/nokogiri/html/sax/parser_context.rb +17 -0
  187. data/lib/nokogiri/html/sax/push_parser.rb +37 -0
  188. data/lib/nokogiri/html.rb +38 -0
  189. data/lib/nokogiri/jruby/dependencies.rb +20 -0
  190. data/lib/nokogiri/syntax_error.rb +5 -0
  191. data/lib/nokogiri/version/constant.rb +5 -0
  192. data/lib/nokogiri/version/info.rb +182 -0
  193. data/lib/nokogiri/version.rb +3 -0
  194. data/lib/nokogiri/xml/attr.rb +15 -0
  195. data/lib/nokogiri/xml/attribute_decl.rb +19 -0
  196. data/lib/nokogiri/xml/builder.rb +447 -0
  197. data/lib/nokogiri/xml/cdata.rb +12 -0
  198. data/lib/nokogiri/xml/character_data.rb +8 -0
  199. data/lib/nokogiri/xml/document.rb +290 -0
  200. data/lib/nokogiri/xml/document_fragment.rb +159 -0
  201. data/lib/nokogiri/xml/dtd.rb +33 -0
  202. data/lib/nokogiri/xml/element_content.rb +37 -0
  203. data/lib/nokogiri/xml/element_decl.rb +14 -0
  204. data/lib/nokogiri/xml/entity_decl.rb +20 -0
  205. data/lib/nokogiri/xml/entity_reference.rb +19 -0
  206. data/lib/nokogiri/xml/namespace.rb +14 -0
  207. data/lib/nokogiri/xml/node/save_options.rb +62 -0
  208. data/lib/nokogiri/xml/node.rb +1240 -0
  209. data/lib/nokogiri/xml/node_set.rb +372 -0
  210. data/lib/nokogiri/xml/notation.rb +7 -0
  211. data/lib/nokogiri/xml/parse_options.rb +127 -0
  212. data/lib/nokogiri/xml/pp/character_data.rb +19 -0
  213. data/lib/nokogiri/xml/pp/node.rb +57 -0
  214. data/lib/nokogiri/xml/pp.rb +3 -0
  215. data/lib/nokogiri/xml/processing_instruction.rb +9 -0
  216. data/lib/nokogiri/xml/reader.rb +116 -0
  217. data/lib/nokogiri/xml/relax_ng.rb +37 -0
  218. data/lib/nokogiri/xml/sax/document.rb +172 -0
  219. data/lib/nokogiri/xml/sax/parser.rb +123 -0
  220. data/lib/nokogiri/xml/sax/parser_context.rb +17 -0
  221. data/lib/nokogiri/xml/sax/push_parser.rb +61 -0
  222. data/lib/nokogiri/xml/sax.rb +5 -0
  223. data/lib/nokogiri/xml/schema.rb +72 -0
  224. data/lib/nokogiri/xml/searchable.rb +239 -0
  225. data/lib/nokogiri/xml/syntax_error.rb +71 -0
  226. data/lib/nokogiri/xml/text.rb +10 -0
  227. data/lib/nokogiri/xml/xpath/syntax_error.rb +12 -0
  228. data/lib/nokogiri/xml/xpath.rb +11 -0
  229. data/lib/nokogiri/xml/xpath_context.rb +17 -0
  230. data/lib/nokogiri/xml.rb +76 -0
  231. data/lib/nokogiri/xslt/stylesheet.rb +26 -0
  232. data/lib/nokogiri/xslt.rb +57 -0
  233. data/lib/nokogiri.rb +144 -0
  234. data/lib/serializer.jar +0 -0
  235. data/lib/xalan.jar +0 -0
  236. data/lib/xercesImpl.jar +0 -0
  237. data/lib/xml-apis.jar +0 -0
  238. data/lib/xsd/xmlparser/nokogiri.rb +103 -0
  239. metadata +531 -0
@@ -0,0 +1,507 @@
1
+ /**
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+ package nokogiri.internals.c14n;
20
+
21
+ import java.util.ArrayList;
22
+ import java.util.HashSet;
23
+ import java.util.Iterator;
24
+ import java.util.List;
25
+ import java.util.Set;
26
+
27
+
28
+ import org.w3c.dom.Attr;
29
+ import org.w3c.dom.Document;
30
+ import org.w3c.dom.Element;
31
+ import org.w3c.dom.NamedNodeMap;
32
+ import org.w3c.dom.Node;
33
+ import org.w3c.dom.NodeList;
34
+ import org.w3c.dom.ProcessingInstruction;
35
+ import org.w3c.dom.Text;
36
+
37
+ /**
38
+ * DOM and XML accessibility and comfort functions.
39
+ *
40
+ * @author Christian Geuer-Pollmann
41
+ */
42
+ public class XMLUtils {
43
+
44
+ /**
45
+ * Constructor XMLUtils
46
+ *
47
+ */
48
+ private XMLUtils() {
49
+ // we don't allow instantiation
50
+ }
51
+
52
+ /**
53
+ * Method getFullTextChildrenFromElement
54
+ *
55
+ * @param element
56
+ * @return the string of children
57
+ */
58
+ public static String getFullTextChildrenFromElement(Element element) {
59
+ StringBuilder sb = new StringBuilder();
60
+
61
+ Node child = element.getFirstChild();
62
+ while (child != null) {
63
+ if (child.getNodeType() == Node.TEXT_NODE) {
64
+ sb.append(((Text)child).getData());
65
+ }
66
+ child = child.getNextSibling();
67
+ }
68
+
69
+ return sb.toString();
70
+ }
71
+
72
+ /**
73
+ * This method returns the owner document of a particular node.
74
+ * This method is necessary because it <I>always</I> returns a
75
+ * {@link Document}. {@link Node#getOwnerDocument} returns <CODE>null</CODE>
76
+ * if the {@link Node} is a {@link Document}.
77
+ *
78
+ * @param node
79
+ * @return the owner document of the node
80
+ */
81
+ public static Document getOwnerDocument(Node node) {
82
+ if (node.getNodeType() == Node.DOCUMENT_NODE) {
83
+ return (Document) node;
84
+ }
85
+ try {
86
+ return node.getOwnerDocument();
87
+ } catch (NullPointerException npe) {
88
+ throw new NullPointerException(npe.getMessage());
89
+ }
90
+ }
91
+
92
+ /**
93
+ * This method returns the first non-null owner document of the Nodes in this Set.
94
+ * This method is necessary because it <I>always</I> returns a
95
+ * {@link Document}. {@link Node#getOwnerDocument} returns <CODE>null</CODE>
96
+ * if the {@link Node} is a {@link Document}.
97
+ *
98
+ * @param xpathNodeSet
99
+ * @return the owner document
100
+ */
101
+ public static Document getOwnerDocument(Set<Node> xpathNodeSet) {
102
+ NullPointerException npe = null;
103
+ for (Node node : xpathNodeSet) {
104
+ int nodeType = node.getNodeType();
105
+ if (nodeType == Node.DOCUMENT_NODE) {
106
+ return (Document) node;
107
+ }
108
+ try {
109
+ if (nodeType == Node.ATTRIBUTE_NODE) {
110
+ return ((Attr)node).getOwnerElement().getOwnerDocument();
111
+ }
112
+ return node.getOwnerDocument();
113
+ } catch (NullPointerException e) {
114
+ npe = e;
115
+ }
116
+ }
117
+
118
+ throw new NullPointerException(npe.getMessage());
119
+ }
120
+
121
+ /**
122
+ * Method convertNodelistToSet
123
+ *
124
+ * @param xpathNodeSet
125
+ * @return the set with the nodelist
126
+ */
127
+ public static Set<Node> convertNodelistToSet(NodeList xpathNodeSet) {
128
+ if (xpathNodeSet == null) {
129
+ return new HashSet<Node>();
130
+ }
131
+
132
+ int length = xpathNodeSet.getLength();
133
+ Set<Node> set = new HashSet<Node>(length);
134
+
135
+ for (int i = 0; i < length; i++) {
136
+ set.add(xpathNodeSet.item(i));
137
+ }
138
+
139
+ return set;
140
+ }
141
+
142
+ /**
143
+ * This method spreads all namespace attributes in a DOM document to their
144
+ * children. This is needed because the XML Signature XPath transform
145
+ * must evaluate the XPath against all nodes in the input, even against
146
+ * XPath namespace nodes. Through a bug in XalanJ2, the namespace nodes are
147
+ * not fully visible in the Xalan XPath model, so we have to do this by
148
+ * hand in DOM spaces so that the nodes become visible in XPath space.
149
+ *
150
+ * @param doc
151
+ * @see <A HREF="http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2650">
152
+ * Namespace axis resolution is not XPath compliant </A>
153
+ */
154
+ public static void circumventBug2650(Document doc) {
155
+
156
+ Element documentElement = doc.getDocumentElement();
157
+
158
+ // if the document element has no xmlns definition, we add xmlns=""
159
+ Attr xmlnsAttr =
160
+ documentElement.getAttributeNodeNS(Constants.NamespaceSpecNS, "xmlns");
161
+
162
+ if (xmlnsAttr == null) {
163
+ documentElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns", "");
164
+ }
165
+
166
+ XMLUtils.circumventBug2650internal(doc);
167
+ }
168
+
169
+ /**
170
+ * This is the work horse for {@link #circumventBug2650}.
171
+ *
172
+ * @param node
173
+ * @see <A HREF="http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2650">
174
+ * Namespace axis resolution is not XPath compliant </A>
175
+ */
176
+ @SuppressWarnings("fallthrough")
177
+ private static void circumventBug2650internal(Node node) {
178
+ Node parent = null;
179
+ Node sibling = null;
180
+ final String namespaceNs = Constants.NamespaceSpecNS;
181
+ do {
182
+ switch (node.getNodeType()) {
183
+ case Node.ELEMENT_NODE :
184
+ Element element = (Element) node;
185
+ if (!element.hasChildNodes()) {
186
+ break;
187
+ }
188
+ if (element.hasAttributes()) {
189
+ NamedNodeMap attributes = element.getAttributes();
190
+ int attributesLength = attributes.getLength();
191
+
192
+ for (Node child = element.getFirstChild(); child!=null;
193
+ child = child.getNextSibling()) {
194
+
195
+ if (child.getNodeType() != Node.ELEMENT_NODE) {
196
+ continue;
197
+ }
198
+ Element childElement = (Element) child;
199
+
200
+ for (int i = 0; i < attributesLength; i++) {
201
+ Attr currentAttr = (Attr) attributes.item(i);
202
+ if (!namespaceNs.equals(currentAttr.getNamespaceURI())) {
203
+ continue;
204
+ }
205
+ if (childElement.hasAttributeNS(namespaceNs,
206
+ currentAttr.getLocalName())) {
207
+ continue;
208
+ }
209
+ childElement.setAttributeNS(namespaceNs,
210
+ currentAttr.getName(),
211
+ currentAttr.getNodeValue());
212
+ }
213
+ }
214
+ }
215
+ case Node.ENTITY_REFERENCE_NODE :
216
+ case Node.DOCUMENT_NODE :
217
+ parent = node;
218
+ sibling = node.getFirstChild();
219
+ break;
220
+ }
221
+ while ((sibling == null) && (parent != null)) {
222
+ sibling = parent.getNextSibling();
223
+ parent = parent.getParentNode();
224
+ }
225
+ if (sibling == null) {
226
+ return;
227
+ }
228
+
229
+ node = sibling;
230
+ sibling = node.getNextSibling();
231
+ } while (true);
232
+ }
233
+
234
+ /**
235
+ * @param sibling
236
+ * @param uri
237
+ * @param nodeName
238
+ * @param number
239
+ * @return nodes with the constrain
240
+ */
241
+ public static Text selectNodeText(Node sibling, String uri, String nodeName, int number) {
242
+ Node n = selectNode(sibling,uri,nodeName,number);
243
+ if (n == null) {
244
+ return null;
245
+ }
246
+ n = n.getFirstChild();
247
+ while (n != null && n.getNodeType() != Node.TEXT_NODE) {
248
+ n = n.getNextSibling();
249
+ }
250
+ return (Text)n;
251
+ }
252
+
253
+ /**
254
+ * @param sibling
255
+ * @param uri
256
+ * @param nodeName
257
+ * @param number
258
+ * @return nodes with the constrain
259
+ */
260
+ public static Element selectNode(Node sibling, String uri, String nodeName, int number) {
261
+ while (sibling != null) {
262
+ if (sibling.getNamespaceURI() != null && sibling.getNamespaceURI().equals(uri)
263
+ && sibling.getLocalName().equals(nodeName)) {
264
+ if (number == 0){
265
+ return (Element)sibling;
266
+ }
267
+ number--;
268
+ }
269
+ sibling = sibling.getNextSibling();
270
+ }
271
+ return null;
272
+ }
273
+
274
+ /**
275
+ * @param sibling
276
+ * @param uri
277
+ * @param nodeName
278
+ * @return nodes with the constraint
279
+ */
280
+ public static Element[] selectNodes(Node sibling, String uri, String nodeName) {
281
+ List<Element> list = new ArrayList<Element>();
282
+ while (sibling != null) {
283
+ if (sibling.getNamespaceURI() != null && sibling.getNamespaceURI().equals(uri)
284
+ && sibling.getLocalName().equals(nodeName)) {
285
+ list.add((Element)sibling);
286
+ }
287
+ sibling = sibling.getNextSibling();
288
+ }
289
+ return list.toArray(new Element[list.size()]);
290
+ }
291
+
292
+ /**
293
+ * @param signatureElement
294
+ * @param inputSet
295
+ * @return nodes with the constrain
296
+ */
297
+ public static Set<Node> excludeNodeFromSet(Node signatureElement, Set<Node> inputSet) {
298
+ Set<Node> resultSet = new HashSet<Node>();
299
+ Iterator<Node> iterator = inputSet.iterator();
300
+
301
+ while (iterator.hasNext()) {
302
+ Node inputNode = iterator.next();
303
+
304
+ if (!XMLUtils.isDescendantOrSelf(signatureElement, inputNode)) {
305
+ resultSet.add(inputNode);
306
+ }
307
+ }
308
+ return resultSet;
309
+ }
310
+
311
+ /**
312
+ * Method getStrFromNode
313
+ *
314
+ * @param xpathnode
315
+ * @return the string for the node.
316
+ */
317
+ public static String getStrFromNode(Node xpathnode) {
318
+ if (xpathnode.getNodeType() == Node.TEXT_NODE) {
319
+ // we iterate over all siblings of the context node because eventually,
320
+ // the text is "polluted" with pi's or comments
321
+ StringBuilder sb = new StringBuilder();
322
+
323
+ for (Node currentSibling = xpathnode.getParentNode().getFirstChild();
324
+ currentSibling != null;
325
+ currentSibling = currentSibling.getNextSibling()) {
326
+ if (currentSibling.getNodeType() == Node.TEXT_NODE) {
327
+ sb.append(((Text) currentSibling).getData());
328
+ }
329
+ }
330
+
331
+ return sb.toString();
332
+ } else if (xpathnode.getNodeType() == Node.ATTRIBUTE_NODE) {
333
+ return ((Attr) xpathnode).getNodeValue();
334
+ } else if (xpathnode.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
335
+ return ((ProcessingInstruction) xpathnode).getNodeValue();
336
+ }
337
+
338
+ return null;
339
+ }
340
+
341
+ /**
342
+ * Returns true if the descendantOrSelf is on the descendant-or-self axis
343
+ * of the context node.
344
+ *
345
+ * @param ctx
346
+ * @param descendantOrSelf
347
+ * @return true if the node is descendant
348
+ */
349
+ public static boolean isDescendantOrSelf(Node ctx, Node descendantOrSelf) {
350
+ if (ctx == descendantOrSelf) {
351
+ return true;
352
+ }
353
+
354
+ Node parent = descendantOrSelf;
355
+
356
+ while (true) {
357
+ if (parent == null) {
358
+ return false;
359
+ }
360
+
361
+ if (parent == ctx) {
362
+ return true;
363
+ }
364
+
365
+ if (parent.getNodeType() == Node.ATTRIBUTE_NODE) {
366
+ parent = ((Attr) parent).getOwnerElement();
367
+ } else {
368
+ parent = parent.getParentNode();
369
+ }
370
+ }
371
+ }
372
+
373
+ /**
374
+ * Returns the attribute value for the attribute with the specified name.
375
+ * Returns null if there is no such attribute, or
376
+ * the empty string if the attribute value is empty.
377
+ *
378
+ * <p>This works around a limitation of the DOM
379
+ * <code>Element.getAttributeNode</code> method, which does not distinguish
380
+ * between an unspecified attribute and an attribute with a value of
381
+ * "" (it returns "" for both cases).
382
+ *
383
+ * @param elem the element containing the attribute
384
+ * @param name the name of the attribute
385
+ * @return the attribute value (may be null if unspecified)
386
+ */
387
+ public static String getAttributeValue(Element elem, String name) {
388
+ Attr attr = elem.getAttributeNodeNS(null, name);
389
+ return (attr == null) ? null : attr.getValue();
390
+ }
391
+
392
+ /**
393
+ * This method is a tree-search to help prevent against wrapping attacks. It checks that no
394
+ * two Elements have ID Attributes that match the "value" argument, if this is the case then
395
+ * "false" is returned. Note that a return value of "true" does not necessarily mean that
396
+ * a matching Element has been found, just that no wrapping attack has been detected.
397
+ */
398
+ public static boolean protectAgainstWrappingAttack(Node startNode, String value) {
399
+ Node startParent = startNode.getParentNode();
400
+ Node processedNode;
401
+ Element foundElement = null;
402
+
403
+ String id = value.trim();
404
+ if (id.charAt(0) == '#') {
405
+ id = id.substring(1);
406
+ }
407
+
408
+ while (startNode != null) {
409
+ if (startNode.getNodeType() == Node.ELEMENT_NODE) {
410
+ Element se = (Element) startNode;
411
+
412
+ NamedNodeMap attributes = se.getAttributes();
413
+ if (attributes != null) {
414
+ for (int i = 0; i < attributes.getLength(); i++) {
415
+ Attr attr = (Attr)attributes.item(i);
416
+ if (attr.isId() && id.equals(attr.getValue())) {
417
+ if (foundElement == null) {
418
+ // Continue searching to find duplicates
419
+ foundElement = attr.getOwnerElement();
420
+ } else {
421
+ //log.debug("Multiple elements with the same 'Id' attribute value!");
422
+ return false;
423
+ }
424
+ }
425
+ }
426
+ }
427
+ }
428
+
429
+ processedNode = startNode;
430
+ startNode = startNode.getFirstChild();
431
+
432
+ // no child, this node is done.
433
+ if (startNode == null) {
434
+ // close node processing, get sibling
435
+ startNode = processedNode.getNextSibling();
436
+ }
437
+
438
+ // no more siblings, get parent, all children
439
+ // of parent are processed.
440
+ while (startNode == null) {
441
+ processedNode = processedNode.getParentNode();
442
+ if (processedNode == startParent) {
443
+ return true;
444
+ }
445
+ // close parent node processing (processed node now)
446
+ startNode = processedNode.getNextSibling();
447
+ }
448
+ }
449
+ return true;
450
+ }
451
+
452
+ /**
453
+ * This method is a tree-search to help prevent against wrapping attacks. It checks that no other
454
+ * Element than the given "knownElement" argument has an ID attribute that matches the "value"
455
+ * argument, which is the ID value of "knownElement". If this is the case then "false" is returned.
456
+ */
457
+ public static boolean protectAgainstWrappingAttack(
458
+ Node startNode, Element knownElement, String value
459
+ ) {
460
+ Node startParent = startNode.getParentNode();
461
+ Node processedNode;
462
+
463
+ String id = value.trim();
464
+ if (id.charAt(0) == '#') {
465
+ id = id.substring(1);
466
+ }
467
+
468
+ while (startNode != null) {
469
+ if (startNode.getNodeType() == Node.ELEMENT_NODE) {
470
+ Element se = (Element) startNode;
471
+
472
+ NamedNodeMap attributes = se.getAttributes();
473
+ if (attributes != null) {
474
+ for (int i = 0; i < attributes.getLength(); i++) {
475
+ Attr attr = (Attr)attributes.item(i);
476
+ if (attr.isId() && id.equals(attr.getValue()) && se != knownElement) {
477
+ //log.debug("Multiple elements with the same 'Id' attribute value!");
478
+ return false;
479
+ }
480
+ }
481
+ }
482
+ }
483
+
484
+ processedNode = startNode;
485
+ startNode = startNode.getFirstChild();
486
+
487
+ // no child, this node is done.
488
+ if (startNode == null) {
489
+ // close node processing, get sibling
490
+ startNode = processedNode.getNextSibling();
491
+ }
492
+
493
+ // no more siblings, get parent, all children
494
+ // of parent are processed.
495
+ while (startNode == null) {
496
+ processedNode = processedNode.getParentNode();
497
+ if (processedNode == startParent) {
498
+ return true;
499
+ }
500
+ // close parent node processing (processed node now)
501
+ startNode = processedNode.getNextSibling();
502
+ }
503
+ }
504
+ return true;
505
+ }
506
+
507
+ }