8165116: redirect function is not allowed even with enableExtensionFunctions
authorjoehw
Wed, 07 Sep 2016 11:00:14 -0700
changeset 40828 3748a4f12d7b
parent 40777 e384420383a5
child 40829 ad509d5baa06
8165116: redirect function is not allowed even with enableExtensionFunctions Reviewed-by: lancea
jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/TransletOutput.java
jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java
jaxp/test/javax/xml/jaxp/unittest/transform/XSLTFunctionsTest.java
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/TransletOutput.java	Wed Jul 05 22:10:57 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/TransletOutput.java	Wed Sep 07 11:00:14 2016 -0700
@@ -1,13 +1,14 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
  */
+
 /*
- * Copyright 2001-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
@@ -17,9 +18,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: TransletOutput.java,v 1.2.4.1 2005/09/05 09:19:44 pvedula Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.compiler;
 
@@ -35,6 +33,7 @@
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
+import jdk.xml.internal.JdkXmlFeatures;
 
 /**
  * @author Morten Jorgensen
@@ -103,8 +102,10 @@
         final InstructionList il = methodGen.getInstructionList();
         final boolean isSecureProcessing = classGen.getParser().getXSLTC()
                                            .isSecureProcessing();
+        final boolean isExtensionFunctionEnabled = classGen.getParser().getXSLTC()
+                .getFeature(JdkXmlFeatures.XmlFeature.ENABLE_EXTENSION_FUNCTION);
 
-        if (isSecureProcessing) {
+        if (isSecureProcessing && !isExtensionFunctionEnabled) {
             int index = cpg.addMethodref(BASIS_LIBRARY_CLASS,
                                          "unallowed_extension_elementF",
                                          "(Ljava/lang/String;)V");
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java	Wed Jul 05 22:10:57 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java	Wed Sep 07 11:00:14 2016 -0700
@@ -111,6 +111,9 @@
 
     private boolean _useServicesMechanism;
 
+    // The OutputStream for redirect function
+    private FileOutputStream output = null;
+
     /**
      * protocols allowed for external references set by the stylesheet processing instruction, Document() function, Import and Include element.
      */
@@ -567,9 +570,10 @@
                dir.mkdirs();
             }
 
+            output = new FileOutputStream(filename, append);
             factory.setEncoding(_encoding);
             factory.setOutputMethod(_method);
-            factory.setOutputStream(new BufferedOutputStream(new FileOutputStream(filename, append)));
+            factory.setOutputStream(new BufferedOutputStream(output));
             factory.setOutputType(TransletOutputHandlerFactory.STREAM);
 
             final SerializationHandler handler
@@ -594,6 +598,9 @@
         try {
             handler.endDocument();
             handler.close();
+            if (output != null) {
+                output.close();
+            }
         }
         catch (Exception e) {
             // what can you do?
--- a/jaxp/test/javax/xml/jaxp/unittest/transform/XSLTFunctionsTest.java	Wed Jul 05 22:10:57 2017 +0200
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/XSLTFunctionsTest.java	Wed Sep 07 11:00:14 2016 -0700
@@ -23,9 +23,12 @@
 
 package transform;
 
+import java.io.IOException;
 import java.io.StringReader;
 import java.io.StringWriter;
-
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
@@ -54,8 +57,39 @@
  * @summary This class contains tests for XSLT functions.
  */
 
-@Listeners({jaxp.library.BasePolicy.class})
+@Listeners({jaxp.library.FilePolicy.class})
 public class XSLTFunctionsTest {
+    /**
+     * @bug 8165116
+     * Verifies that redirect works properly when extension function is enabled
+     *
+     * @param xml the XML source
+     * @param xsl the stylesheet that redirect output to a file
+     * @param output the output file
+     * @param redirect the redirect file
+     * @throws Exception if the test fails
+     **/
+    @Test(dataProvider = "redirect")
+    public void testRedirect(String xml, String xsl, String output, String redirect) throws Exception {
+
+        TransformerFactory tf = TransformerFactory.newInstance();
+        tf.setFeature(ORACLE_ENABLE_EXTENSION_FUNCTION, true);
+        Transformer t = tf.newTransformer(new StreamSource(new StringReader(xsl)));
+
+        //Transform the xml
+        t.transform(new StreamSource(new StringReader(xml)), new StreamResult(new StringWriter()));
+
+        // Verifies that the output is redirected successfully
+        String userDir = getSystemProperty("user.dir");
+        Path pathOutput = Paths.get(userDir, output);
+        Path pathRedirect = Paths.get(userDir, redirect);
+        Assert.assertTrue(Files.exists(pathOutput));
+        Assert.assertTrue(Files.exists(pathRedirect));
+        System.out.println("Output to " + pathOutput + " successful.");
+        System.out.println("Redirect to " + pathRedirect + " successful.");
+        Files.deleteIfExists(pathOutput);
+        Files.deleteIfExists(pathRedirect);
+    }
 
     /**
      * @bug 8161454
@@ -177,6 +211,13 @@
         };
     }
 
+    @DataProvider(name = "redirect")
+    public static Object[][] getData() {
+        return new Object[][] {
+            {documentTestXml, xslRedirect, "testoutput.xml", "testredirect.xml"},
+        };
+    }
+
     static final String documentTestXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Test>Doc</Test>";
 
     static final String documentTestExternalDoc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Test>External Doc</Test>";
@@ -197,6 +238,23 @@
     static final String documentTesteExpectedResult = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                                                     + "<root>[Test:Doc][Test:External Doc]</root>";
 
+    static String xslRedirect = " <xsl:stylesheet \n"
+            + "   xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\n"
+            + "   xmlns:xsltc=\"http://xml.apache.org/xalan/xsltc\"\n"
+            + "   xmlns:redirect=\"http://xml.apache.org/xalan/redirect\"\n"
+            + "   extension-element-prefixes=\"xsltc redirect\"\n"
+            + "   version=\"1.0\">\n"
+            + "   <xsl:template match=\"/\">\n"
+            + "     <xsl:text>This goes to standard output</xsl:text>\n"
+            + "     <xsltc:output file=\"testoutput.xml\">\n"
+            + "       <xsl:text>This ends up in the file 'testoutput.xml'</xsl:text>\n"
+            + "     </xsltc:output>\n"
+            + "     <redirect:write file=\"testredirect.xml\">\n"
+            + "       <xsl:text>This ends up in the file 'testredirect.xml'</xsl:text>\n"
+            + "     </redirect:write>\n"
+            + "   </xsl:template>\n"
+            + "</xsl:stylesheet>";
+
     public static final String ORACLE_JAXP_PROPERTY_PREFIX =
         "http://www.oracle.com/xml/jaxp/properties/";
     /**