1 /*
   2  * Copyright (c) 2017, 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.xpath.internal.functions;
  22 
  23 import com.sun.org.apache.xpath.internal.XPathContext;
  24 import com.sun.org.apache.xpath.internal.objects.XObject;
  25 import com.sun.org.apache.xpath.internal.objects.XString;
  26 import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
  27 import java.io.BufferedInputStream;
  28 import java.io.InputStream;
  29 import java.util.Properties;
  30 import jdk.xml.internal.SecuritySupport;
  31 
  32 /**
  33  * Execute the SystemProperty() function.
  34  * @xsl.usage advanced
  35  * @LastModified: Sep 2017
  36  */
  37 public class FuncSystemProperty extends FunctionOneArg
  38 {
  39     static final long serialVersionUID = 3694874980992204867L;
  40   /**
  41    * The path/filename of the property file: XSLTInfo.properties
  42    * Maintenance note: see also
  43    * com.sun.org.apache.xalan.internal.processor.TransformerFactoryImpl.XSLT_PROPERTIES
  44    */
  45   static final String XSLT_PROPERTIES =
  46             "com/sun/org/apache/xalan/internal/res/XSLTInfo.properties";
  47 
  48   /**
  49    * Execute the function.  The function must return
  50    * a valid object.
  51    * @param xctxt The current execution context.
  52    * @return A valid XObject.
  53    *
  54    * @throws javax.xml.transform.TransformerException
  55    */
  56   public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
  57   {
  58 
  59     String fullName = m_arg0.execute(xctxt).str();
  60     int indexOfNSSep = fullName.indexOf(':');
  61     String result;
  62     String propName = "";
  63 
  64     // List of properties where the name of the
  65     // property argument is to be looked for.
  66     Properties xsltInfo = new Properties();
  67 
  68     loadPropertyFile(xsltInfo);
  69 
  70     if (indexOfNSSep > 0)
  71     {
  72       String prefix = (indexOfNSSep >= 0)
  73                       ? fullName.substring(0, indexOfNSSep) : "";
  74       String namespace;
  75 
  76       namespace = xctxt.getNamespaceContext().getNamespaceForPrefix(prefix);
  77       propName = (indexOfNSSep < 0)
  78                  ? fullName : fullName.substring(indexOfNSSep + 1);
  79 
  80       if (namespace.startsWith("http://www.w3.org/XSL/Transform")
  81               || namespace.equals("http://www.w3.org/1999/XSL/Transform"))
  82       {
  83         result = xsltInfo.getProperty(propName);
  84 
  85         if (null == result)
  86         {
  87           warn(xctxt, XPATHErrorResources.WG_PROPERTY_NOT_SUPPORTED,
  88                new Object[]{ fullName });  //"XSL Property not supported: "+fullName);
  89 
  90           return XString.EMPTYSTRING;
  91         }
  92       }
  93       else
  94       {
  95         warn(xctxt, XPATHErrorResources.WG_DONT_DO_ANYTHING_WITH_NS,
  96              new Object[]{ namespace,
  97                            fullName });  //"Don't currently do anything with namespace "+namespace+" in property: "+fullName);
  98 
  99         try
 100         {
 101           result = SecuritySupport.getSystemProperty(propName);
 102 
 103           if (null == result)
 104           {
 105 
 106             // result = System.getenv(propName);
 107             return XString.EMPTYSTRING;
 108           }
 109         }
 110         catch (SecurityException se)
 111         {
 112           warn(xctxt, XPATHErrorResources.WG_SECURITY_EXCEPTION,
 113                new Object[]{ fullName });  //"SecurityException when trying to access XSL system property: "+fullName);
 114 
 115           return XString.EMPTYSTRING;
 116         }
 117       }
 118     }
 119     else
 120     {
 121       try
 122       {
 123         result = SecuritySupport.getSystemProperty(fullName);
 124 
 125         if (null == result)
 126         {
 127 
 128           // result = System.getenv(fullName);
 129           return XString.EMPTYSTRING;
 130         }
 131       }
 132       catch (SecurityException se)
 133       {
 134         warn(xctxt, XPATHErrorResources.WG_SECURITY_EXCEPTION,
 135              new Object[]{ fullName });  //"SecurityException when trying to access XSL system property: "+fullName);
 136 
 137         return XString.EMPTYSTRING;
 138       }
 139     }
 140 
 141     if (propName.equals("version") && result.length() > 0)
 142     {
 143       try
 144       {
 145         // Needs to return the version number of the spec we conform to.
 146         return new XString("1.0");
 147       }
 148       catch (Exception ex)
 149       {
 150         return new XString(result);
 151       }
 152     }
 153     else
 154       return new XString(result);
 155   }
 156 
 157   /**
 158    * Retrieve a property bundle from XSLT_PROPERTIES
 159    *
 160    * @param target The target property bag the file will be placed into.
 161    */
 162   private void loadPropertyFile(Properties target)
 163   {
 164     try
 165     {
 166       // Use SecuritySupport class to provide privileged access to property file
 167       InputStream is = SecuritySupport.getResourceAsStream(XSLT_PROPERTIES);
 168 
 169       // get a buffered version
 170       try (BufferedInputStream bis = new BufferedInputStream(is)) {
 171           target.load(bis);  // and load up the property bag from this
 172       }
 173     }
 174     catch (Exception ex)
 175     {
 176       // ex.printStackTrace();
 177       throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException(ex);
 178     }
 179   }
 180 }