From 6daac1ed0ca023f6407a0724d4c3d1d262ce8d1f Mon Sep 17 00:00:00 2001 From: JoeWang-Java Date: Tue, 3 Dec 2024 00:58:52 +0000 Subject: [PATCH 1/3] 8343001: Adjust XSLT and XPath Extension Function Property --- .../internal/res/XSLTErrorResources.java | 9 +- .../internal/xsltc/compiler/FunctionCall.java | 83 +++++---- .../xalan/internal/xsltc/compiler/XSLTC.java | 8 +- .../xsltc/compiler/util/ErrorMessages.java | 11 +- .../xsltc/compiler/util/ErrorMsg.java | 3 +- .../internal/xsltc/runtime/ErrorMessages.java | 14 +- .../xsltc/trax/TransformerFactoryImpl.java | 5 +- .../internal/xsltc/trax/TransformerImpl.java | 7 +- .../jdk/xml/internal/JdkXmlFeatures.java | 15 +- src/java.xml/share/conf/jaxp.properties | 7 +- .../libs/jaxp/library/JAXPTestUtilities.java | 38 +++++ .../common/config/ImplProperties.java | 2 +- .../jaxp/unittest/transform/Bug6513892.java | 10 +- .../unittest/transform/ErrorListenerTest.java | 6 +- .../transform/SecureProcessingTest.java | 158 ++++++++---------- .../unittest/transform/XSLTFunctionsTest.java | 113 +++++++------ .../javax/xml/jaxp/common/8032908/XSLT.java | 6 +- .../javax/xml/jaxp/parsers/8024707/XSLT.java | 6 +- .../transform/8004476/XSLTExFuncTest.java | 8 +- 19 files changed, 275 insertions(+), 234 deletions(-) diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources.java index e5b8aeabfd20a..a1f1a8a070519 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ * Array. You also need to update MAX_CODE for error strings * and MAX_WARNING for warnings ( Needed for only information * purpose ) - * @LastModified: May 2022 + * @LastModified: Dec 2024 */ public class XSLTErrorResources extends ListResourceBundle { @@ -1197,7 +1197,10 @@ public Object[][] getContents() "Cannot set the feature ''{0}'' on this TransformerFactory."}, { ER_EXTENSION_ELEMENT_NOT_ALLOWED_IN_SECURE_PROCESSING, - "Use of the extension element ''{0}'' is not allowed when the secure processing feature is set to true."}, + "Use of the extension function ''{0}'' is not allowed when extension " + + "functions are disabled by the secure processing feature or " + + "the property ''jdk.xml.enableExtensionFunctions''. " + + "To enable extension functions, set ''jdk.xml.enableExtensionFunctions'' to ''true''."}, { ER_NAMESPACE_CONTEXT_NULL_NAMESPACE, "Cannot get the prefix for a null namespace uri."}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java index cd7c9e4983433..2cf491d96f5ae 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -62,7 +62,7 @@ * @author Morten Jorgensen * @author Erwin Bolwidt * @author Todd Miller - * @LastModified: Nov 2017 + * @LastModified: Dec 2024 */ class FunctionCall extends Expression { @@ -958,12 +958,12 @@ public boolean isExtension() { * after stripping its namespace or null * if no such methods exist. */ - private List findMethods() { + private List findMethods() throws TypeCheckError { - List result = null; - final String namespace = _fname.getNamespace(); + List result = null; + final String namespace = _fname.getNamespace(); - if (_className != null && _className.length() > 0) { + if (_className != null && _className.length() > 0) { final int nArgs = _arguments.size(); try { if (_clazz == null) { @@ -971,48 +971,45 @@ private List findMethods() { final boolean isExtensionFunctionEnabled = getXSLTC() .getFeature(JdkXmlFeatures.XmlFeature.ENABLE_EXTENSION_FUNCTION); - //Check if FSP and SM - only then process with loading - if (namespace != null && isSecureProcessing - && isExtensionFunctionEnabled - && (namespace.startsWith(JAVA_EXT_XALAN) - || namespace.startsWith(JAVA_EXT_XSLTC) - || namespace.startsWith(JAVA_EXT_XALAN_OLD) - || namespace.startsWith(XALAN_CLASSPACKAGE_NAMESPACE))) { - _clazz = getXSLTC().loadExternalFunction(_className); + // the property has the precedence + if (isExtensionFunctionEnabled) { + if (getXSLTC().hasExtensionClassLoader()) { + _clazz = getXSLTC().loadExternalFunction(_className); + } else { + _clazz = ObjectFactory.findProviderClass(_className, true); + } + if (_clazz == null) { + final ErrorMsg msg + = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, _className); + getParser().reportError(Constants.ERROR, msg); + return null; + } } else { - _clazz = ObjectFactory.findProviderClass(_className, true); + throw new TypeCheckError(ErrorMsg.UNSUPPORTED_EXT_FUNC_ERR, _className); } - - if (_clazz == null) { - final ErrorMsg msg = - new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, _className); - getParser().reportError(Constants.ERROR, msg); } - } - - final String methodName = _fname.getLocalPart(); - final Method[] methods = _clazz.getMethods(); - - for (int i = 0; i < methods.length; i++) { - final int mods = methods[i].getModifiers(); - // Is it public and same number of args ? - if (Modifier.isPublic(mods) - && methods[i].getName().equals(methodName) - && methods[i].getParameterTypes().length == nArgs) - { - if (result == null) { - result = new ArrayList<>(); - } - result.add(methods[i]); + + final String methodName = _fname.getLocalPart(); + final Method[] methods = _clazz.getMethods(); + + for (int i = 0; i < methods.length; i++) { + final int mods = methods[i].getModifiers(); + // Is it public and same number of args ? + if (Modifier.isPublic(mods) + && methods[i].getName().equals(methodName) + && methods[i].getParameterTypes().length == nArgs) { + if (result == null) { + result = new ArrayList<>(); + } + result.add(methods[i]); + } } - } - } - catch (ClassNotFoundException e) { - final ErrorMsg msg = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, _className); - getParser().reportError(Constants.ERROR, msg); + } catch (ClassNotFoundException e) { + final ErrorMsg msg = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, _className); + getParser().reportError(Constants.ERROR, msg); } - } - return result; + } + return result; } /** diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java index 9a256efc5a1f5..52edad7c22a86 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -57,7 +57,7 @@ * @author G. Todd Miller * @author Morten Jorgensen * @author John Howard (johnh@schemasoft.com) - * @LastModified: Jan 2022 + * @LastModified: Dec 2024 */ public final class XSLTC { @@ -291,6 +291,10 @@ private void setExternalExtensionFunctions(String name, Class clazz) { } } + boolean hasExtensionClassLoader() { + return _extensionClassLoader != null; + } + /* * Function loads an external extension function. * The filtering of function types (external,internal) takes place in FunctionCall class diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java index c34f4fa59eb87..660d1194b3079 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java @@ -24,7 +24,7 @@ /** * @author Morten Jorgensen - * @LastModified: Nov 2024 + * @LastModified: Dec 2024 */ public class ErrorMessages extends ListResourceBundle { @@ -552,6 +552,15 @@ public Object[][] getContents() {ErrorMsg.DATA_CONVERSION_ERR, "Cannot convert data-type ''{0}'' to ''{1}''."}, + /* + * Note to translators: property name "jdk.xml.enableExtensionFunctions" + * and value "true" should not be translated. + */ + {ErrorMsg.UNSUPPORTED_EXT_FUNC_ERR, + "Use of the extension function ''{0}'' is not allowed when extension " + + "functions are disabled by the secure processing feature or " + + "the property ''jdk.xml.enableExtensionFunctions''. " + + "To enable extension functions, set ''jdk.xml.enableExtensionFunctions'' to ''true''."}, /* * Note to translators: "Templates" is a Java class name that should * not be translated. diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java index c586ad2674c37..8ef4c9c86b605 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java @@ -33,7 +33,7 @@ * @author G. Todd Miller * @author Erwin Bolwidt * @author Morten Jorgensen - * @LastModified: Nov 2024 + * @LastModified: Dec 2024 */ public final class ErrorMsg { @@ -105,6 +105,7 @@ public final class ErrorMsg { public static final String ATTR_VAL_TEMPLATE_ERR = "ATTR_VAL_TEMPLATE_ERR"; public static final String UNKNOWN_SIG_TYPE_ERR = "UNKNOWN_SIG_TYPE_ERR"; public static final String DATA_CONVERSION_ERR = "DATA_CONVERSION_ERR"; + public static final String UNSUPPORTED_EXT_FUNC_ERR = "UNSUPPORTED_EXT_FUNC_ERR"; // JAXP/TrAX error messages public static final String NO_TRANSLET_CLASS_ERR = "NO_TRANSLET_CLASS_ERR"; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java index 54ecd80e55e21..3b1b9717bb369 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -25,6 +24,7 @@ /** * @author Morten Jorgensen + * @LastModified: Dec 2024 */ public class ErrorMessages extends ListResourceBundle { @@ -275,10 +275,16 @@ public Object[][] getContents() "An attribute whose value must be an NCName had the value ''{0}''"}, {BasisLibrary.UNALLOWED_EXTENSION_FUNCTION_ERR, - "Use of the extension function ''{0}'' is not allowed when the secure processing feature is set to true."}, + "Use of the extension function ''{0}'' is not allowed when extension " + + "functions are disabled by the secure processing feature or " + + "the property ''jdk.xml.enableExtensionFunctions''. " + + "To enable extension functions, set ''jdk.xml.enableExtensionFunctions'' to ''true''."}, {BasisLibrary.UNALLOWED_EXTENSION_ELEMENT_ERR, - "Use of the extension element ''{0}'' is not allowed when the secure processing feature is set to true."}, + "Use of the extension function ''{0}'' is not allowed when extension " + + "functions are disabled by the secure processing feature or " + + "the property ''jdk.xml.enableExtensionFunctions''. " + + "To enable extension functions, set ''jdk.xml.enableExtensionFunctions'' to ''true''."}, }; } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java index 440df5593eafb..d9af6f4744045 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java @@ -75,7 +75,6 @@ import jdk.xml.internal.JdkXmlUtils; import jdk.xml.internal.JdkProperty.ImplPropMap; import jdk.xml.internal.JdkProperty.State; -import jdk.xml.internal.SecuritySupport; import jdk.xml.internal.TransformErrorListener; import jdk.xml.internal.XMLSecurityManager; import org.xml.sax.InputSource; @@ -88,7 +87,7 @@ * @author G. Todd Miller * @author Morten Jorgensen * @author Santiago Pericas-Geertsen - * @LastModified: Nov 2024 + * @LastModified: Dec 2024 */ public class TransformerFactoryImpl extends SAXTransformerFactory implements SourceLoader @@ -216,7 +215,7 @@ public PIParamWrapper(String media, String title, String charset) { /** *

State of secure processing feature.

*/ - private boolean _isNotSecureProcessing = true; + private boolean _isNotSecureProcessing = false; /** *

State of secure mode.

*/ diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java index f551024408b3a..32eaec026bf96 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -100,7 +100,7 @@ * @author Morten Jorgensen * @author G. Todd Miller * @author Santiago Pericas-Geertsen - * @LastModified: July 2023 + * @LastModified: Dec 2024 */ public final class TransformerImpl extends Transformer implements DOMCache @@ -206,7 +206,7 @@ public final class TransformerImpl extends Transformer /** * State of the secure processing feature. */ - private boolean _isSecureProcessing = false; + private boolean _isSecureProcessing = true; /** * Indicates whether 3rd party parser may be used to override the system-default @@ -292,6 +292,7 @@ protected TransformerImpl(Translet translet, Properties outputProperties, _propertiesClone = (Properties) _properties.clone(); _indentNumber = indentNumber; _tfactory = tfactory; + _isSecureProcessing = _tfactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING); _overrideDefaultParser = _tfactory.overrideDefaultParser(); _accessExternalDTD = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD); _securityManager = (XMLSecurityManager)_tfactory.getAttribute(JdkConstants.SECURITY_MANAGER); diff --git a/src/java.xml/share/classes/jdk/xml/internal/JdkXmlFeatures.java b/src/java.xml/share/classes/jdk/xml/internal/JdkXmlFeatures.java index b3b4258891145..e8e5c2c83ded1 100644 --- a/src/java.xml/share/classes/jdk/xml/internal/JdkXmlFeatures.java +++ b/src/java.xml/share/classes/jdk/xml/internal/JdkXmlFeatures.java @@ -52,7 +52,7 @@ public static enum XmlFeature { * function is disabled. */ ENABLE_EXTENSION_FUNCTION(ImplPropMap.ENABLEEXTFUNC, null, null, true, - null, null, true, false, true, true), + null, null, false, false, true, true), /** * The {@link javax.xml.XMLConstants.USE_CATALOG} feature. * FSP: USE_CATALOG is not enforced by FSP. @@ -382,13 +382,7 @@ public int getIndex(String propertyName) { */ private void readSystemProperties() { for (XmlFeature feature : XmlFeature.values()) { - if (!getSystemProperty(feature, feature.systemProperty())) { - //if system property is not found, try the older form if any - String oldName = feature.systemPropertyOld(); - if (oldName != null) { - getSystemProperty(feature, oldName); - } - } + getSystemProperty(feature, feature.systemProperty()); } } @@ -402,6 +396,11 @@ private void readSystemProperties() { private boolean getSystemProperty(XmlFeature feature, String sysPropertyName) { try { String value = System.getProperty(sysPropertyName); + if (value == null && feature.systemPropertyOld() != null) { + // legacy system property + value = System.getProperty(feature.systemPropertyOld()); + } + if (value != null && !value.isEmpty()) { setFeature(feature, State.SYSTEMPROPERTY, Boolean.parseBoolean(value)); return true; diff --git a/src/java.xml/share/conf/jaxp.properties b/src/java.xml/share/conf/jaxp.properties index b011586c13c6a..2b7136319cea0 100644 --- a/src/java.xml/share/conf/jaxp.properties +++ b/src/java.xml/share/conf/jaxp.properties @@ -57,11 +57,10 @@ # Extension Functions: # # This property determines whether XSLT and XPath extension functions are allowed. -# The value type is boolean and the default value is true (allowing -# extension functions). The following entry overrides the default value and -# disallows extension functions: +# The value type is boolean and the default value is false (disallowing +# extension functions). # -# jdk.xml.enableExtensionFunctions=false +jdk.xml.enableExtensionFunctions=false # # # Overriding the default parser: diff --git a/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java b/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java index 8f72543db8e3a..8f95cb90f82b3 100644 --- a/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java +++ b/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java @@ -51,6 +51,7 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import org.testng.Assert; import org.w3c.dom.Document; import org.w3c.dom.Node; @@ -60,6 +61,15 @@ * This is an interface provide basic support for JAXP functional test. */ public class JAXPTestUtilities { + public static String CLS_DIR = System.getProperty("test.classes"); + public static String SRC_DIR = System.getProperty("test.src"); + public static boolean isWindows = false; + static { + if (System.getProperty("os.name").contains("Windows")) { + isWindows = true; + } + }; + /** * Prefix for error message. */ @@ -373,6 +383,34 @@ public interface RunnableWithException { void run() throws Exception; } + /** + * Asserts the run does not cause a Throwable. May be replaced with JUnit 5. + * @param runnable the runnable + * @param message the message if the test fails + */ + public static void assertDoesNotThrow(Assert.ThrowingRunnable runnable, String message) { + try { + runnable.run(); + } catch (Throwable t) { + Assert.fail(message + "\n Exception thrown: " + t.getMessage()); + } + } + + /** + * Returns the System identifier (URI) of the source. + * @param path the path to the source + * @return the System identifier + */ + public static String getSystemId(String path) { + if (path == null) return null; + String xmlSysId = "file://" + path; + if (isWindows) { + path = path.replace('\\', '/'); + xmlSysId = "file:///" + path; + } + return xmlSysId; + } + /** * Current test directory. */ diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/config/ImplProperties.java b/test/jaxp/javax/xml/jaxp/unittest/common/config/ImplProperties.java index e72252e0f677e..4f38f9152b458 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/common/config/ImplProperties.java +++ b/test/jaxp/javax/xml/jaxp/unittest/common/config/ImplProperties.java @@ -102,7 +102,7 @@ public static enum PropertyType { "0", "1000000", "3000000", "10000", "5000", "0", "1000", "10", "100", "10000"}, // default values in JDK 24 - {"true", "false", "continue", "allow", "2500", "100000", + {"false", "false", "continue", "allow", "2500", "100000", "100000", "15000", "100000", "200", "5000", "100", "1000", "10", "100", "10000"}, // default values in jaxp-strict.properties.template, since JDK 23 diff --git a/test/jaxp/javax/xml/jaxp/unittest/transform/Bug6513892.java b/test/jaxp/javax/xml/jaxp/unittest/transform/Bug6513892.java index 349e137d6644e..0d39d427e956c 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/transform/Bug6513892.java +++ b/test/jaxp/javax/xml/jaxp/unittest/transform/Bug6513892.java @@ -33,28 +33,22 @@ import javax.xml.transform.stream.StreamSource; import org.testng.Assert; -import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import org.w3c.dom.Document; /* * @test - * @bug 6513892 + * @bug 6513892 8343001 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @run testng/othervm transform.Bug6513892 * @summary Test the output encoding of the transform is the same as that of the redirect extension. */ public class Bug6513892 { - @BeforeClass - public void setup(){ - if (System.getSecurityManager() != null) - System.setSecurityManager(null); - } - @Test public void test0() { try { TransformerFactory tf = TransformerFactory.newInstance(); + tf.setFeature("jdk.xml.enableExtensionFunctions", true); Transformer t = tf.newTransformer(new StreamSource(getClass().getResourceAsStream("redirect.xsl"), getClass().getResource("redirect.xsl") .toString())); diff --git a/test/jaxp/javax/xml/jaxp/unittest/transform/ErrorListenerTest.java b/test/jaxp/javax/xml/jaxp/unittest/transform/ErrorListenerTest.java index dbe1dcfe00ffa..139cf2911e6f6 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/transform/ErrorListenerTest.java +++ b/test/jaxp/javax/xml/jaxp/unittest/transform/ErrorListenerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, 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 @@ -50,9 +50,9 @@ /* * @test - * @bug 8157830 8228854 + * @bug 8157830 8228854 8343001 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest - * @run testng/othervm transform.ErrorListenerTest + * @run testng/othervm -Djdk.xml.enableExtensionFunctions=true transform.ErrorListenerTest * @summary Verifies that ErrorListeners are handled properly */ public class ErrorListenerTest { diff --git a/test/jaxp/javax/xml/jaxp/unittest/transform/SecureProcessingTest.java b/test/jaxp/javax/xml/jaxp/unittest/transform/SecureProcessingTest.java index 1d5fa236279f3..673c3c733266f 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/transform/SecureProcessingTest.java +++ b/test/jaxp/javax/xml/jaxp/unittest/transform/SecureProcessingTest.java @@ -23,114 +23,98 @@ package transform; -import java.io.InputStream; import java.io.StringWriter; - import javax.xml.XMLConstants; import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; - +import static jaxp.library.JAXPTestUtilities.SRC_DIR; +import static jaxp.library.JAXPTestUtilities.assertDoesNotThrow; +import static jaxp.library.JAXPTestUtilities.getSystemId; import org.testng.Assert; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import static transform.XSLTFunctionsTest.SP_ENABLE_EXTENSION_FUNCTION_SPEC; /* * @test + * @bug 8343001 8343001 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @run testng/othervm transform.SecureProcessingTest - * @summary Test XSLT shall report TransformerException for unsafe xsl when FEATURE_SECURE_PROCESSING is true. + * @summary Verifies that XSLT reports TransformerException as it processes xsl + * using extension functions while FEATURE_SECURE_PROCESSING is set to true. */ public class SecureProcessingTest { - @Test - public void testSecureProcessing() { - boolean _isSecureMode = System.getSecurityManager() != null; - // SECURE_PROCESSING == false + /** + * Test state + */ + public static enum TestState { + DEFAULT, // the default state + SETFSP, // set FEATURE_SECURE_PROCESSING + SETPROPERTY; // set the enalbeExtensionFunctions property + } - // the style sheet - InputStream xslStream = this.getClass().getResourceAsStream("SecureProcessingTest.xsl"); - StreamSource xslSource = new StreamSource(xslStream); + @DataProvider(name = "extFunc") + public Object[][] getExtFuncSettings() throws Exception { + return new Object[][] { + // by default, Extension Functions are disallowed + { TestState.DEFAULT, true, null, false, TransformerException.class}, + // set FSP=true, Extension Functions are disallowed + { TestState.SETFSP, true, null, false, TransformerException.class}, + // turning off FSP does not enable Extension Functions + { TestState.SETFSP, false, null, false, TransformerException.class}, + // between FSP and the Extension Functions property (jdk.xml.enableExtensionFunctions), + // the later takes precedence + { TestState.SETPROPERTY, true, SP_ENABLE_EXTENSION_FUNCTION_SPEC, false, TransformerException.class}, + { TestState.SETPROPERTY, true, SP_ENABLE_EXTENSION_FUNCTION_SPEC, true, null}, + }; + } + /** + * Verifies the effect of FEATURE_SECURE_PROCESSING (FSP) and the precedence + * between FSP and the Extension Functions property. + * + * @param testState the state of the test + * @param fspValue the FSP value to be set + * @param property the Extension Functions property + * @param propertyValue the property value + * @param expectedThrow the expected throw if the specified DTD can not be + * resolved. + * @throws Exception if the test fails + */ + @Test(dataProvider = "extFunc") + public void testFSP(TestState testState, boolean fspValue, String property, + boolean propertyValue, Class expectedThrow) + throws Exception { + final TransformerFactory tf = TransformerFactory.newInstance(); + switch (testState) { + case DEFAULT: + break; + case SETFSP: + tf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, fspValue); + break; + case SETPROPERTY: + tf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, fspValue); + tf.setFeature(property, propertyValue); + break; + } + if (expectedThrow == null) { + assertDoesNotThrow(() -> runTransform(tf), "Unexpected exception."); + } else { + Assert.assertThrows(expectedThrow, () -> runTransform(tf)); + } + } - // the xml source - InputStream xmlStream = this.getClass().getResourceAsStream("SecureProcessingTest.xml"); - StreamSource xmlSource = new StreamSource(xmlStream); + private void runTransform(TransformerFactory tf) + throws Exception { + StreamSource xslSource = new StreamSource(getSystemId(SRC_DIR + "/SecureProcessingTest.xsl")); + StreamSource xmlSource = new StreamSource(getSystemId(SRC_DIR + "/SecureProcessingTest.xml")); // the xml result StringWriter xmlResultString = new StringWriter(); StreamResult xmlResultStream = new StreamResult(xmlResultString); - - // the transformer - TransformerFactory transformerFactory = null; - Transformer transformer = null; - - // transform with a non-secure Transformer - // expect success - String xmlResult; - if (!_isSecureMode) { // jaxp secure feature can not be turned off when - // security manager is present - try { - transformerFactory = TransformerFactory.newInstance(); - transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); - transformer = transformerFactory.newTransformer(xslSource); - transformer.transform(xmlSource, xmlResultStream); - } catch (TransformerConfigurationException ex) { - ex.printStackTrace(); - Assert.fail(ex.toString()); - } catch (TransformerException ex) { - ex.printStackTrace(); - Assert.fail(ex.toString()); - } - - // expected success - // and the result is ... - xmlResult = xmlResultString.toString(); - System.out.println("Transformation result (SECURE_PROCESSING == false) = \"" + xmlResult + "\""); - } - - // now do same transformation but with SECURE_PROCESSING == true - // expect Exception - boolean exceptionCaught = false; - - // the style sheet - xslStream = this.getClass().getResourceAsStream("SecureProcessingTest.xsl"); - xslSource = new StreamSource(xslStream); - - // the xml source - xmlStream = this.getClass().getResourceAsStream("SecureProcessingTest.xml"); - xmlSource = new StreamSource(xmlStream); - - // the xml result - xmlResultString = new StringWriter(); - xmlResultStream = new StreamResult(xmlResultString); - - // the transformer - transformerFactory = null; - transformer = null; - - // transform with a secure Transformer - try { - transformerFactory = TransformerFactory.newInstance(); - transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); - transformer = transformerFactory.newTransformer(xslSource); - transformer.transform(xmlSource, xmlResultStream); - } catch (TransformerConfigurationException ex) { - ex.printStackTrace(); - Assert.fail(ex.toString()); - } catch (TransformerException ex) { - // expected failure - System.out.println("expected failure: " + ex.toString()); - ex.printStackTrace(System.out); - exceptionCaught = true; - } - - // unexpected success? - if (!exceptionCaught) { - // and the result is ... - xmlResult = xmlResultString.toString(); - System.err.println("Transformation result (SECURE_PROCESSING == true) = \"" + xmlResult + "\""); - Assert.fail("SECURITY_PROCESSING == true, expected failure but got result: \"" + xmlResult + "\""); - } + Transformer transformer = tf.newTransformer(xslSource); + transformer.transform(xmlSource, xmlResultStream); } } diff --git a/test/jaxp/javax/xml/jaxp/unittest/transform/XSLTFunctionsTest.java b/test/jaxp/javax/xml/jaxp/unittest/transform/XSLTFunctionsTest.java index 24570c20bad70..11bd3d3a40125 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/transform/XSLTFunctionsTest.java +++ b/test/jaxp/javax/xml/jaxp/unittest/transform/XSLTFunctionsTest.java @@ -23,7 +23,6 @@ package transform; -import java.io.FilePermission; import java.io.StringReader; import java.io.StringWriter; import java.nio.file.Files; @@ -36,16 +35,18 @@ import javax.xml.transform.URIResolver; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import static jaxp.library.JAXPTestUtilities.SRC_DIR; +import static jaxp.library.JAXPTestUtilities.assertDoesNotThrow; +import static jaxp.library.JAXPTestUtilities.getSystemId; +import static jaxp.library.JAXPTestUtilities.getSystemProperty; import org.testng.Assert; +import static org.testng.Assert.assertEquals; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import static org.testng.Assert.assertEquals; -import static jaxp.library.JAXPTestUtilities.clearSystemProperty; -import static jaxp.library.JAXPTestUtilities.setSystemProperty; -import static jaxp.library.JAXPTestUtilities.getSystemProperty; /* * @test + * @bug 8062518 8153082 8165116 8343001 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @compile DocumentExtFunc.java * @run testng/othervm transform.XSLTFunctionsTest @@ -53,6 +54,21 @@ */ public class XSLTFunctionsTest { + @DataProvider(name = "propertyName") + public static Object[][] getSettings() { + return new Object[][] { + // legacy property name + {ORACLE_ENABLE_EXTENSION_FUNCTION, true, true, null}, + {ORACLE_ENABLE_EXTENSION_FUNCTION, true, false, TransformerException.class}, + // legacy system property name + {SP_ENABLE_EXTENSION_FUNCTION, false, true, null}, + {SP_ENABLE_EXTENSION_FUNCTION, false, false, TransformerException.class}, + // current property and system property name + {SP_ENABLE_EXTENSION_FUNCTION_SPEC, true, true, null}, + {SP_ENABLE_EXTENSION_FUNCTION_SPEC, true, false, TransformerException.class}, + }; + } + /** * @bug 8165116 * Verifies that redirect works properly when extension function is enabled @@ -86,59 +102,50 @@ public void testRedirect(String xml, String xsl, String output, String redirect) } /** - * @bug 8161454 - * Verifies that the new / correct name is supported, as is the old / incorrect - * one for compatibility + * @bug 8161454 8343001 + * Verifies that legacy property names are continually supported for compatibility. + * + * @param property the property name + * @param isAPIProperty indicates whether the property can be set via the factory + * @param value the property value + * @param expectedThrow the expected throw if the specified DTD can not be + * resolved. + * @throws Exception if the test fails */ - @Test - public void testNameChange() { - - boolean feature; - TransformerFactory tf = TransformerFactory.newInstance(); - feature = tf.getFeature(ORACLE_ENABLE_EXTENSION_FUNCTION); - System.out.println("Default setting: " + feature); - // The default: true if no SecurityManager, false otherwise - Assert.assertTrue(feature == getDefault()); - - setSystemProperty(SP_ENABLE_EXTENSION_FUNCTION, getDefaultOpposite()); - tf = TransformerFactory.newInstance(); - feature = tf.getFeature(ORACLE_ENABLE_EXTENSION_FUNCTION); - System.out.println("After setting " + SP_ENABLE_EXTENSION_FUNCTION + ": " + feature); - clearSystemProperty(SP_ENABLE_EXTENSION_FUNCTION); - // old/incorrect name is still supported - Assert.assertTrue(feature != getDefault()); - - setSystemProperty(SP_ENABLE_EXTENSION_FUNCTION_SPEC, getDefaultOpposite()); - tf = TransformerFactory.newInstance(); - feature = tf.getFeature(ORACLE_ENABLE_EXTENSION_FUNCTION); - System.out.println("After setting " + SP_ENABLE_EXTENSION_FUNCTION_SPEC + ": " + feature); - clearSystemProperty(SP_ENABLE_EXTENSION_FUNCTION_SPEC); - // new/correct name is effective - Assert.assertTrue(feature != getDefault()); - } - - final boolean isSecure; - { - String runSecMngr = getSystemProperty("runSecMngr"); - isSecure = runSecMngr != null && runSecMngr.equals("true"); - } - - // The default: true if no SecurityManager, false otherwise - private boolean getDefault() { - if (isSecure) { - return false; + @Test(dataProvider = "propertyName") + public void testNameChange(String property, boolean isAPIProperty, + boolean value, Class expectedThrow) + throws Exception { + if (expectedThrow == null) { + assertDoesNotThrow(() -> runTransform(property, isAPIProperty, value), + "Extension Functions property is set to " + value + " but exception is thrown."); } else { - return true; + Assert.assertThrows(expectedThrow, + () -> runTransform(property, isAPIProperty, value)); } } - // Gets a String value that is opposite to the default value - private String getDefaultOpposite() { - if (isSecure) { - return "true"; - } else { - return "false"; + private void runTransform(String property, boolean isAPIProperty, boolean value) + throws Exception { + StreamSource xslSource = new StreamSource(getSystemId(SRC_DIR + "/SecureProcessingTest.xsl")); + StreamSource xmlSource = new StreamSource(getSystemId(SRC_DIR + "/SecureProcessingTest.xml")); + + // the xml result + StringWriter xmlResultString = new StringWriter(); + StreamResult xmlResultStream = new StreamResult(xmlResultString); + + if (!isAPIProperty) { + System.setProperty(property, Boolean.toString(value)); + } + TransformerFactory tf = TransformerFactory.newInstance(); + if (isAPIProperty) { + tf.setFeature(property, value); + } + Transformer transformer = tf.newTransformer(xslSource); + if (!isAPIProperty) { + System.clearProperty(property); } + transformer.transform(xmlSource, xmlResultStream); } /** @@ -152,7 +159,7 @@ private String getDefaultOpposite() { * @param externalDoc Content of the external xml document * @param expectedResult Expected transformation result **/ - @Test(dataProvider = "document") + //@Test(dataProvider = "document") public void testDocument(final String xml, final String xsl, final String externalDoc, final String expectedResult) throws Exception { // Prepare sources for transormation diff --git a/test/jdk/javax/xml/jaxp/common/8032908/XSLT.java b/test/jdk/javax/xml/jaxp/common/8032908/XSLT.java index 22a4346edae72..d4d84bf2b9ea8 100644 --- a/test/jdk/javax/xml/jaxp/common/8032908/XSLT.java +++ b/test/jdk/javax/xml/jaxp/common/8032908/XSLT.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, 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 @@ -23,12 +23,12 @@ /** * @test - * @bug 8032908 8081392 + * @bug 8032908 8081392 8343001 * @summary Test if Node.getTextContent() function correctly returns children * content and also check that Node.getNodeValue() returns null value for * Element nodes * @compile TestFunc.java XSLT.java - * @run main/othervm XSLT + * @run main/othervm -Djdk.xml.enableExtensionFunctions=true XSLT */ import java.io.ByteArrayOutputStream; import javax.xml.transform.Transformer; diff --git a/test/jdk/javax/xml/jaxp/parsers/8024707/XSLT.java b/test/jdk/javax/xml/jaxp/parsers/8024707/XSLT.java index e6a03f5af683c..89cb0741cfac1 100644 --- a/test/jdk/javax/xml/jaxp/parsers/8024707/XSLT.java +++ b/test/jdk/javax/xml/jaxp/parsers/8024707/XSLT.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, 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 @@ -23,10 +23,10 @@ /** * @test - * @bug 8024707 + * @bug 8024707 8343001 * @summary Test for XSLT extension function with 1 element sized nodelist * @compile TestFunc.java XSLT.java - * @run main/othervm XSLT + * @run main/othervm -Djdk.xml.enableExtensionFunctions=true XSLT * @author aleksej.efimov@oracle.com */ diff --git a/test/jdk/javax/xml/jaxp/transform/8004476/XSLTExFuncTest.java b/test/jdk/javax/xml/jaxp/transform/8004476/XSLTExFuncTest.java index e23a0329bbaed..dc75a7980ae91 100644 --- a/test/jdk/javax/xml/jaxp/transform/8004476/XSLTExFuncTest.java +++ b/test/jdk/javax/xml/jaxp/transform/8004476/XSLTExFuncTest.java @@ -30,7 +30,7 @@ /** * @test - * @bug 8004476 + * @bug 8004476 8343001 * @summary test XSLT extension functions * @run main/othervm XSLTExFuncTest */ @@ -77,18 +77,18 @@ public static void main(String[] args) { } /** - * by default, extension function is enabled + * As of JDK-8343001, extension function is disabled by default. */ public void testExtFunc() { TransformerFactory factory = TransformerFactory.newInstance(); try { transform(factory); - System.out.println("testExtFunc: OK"); } catch (TransformerConfigurationException e) { fail(e.getMessage()); } catch (TransformerException ex) { - fail(ex.getMessage()); + //expected since extension function is disallowed + System.out.println("testExtFunc: OK"); } } From 83f44f49618d02ac13ba4e07aa531ac7a70fa5e8 Mon Sep 17 00:00:00 2001 From: JoeWang-Java Date: Tue, 3 Dec 2024 17:38:49 +0000 Subject: [PATCH 2/3] uncomment a test in XSLTFunctionsTest --- .../javax/xml/jaxp/unittest/transform/XSLTFunctionsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jaxp/javax/xml/jaxp/unittest/transform/XSLTFunctionsTest.java b/test/jaxp/javax/xml/jaxp/unittest/transform/XSLTFunctionsTest.java index 11bd3d3a40125..4e5d03151a917 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/transform/XSLTFunctionsTest.java +++ b/test/jaxp/javax/xml/jaxp/unittest/transform/XSLTFunctionsTest.java @@ -159,7 +159,7 @@ private void runTransform(String property, boolean isAPIProperty, boolean value) * @param externalDoc Content of the external xml document * @param expectedResult Expected transformation result **/ - //@Test(dataProvider = "document") + @Test(dataProvider = "document") public void testDocument(final String xml, final String xsl, final String externalDoc, final String expectedResult) throws Exception { // Prepare sources for transormation From a4b3932dcf6753ad201d90cfa2edfeea9fac56d9 Mon Sep 17 00:00:00 2001 From: JoeWang-Java Date: Tue, 3 Dec 2024 19:37:56 +0000 Subject: [PATCH 3/3] fix error message and inline windows check --- .../xalan/internal/xsltc/runtime/ErrorMessages.java | 2 +- .../jaxp/libs/jaxp/library/JAXPTestUtilities.java | 12 +++--------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java index 3b1b9717bb369..453c008c0a922 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java @@ -281,7 +281,7 @@ public Object[][] getContents() + "To enable extension functions, set ''jdk.xml.enableExtensionFunctions'' to ''true''."}, {BasisLibrary.UNALLOWED_EXTENSION_ELEMENT_ERR, - "Use of the extension function ''{0}'' is not allowed when extension " + "Use of the extension element ''{0}'' is not allowed when extension " + "functions are disabled by the secure processing feature or " + "the property ''jdk.xml.enableExtensionFunctions''. " + "To enable extension functions, set ''jdk.xml.enableExtensionFunctions'' to ''true''."}, diff --git a/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java b/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java index 8f95cb90f82b3..bc12f14dd0940 100644 --- a/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java +++ b/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java @@ -61,15 +61,9 @@ * This is an interface provide basic support for JAXP functional test. */ public class JAXPTestUtilities { - public static String CLS_DIR = System.getProperty("test.classes"); - public static String SRC_DIR = System.getProperty("test.src"); - public static boolean isWindows = false; - static { - if (System.getProperty("os.name").contains("Windows")) { - isWindows = true; - } - }; - + public static final String CLS_DIR = System.getProperty("test.classes"); + public static final String SRC_DIR = System.getProperty("test.src"); + public static final boolean isWindows = System.getProperty("os.name").contains("Windows"); /** * Prefix for error message. */