src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java

Print this page

        

*** 1,29 **** /* * reserved comment block * DO NOT REMOVE OR ALTER! */ ! /* ! * Copyright 1999-2004 The Apache Software Foundation. ! * ! * Licensed under the Apache License, Version 2.0 (the "License"); ! * you may not use this file except in compliance with the License. ! * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * ! * Unless required by applicable law or agreed to in writing, software ! * distributed under the License is distributed on an "AS IS" BASIS, ! * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ! * See the License for the specific language governing permissions and ! * limitations under the License. ! * */ package com.sun.org.apache.xml.internal.security.c14n.implementations; - - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; --- 1,29 ---- /* * reserved comment block * DO NOT REMOVE OR ALTER! */ ! /** ! * Licensed to the Apache Software Foundation (ASF) under one ! * or more contributor license agreements. See the NOTICE file ! * distributed with this work for additional information ! * regarding copyright ownership. The ASF licenses this file ! * to you under the Apache License, Version 2.0 (the ! * "License"); you may not use this file except in compliance ! * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * ! * Unless required by applicable law or agreed to in writing, ! * software distributed under the License is distributed on an ! * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ! * KIND, either express or implied. See the License for the ! * specific language governing permissions and limitations ! * under the License. */ package com.sun.org.apache.xml.internal.security.c14n.implementations; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList;
*** 31,46 **** import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Set; - import java.util.SortedSet; - import java.util.Collection; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; - import javax.xml.xpath.XPath; import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException; import com.sun.org.apache.xml.internal.security.c14n.CanonicalizerSpi; import com.sun.org.apache.xml.internal.security.c14n.helper.AttrCompare; import com.sun.org.apache.xml.internal.security.signature.NodeFilter; --- 31,44 ---- import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Set; + import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException; import com.sun.org.apache.xml.internal.security.c14n.CanonicalizerSpi; import com.sun.org.apache.xml.internal.security.c14n.helper.AttrCompare; import com.sun.org.apache.xml.internal.security.signature.NodeFilter;
*** 54,177 **** import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.ProcessingInstruction; import org.xml.sax.SAXException; - /** * Abstract base class for canonicalization algorithms. * * @author Christian Geuer-Pollmann <geuerp@apache.org> - * @version $Revision: 1.5 $ */ public abstract class CanonicalizerBase extends CanonicalizerSpi { ! //Constants to be outputed, In char array form, so ! //less garbage is generate when outputed. ! private static final byte[] _END_PI = {'?','>'}; ! private static final byte[] _BEGIN_PI = {'<','?'}; ! private static final byte[] _END_COMM = {'-','-','>'}; ! private static final byte[] _BEGIN_COMM = {'<','!','-','-'}; ! private static final byte[] __XA_ = {'&','#','x','A',';'}; ! private static final byte[] __X9_ = {'&','#','x','9',';'}; ! private static final byte[] _QUOT_ = {'&','q','u','o','t',';'}; ! private static final byte[] __XD_ = {'&','#','x','D',';'}; ! private static final byte[] _GT_ = {'&','g','t',';'}; ! private static final byte[] _LT_ = {'&','l','t',';'}; ! private static final byte[] _END_TAG = {'<','/'}; ! private static final byte[] _AMP_ = {'&','a','m','p',';'}; ! final static AttrCompare COMPARE=new AttrCompare(); ! final static String XML="xml"; ! final static String XMLNS="xmlns"; ! final static byte[] equalsStr= {'=','\"'}; ! static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1; ! static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0; ! static final int NODE_AFTER_DOCUMENT_ELEMENT = 1; ! //The null xmlns definiton. protected static final Attr nullNode; static { try { ! nullNode=DocumentBuilderFactory.newInstance(). ! newDocumentBuilder().newDocument().createAttributeNS(Constants.NamespaceSpecNS,XMLNS); nullNode.setValue(""); } catch (Exception e) { ! throw new RuntimeException("Unable to create nullNode"/*,*/+e); } } ! List<NodeFilter> nodeFilter; ! boolean _includeComments; ! Set<Node> _xpathNodeSet = null; /** ! * The node to be skiped/excluded from the DOM tree * in subtree canonicalizations. */ ! Node _excludeNode =null; ! OutputStream _writer = new UnsyncByteArrayOutputStream();//null; /** * Constructor CanonicalizerBase * * @param includeComments */ public CanonicalizerBase(boolean includeComments) { ! this._includeComments = includeComments; } /** * Method engineCanonicalizeSubTree * @inheritDoc * @param rootNode * @throws CanonicalizationException */ public byte[] engineCanonicalizeSubTree(Node rootNode) throws CanonicalizationException { ! return engineCanonicalizeSubTree(rootNode,(Node)null); } /** * Method engineCanonicalizeXPathNodeSet * @inheritDoc * @param xpathNodeSet * @throws CanonicalizationException */ public byte[] engineCanonicalizeXPathNodeSet(Set<Node> xpathNodeSet) throws CanonicalizationException { ! this._xpathNodeSet = xpathNodeSet; ! return engineCanonicalizeXPathNodeSetInternal(XMLUtils.getOwnerDocument(this._xpathNodeSet)); } /** * Canonicalizes a Subtree node. * @param input the root of the subtree to canicalize * @return The canonicalize stream. * @throws CanonicalizationException */ ! public byte[] engineCanonicalize(XMLSignatureInput input) ! throws CanonicalizationException { try { ! if (input.isExcludeComments()) ! _includeComments = false; ! byte[] bytes; if (input.isOctetStream()) { return engineCanonicalize(input.getBytes()); } if (input.isElement()) { ! bytes = engineCanonicalizeSubTree(input.getSubNode(), input ! .getExcludeNode()); ! return bytes; } else if (input.isNodeSet()) { ! nodeFilter=input.getNodeFilters(); circumventBugIfNeeded(input); if (input.getSubNode() != null) { ! bytes = engineCanonicalizeXPathNodeSetInternal(input.getSubNode()); } else { ! bytes = engineCanonicalizeXPathNodeSet(input.getNodeSet()); } - return bytes; - } return null; } catch (CanonicalizationException ex) { throw new CanonicalizationException("empty", ex); } catch (ParserConfigurationException ex) { --- 52,171 ---- import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.ProcessingInstruction; import org.xml.sax.SAXException; /** * Abstract base class for canonicalization algorithms. * * @author Christian Geuer-Pollmann <geuerp@apache.org> */ public abstract class CanonicalizerBase extends CanonicalizerSpi { ! public static final String XML = "xml"; ! public static final String XMLNS = "xmlns"; ! ! protected static final AttrCompare COMPARE = new AttrCompare(); protected static final Attr nullNode; + + private static final byte[] END_PI = {'?','>'}; + private static final byte[] BEGIN_PI = {'<','?'}; + private static final byte[] END_COMM = {'-','-','>'}; + private static final byte[] BEGIN_COMM = {'<','!','-','-'}; + private static final byte[] XA = {'&','#','x','A',';'}; + private static final byte[] X9 = {'&','#','x','9',';'}; + private static final byte[] QUOT = {'&','q','u','o','t',';'}; + private static final byte[] XD = {'&','#','x','D',';'}; + private static final byte[] GT = {'&','g','t',';'}; + private static final byte[] LT = {'&','l','t',';'}; + private static final byte[] END_TAG = {'<','/'}; + private static final byte[] AMP = {'&','a','m','p',';'}; + private static final byte[] equalsStr = {'=','\"'}; + + protected static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1; + protected static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0; + protected static final int NODE_AFTER_DOCUMENT_ELEMENT = 1; + static { + // The null xmlns definition. try { ! DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); ! nullNode = documentBuilder.newDocument().createAttributeNS(Constants.NamespaceSpecNS, XMLNS); nullNode.setValue(""); } catch (Exception e) { ! throw new RuntimeException("Unable to create nullNode: " + e); } } ! private List<NodeFilter> nodeFilter; ! private boolean includeComments; ! private Set<Node> xpathNodeSet; /** ! * The node to be skipped/excluded from the DOM tree * in subtree canonicalizations. */ ! private Node excludeNode; ! private OutputStream writer = new ByteArrayOutputStream(); /** * Constructor CanonicalizerBase * * @param includeComments */ public CanonicalizerBase(boolean includeComments) { ! this.includeComments = includeComments; } /** * Method engineCanonicalizeSubTree * @inheritDoc * @param rootNode * @throws CanonicalizationException */ public byte[] engineCanonicalizeSubTree(Node rootNode) throws CanonicalizationException { ! return engineCanonicalizeSubTree(rootNode, (Node)null); } + /** * Method engineCanonicalizeXPathNodeSet * @inheritDoc * @param xpathNodeSet * @throws CanonicalizationException */ public byte[] engineCanonicalizeXPathNodeSet(Set<Node> xpathNodeSet) throws CanonicalizationException { ! this.xpathNodeSet = xpathNodeSet; ! return engineCanonicalizeXPathNodeSetInternal(XMLUtils.getOwnerDocument(this.xpathNodeSet)); } /** * Canonicalizes a Subtree node. * @param input the root of the subtree to canicalize * @return The canonicalize stream. * @throws CanonicalizationException */ ! public byte[] engineCanonicalize(XMLSignatureInput input) throws CanonicalizationException { try { ! if (input.isExcludeComments()) { ! includeComments = false; ! } if (input.isOctetStream()) { return engineCanonicalize(input.getBytes()); } if (input.isElement()) { ! return engineCanonicalizeSubTree(input.getSubNode(), input.getExcludeNode()); } else if (input.isNodeSet()) { ! nodeFilter = input.getNodeFilters(); circumventBugIfNeeded(input); if (input.getSubNode() != null) { ! return engineCanonicalizeXPathNodeSetInternal(input.getSubNode()); } else { ! return engineCanonicalizeXPathNodeSet(input.getNodeSet()); } } return null; } catch (CanonicalizationException ex) { throw new CanonicalizationException("empty", ex); } catch (ParserConfigurationException ex) {
*** 180,231 **** throw new CanonicalizationException("empty", ex); } catch (SAXException ex) { throw new CanonicalizationException("empty", ex); } } /** ! * @param _writer The _writer to set. */ ! public void setWriter(OutputStream _writer) { ! this._writer = _writer; } /** * Canonicalizes a Subtree node. * * @param rootNode ! * the root of the subtree to canicalize * @param excludeNode ! * a node to be excluded from the canicalize operation * @return The canonicalize stream. * @throws CanonicalizationException */ ! byte[] engineCanonicalizeSubTree(Node rootNode,Node excludeNode) throws CanonicalizationException { ! this._excludeNode = excludeNode; try { ! NameSpaceSymbTable ns=new NameSpaceSymbTable(); ! int nodeLevel=NODE_BEFORE_DOCUMENT_ELEMENT; ! if (rootNode != null && rootNode.getNodeType() == Node.ELEMENT_NODE) { //Fills the nssymbtable with the definitions of the parent of the root subnode ! getParentNameSpaces((Element)rootNode,ns); ! nodeLevel=NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; } ! this.canonicalizeSubTree(rootNode,ns,rootNode,nodeLevel); ! this._writer.close(); ! if (this._writer instanceof ByteArrayOutputStream) { ! byte []result=((ByteArrayOutputStream)this._writer).toByteArray(); if (reset) { ! ((ByteArrayOutputStream)this._writer).reset(); } return result; ! } else if (this._writer instanceof UnsyncByteArrayOutputStream) { ! byte []result=((UnsyncByteArrayOutputStream)this._writer).toByteArray(); if (reset) { ! ((UnsyncByteArrayOutputStream)this._writer).reset(); } return result; } return null; } catch (UnsupportedEncodingException ex) { throw new CanonicalizationException("empty", ex); --- 174,232 ---- throw new CanonicalizationException("empty", ex); } catch (SAXException ex) { throw new CanonicalizationException("empty", ex); } } + /** ! * @param writer The writer to set. */ ! public void setWriter(OutputStream writer) { ! this.writer = writer; } /** * Canonicalizes a Subtree node. * * @param rootNode ! * the root of the subtree to canonicalize * @param excludeNode ! * a node to be excluded from the canonicalize operation * @return The canonicalize stream. * @throws CanonicalizationException */ ! protected byte[] engineCanonicalizeSubTree(Node rootNode, Node excludeNode) throws CanonicalizationException { ! this.excludeNode = excludeNode; try { ! NameSpaceSymbTable ns = new NameSpaceSymbTable(); ! int nodeLevel = NODE_BEFORE_DOCUMENT_ELEMENT; ! if (rootNode != null && Node.ELEMENT_NODE == rootNode.getNodeType()) { //Fills the nssymbtable with the definitions of the parent of the root subnode ! getParentNameSpaces((Element)rootNode, ns); ! nodeLevel = NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; } ! this.canonicalizeSubTree(rootNode, ns, rootNode, nodeLevel); ! this.writer.flush(); ! if (this.writer instanceof ByteArrayOutputStream) { ! byte[] result = ((ByteArrayOutputStream)this.writer).toByteArray(); if (reset) { ! ((ByteArrayOutputStream)this.writer).reset(); ! } else { ! this.writer.close(); } return result; ! } else if (this.writer instanceof UnsyncByteArrayOutputStream) { ! byte[] result = ((UnsyncByteArrayOutputStream)this.writer).toByteArray(); if (reset) { ! ((UnsyncByteArrayOutputStream)this.writer).reset(); ! } else { ! this.writer.close(); } return result; + } else { + this.writer.close(); } return null; } catch (UnsupportedEncodingException ex) { throw new CanonicalizationException("empty", ex);
*** 242,279 **** * @param ns * @param endnode * @throws CanonicalizationException * @throws IOException */ ! final void canonicalizeSubTree(Node currentNode, NameSpaceSymbTable ns,Node endnode, ! int documentLevel) ! throws CanonicalizationException, IOException { ! if (isVisibleInt(currentNode)==-1) return; ! Node sibling=null; ! Node parentNode=null; ! final OutputStream writer=this._writer; ! final Node excludeNode=this._excludeNode; ! final boolean includeComments=this._includeComments; ! Map<String, byte[]> cache=new HashMap<String, byte[]>(); do { switch (currentNode.getNodeType()) { - case Node.DOCUMENT_TYPE_NODE : - default : - break; - case Node.ENTITY_NODE : case Node.NOTATION_NODE : case Node.ATTRIBUTE_NODE : // illegal node type during traversal throw new CanonicalizationException("empty"); case Node.DOCUMENT_FRAGMENT_NODE : case Node.DOCUMENT_NODE : ns.outputNodePush(); ! sibling= currentNode.getFirstChild(); break; case Node.COMMENT_NODE : if (includeComments) { outputCommentToWriter((Comment) currentNode, writer, documentLevel); --- 243,277 ---- * @param ns * @param endnode * @throws CanonicalizationException * @throws IOException */ ! protected final void canonicalizeSubTree( ! Node currentNode, NameSpaceSymbTable ns, Node endnode, int documentLevel ! ) throws CanonicalizationException, IOException { ! if (isVisibleInt(currentNode) == -1) { return; ! } ! Node sibling = null; ! Node parentNode = null; ! final OutputStream writer = this.writer; ! final Node excludeNode = this.excludeNode; ! final boolean includeComments = this.includeComments; ! Map<String, byte[]> cache = new HashMap<String, byte[]>(); do { switch (currentNode.getNodeType()) { case Node.ENTITY_NODE : case Node.NOTATION_NODE : case Node.ATTRIBUTE_NODE : // illegal node type during traversal throw new CanonicalizationException("empty"); case Node.DOCUMENT_FRAGMENT_NODE : case Node.DOCUMENT_NODE : ns.outputNodePush(); ! sibling = currentNode.getFirstChild(); break; case Node.COMMENT_NODE : if (includeComments) { outputCommentToWriter((Comment) currentNode, writer, documentLevel);
*** 288,645 **** case Node.CDATA_SECTION_NODE : outputTextToWriter(currentNode.getNodeValue(), writer); break; case Node.ELEMENT_NODE : ! documentLevel=NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; ! if (currentNode==excludeNode) { break; } ! Element currentElement = (Element) currentNode; //Add a level to the nssymbtable. So latter can be pop-back. ns.outputNodePush(); writer.write('<'); ! String name=currentElement.getTagName(); ! UtfHelpper.writeByte(name,writer,cache); ! Iterator<Attr> attrs = this.handleAttributesSubtree(currentElement,ns); ! if (attrs!=null) { //we output all Attrs which are available while (attrs.hasNext()) { Attr attr = attrs.next(); ! outputAttrToWriter(attr.getNodeName(),attr.getNodeValue(), writer,cache); } } writer.write('>'); ! sibling= currentNode.getFirstChild(); ! if (sibling==null) { ! writer.write(_END_TAG); ! UtfHelpper.writeStringToUtf8(name,writer); writer.write('>'); ! //We fineshed with this level, pop to the previous definitions. ns.outputNodePop(); if (parentNode != null) { ! sibling= currentNode.getNextSibling(); } } else { ! parentNode=currentElement; } break; } ! while (sibling==null && parentNode!=null) { ! writer.write(_END_TAG); ! UtfHelpper.writeByte(((Element)parentNode).getTagName(),writer,cache); writer.write('>'); ! //We fineshed with this level, pop to the previous definitions. ns.outputNodePop(); ! if (parentNode==endnode) return; ! sibling=parentNode.getNextSibling(); ! parentNode=parentNode.getParentNode(); ! if (parentNode !=null && parentNode.getNodeType() != Node.ELEMENT_NODE) { ! documentLevel=NODE_AFTER_DOCUMENT_ELEMENT; ! parentNode=null; } } ! if (sibling==null) return; ! currentNode=sibling; ! sibling=currentNode.getNextSibling(); } while(true); } - private byte[] engineCanonicalizeXPathNodeSetInternal(Node doc) throws CanonicalizationException { - try { ! this.canonicalizeXPathNodeSet(doc,doc); ! this._writer.close(); ! if (this._writer instanceof ByteArrayOutputStream) { ! byte [] sol=((ByteArrayOutputStream)this._writer).toByteArray(); if (reset) { ! ((ByteArrayOutputStream)this._writer).reset(); } return sol; ! } else if (this._writer instanceof UnsyncByteArrayOutputStream) { ! byte []result=((UnsyncByteArrayOutputStream)this._writer).toByteArray(); if (reset) { ! ((UnsyncByteArrayOutputStream)this._writer).reset(); } return result; } return null; } catch (UnsupportedEncodingException ex) { throw new CanonicalizationException("empty", ex); } catch (IOException ex) { throw new CanonicalizationException("empty", ex); } } /** ! * Canoicalizes all the nodes included in the currentNode and contained in the ! * _xpathNodeSet field. * * @param currentNode * @param endnode * @throws CanonicalizationException * @throws IOException */ ! final void canonicalizeXPathNodeSet(Node currentNode,Node endnode ) throws CanonicalizationException, IOException { ! if (isVisibleInt(currentNode)==-1) return; boolean currentNodeIsVisible = false; ! NameSpaceSymbTable ns=new NameSpaceSymbTable(); ! if (currentNode != null && currentNode.getNodeType() == Node.ELEMENT_NODE) ! getParentNameSpaces((Element)currentNode,ns); ! Node sibling=null; ! Node parentNode=null; ! OutputStream writer=this._writer; ! int documentLevel=NODE_BEFORE_DOCUMENT_ELEMENT; ! Map<String, byte[]> cache=new HashMap<String,byte[]>(); do { switch (currentNode.getNodeType()) { - case Node.DOCUMENT_TYPE_NODE : - default : - break; - case Node.ENTITY_NODE : case Node.NOTATION_NODE : case Node.ATTRIBUTE_NODE : // illegal node type during traversal throw new CanonicalizationException("empty"); case Node.DOCUMENT_FRAGMENT_NODE : case Node.DOCUMENT_NODE : ns.outputNodePush(); ! //currentNode = currentNode.getFirstChild(); ! sibling= currentNode.getFirstChild(); break; case Node.COMMENT_NODE : ! if (this._includeComments && (isVisibleDO(currentNode,ns.getLevel())==1)) { outputCommentToWriter((Comment) currentNode, writer, documentLevel); } break; case Node.PROCESSING_INSTRUCTION_NODE : ! if (isVisible(currentNode)) outputPItoWriter((ProcessingInstruction) currentNode, writer, documentLevel); break; case Node.TEXT_NODE : case Node.CDATA_SECTION_NODE : if (isVisible(currentNode)) { outputTextToWriter(currentNode.getNodeValue(), writer); for (Node nextSibling = currentNode.getNextSibling(); ! (nextSibling != null) ! && ((nextSibling.getNodeType() == Node.TEXT_NODE) ! || (nextSibling.getNodeType() ! == Node.CDATA_SECTION_NODE)); nextSibling = nextSibling.getNextSibling()) { outputTextToWriter(nextSibling.getNodeValue(), writer); ! currentNode=nextSibling; ! sibling=currentNode.getNextSibling(); } - } break; case Node.ELEMENT_NODE : ! documentLevel=NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; Element currentElement = (Element) currentNode; //Add a level to the nssymbtable. So latter can be pop-back. ! String name=null; ! int i=isVisibleDO(currentNode,ns.getLevel()); ! if (i==-1) { ! sibling= currentNode.getNextSibling(); break; } ! currentNodeIsVisible=(i==1); if (currentNodeIsVisible) { ns.outputNodePush(); writer.write('<'); ! name=currentElement.getTagName(); ! UtfHelpper.writeByte(name,writer,cache); } else { ns.push(); } Iterator<Attr> attrs = handleAttributes(currentElement,ns); ! if (attrs!=null) { //we output all Attrs which are available while (attrs.hasNext()) { Attr attr = attrs.next(); ! outputAttrToWriter(attr.getNodeName(),attr.getNodeValue(), writer,cache); } } if (currentNodeIsVisible) { writer.write('>'); } ! sibling= currentNode.getFirstChild(); ! if (sibling==null) { if (currentNodeIsVisible) { ! writer.write(_END_TAG); ! UtfHelpper.writeByte(name,writer,cache); writer.write('>'); ! //We fineshed with this level, pop to the previous definitions. ns.outputNodePop(); } else { ns.pop(); } if (parentNode != null) { ! sibling= currentNode.getNextSibling(); } } else { ! parentNode=currentElement; } break; } ! while (sibling==null && parentNode!=null) { if (isVisible(parentNode)) { ! writer.write(_END_TAG); ! UtfHelpper.writeByte(((Element)parentNode).getTagName(),writer,cache); writer.write('>'); ! //We fineshed with this level, pop to the previous definitions. ns.outputNodePop(); } else { ns.pop(); } ! if (parentNode==endnode) return; ! sibling=parentNode.getNextSibling(); ! parentNode=parentNode.getParentNode(); ! if (parentNode != null && parentNode.getNodeType() != Node.ELEMENT_NODE) { ! parentNode=null; ! documentLevel=NODE_AFTER_DOCUMENT_ELEMENT; } } ! if (sibling==null) return; ! currentNode=sibling; ! sibling=currentNode.getNextSibling(); } while(true); } ! int isVisibleDO(Node currentNode,int level) { ! if (nodeFilter!=null) { ! Iterator<NodeFilter> it=nodeFilter.iterator(); while (it.hasNext()) { ! int i=(it.next()).isNodeIncludeDO(currentNode,level); ! if (i!=1) return i; } } ! if ((this._xpathNodeSet!=null) && !this._xpathNodeSet.contains(currentNode)) return 0; return 1; } ! int isVisibleInt(Node currentNode) { ! if (nodeFilter!=null) { ! Iterator<NodeFilter> it=nodeFilter.iterator(); while (it.hasNext()) { ! int i=(it.next()).isNodeInclude(currentNode); ! if (i!=1) return i; } } ! if ((this._xpathNodeSet!=null) && !this._xpathNodeSet.contains(currentNode)) return 0; return 1; } ! boolean isVisible(Node currentNode) { ! if (nodeFilter!=null) { ! Iterator<NodeFilter> it=nodeFilter.iterator(); while (it.hasNext()) { ! if ((it.next()).isNodeInclude(currentNode)!=1) return false; } } ! if ((this._xpathNodeSet!=null) && !this._xpathNodeSet.contains(currentNode)) return false; return true; } ! void handleParent(Element e,NameSpaceSymbTable ns) { ! if (!e.hasAttributes()) { return; } NamedNodeMap attrs = e.getAttributes(); int attrsLength = attrs.getLength(); for (int i = 0; i < attrsLength; i++) { ! Attr N = (Attr) attrs.item(i); ! if (Constants.NamespaceSpecNS!=N.getNamespaceURI()) { ! //Not a namespace definition, ignore. ! continue; ! } ! String NName=N.getLocalName(); ! String NValue=N.getNodeValue(); ! if (XML.equals(NName) ! && Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) { ! continue; } ! ns.addMapping(NName,NValue,N); } } /** ! * Adds to ns the definitons from the parent elements of el * @param el * @param ns */ ! final void getParentNameSpaces(Element el,NameSpaceSymbTable ns) { ! List<Element> parents=new ArrayList<Element>(10); ! Node n1=el.getParentNode(); ! if (n1 == null || n1.getNodeType() != Node.ELEMENT_NODE) { return; } ! //Obtain all the parents of the elemnt Node parent = n1; ! while (parent!=null && parent.getNodeType() == Node.ELEMENT_NODE) { parents.add((Element)parent); parent = parent.getParentNode(); } //Visit them in reverse order. ! ListIterator<Element> it=parents.listIterator(parents.size()); while (it.hasPrevious()) { ! Element ele=it.previous(); handleParent(ele, ns); } Attr nsprefix; ! if (((nsprefix=ns.getMappingWithoutRendered("xmlns"))!=null) && "".equals(nsprefix.getValue())) { ! ns.addMappingAndRender("xmlns","",nullNode); } } /** * Obtain the attributes to output for this node in XPathNodeSet c14n. * ! * @param E * @param ns * @return the attributes nodes to output. * @throws CanonicalizationException */ ! abstract Iterator<Attr> handleAttributes(Element E, NameSpaceSymbTable ns ) throws CanonicalizationException; /** * Obtain the attributes to output for this node in a Subtree c14n. * ! * @param E * @param ns * @return the attributes nodes to output. * @throws CanonicalizationException */ ! abstract Iterator<Attr> handleAttributesSubtree(Element E, NameSpaceSymbTable ns) throws CanonicalizationException; ! abstract void circumventBugIfNeeded(XMLSignatureInput input) throws CanonicalizationException, ParserConfigurationException, IOException, SAXException; /** * Outputs an Attribute to the internal Writer. * * The string value of the node is modified by replacing --- 286,677 ---- case Node.CDATA_SECTION_NODE : outputTextToWriter(currentNode.getNodeValue(), writer); break; case Node.ELEMENT_NODE : ! documentLevel = NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; ! if (currentNode == excludeNode) { break; } ! Element currentElement = (Element)currentNode; //Add a level to the nssymbtable. So latter can be pop-back. ns.outputNodePush(); writer.write('<'); ! String name = currentElement.getTagName(); ! UtfHelpper.writeByte(name, writer, cache); ! Iterator<Attr> attrs = this.handleAttributesSubtree(currentElement, ns); ! if (attrs != null) { //we output all Attrs which are available while (attrs.hasNext()) { Attr attr = attrs.next(); ! outputAttrToWriter(attr.getNodeName(), attr.getNodeValue(), writer, cache); } } writer.write('>'); ! sibling = currentNode.getFirstChild(); ! if (sibling == null) { ! writer.write(END_TAG); ! UtfHelpper.writeStringToUtf8(name, writer); writer.write('>'); ! //We finished with this level, pop to the previous definitions. ns.outputNodePop(); if (parentNode != null) { ! sibling = currentNode.getNextSibling(); } } else { ! parentNode = currentElement; } break; + + case Node.DOCUMENT_TYPE_NODE : + default : + break; } ! while (sibling == null && parentNode != null) { ! writer.write(END_TAG); ! UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache); writer.write('>'); ! //We finished with this level, pop to the previous definitions. ns.outputNodePop(); ! if (parentNode == endnode) { return; ! } ! sibling = parentNode.getNextSibling(); ! parentNode = parentNode.getParentNode(); ! if (parentNode == null || Node.ELEMENT_NODE != parentNode.getNodeType()) { ! documentLevel = NODE_AFTER_DOCUMENT_ELEMENT; ! parentNode = null; } } ! if (sibling == null) { return; ! } ! currentNode = sibling; ! sibling = currentNode.getNextSibling(); } while(true); } private byte[] engineCanonicalizeXPathNodeSetInternal(Node doc) throws CanonicalizationException { try { ! this.canonicalizeXPathNodeSet(doc, doc); ! this.writer.flush(); ! if (this.writer instanceof ByteArrayOutputStream) { ! byte[] sol = ((ByteArrayOutputStream)this.writer).toByteArray(); if (reset) { ! ((ByteArrayOutputStream)this.writer).reset(); ! } else { ! this.writer.close(); } return sol; ! } else if (this.writer instanceof UnsyncByteArrayOutputStream) { ! byte[] result = ((UnsyncByteArrayOutputStream)this.writer).toByteArray(); if (reset) { ! ((UnsyncByteArrayOutputStream)this.writer).reset(); ! } else { ! this.writer.close(); } return result; + } else { + this.writer.close(); } return null; } catch (UnsupportedEncodingException ex) { throw new CanonicalizationException("empty", ex); } catch (IOException ex) { throw new CanonicalizationException("empty", ex); } } /** ! * Canonicalizes all the nodes included in the currentNode and contained in the ! * xpathNodeSet field. * * @param currentNode * @param endnode * @throws CanonicalizationException * @throws IOException */ ! protected final void canonicalizeXPathNodeSet(Node currentNode, Node endnode) throws CanonicalizationException, IOException { ! if (isVisibleInt(currentNode) == -1) { return; + } boolean currentNodeIsVisible = false; ! NameSpaceSymbTable ns = new NameSpaceSymbTable(); ! if (currentNode != null && Node.ELEMENT_NODE == currentNode.getNodeType()) { ! getParentNameSpaces((Element)currentNode, ns); ! } ! if (currentNode == null) { ! return; ! } ! Node sibling = null; ! Node parentNode = null; ! OutputStream writer = this.writer; ! int documentLevel = NODE_BEFORE_DOCUMENT_ELEMENT; ! Map<String, byte[]> cache = new HashMap<String, byte[]>(); do { switch (currentNode.getNodeType()) { case Node.ENTITY_NODE : case Node.NOTATION_NODE : case Node.ATTRIBUTE_NODE : // illegal node type during traversal throw new CanonicalizationException("empty"); case Node.DOCUMENT_FRAGMENT_NODE : case Node.DOCUMENT_NODE : ns.outputNodePush(); ! sibling = currentNode.getFirstChild(); break; case Node.COMMENT_NODE : ! if (this.includeComments && (isVisibleDO(currentNode, ns.getLevel()) == 1)) { outputCommentToWriter((Comment) currentNode, writer, documentLevel); } break; case Node.PROCESSING_INSTRUCTION_NODE : ! if (isVisible(currentNode)) { outputPItoWriter((ProcessingInstruction) currentNode, writer, documentLevel); + } break; case Node.TEXT_NODE : case Node.CDATA_SECTION_NODE : if (isVisible(currentNode)) { outputTextToWriter(currentNode.getNodeValue(), writer); for (Node nextSibling = currentNode.getNextSibling(); ! (nextSibling != null) && ((nextSibling.getNodeType() == Node.TEXT_NODE) ! || (nextSibling.getNodeType() == Node.CDATA_SECTION_NODE)); nextSibling = nextSibling.getNextSibling()) { outputTextToWriter(nextSibling.getNodeValue(), writer); ! currentNode = nextSibling; ! sibling = currentNode.getNextSibling(); } } break; case Node.ELEMENT_NODE : ! documentLevel = NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT; Element currentElement = (Element) currentNode; //Add a level to the nssymbtable. So latter can be pop-back. ! String name = null; ! int i = isVisibleDO(currentNode, ns.getLevel()); ! if (i == -1) { ! sibling = currentNode.getNextSibling(); break; } ! currentNodeIsVisible = (i == 1); if (currentNodeIsVisible) { ns.outputNodePush(); writer.write('<'); ! name = currentElement.getTagName(); ! UtfHelpper.writeByte(name, writer, cache); } else { ns.push(); } Iterator<Attr> attrs = handleAttributes(currentElement,ns); ! if (attrs != null) { //we output all Attrs which are available while (attrs.hasNext()) { Attr attr = attrs.next(); ! outputAttrToWriter(attr.getNodeName(), attr.getNodeValue(), writer, cache); } } if (currentNodeIsVisible) { writer.write('>'); } ! sibling = currentNode.getFirstChild(); ! if (sibling == null) { if (currentNodeIsVisible) { ! writer.write(END_TAG); ! UtfHelpper.writeByte(name, writer, cache); writer.write('>'); ! //We finished with this level, pop to the previous definitions. ns.outputNodePop(); } else { ns.pop(); } if (parentNode != null) { ! sibling = currentNode.getNextSibling(); } } else { ! parentNode = currentElement; } break; + + case Node.DOCUMENT_TYPE_NODE : + default : + break; } ! while (sibling == null && parentNode != null) { if (isVisible(parentNode)) { ! writer.write(END_TAG); ! UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache); writer.write('>'); ! //We finished with this level, pop to the previous definitions. ns.outputNodePop(); } else { ns.pop(); } ! if (parentNode == endnode) { return; ! } ! sibling = parentNode.getNextSibling(); ! parentNode = parentNode.getParentNode(); ! if (parentNode == null || Node.ELEMENT_NODE != parentNode.getNodeType()) { ! parentNode = null; ! documentLevel = NODE_AFTER_DOCUMENT_ELEMENT; } } ! if (sibling == null) { return; ! } ! currentNode = sibling; ! sibling = currentNode.getNextSibling(); } while(true); } ! ! protected int isVisibleDO(Node currentNode, int level) { ! if (nodeFilter != null) { ! Iterator<NodeFilter> it = nodeFilter.iterator(); while (it.hasNext()) { ! int i = (it.next()).isNodeIncludeDO(currentNode, level); ! if (i != 1) { return i; } } ! } ! if ((this.xpathNodeSet != null) && !this.xpathNodeSet.contains(currentNode)) { return 0; + } return 1; } ! ! protected int isVisibleInt(Node currentNode) { ! if (nodeFilter != null) { ! Iterator<NodeFilter> it = nodeFilter.iterator(); while (it.hasNext()) { ! int i = (it.next()).isNodeInclude(currentNode); ! if (i != 1) { return i; } } ! } ! if ((this.xpathNodeSet != null) && !this.xpathNodeSet.contains(currentNode)) { return 0; + } return 1; } ! protected boolean isVisible(Node currentNode) { ! if (nodeFilter != null) { ! Iterator<NodeFilter> it = nodeFilter.iterator(); while (it.hasNext()) { ! if (it.next().isNodeInclude(currentNode) != 1) { return false; } } ! } ! if ((this.xpathNodeSet != null) && !this.xpathNodeSet.contains(currentNode)) { return false; + } return true; } ! protected void handleParent(Element e, NameSpaceSymbTable ns) { ! if (!e.hasAttributes() && e.getNamespaceURI() == null) { return; } NamedNodeMap attrs = e.getAttributes(); int attrsLength = attrs.getLength(); for (int i = 0; i < attrsLength; i++) { ! Attr attribute = (Attr) attrs.item(i); ! String NName = attribute.getLocalName(); ! String NValue = attribute.getNodeValue(); ! if (Constants.NamespaceSpecNS.equals(attribute.getNamespaceURI()) ! && (!XML.equals(NName) || !Constants.XML_LANG_SPACE_SpecNS.equals(NValue))) { ! ns.addMapping(NName, NValue, attribute); ! } } ! if (e.getNamespaceURI() != null) { ! String NName = e.getPrefix(); ! String NValue = e.getNamespaceURI(); ! String Name; ! if (NName == null || NName.equals("")) { ! NName = XMLNS; ! Name = XMLNS; ! } else { ! Name = XMLNS + ":" + NName; ! } ! Attr n = e.getOwnerDocument().createAttributeNS("http://www.w3.org/2000/xmlns/", Name); ! n.setValue(NValue); ! ns.addMapping(NName, NValue, n); } } /** ! * Adds to ns the definitions from the parent elements of el * @param el * @param ns */ ! protected final void getParentNameSpaces(Element el, NameSpaceSymbTable ns) { ! Node n1 = el.getParentNode(); ! if (n1 == null || Node.ELEMENT_NODE != n1.getNodeType()) { return; } ! //Obtain all the parents of the element ! List<Element> parents = new ArrayList<Element>(); Node parent = n1; ! while (parent != null && Node.ELEMENT_NODE == parent.getNodeType()) { parents.add((Element)parent); parent = parent.getParentNode(); } //Visit them in reverse order. ! ListIterator<Element> it = parents.listIterator(parents.size()); while (it.hasPrevious()) { ! Element ele = it.previous(); handleParent(ele, ns); } + parents.clear(); Attr nsprefix; ! if (((nsprefix = ns.getMappingWithoutRendered(XMLNS)) != null) && "".equals(nsprefix.getValue())) { ! ns.addMappingAndRender(XMLNS, "", nullNode); } } + /** * Obtain the attributes to output for this node in XPathNodeSet c14n. * ! * @param element * @param ns * @return the attributes nodes to output. * @throws CanonicalizationException */ ! abstract Iterator<Attr> handleAttributes(Element element, NameSpaceSymbTable ns) throws CanonicalizationException; /** * Obtain the attributes to output for this node in a Subtree c14n. * ! * @param element * @param ns * @return the attributes nodes to output. * @throws CanonicalizationException */ ! abstract Iterator<Attr> handleAttributesSubtree(Element element, NameSpaceSymbTable ns) throws CanonicalizationException; ! abstract void circumventBugIfNeeded(XMLSignatureInput input) ! throws CanonicalizationException, ParserConfigurationException, IOException, SAXException; /** * Outputs an Attribute to the internal Writer. * * The string value of the node is modified by replacing
*** 656,708 **** * @param name * @param value * @param writer * @throws IOException */ ! static final void outputAttrToWriter(final String name, final String value, final OutputStream writer, ! final Map<String, byte[]> cache) throws IOException { writer.write(' '); ! UtfHelpper.writeByte(name,writer,cache); writer.write(equalsStr); ! byte []toWrite; final int length = value.length(); ! int i=0; while (i < length) { char c = value.charAt(i++); switch (c) { case '&' : ! toWrite=_AMP_; break; case '<' : ! toWrite=_LT_; break; case '"' : ! toWrite=_QUOT_; break; case 0x09 : // '\t' ! toWrite=__X9_; break; case 0x0A : // '\n' ! toWrite=__XA_; break; case 0x0D : // '\r' ! toWrite=__XD_; break; default : ! if (c < 0x80 ) { writer.write(c); } else { ! UtfHelpper.writeCharToUtf8(c,writer); ! }; continue; } writer.write(toWrite); } --- 688,742 ---- * @param name * @param value * @param writer * @throws IOException */ ! protected static final void outputAttrToWriter( ! final String name, final String value, ! final OutputStream writer, final Map<String, byte[]> cache ! ) throws IOException { writer.write(' '); ! UtfHelpper.writeByte(name, writer, cache); writer.write(equalsStr); ! byte[] toWrite; final int length = value.length(); ! int i = 0; while (i < length) { char c = value.charAt(i++); switch (c) { case '&' : ! toWrite = AMP; break; case '<' : ! toWrite = LT; break; case '"' : ! toWrite = QUOT; break; case 0x09 : // '\t' ! toWrite = X9; break; case 0x0A : // '\n' ! toWrite = XA; break; case 0x0D : // '\r' ! toWrite = XD; break; default : ! if (c < 0x80) { writer.write(c); } else { ! UtfHelpper.writeCharToUtf8(c, writer); ! } continue; } writer.write(toWrite); }
*** 714,743 **** * * @param currentPI * @param writer where to write the things * @throws IOException */ ! static final void outputPItoWriter(ProcessingInstruction currentPI, OutputStream writer,int position) throws IOException { ! if (position == NODE_AFTER_DOCUMENT_ELEMENT) { writer.write('\n'); } ! writer.write(_BEGIN_PI); final String target = currentPI.getTarget(); int length = target.length(); for (int i = 0; i < length; i++) { ! char c=target.charAt(i); ! if (c==0x0D) { ! writer.write(__XD_); } else { if (c < 0x80) { writer.write(c); } else { ! UtfHelpper.writeCharToUtf8(c,writer); ! }; } } final String data = currentPI.getData(); --- 748,778 ---- * * @param currentPI * @param writer where to write the things * @throws IOException */ ! protected void outputPItoWriter( ! ProcessingInstruction currentPI, OutputStream writer, int position ! ) throws IOException { if (position == NODE_AFTER_DOCUMENT_ELEMENT) { writer.write('\n'); } ! writer.write(BEGIN_PI); final String target = currentPI.getTarget(); int length = target.length(); for (int i = 0; i < length; i++) { ! char c = target.charAt(i); ! if (c == 0x0D) { ! writer.write(XD); } else { if (c < 0x80) { writer.write(c); } else { ! UtfHelpper.writeCharToUtf8(c, writer); ! } } } final String data = currentPI.getData();
*** 745,764 **** if (length > 0) { writer.write(' '); for (int i = 0; i < length; i++) { ! char c=data.charAt(i); ! if (c==0x0D) { ! writer.write(__XD_); } else { ! UtfHelpper.writeCharToUtf8(c,writer); } } } ! writer.write(_END_PI); if (position == NODE_BEFORE_DOCUMENT_ELEMENT) { writer.write('\n'); } } --- 780,799 ---- if (length > 0) { writer.write(' '); for (int i = 0; i < length; i++) { ! char c = data.charAt(i); ! if (c == 0x0D) { ! writer.write(XD); } else { ! UtfHelpper.writeCharToUtf8(c, writer); } } } ! writer.write(END_PI); if (position == NODE_BEFORE_DOCUMENT_ELEMENT) { writer.write('\n'); } }
*** 767,799 **** * * @param currentComment * @param writer writer where to write the things * @throws IOException */ ! static final void outputCommentToWriter(Comment currentComment, OutputStream writer,int position) throws IOException { if (position == NODE_AFTER_DOCUMENT_ELEMENT) { writer.write('\n'); } ! writer.write(_BEGIN_COMM); final String data = currentComment.getData(); final int length = data.length(); for (int i = 0; i < length; i++) { ! char c=data.charAt(i); ! if (c==0x0D) { ! writer.write(__XD_); } else { if (c < 0x80) { writer.write(c); } else { ! UtfHelpper.writeCharToUtf8(c,writer); ! }; } } ! writer.write(_END_COMM); if (position == NODE_BEFORE_DOCUMENT_ELEMENT) { writer.write('\n'); } } --- 802,836 ---- * * @param currentComment * @param writer writer where to write the things * @throws IOException */ ! protected void outputCommentToWriter( ! Comment currentComment, OutputStream writer, int position ! ) throws IOException { if (position == NODE_AFTER_DOCUMENT_ELEMENT) { writer.write('\n'); } ! writer.write(BEGIN_COMM); final String data = currentComment.getData(); final int length = data.length(); for (int i = 0; i < length; i++) { ! char c = data.charAt(i); ! if (c == 0x0D) { ! writer.write(XD); } else { if (c < 0x80) { writer.write(c); } else { ! UtfHelpper.writeCharToUtf8(c, writer); ! } } } ! writer.write(END_COMM); if (position == NODE_BEFORE_DOCUMENT_ELEMENT) { writer.write('\n'); } }
*** 802,849 **** * * @param text * @param writer writer where to write the things * @throws IOException */ ! static final void outputTextToWriter(final String text, final OutputStream writer) throws IOException { final int length = text.length(); ! byte []toWrite; for (int i = 0; i < length; i++) { char c = text.charAt(i); switch (c) { case '&' : ! toWrite=_AMP_; break; case '<' : ! toWrite=_LT_; break; case '>' : ! toWrite=_GT_; break; case 0xD : ! toWrite=__XD_; break; default : if (c < 0x80) { writer.write(c); } else { ! UtfHelpper.writeCharToUtf8(c,writer); ! }; continue; } writer.write(toWrite); } } - @SuppressWarnings("unchecked") - protected Collection<Attr> getSortedSetAsCollection(SortedSet<Attr> result) { - return (Collection<Attr>)(Collection)result; - } - - } --- 839,882 ---- * * @param text * @param writer writer where to write the things * @throws IOException */ ! protected static final void outputTextToWriter( ! final String text, final OutputStream writer ! ) throws IOException { final int length = text.length(); ! byte[] toWrite; for (int i = 0; i < length; i++) { char c = text.charAt(i); switch (c) { case '&' : ! toWrite = AMP; break; case '<' : ! toWrite = LT; break; case '>' : ! toWrite = GT; break; case 0xD : ! toWrite = XD; break; default : if (c < 0x80) { writer.write(c); } else { ! UtfHelpper.writeCharToUtf8(c, writer); ! } continue; } writer.write(toWrite); } } }