1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 /*
   5  * Licensed to the Apache Software Foundation (ASF) under one or more
   6  * contributor license agreements.  See the NOTICE file distributed with
   7  * this work for additional information regarding copyright ownership.
   8  * The ASF licenses this file to You under the Apache License, Version 2.0
   9  * (the "License"); you may not use this file except in compliance with
  10  * the License.  You may obtain a copy of the License at
  11  *
  12  *     http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 
  21 package com.sun.org.apache.xalan.internal.xsltc.trax;
  22 
  23 import com.sun.org.apache.xalan.internal.XalanConstants;
  24 import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
  25 import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
  26 import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC;
  27 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
  28 import java.io.InputStream;
  29 import java.io.Reader;
  30 import javax.xml.XMLConstants;
  31 import javax.xml.catalog.CatalogFeatures;
  32 import javax.xml.catalog.CatalogFeatures.Feature;
  33 import javax.xml.parsers.ParserConfigurationException;
  34 import javax.xml.parsers.SAXParserFactory;
  35 import javax.xml.stream.XMLEventReader;
  36 import javax.xml.stream.XMLStreamReader;
  37 import javax.xml.transform.Source;
  38 import javax.xml.transform.TransformerConfigurationException;
  39 import javax.xml.transform.dom.DOMSource;
  40 import javax.xml.transform.sax.SAXSource;
  41 import javax.xml.transform.stax.StAXSource;
  42 import javax.xml.transform.stream.StreamSource;
  43 import jdk.xml.internal.JdkXmlFeatures;
  44 import jdk.xml.internal.JdkXmlUtils;
  45 import org.w3c.dom.Document;
  46 import org.xml.sax.InputSource;
  47 import org.xml.sax.SAXException;
  48 import org.xml.sax.SAXNotRecognizedException;
  49 import org.xml.sax.SAXNotSupportedException;
  50 import org.xml.sax.XMLReader;
  51 import org.xml.sax.helpers.XMLReaderFactory;
  52 
  53 /**
  54  * @author Santiago Pericas-Geertsen
  55  *
  56  * Added Catalog Support for URI resolution
  57  */
  58 public final class Util {
  59 
  60     public static String baseName(String name) {
  61         return com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util.baseName(name);
  62     }
  63 
  64     public static String noExtName(String name) {
  65         return com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util.noExtName(name);
  66     }
  67 
  68     public static String toJavaName(String name) {
  69         return com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util.toJavaName(name);
  70     }
  71 
  72     /**
  73      * Creates a SAX2 InputSource object from a TrAX Source object
  74      */
  75     public static InputSource getInputSource(XSLTC xsltc, Source source)
  76         throws TransformerConfigurationException
  77     {
  78         InputSource input = null;
  79 
  80         String systemId = source.getSystemId();
  81 
  82         try {
  83             // Try to get InputSource from SAXSource input
  84             if (source instanceof SAXSource) {
  85                 final SAXSource sax = (SAXSource)source;
  86                 input = sax.getInputSource();
  87                 // Pass the SAX parser to the compiler
  88                 try {
  89                     XMLReader reader = sax.getXMLReader();
  90 
  91                      /*
  92                       * Fix for bug 24695
  93                       * According to JAXP 1.2 specification if a SAXSource
  94                       * is created using a SAX InputSource the Transformer or
  95                       * TransformerFactory creates a reader via the
  96                       * XMLReaderFactory if setXMLReader is not used
  97                       */
  98 
  99                     if (reader == null) {
 100                        try {
 101                            reader= XMLReaderFactory.createXMLReader();
 102                            try {
 103                                 reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,
 104                                             xsltc.isSecureProcessing());
 105                            } catch (SAXNotRecognizedException e) {
 106                                 XMLSecurityManager.printWarning(reader.getClass().getName(),
 107                                         XMLConstants.FEATURE_SECURE_PROCESSING, e);
 108                            }
 109                        } catch (Exception e ) {
 110                            try {
 111 
 112                                //Incase there is an exception thrown
 113                                // resort to JAXP
 114                                SAXParserFactory parserFactory = FactoryImpl.getSAXFactory(xsltc.useServicesMechnism());
 115                                parserFactory.setNamespaceAware(true);
 116 
 117                                if (xsltc.isSecureProcessing()) {
 118                                   try {
 119                                       parserFactory.setFeature(
 120                                           XMLConstants.FEATURE_SECURE_PROCESSING, true);
 121                                   }
 122                                   catch (org.xml.sax.SAXException se) {}
 123                                }
 124 
 125                                reader = parserFactory.newSAXParser()
 126                                      .getXMLReader();
 127 
 128 
 129                            } catch (ParserConfigurationException pce ) {
 130                                throw new TransformerConfigurationException
 131                                  ("ParserConfigurationException" ,pce);
 132                            }
 133                        }
 134                     }
 135                     reader.setFeature
 136                         ("http://xml.org/sax/features/namespaces",true);
 137                     reader.setFeature
 138                         ("http://xml.org/sax/features/namespace-prefixes",false);
 139 
 140                     try {
 141                         reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
 142                                    xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
 143                     } catch (SAXNotRecognizedException e) {
 144                         XMLSecurityManager.printWarning(reader.getClass().getName(),
 145                                 XMLConstants.ACCESS_EXTERNAL_DTD, e);
 146                     }
 147 
 148                     String lastProperty = "";
 149                     try {
 150                         XMLSecurityManager securityManager =
 151                                 (XMLSecurityManager)xsltc.getProperty(XalanConstants.SECURITY_MANAGER);
 152                         if (securityManager != null) {
 153                             for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) {
 154                                 lastProperty = limit.apiProperty();
 155                                 reader.setProperty(lastProperty,
 156                                         securityManager.getLimitValueAsString(limit));
 157                             }
 158                             if (securityManager.printEntityCountInfo()) {
 159                                 lastProperty = XalanConstants.JDK_ENTITY_COUNT_INFO;
 160                                 reader.setProperty(XalanConstants.JDK_ENTITY_COUNT_INFO, XalanConstants.JDK_YES);
 161                             }
 162                         }
 163                     } catch (SAXException se) {
 164                         XMLSecurityManager.printWarning(reader.getClass().getName(), lastProperty, se);
 165                     }
 166 
 167                     boolean supportCatalog = true;
 168                     boolean useCatalog = xsltc.getFeature(JdkXmlFeatures.XmlFeature.USE_CATALOG);
 169                     try {
 170                         reader.setFeature(JdkXmlUtils.USE_CATALOG, useCatalog);
 171                     }
 172                     catch (SAXNotRecognizedException | SAXNotSupportedException e) {
 173                         supportCatalog = false;
 174                     }
 175 
 176                     if (supportCatalog & useCatalog) {
 177                         try {
 178                             CatalogFeatures cf = (CatalogFeatures)xsltc.getProperty(JdkXmlFeatures.CATALOG_FEATURES);
 179                             if (cf != null) {
 180                                 for (Feature f : CatalogFeatures.Feature.values()) {
 181                                     reader.setProperty(f.getPropertyName(), cf.get(f));
 182                                 }
 183                             }
 184                         } catch (SAXNotRecognizedException e) {
 185                             //shall not happen for internal settings
 186                         }
 187                     }
 188 
 189                     xsltc.setXMLReader(reader);
 190                 }catch (SAXNotRecognizedException snre ) {
 191                   throw new TransformerConfigurationException
 192                        ("SAXNotRecognizedException ",snre);
 193                 }catch (SAXNotSupportedException snse ) {
 194                   throw new TransformerConfigurationException
 195                        ("SAXNotSupportedException ",snse);
 196                 }catch (SAXException se ) {
 197                   throw new TransformerConfigurationException
 198                        ("SAXException ",se);
 199                 }
 200 
 201             }
 202             // handle  DOMSource
 203             else if (source instanceof DOMSource) {
 204                 final DOMSource domsrc = (DOMSource)source;
 205                 final Document dom = (Document)domsrc.getNode();
 206                 final DOM2SAX dom2sax = new DOM2SAX(dom);
 207                 xsltc.setXMLReader(dom2sax);
 208 
 209                 // Try to get SAX InputSource from DOM Source.
 210                 input = SAXSource.sourceToInputSource(source);
 211                 if (input == null){
 212                     input = new InputSource(domsrc.getSystemId());
 213                 }
 214             }
 215 
 216             // handle StAXSource
 217             else if (source instanceof StAXSource) {
 218                 final StAXSource staxSource = (StAXSource)source;
 219                 StAXEvent2SAX staxevent2sax = null;
 220                 StAXStream2SAX staxStream2SAX = null;
 221                 if (staxSource.getXMLEventReader() != null) {
 222                     final XMLEventReader xmlEventReader = staxSource.getXMLEventReader();
 223                     staxevent2sax = new StAXEvent2SAX(xmlEventReader);
 224                     xsltc.setXMLReader(staxevent2sax);
 225                 } else if (staxSource.getXMLStreamReader() != null) {
 226                     final XMLStreamReader xmlStreamReader = staxSource.getXMLStreamReader();
 227                     staxStream2SAX = new StAXStream2SAX(xmlStreamReader);
 228                     xsltc.setXMLReader(staxStream2SAX);
 229                 }
 230 
 231                 // get sax InputSource from StAXSource
 232                 input = SAXSource.sourceToInputSource(source);
 233                 if (input == null){
 234                     input = new InputSource(staxSource.getSystemId());
 235                 }
 236             }
 237 
 238             // Try to get InputStream or Reader from StreamSource
 239             else if (source instanceof StreamSource) {
 240                 final StreamSource stream = (StreamSource)source;
 241                 final InputStream istream = stream.getInputStream();
 242                 final Reader reader = stream.getReader();
 243                 xsltc.setXMLReader(null);     // Clear old XML reader
 244 
 245                 // Create InputSource from Reader or InputStream in Source
 246                 if (istream != null) {
 247                     input = new InputSource(istream);
 248                 }
 249                 else if (reader != null) {
 250                     input = new InputSource(reader);
 251                 }
 252                 else {
 253                     input = new InputSource(systemId);
 254                 }
 255             }
 256             else {
 257                 ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_SOURCE_ERR);
 258                 throw new TransformerConfigurationException(err.toString());
 259             }
 260             input.setSystemId(systemId);
 261         }
 262         catch (NullPointerException e) {
 263             ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_SOURCE_ERR,
 264                                         "TransformerFactory.newTemplates()");
 265             throw new TransformerConfigurationException(err.toString());
 266         }
 267         catch (SecurityException e) {
 268             ErrorMsg err = new ErrorMsg(ErrorMsg.FILE_ACCESS_ERR, systemId);
 269             throw new TransformerConfigurationException(err.toString());
 270         }
 271         return input;
 272     }
 273 
 274 }