8040228: TransformerConfigurationException occurs with security manager, FSP and XSLT Ext

Reviewed-by: joehw, lancea, ahgross
This commit is contained in:
Aleksei Efimov 2015-03-05 12:05:56 +03:00
parent ec05163d91
commit 2b912ed601
7 changed files with 180 additions and 43 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -150,6 +150,16 @@ public final class XalanConstants {
*/
public static final String SP_MAX_ELEMENT_DEPTH = "jdk.xml.maxElementDepth";
/**
* JDK TransformerFactory and Transformer attribute that specifies a class
* loader that will be used for extension functions class loading
* Value: a "null", the default value, means that the default EF class loading
* path will be used.
* Instance of ClassLoader: the specified instance of ClassLoader will be used
* for extension functions loading during translation process
*/
public static final String JDK_EXTENSION_CLASSLOADER = "jdk.xml.transform.extensionClassLoader";
//legacy System Properties
public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit";
public static final String ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ;

View file

@ -104,6 +104,9 @@ class FunctionCall extends Expression {
protected final static String EXSLT_STRINGS =
"http://exslt.org/strings";
protected final static String XALAN_CLASSPACKAGE_NAMESPACE =
"xalan://";
// Namespace format constants
protected final static int NAMESPACE_FORMAT_JAVA = 0;
protected final static int NAMESPACE_FORMAT_CLASS = 1;
@ -901,7 +904,21 @@ class FunctionCall extends Expression {
final int nArgs = _arguments.size();
try {
if (_clazz == null) {
final boolean isSecureProcessing = getXSLTC().isSecureProcessing();
final boolean isExtensionFunctionEnabled = getXSLTC()
.getFeature(FeatureManager.Feature.ORACLE_ENABLE_EXTENSION_FUNCTION);
//Check if FSP and SM - only then process with loading
if (namespace != null && isSecureProcessing
&& isExtensionFunctionEnabled
&& (namespace.equals(JAVA_EXT_XALAN)
|| namespace.equals(JAVA_EXT_XSLTC)
|| namespace.equals(JAVA_EXT_XALAN_OLD)
|| namespace.startsWith(XALAN_CLASSPACKAGE_NAMESPACE))) {
_clazz = getXSLTC().loadExternalFunction(_className);
} else {
_clazz = ObjectFactory.findProviderClass(_className, true);
}
if (_clazz == null) {
final ErrorMsg msg =

View file

@ -23,24 +23,6 @@
package com.sun.org.apache.xalan.internal.xsltc.compiler;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import javax.xml.XMLConstants;
import com.sun.org.apache.bcel.internal.classfile.JavaClass;
import com.sun.org.apache.xalan.internal.XalanConstants;
import com.sun.org.apache.xalan.internal.utils.FeatureManager;
@ -50,7 +32,27 @@ import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
import com.sun.org.apache.xml.internal.dtm.DTM;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import javax.xml.XMLConstants;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
@ -152,12 +154,26 @@ public final class XSLTC {
private final FeatureManager _featureManager;
/**
* Extension function class loader variables
*/
/* Class loader reference that will be used to external extension functions loading */
private ClassLoader _extensionClassLoader;
/**
* HashSet with the loaded classes
*/
private final Map<String, Class> _externalExtensionFunctions;
/**
* XSLTC compiler constructor
*/
public XSLTC(boolean useServicesMechanism, FeatureManager featureManager) {
_parser = new Parser(this, useServicesMechanism);
_featureManager = featureManager;
_extensionClassLoader = null;
_externalExtensionFunctions = new HashMap<>();
}
/**
@ -207,6 +223,8 @@ public final class XSLTC {
return _accessExternalDTD;
} else if (name.equals(XalanConstants.SECURITY_MANAGER)) {
return _xmlSecurityManager;
} else if (name.equals(XalanConstants.JDK_EXTENSION_CLASSLOADER)) {
return _extensionClassLoader;
}
return null;
}
@ -222,6 +240,11 @@ public final class XSLTC {
_accessExternalDTD = (String)value;
} else if (name.equals(XalanConstants.SECURITY_MANAGER)) {
_xmlSecurityManager = (XMLSecurityManager)value;
} else if (name.equals(XalanConstants.JDK_EXTENSION_CLASSLOADER)) {
_extensionClassLoader = (ClassLoader) value;
/* Clear the external extension functions HashMap if extension class
loader was changed */
_externalExtensionFunctions.clear();
}
}
@ -256,6 +279,41 @@ public final class XSLTC {
_bcelClasses = new Vector();
}
private void setExternalExtensionFunctions(String name, Class clazz) {
if (_isSecureProcessing && clazz != null && !_externalExtensionFunctions.containsKey(name)) {
_externalExtensionFunctions.put(name, clazz);
}
}
/*
* Function loads an external external extension functions.
* The filtering of function types (external,internal) takes place in FunctionCall class
*
*/
Class loadExternalFunction(String name) throws ClassNotFoundException {
Class loaded = null;
//Check if the function is not loaded already
if (_externalExtensionFunctions.containsKey(name)) {
loaded = _externalExtensionFunctions.get(name);
} else if (_extensionClassLoader != null) {
loaded = Class.forName(name, true, _extensionClassLoader);
setExternalExtensionFunctions(name, loaded);
}
if (loaded == null) {
throw new ClassNotFoundException(name);
}
//Return loaded class
return (Class) loaded;
}
/*
* Returns unmodifiable view of HashMap with loaded external extension
* functions - will be needed for the TransformerImpl
*/
public Map<String, Class> getExternalExtensionFunctions() {
return Collections.unmodifiableMap(_externalExtensionFunctions);
}
/**
* Initializes the compiler to produce a new translet
*/
@ -283,6 +341,7 @@ public final class XSLTC {
-1, // LEVEL_MULTIPLE
-1 // LEVEL_ANY
};
_externalExtensionFunctions.clear();
}
/**

View file

@ -602,6 +602,9 @@ public class ErrorMessages extends ListResourceBundle {
{ErrorMsg.JAXP_INVALID_ATTR_ERR,
"TransformerFactory does not recognise attribute ''{0}''."},
{ErrorMsg.JAXP_INVALID_ATTR_VALUE_ERR,
"Incorrect value specified for ''{0}'' attribute."},
/*
* Note to translators: "setResult()" and "startDocument()" are Java
* method names that should not be translated.

View file

@ -117,6 +117,7 @@ public final class ErrorMsg {
public static final String JAXP_NO_SOURCE_ERR = "JAXP_NO_SOURCE_ERR";
public static final String JAXP_COMPILE_ERR = "JAXP_COMPILE_ERR";
public static final String JAXP_INVALID_ATTR_ERR = "JAXP_INVALID_ATTR_ERR";
public static final String JAXP_INVALID_ATTR_VALUE_ERR = "JAXP_INVALID_ATTR_VALUE_ERR";
public static final String JAXP_SET_RESULT_ERR = "JAXP_SET_RESULT_ERR";
public static final String JAXP_NO_TRANSLET_ERR = "JAXP_NO_TRANSLET_ERR";
public static final String JAXP_NO_HANDLER_ERR = "JAXP_NO_HANDLER_ERR";

View file

@ -24,27 +24,26 @@
package com.sun.org.apache.xalan.internal.xsltc.trax;
import com.sun.org.apache.xalan.internal.XalanConstants;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Properties;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.xml.XMLConstants;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.URIResolver;
import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.Translet;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable;
import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Map;
import java.util.Properties;
import javax.xml.XMLConstants;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.URIResolver;
/**
* @author Morten Jorgensen
@ -131,8 +130,30 @@ public final class TemplatesImpl implements Templates, Serializable {
private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
static final class TransletClassLoader extends ClassLoader {
private final Map<String,Class> _loadedExternalExtensionFunctions;
TransletClassLoader(ClassLoader parent) {
super(parent);
_loadedExternalExtensionFunctions = null;
}
TransletClassLoader(ClassLoader parent,Map<String, Class> mapEF) {
super(parent);
_loadedExternalExtensionFunctions = mapEF;
}
public Class<?> loadClass(String name) throws ClassNotFoundException {
Class<?> ret = null;
// The _loadedExternalExtensionFunctions will be empty when the
// SecurityManager is not set and the FSP is turned off
if (_loadedExternalExtensionFunctions != null) {
ret = _loadedExternalExtensionFunctions.get(name);
}
if (ret == null) {
ret = super.loadClass(name);
}
return ret;
}
/**
@ -330,7 +351,7 @@ public final class TemplatesImpl implements Templates, Serializable {
TransletClassLoader loader = (TransletClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return new TransletClassLoader(ObjectFactory.findClassLoader());
return new TransletClassLoader(ObjectFactory.findClassLoader(),_tfactory.getExternalExtensionsMap());
}
});

View file

@ -27,12 +27,12 @@ import com.sun.org.apache.xalan.internal.XalanConstants;
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
import com.sun.org.apache.xalan.internal.utils.FeatureManager;
import com.sun.org.apache.xalan.internal.utils.FeaturePropertyBase;
import com.sun.org.apache.xalan.internal.utils.FeaturePropertyBase.State;
import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager;
import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager.Property;
import com.sun.org.apache.xalan.internal.utils.FeaturePropertyBase.State;
import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants;
import com.sun.org.apache.xalan.internal.xsltc.compiler.SourceLoader;
import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC;
@ -50,6 +50,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
import java.util.zip.ZipEntry;
@ -57,7 +58,6 @@ import java.util.zip.ZipFile;
import javax.xml.XMLConstants;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
@ -231,6 +231,13 @@ public class TransformerFactoryImpl
private final FeatureManager _featureManager;
private ClassLoader _extensionClassLoader = null;
// Unmodifiable view of external extension function from xslt compiler
// It will be populated by user-specified extension functions during the
// type checking
private Map<String, Class> _xsltcExtensionFunctions;
/**
* javax.xml.transform.sax.TransformerFactory implementation.
*/
@ -261,6 +268,12 @@ public class TransformerFactoryImpl
//Parser's security manager
_xmlSecurityManager = new XMLSecurityManager(true);
//Unmodifiable hash map with loaded external extension functions
_xsltcExtensionFunctions = null;
}
public Map<String,Class> getExternalExtensionsMap() {
return _xsltcExtensionFunctions;
}
/**
@ -324,6 +337,8 @@ public class TransformerFactoryImpl
return Boolean.FALSE;
} else if (name.equals(XalanConstants.SECURITY_MANAGER)) {
return _xmlSecurityManager;
} else if (name.equals(XalanConstants.JDK_EXTENSION_CLASSLOADER)) {
return _extensionClassLoader;
}
/** Check to see if the property is managed by the security manager **/
@ -439,6 +454,16 @@ public class TransformerFactoryImpl
return;
}
}
else if ( name.equals(XalanConstants.JDK_EXTENSION_CLASSLOADER)) {
if (value instanceof ClassLoader) {
_extensionClassLoader = (ClassLoader) value;
return;
} else {
final ErrorMsg err
= new ErrorMsg(ErrorMsg.JAXP_INVALID_ATTR_VALUE_ERR, "Extension Functions ClassLoader");
throw new IllegalArgumentException(err.toString());
}
}
if (_xmlSecurityManager != null &&
_xmlSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) {
@ -881,7 +906,6 @@ public class TransformerFactoryImpl
// Reset the per-session attributes to their default values
// after each newTemplates() call.
resetTransientAttributes();
return new TemplatesImpl(bytecodes, transletClassName, null, _indentNumber, this);
}
}
@ -898,8 +922,10 @@ public class TransformerFactoryImpl
xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, _accessExternalStylesheet);
xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
xsltc.setProperty(XalanConstants.SECURITY_MANAGER, _xmlSecurityManager);
xsltc.setProperty(XalanConstants.JDK_EXTENSION_CLASSLOADER, _extensionClassLoader);
xsltc.init();
if (!_isNotSecureProcessing)
_xsltcExtensionFunctions = xsltc.getExternalExtensionFunctions();
// Set a document loader (for xsl:include/import) if defined
if (_uriResolver != null) {
xsltc.setSourceLoader(this);