mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-22 15:12:38 +00:00 
			
		
		
		
	39828: Merged V4.1 to V4.1-BUG-FIX
      39827: Merged PATCHES/V4.0.2 to V4.1
         39825: ALF-13453 / ALF-13844: Merged V3.4-BUG-FIX to PATCHES/V4.0.2
            39823: ALF-13552, ALF-13978: Reverse merged the following revisions - won't fix due to regressions and not a serious vulnerability
               35341: ALF-13552: Merged V4.0 to V3.4
                  35296: ALF-13453: Merged V4.0-BUG-FIX to V4.0
                     35295: Fix for ALF-13453: Remote Code Execution (can create reverse shell)
                  35304: ALF-13453: Extra fix to ensure xalan namespace isn't declared with global scope and can't be hijacked by an input stylesheet
                  35307: ALF-13453: Duplicated extra fix to duplicate code in XSLTRenderingEngine!
               36101: ALF-13978: Merged V4.0-BUG-FIX to V3.4
                  36014: ALF-13844: XSLT Filtering Not 100% Secure
                     - added more namespaces to the security filter.
                     - verified that include/import uses the security filter.
               36108: ALF-13978: Fixed compilation errors
            39824: ALF-13552, ALF-13978: Fixed compilation errors
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@39829 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
		
	
		
			
				
	
	
		
			297 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			297 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| /*
 | |
|  * Copyright (C) 2005-2010 Alfresco Software Limited.
 | |
|  *
 | |
|  * This file is part of Alfresco
 | |
|  *
 | |
|  * Alfresco is free software: you can redistribute it and/or modify
 | |
|  * it under the terms of the GNU Lesser General Public License as published by
 | |
|  * the Free Software Foundation, either version 3 of the License, or
 | |
|  * (at your option) any later version.
 | |
|  *
 | |
|  * Alfresco is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  * GNU Lesser General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU Lesser General Public License
 | |
|  * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| 
 | |
| package org.alfresco.util;
 | |
| 
 | |
| import java.io.*;
 | |
| 
 | |
| import javax.xml.parsers.DocumentBuilder;
 | |
| import javax.xml.parsers.DocumentBuilderFactory;
 | |
| import javax.xml.parsers.ParserConfigurationException;
 | |
| import javax.xml.transform.OutputKeys;
 | |
| import javax.xml.transform.Transformer;
 | |
| import javax.xml.transform.TransformerException;
 | |
| import javax.xml.transform.TransformerFactory;
 | |
| import javax.xml.transform.dom.DOMSource;
 | |
| import javax.xml.transform.stream.StreamResult;
 | |
| import org.alfresco.model.ContentModel;
 | |
| import org.alfresco.service.cmr.avm.AVMService;
 | |
| import org.alfresco.service.cmr.repository.ContentReader;
 | |
| import org.alfresco.service.cmr.repository.ContentService;
 | |
| import org.alfresco.service.cmr.repository.NodeRef;
 | |
| import org.apache.commons.logging.Log;
 | |
| import org.apache.commons.logging.LogFactory;
 | |
| import org.w3c.dom.*;
 | |
| import org.xml.sax.InputSource;
 | |
| import org.xml.sax.SAXException;
 | |
| 
 | |
| /**
 | |
|  * XML utility functions.
 | |
|  * 
 | |
|  * @author Ariel Backenroth
 | |
|  */
 | |
| public class XMLUtil
 | |
| {   
 | |
|    private static final Log LOGGER = LogFactory.getLog(XMLUtil.class);
 | |
| 
 | |
|    /** utility function for creating a document */
 | |
|    public static Document newDocument()
 | |
|    {
 | |
|       return XMLUtil.getDocumentBuilder().newDocument();
 | |
|    }
 | |
| 
 | |
|    /** utility function for serializing a node */
 | |
|    public static void print(final Node n, final Writer output)
 | |
|    {
 | |
|       XMLUtil.print(n, output, true);
 | |
|    }
 | |
|    
 | |
|    /** utility function for serializing a node */
 | |
|    public static void print(final Node n, final Writer output, final boolean indent)
 | |
|    {
 | |
|       try 
 | |
|       {
 | |
|          final TransformerFactory tf = TransformerFactory.newInstance();
 | |
|          final Transformer t = tf.newTransformer();
 | |
|          t.setOutputProperty(OutputKeys.INDENT, indent ? "yes" : "no");
 | |
|          t.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
 | |
|          t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
 | |
|          t.setOutputProperty(OutputKeys.METHOD, "xml");
 | |
|          if (LOGGER.isDebugEnabled())
 | |
|          {
 | |
|             LOGGER.debug("writing out a document for " + 
 | |
|       			 (n instanceof Document
 | |
|       			  ? ((Document)n).getDocumentElement()
 | |
|       			  : n).getNodeName() + 
 | |
|    			     " to " + (output instanceof StringWriter
 | |
|                                        ? "string"
 | |
|                                        : output));
 | |
|          }
 | |
|          t.transform(new DOMSource(n), new StreamResult(output));
 | |
|       }
 | |
|       catch (TransformerException te)
 | |
|       {
 | |
|          te.printStackTrace();
 | |
|          assert false : te.getMessage();
 | |
|       }
 | |
|    }
 | |
| 
 | |
|    /** utility function for serializing a node */
 | |
|    public static void print(final Node n, final File output)
 | |
|       throws IOException
 | |
|    {
 | |
|       XMLUtil.print(n, new FileWriter(output));
 | |
|    }
 | |
|    
 | |
|    /** utility function for serializing a node */
 | |
|    public static String toString(final Node n)
 | |
|    {
 | |
|       return XMLUtil.toString(n, true);
 | |
|    }
 | |
| 
 | |
|    /** utility function for serializing a node */
 | |
|    public static String toString(final Node n, final boolean indent)
 | |
|    {
 | |
|       final StringWriter result = new StringWriter();
 | |
|       XMLUtil.print(n, result, indent);
 | |
|       return result.toString();
 | |
|    }
 | |
|    
 | |
|    /** utility function for parsing xml */
 | |
|    public static Document parse(final String source)
 | |
|       throws SAXException,
 | |
|       IOException
 | |
|    {
 | |
|       return XMLUtil.parse(new ByteArrayInputStream(source.getBytes("UTF-8")));
 | |
|    }
 | |
|    
 | |
|    /** utility function for parsing xml */
 | |
|    public static Document parse(final NodeRef nodeRef,
 | |
|                                 final ContentService contentService)
 | |
|       throws SAXException,
 | |
|       IOException
 | |
|    {
 | |
|       final ContentReader contentReader = 
 | |
|          contentService.getReader(nodeRef, ContentModel.TYPE_CONTENT);
 | |
|       final InputStream in = contentReader.getContentInputStream();
 | |
|       return XMLUtil.parse(in);
 | |
|    }
 | |
| 
 | |
|    /** utility function for parsing xml */
 | |
|    public static Document parse(final int version, 
 | |
|                                 final String path,
 | |
|                                 final AVMService avmService)
 | |
|       throws SAXException,
 | |
|       IOException
 | |
|    {
 | |
|       return XMLUtil.parse(avmService.getFileInputStream(version, path));
 | |
|    }
 | |
|    
 | |
|    /** utility function for parsing xml */
 | |
|    public static Document parse(final File source)
 | |
|       throws SAXException,
 | |
|       IOException
 | |
|    {
 | |
|       return XMLUtil.parse(new FileInputStream(source));
 | |
|    }
 | |
|    
 | |
|    /** utility function for parsing xml */
 | |
|    public static Document parse(final InputStream source)
 | |
|       throws SAXException,
 | |
|       IOException
 | |
|    {
 | |
|       try
 | |
|       {
 | |
|          final DocumentBuilder db = XMLUtil.getDocumentBuilder();
 | |
|          return db.parse(source);
 | |
|       }
 | |
|       finally
 | |
|       {
 | |
|          source.close();
 | |
|       }
 | |
|    }
 | |
| 
 | |
|    /** utility function for parsing xml */
 | |
|    public static Document parse(final Reader source)
 | |
|       throws SAXException,
 | |
|       IOException
 | |
|    {
 | |
|       try
 | |
|       {
 | |
|          final DocumentBuilder db = XMLUtil.getDocumentBuilder();
 | |
|          return db.parse(new InputSource(source));
 | |
|       }
 | |
|       finally
 | |
|       {
 | |
|          source.close();
 | |
|       }
 | |
|    }
 | |
| 
 | |
|    /** provides a document builder that is namespace aware but not validating by default */
 | |
|    public static DocumentBuilder getDocumentBuilder()
 | |
|    {
 | |
|       return XMLUtil.getDocumentBuilder(true, false);
 | |
|    }
 | |
| 
 | |
|    /**
 | |
|     * FOR DIAGNOSTIC PURPOSES ONLY - incomplete<br/>
 | |
|     * Builds a path to the node relative to the to node provided.
 | |
|     * @param from the node from which to build the xpath
 | |
|     * @param to an ancestor of <tt>from</tt> which will be the root of the path
 | |
|     * @return an xpath to <tt>to</tt> rooted at <tt>from</tt>.
 | |
|     */
 | |
|    public static String buildXPath(final Node from, final Element to)
 | |
|    {
 | |
|       String result = "";
 | |
|       Node tmp = from;
 | |
|       do
 | |
|       {
 | |
|          if (tmp instanceof Attr)
 | |
|          {
 | |
|             assert result.length() == 0;
 | |
|             result = "@" + tmp.getNodeName();
 | |
|          }
 | |
|          else if (tmp instanceof Element)
 | |
|          {
 | |
|             Node tmp2 = tmp;
 | |
|             int position = 1;
 | |
|             while (tmp2.getPreviousSibling() != null)
 | |
|             {
 | |
|                if (tmp2.getNodeName().equals(tmp.getNodeName()))
 | |
|                {
 | |
|                   position++;
 | |
|                }
 | |
|                tmp2 = tmp2.getPreviousSibling();
 | |
|             }
 | |
|             String part = tmp.getNodeName() + "[" + position + "]";
 | |
|             result = "/" + part + result;
 | |
|          }
 | |
|          else if (tmp instanceof Text)
 | |
|          {
 | |
|             assert result.length() == 0;
 | |
|             result = "/text()";
 | |
|          }
 | |
|          else
 | |
|          {
 | |
|             if (LOGGER.isDebugEnabled())
 | |
|             {
 | |
|                throw new IllegalArgumentException("unsupported node type " + tmp);
 | |
|             }
 | |
|          }
 | |
|          tmp = tmp.getParentNode();
 | |
|       }
 | |
|       while (tmp != to.getParentNode() && tmp != null);
 | |
|       return result;
 | |
|    }
 | |
| 
 | |
|    public static DocumentBuilder getDocumentBuilder(final boolean namespaceAware,
 | |
|                                                     final boolean validating)
 | |
|    { 
 | |
|       try
 | |
|       {
 | |
|          final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 | |
|          dbf.setNamespaceAware(namespaceAware);
 | |
|          dbf.setValidating(validating);
 | |
|          return dbf.newDocumentBuilder();
 | |
|       }
 | |
|       catch (ParserConfigurationException pce)
 | |
|       {
 | |
|          LOGGER.error(pce);
 | |
|          return null;
 | |
|       }
 | |
|    }
 | |
| 
 | |
|    /**
 | |
|     * Provides a NodeList of multiple nodelists
 | |
|     */
 | |
|    public static NodeList combine(final NodeList... nls)
 | |
|    {
 | |
| 
 | |
|       return new NodeList()
 | |
|       {
 | |
|          public Node item(final int index)
 | |
|          {
 | |
|             int offset = 0;
 | |
|             for (int i = 0; i < nls.length; i++)
 | |
|             {
 | |
|                if (index - offset < nls[i].getLength())
 | |
|                {
 | |
|                   return nls[i].item(index - offset);
 | |
|                }
 | |
|                else
 | |
|                {
 | |
|                   offset += nls[i].getLength();
 | |
|                }
 | |
|             }
 | |
|             return null;
 | |
|          }
 | |
| 
 | |
|          public int getLength()
 | |
|          {
 | |
|             int result = 0;
 | |
|             for (int i = 0; i < nls.length; i++)
 | |
|             {
 | |
|                result += nls[i].getLength();
 | |
|             }
 | |
|             return result;
 | |
|          }
 | |
|       };
 | |
|    }
 | |
| }
 |