src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.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.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; --- 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.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator;
*** 45,390 **** import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.xml.sax.SAXException; - /** * Implements <A HREF="http://www.w3.org/TR/2001/REC-xml-c14n-20010315">Canonical * XML Version 1.0</A>, a W3C Recommendation from 15 March 2001. * * @author Christian Geuer-Pollmann <geuerp@apache.org> - * @version $Revision: 1.5 $ */ public abstract class Canonicalizer20010315 extends CanonicalizerBase { ! boolean firstCall=true; ! final SortedSet<Attr> result= new TreeSet<Attr>(COMPARE); ! static final String XMLNS_URI=Constants.NamespaceSpecNS; ! static final String XML_LANG_URI=Constants.XML_LANG_SPACE_SpecNS; ! static class XmlAttrStack { ! int currentLevel=0; ! int lastlevel=0; ! XmlsStackElement cur; static class XmlsStackElement { int level; ! boolean rendered=false; ! List<Attr> nodes=new ArrayList<Attr>(); }; ! List<XmlsStackElement> levels=new ArrayList<XmlsStackElement>(); void push(int level) { ! currentLevel=level; ! if (currentLevel==-1) return; ! cur=null; ! while (lastlevel>=currentLevel) { ! levels.remove(levels.size()-1); ! if (levels.size()==0) { ! lastlevel=0; return; } ! lastlevel=(levels.get(levels.size()-1)).level; } } void addXmlnsAttr(Attr n) { ! if (cur==null) { ! cur=new XmlsStackElement(); ! cur.level=currentLevel; levels.add(cur); ! lastlevel=currentLevel; } cur.nodes.add(n); } void getXmlnsAttr(Collection<Attr> col) { ! int size=levels.size()-1; ! if (cur==null) { ! cur=new XmlsStackElement(); ! cur.level=currentLevel; ! lastlevel=currentLevel; levels.add(cur); } ! boolean parentRendered=false; ! XmlsStackElement e=null; ! if (size==-1) { ! parentRendered=true; } else { ! e=levels.get(size); ! if (e.rendered && e.level+1==currentLevel) ! parentRendered=true; ! } if (parentRendered) { col.addAll(cur.nodes); ! cur.rendered=true; return; } ! Map<String,Attr> loa = new HashMap<String,Attr>(); ! for (;size>=0;size--) { ! e=levels.get(size); ! Iterator<Attr> it=e.nodes.iterator(); while (it.hasNext()) { ! Attr n=it.next(); ! if (!loa.containsKey(n.getName())) ! loa.put(n.getName(),n); } - //if (e.rendered) - //break; ! }; ! //cur.nodes.clear(); ! //cur.nodes.addAll(loa.values()); ! cur.rendered=true; col.addAll(loa.values()); } } ! XmlAttrStack xmlattrStack=new XmlAttrStack(); /** * Constructor Canonicalizer20010315 * * @param includeComments */ public Canonicalizer20010315(boolean includeComments) { super(includeComments); } /** ! * Returns the Attr[]s to be outputted for the given element. * <br> * The code of this method is a copy of {@link #handleAttributes(Element, * NameSpaceSymbTable)}, * whereas it takes into account that subtree-c14n is -- well -- subtree-based. * So if the element in question isRoot of c14n, it's parent is not in the * node set, as well as all other ancestors. * ! * @param E * @param ns ! * @return the Attr[]s to be outputted * @throws CanonicalizationException */ ! Iterator<Attr> handleAttributesSubtree(Element E, NameSpaceSymbTable ns ) throws CanonicalizationException { ! if (!E.hasAttributes() && !firstCall) { return null; } ! // result will contain the attrs which have to be outputted final SortedSet<Attr> result = this.result; result.clear(); ! NamedNodeMap attrs = E.getAttributes(); int attrsLength = attrs.getLength(); for (int i = 0; i < attrsLength; i++) { ! Attr N = (Attr) attrs.item(i); ! String NUri =N.getNamespaceURI(); ! if (XMLNS_URI!=NUri) { //It's not a namespace attr node. Add to the result and continue. ! result.add(N); ! continue; ! } ! ! String NName=N.getLocalName(); ! String NValue=N.getValue(); ! if (XML.equals(NName) ! && XML_LANG_URI.equals(NValue)) { //The default mapping for xml must not be output. ! continue; ! } ! ! Node n=ns.addMappingAndRender(NName,NValue,N); ! if (n!=null) { //Render the ns definition result.add((Attr)n); ! if (C14nHelper.namespaceIsRelative(N)) { ! Object exArgs[] = { E.getTagName(), NName, N.getNodeValue() }; throw new CanonicalizationException( ! "c14n.Canonicalizer.RelativeNamespace", exArgs); } } } if (firstCall) { //It is the first node of the subtree //Obtain all the namespaces defined in the parents, and added to the output. ! ns.getUnrenderedNodes(getSortedSetAsCollection(result)); //output the attributes in the xml namespace. xmlattrStack.getXmlnsAttr(result); ! firstCall=false; } return result.iterator(); } /** ! * Returns the Attr[]s to be outputted for the given element. * <br> * IMPORTANT: This method expects to work on a modified DOM tree, i.e. a DOM which has * been prepared using {@link com.sun.org.apache.xml.internal.security.utils.XMLUtils#circumventBug2650( * org.w3c.dom.Document)}. * ! * @param E * @param ns ! * @return the Attr[]s to be outputted * @throws CanonicalizationException */ ! Iterator<Attr> handleAttributes(Element E, NameSpaceSymbTable ns ) throws CanonicalizationException { ! // result will contain the attrs which have to be outputted xmlattrStack.push(ns.getLevel()); ! boolean isRealVisible=isVisibleDO(E,ns.getLevel())==1; ! NamedNodeMap attrs = null; ! int attrsLength = 0; ! if (E.hasAttributes()) { ! attrs=E.getAttributes(); ! attrsLength= attrs.getLength(); ! } ! ! ! SortedSet<Attr> result = this.result; result.clear(); for (int i = 0; i < attrsLength; i++) { ! Attr N = (Attr) attrs.item(i); ! String NUri =N.getNamespaceURI(); ! if (XMLNS_URI!=NUri) { //A non namespace definition node. ! if (XML_LANG_URI==NUri) { ! xmlattrStack.addXmlnsAttr(N); ! } else if (isRealVisible){ //The node is visible add the attribute to the list of output attributes. ! result.add(N); } ! //keep working ! continue; ! } ! ! String NName=N.getLocalName(); ! String NValue=N.getValue(); ! if ("xml".equals(NName) ! && XML_LANG_URI.equals(NValue)) { /* except omit namespace node with local name xml, which defines * the xml prefix, if its string value is http://www.w3.org/XML/1998/namespace. */ - continue; - } //add the prefix binding to the ns symb table. ! //ns.addInclusiveMapping(NName,NValue,N,isRealVisible); ! if (isVisible(N)) { ! if (!isRealVisible && ns.removeMappingIfRender(NName)) { ! continue; ! } //The xpath select this node output it if needed. ! //Node n=ns.addMappingAndRenderXNodeSet(NName,NValue,N,isRealVisible); ! Node n=ns.addMappingAndRender(NName,NValue,N); ! if (n!=null) { result.add((Attr)n); ! if (C14nHelper.namespaceIsRelative(N)) { ! Object exArgs[] = { E.getTagName(), NName, N.getNodeValue() }; throw new CanonicalizationException( ! "c14n.Canonicalizer.RelativeNamespace", exArgs); } } } else { ! if (isRealVisible && NName!=XMLNS) { ns.removeMapping(NName); } else { ! ns.addMapping(NName,NValue,N); } } } if (isRealVisible) { //The element is visible, handle the xmlns definition ! Attr xmlns = E.getAttributeNodeNS(XMLNS_URI, XMLNS); ! Node n=null; if (xmlns == null) { //No xmlns def just get the already defined. ! n=ns.getMapping(XMLNS); ! } else if ( !isVisible(xmlns)) { //There is a definition but the xmlns is not selected by the xpath. //then xmlns="" ! n=ns.addMappingAndRender(XMLNS,"",nullNode); } //output the xmlns def if needed. ! if (n!=null) { result.add((Attr)n); } //Float all xml:* attributes of the unselected parent elements to this one. - //addXmlAttributes(E,result); xmlattrStack.getXmlnsAttr(result); ! ns.getUnrenderedNodes(getSortedSetAsCollection(result)); ! } return result.iterator(); } - /** - * Always throws a CanonicalizationException because this is inclusive c14n. - * - * @param xpathNodeSet - * @param inclusiveNamespaces - * @return none it always fails - * @throws CanonicalizationException always - */ - public byte[] engineCanonicalizeXPathNodeSet(Set<Node> xpathNodeSet, String inclusiveNamespaces) - throws CanonicalizationException { - - /** $todo$ well, should we throw UnsupportedOperationException ? */ - throw new CanonicalizationException( - "c14n.Canonicalizer.UnsupportedOperation"); - } - - /** - * Always throws a CanonicalizationException because this is inclusive c14n. - * - * @param rootNode - * @param inclusiveNamespaces - * @return none it always fails - * @throws CanonicalizationException - */ - public byte[] engineCanonicalizeSubTree(Node rootNode, String inclusiveNamespaces) - throws CanonicalizationException { ! /** $todo$ well, should we throw UnsupportedOperationException ? */ ! throw new CanonicalizationException( ! "c14n.Canonicalizer.UnsupportedOperation"); ! } ! void circumventBugIfNeeded(XMLSignatureInput input) throws CanonicalizationException, ParserConfigurationException, IOException, SAXException { ! if (!input.isNeedsToBeExpanded()) return; Document doc = null; if (input.getSubNode() != null) { ! doc=XMLUtils.getOwnerDocument(input.getSubNode()); } else { ! doc=XMLUtils.getOwnerDocument(input.getNodeSet()); } XMLUtils.circumventBug2650(doc); - } ! void handleParent(Element e, NameSpaceSymbTable ns) { ! if (!e.hasAttributes()) { return; } xmlattrStack.push(-1); 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. ! if (XML_LANG_URI==N.getNamespaceURI()) { ! xmlattrStack.addXmlnsAttr(N); ! } ! 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); } } } --- 45,394 ---- import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.xml.sax.SAXException; /** * Implements <A HREF="http://www.w3.org/TR/2001/REC-xml-c14n-20010315">Canonical * XML Version 1.0</A>, a W3C Recommendation from 15 March 2001. * * @author Christian Geuer-Pollmann <geuerp@apache.org> */ public abstract class Canonicalizer20010315 extends CanonicalizerBase { ! private static final String XMLNS_URI = Constants.NamespaceSpecNS; ! private static final String XML_LANG_URI = Constants.XML_LANG_SPACE_SpecNS; ! ! private boolean firstCall = true; ! private final SortedSet<Attr> result = new TreeSet<Attr>(COMPARE); ! ! private static class XmlAttrStack { static class XmlsStackElement { int level; ! boolean rendered = false; ! List<Attr> nodes = new ArrayList<Attr>(); }; ! ! int currentLevel = 0; ! int lastlevel = 0; ! XmlsStackElement cur; ! List<XmlsStackElement> levels = new ArrayList<XmlsStackElement>(); ! void push(int level) { ! currentLevel = level; ! if (currentLevel == -1) { return; ! } ! cur = null; ! while (lastlevel >= currentLevel) { ! levels.remove(levels.size() - 1); ! int newSize = levels.size(); ! if (newSize == 0) { ! lastlevel = 0; return; } ! lastlevel = (levels.get(newSize - 1)).level; } } + void addXmlnsAttr(Attr n) { ! if (cur == null) { ! cur = new XmlsStackElement(); ! cur.level = currentLevel; levels.add(cur); ! lastlevel = currentLevel; } cur.nodes.add(n); } + void getXmlnsAttr(Collection<Attr> col) { ! int size = levels.size() - 1; ! if (cur == null) { ! cur = new XmlsStackElement(); ! cur.level = currentLevel; ! lastlevel = currentLevel; levels.add(cur); } ! boolean parentRendered = false; ! XmlsStackElement e = null; ! if (size == -1) { ! parentRendered = true; } else { ! e = levels.get(size); ! if (e.rendered && e.level + 1 == currentLevel) { ! parentRendered = true; ! } } if (parentRendered) { col.addAll(cur.nodes); ! cur.rendered = true; return; } ! Map<String, Attr> loa = new HashMap<String, Attr>(); ! for (; size >= 0; size--) { ! e = levels.get(size); ! Iterator<Attr> it = e.nodes.iterator(); while (it.hasNext()) { ! Attr n = it.next(); ! if (!loa.containsKey(n.getName())) { ! loa.put(n.getName(), n); ! } ! } } ! cur.rendered = true; col.addAll(loa.values()); } } ! ! private XmlAttrStack xmlattrStack = new XmlAttrStack(); ! /** * Constructor Canonicalizer20010315 * * @param includeComments */ public Canonicalizer20010315(boolean includeComments) { super(includeComments); } /** ! * Always throws a CanonicalizationException because this is inclusive c14n. ! * ! * @param xpathNodeSet ! * @param inclusiveNamespaces ! * @return none it always fails ! * @throws CanonicalizationException always ! */ ! public byte[] engineCanonicalizeXPathNodeSet(Set<Node> xpathNodeSet, String inclusiveNamespaces) ! throws CanonicalizationException { ! ! /** $todo$ well, should we throw UnsupportedOperationException ? */ ! throw new CanonicalizationException("c14n.Canonicalizer.UnsupportedOperation"); ! } ! ! /** ! * Always throws a CanonicalizationException because this is inclusive c14n. ! * ! * @param rootNode ! * @param inclusiveNamespaces ! * @return none it always fails ! * @throws CanonicalizationException ! */ ! public byte[] engineCanonicalizeSubTree(Node rootNode, String inclusiveNamespaces) ! throws CanonicalizationException { ! ! /** $todo$ well, should we throw UnsupportedOperationException ? */ ! throw new CanonicalizationException("c14n.Canonicalizer.UnsupportedOperation"); ! } ! ! /** ! * Returns the Attr[]s to be output for the given element. * <br> * The code of this method is a copy of {@link #handleAttributes(Element, * NameSpaceSymbTable)}, * whereas it takes into account that subtree-c14n is -- well -- subtree-based. * So if the element in question isRoot of c14n, it's parent is not in the * node set, as well as all other ancestors. * ! * @param element * @param ns ! * @return the Attr[]s to be output * @throws CanonicalizationException */ ! @Override ! protected Iterator<Attr> handleAttributesSubtree(Element element, NameSpaceSymbTable ns) throws CanonicalizationException { ! if (!element.hasAttributes() && !firstCall) { return null; } ! // result will contain the attrs which have to be output final SortedSet<Attr> result = this.result; result.clear(); ! ! if (element.hasAttributes()) { ! NamedNodeMap attrs = element.getAttributes(); int attrsLength = attrs.getLength(); for (int i = 0; i < attrsLength; i++) { ! Attr attribute = (Attr) attrs.item(i); ! String NUri = attribute.getNamespaceURI(); ! String NName = attribute.getLocalName(); ! String NValue = attribute.getValue(); ! if (!XMLNS_URI.equals(NUri)) { //It's not a namespace attr node. Add to the result and continue. ! result.add(attribute); ! } else if (!(XML.equals(NName) && XML_LANG_URI.equals(NValue))) { //The default mapping for xml must not be output. ! Node n = ns.addMappingAndRender(NName, NValue, attribute); ! if (n != null) { //Render the ns definition result.add((Attr)n); ! if (C14nHelper.namespaceIsRelative(attribute)) { ! Object exArgs[] = { element.getTagName(), NName, attribute.getNodeValue() }; throw new CanonicalizationException( ! "c14n.Canonicalizer.RelativeNamespace", exArgs ! ); ! } ! } } } } if (firstCall) { //It is the first node of the subtree //Obtain all the namespaces defined in the parents, and added to the output. ! ns.getUnrenderedNodes(result); //output the attributes in the xml namespace. xmlattrStack.getXmlnsAttr(result); ! firstCall = false; } return result.iterator(); } /** ! * Returns the Attr[]s to be output for the given element. * <br> * IMPORTANT: This method expects to work on a modified DOM tree, i.e. a DOM which has * been prepared using {@link com.sun.org.apache.xml.internal.security.utils.XMLUtils#circumventBug2650( * org.w3c.dom.Document)}. * ! * @param element * @param ns ! * @return the Attr[]s to be output * @throws CanonicalizationException */ ! @Override ! protected Iterator<Attr> handleAttributes(Element element, NameSpaceSymbTable ns) ! throws CanonicalizationException { ! // result will contain the attrs which have to be output xmlattrStack.push(ns.getLevel()); ! boolean isRealVisible = isVisibleDO(element, ns.getLevel()) == 1; ! final SortedSet<Attr> result = this.result; result.clear(); + if (element.hasAttributes()) { + NamedNodeMap attrs = element.getAttributes(); + int attrsLength = attrs.getLength(); + for (int i = 0; i < attrsLength; i++) { ! Attr attribute = (Attr) attrs.item(i); ! String NUri = attribute.getNamespaceURI(); ! String NName = attribute.getLocalName(); ! String NValue = attribute.getValue(); ! if (!XMLNS_URI.equals(NUri)) { //A non namespace definition node. ! if (XML_LANG_URI.equals(NUri)) { ! xmlattrStack.addXmlnsAttr(attribute); ! } else if (isRealVisible) { //The node is visible add the attribute to the list of output attributes. ! result.add(attribute); } ! } else if (!XML.equals(NName) || !XML_LANG_URI.equals(NValue)) { /* except omit namespace node with local name xml, which defines * the xml prefix, if its string value is http://www.w3.org/XML/1998/namespace. */ //add the prefix binding to the ns symb table. ! if (isVisible(attribute)) { ! if (isRealVisible || !ns.removeMappingIfRender(NName)) { //The xpath select this node output it if needed. ! Node n = ns.addMappingAndRender(NName, NValue, attribute); ! if (n != null) { result.add((Attr)n); ! if (C14nHelper.namespaceIsRelative(attribute)) { ! Object exArgs[] = { element.getTagName(), NName, attribute.getNodeValue() }; throw new CanonicalizationException( ! "c14n.Canonicalizer.RelativeNamespace", exArgs ! ); ! } } } } else { ! if (isRealVisible && !XMLNS.equals(NName)) { ns.removeMapping(NName); } else { ! ns.addMapping(NName, NValue, attribute); ! } ! } } } } if (isRealVisible) { //The element is visible, handle the xmlns definition ! Attr xmlns = element.getAttributeNodeNS(XMLNS_URI, XMLNS); ! Node n = null; if (xmlns == null) { //No xmlns def just get the already defined. ! n = ns.getMapping(XMLNS); ! } else if (!isVisible(xmlns)) { //There is a definition but the xmlns is not selected by the xpath. //then xmlns="" ! n = ns.addMappingAndRender(XMLNS, "", nullNode); } //output the xmlns def if needed. ! if (n != null) { result.add((Attr)n); } //Float all xml:* attributes of the unselected parent elements to this one. xmlattrStack.getXmlnsAttr(result); ! ns.getUnrenderedNodes(result); } return result.iterator(); } ! protected void circumventBugIfNeeded(XMLSignatureInput input) ! throws CanonicalizationException, ParserConfigurationException, IOException, SAXException { ! if (!input.isNeedsToBeExpanded()) { return; + } Document doc = null; if (input.getSubNode() != null) { ! doc = XMLUtils.getOwnerDocument(input.getSubNode()); } else { ! doc = XMLUtils.getOwnerDocument(input.getNodeSet()); } XMLUtils.circumventBug2650(doc); } ! @Override ! protected void handleParent(Element e, NameSpaceSymbTable ns) { ! if (!e.hasAttributes() && e.getNamespaceURI() == null) { return; } xmlattrStack.push(-1); 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())) { ! if (!XML.equals(NName) || !Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) { ! ns.addMapping(NName, NValue, attribute); ! } ! } else if (XML_LANG_URI.equals(attribute.getNamespaceURI())) { ! xmlattrStack.addXmlnsAttr(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); } } }