Import test for javax.xml.transform from 9+181

The test are unmodified, and will be patched to be runnable
on Android in the next change.

It adds coverage to methods, e.g.
javax.xml.transform.sax.SAXSource(InputSource)

Bug: 119393918
Test: N/A
Change-Id: If8bcb649d9096b913096e91474b17ef15a88c1ab
diff --git a/ojluni/src/test/javax/xml/jaxp/transform/SecureProcessingTest.xml b/ojluni/src/test/javax/xml/jaxp/transform/SecureProcessingTest.xml
new file mode 100644
index 0000000..bc916a9
--- /dev/null
+++ b/ojluni/src/test/javax/xml/jaxp/transform/SecureProcessingTest.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<helloWorld/>
diff --git a/ojluni/src/test/javax/xml/jaxp/transform/TestBase.java b/ojluni/src/test/javax/xml/jaxp/transform/TestBase.java
new file mode 100644
index 0000000..11333fa
--- /dev/null
+++ b/ojluni/src/test/javax/xml/jaxp/transform/TestBase.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2013, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Policy;
+
+/**
+ *
+ *
+ * @author huizhe.wang@oracle.com
+ */
+public class TestBase {
+    public static boolean isWindows = false;
+    static {
+        if (System.getProperty("os.name").indexOf("Windows")>-1) {
+            isWindows = true;
+        }
+    };
+
+    String filepath;
+    boolean hasSM;
+    String curDir;
+    Policy origPolicy;
+    String testName;
+    static String errMessage;
+
+    int passed = 0, failed = 0;
+
+    /**
+     * Creates a new instance of StreamReader
+     */
+    public TestBase(String name) {
+        testName = name;
+    }
+
+    //junit @Override
+    protected void setUp() {
+        if (System.getSecurityManager() != null) {
+            hasSM = true;
+            System.setSecurityManager(null);
+        }
+
+        filepath = System.getProperty("test.src");
+        if (filepath == null) {
+            //current directory
+            filepath = System.getProperty("user.dir");
+        }
+        origPolicy = Policy.getPolicy();
+
+    }
+
+    //junit @Override
+    public void tearDown() {
+        // turn off security manager and restore policy
+        System.setSecurityManager(null);
+        Policy.setPolicy(origPolicy);
+        if (hasSM) {
+            System.setSecurityManager(new SecurityManager());
+        }
+        System.out.println("\nNumber of tests passed: " + passed);
+        System.out.println("Number of tests failed: " + failed + "\n");
+
+        if (errMessage != null ) {
+            throw new RuntimeException(errMessage);
+        }
+    }
+
+    void fail(String errMsg) {
+        if (errMessage == null) {
+            errMessage = errMsg;
+        } else {
+            errMessage = errMessage + "\n" + errMsg;
+        }
+        failed++;
+    }
+
+    void success(String msg) {
+        passed++;
+        System.out.println(msg);
+    }
+
+}
diff --git a/ojluni/src/test/javax/xml/jaxp/transform/XPathExFuncTest.java b/ojluni/src/test/javax/xml/jaxp/transform/XPathExFuncTest.java
new file mode 100644
index 0000000..5680067
--- /dev/null
+++ b/ojluni/src/test/javax/xml/jaxp/transform/XPathExFuncTest.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2013, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ * @test
+ * @bug 8004476
+ * @summary test XPath extension functions
+ * @run main/othervm XPathExFuncTest
+ */
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.AllPermission;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.util.Iterator;
+import java.util.List;
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import javax.xml.xpath.XPathFactoryConfigurationException;
+import javax.xml.xpath.XPathFunction;
+import javax.xml.xpath.XPathFunctionException;
+import javax.xml.xpath.XPathFunctionResolver;
+import org.w3c.dom.Document;
+
+/**
+ * test XPath extension functions
+ *
+ * @author huizhe.wang@oracle.com
+ */
+public class XPathExFuncTest extends TestBase {
+
+    final static String ENABLE_EXTENSION_FUNCTIONS = "http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions";
+    final static String CLASSNAME = "DocumentBuilderFactoryImpl";
+    final String XPATH_EXPRESSION = "ext:helloWorld()";
+
+    /**
+     * Creates a new instance of StreamReader
+     */
+    public XPathExFuncTest(String name) {
+        super(name);
+    }
+    boolean hasSM;
+    String xslFile, xslFileId;
+    String xmlFile, xmlFileId;
+
+    protected void setUp() {
+        super.setUp();
+        xmlFile = filepath + "/SecureProcessingTest.xml";
+
+    }
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        XPathExFuncTest test = new XPathExFuncTest("OneTest");
+        test.setUp();
+
+        test.testExtFunc();
+        test.testExtFuncNotAllowed();
+        test.testEnableExtFunc();
+        test.tearDown();
+
+    }
+
+    /**
+     * by default, extension function is enabled
+     */
+    public void testExtFunc() {
+
+        try {
+            evaluate(false);
+            System.out.println("testExtFunc: OK");
+        } catch (XPathFactoryConfigurationException e) {
+            fail(e.getMessage());
+        } catch (XPathExpressionException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * Security is enabled, extension function not allowed
+     */
+    public void testExtFuncNotAllowed() {
+        Policy p = new SimplePolicy(new AllPermission());
+        Policy.setPolicy(p);
+        System.setSecurityManager(new SecurityManager());
+
+        try {
+            evaluate(false);
+        } catch (XPathFactoryConfigurationException e) {
+            fail(e.getMessage());
+        } catch (XPathExpressionException ex) {
+            //expected since extension function is disallowed
+            System.out.println("testExtFuncNotAllowed: OK");
+        } finally {
+            System.setSecurityManager(null);
+        }
+    }
+
+    /**
+     * Security is enabled, use new feature: enableExtensionFunctions
+     */
+    public void testEnableExtFunc() {
+        Policy p = new SimplePolicy(new AllPermission());
+        Policy.setPolicy(p);
+        System.setSecurityManager(new SecurityManager());
+
+
+        try {
+            evaluate(true);
+            System.out.println("testEnableExt: OK");
+        } catch (XPathFactoryConfigurationException e) {
+            fail(e.getMessage());
+        } catch (XPathExpressionException e) {
+            fail(e.getMessage());
+        } finally {
+            System.setSecurityManager(null);
+        }
+    }
+
+    Document getDocument() {
+        // the xml source
+        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder documentBuilder = null;
+        Document document = null;
+
+        try {
+            documentBuilder = documentBuilderFactory.newDocumentBuilder();
+            InputStream xmlStream = new FileInputStream(xmlFile);
+            document = documentBuilder.parse(xmlStream);
+        } catch (Exception e) {
+            fail(e.toString());
+        }
+        return document;
+    }
+
+    void evaluate(boolean enableExt) throws XPathFactoryConfigurationException, XPathExpressionException {
+        Document document = getDocument();
+
+        XPathFactory xPathFactory = XPathFactory.newInstance();
+        /**
+         * Use of the extension function 'http://exslt.org/strings:tokenize' is
+         * not allowed when the secure processing feature is set to true.
+         * Attempt to use the new property to enable extension function
+         */
+        if (enableExt) {
+            boolean isExtensionSupported = enableExtensionFunction(xPathFactory);
+        }
+
+        xPathFactory.setXPathFunctionResolver(new MyXPathFunctionResolver());
+        if (System.getSecurityManager() == null) {
+            xPathFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false);
+        }
+
+        XPath xPath = xPathFactory.newXPath();
+        xPath.setNamespaceContext(new MyNamespaceContext());
+
+        String xPathResult = xPath.evaluate(XPATH_EXPRESSION, document);
+        System.out.println(
+                "XPath result (enableExtensionFunction == " + enableExt + ") = \""
+                + xPathResult
+                + "\"");
+    }
+
+    public class MyXPathFunctionResolver
+            implements XPathFunctionResolver {
+
+        public XPathFunction resolveFunction(QName functionName, int arity) {
+
+            // not a real ewsolver, always return a default XPathFunction
+            return new MyXPathFunction();
+        }
+    }
+
+    public class MyXPathFunction
+            implements XPathFunction {
+
+        public Object evaluate(List list) throws XPathFunctionException {
+
+            return "Hello World";
+        }
+    }
+
+    public class MyNamespaceContext implements NamespaceContext {
+
+        public String getNamespaceURI(String prefix) {
+            if (prefix == null) {
+                throw new IllegalArgumentException("The prefix cannot be null.");
+            }
+
+            if (prefix.equals("ext")) {
+                return "http://ext.com";
+            } else {
+                return null;
+            }
+        }
+
+        public String getPrefix(String namespace) {
+
+            if (namespace == null) {
+                throw new IllegalArgumentException("The namespace uri cannot be null.");
+            }
+
+            if (namespace.equals("http://ext.com")) {
+                return "ext";
+            } else {
+                return null;
+            }
+        }
+
+        public Iterator getPrefixes(String namespace) {
+            return null;
+        }
+    }
+
+    boolean enableExtensionFunction(XPathFactory factory) {
+        boolean isSupported = true;
+        try {
+            factory.setFeature(ENABLE_EXTENSION_FUNCTIONS, true);
+        } catch (XPathFactoryConfigurationException ex) {
+            isSupported = false;
+        }
+        return isSupported;
+    }
+
+    class SimplePolicy extends Policy {
+
+        private final Permissions perms;
+
+        public SimplePolicy(Permission... permissions) {
+            perms = new Permissions();
+            for (Permission permission : permissions) {
+                perms.add(permission);
+            }
+        }
+
+        @Override
+        public PermissionCollection getPermissions(CodeSource cs) {
+            return perms;
+        }
+
+        @Override
+        public PermissionCollection getPermissions(ProtectionDomain pd) {
+            return perms;
+        }
+
+        @Override
+        public boolean implies(ProtectionDomain pd, Permission p) {
+            return perms.implies(p);
+        }
+
+        //for older jdk
+        @Override
+        public void refresh() {
+        }
+    }
+}
diff --git a/ojluni/src/test/javax/xml/jaxp/transform/XSLTExFuncTest.java b/ojluni/src/test/javax/xml/jaxp/transform/XSLTExFuncTest.java
new file mode 100644
index 0000000..b86bcff
--- /dev/null
+++ b/ojluni/src/test/javax/xml/jaxp/transform/XSLTExFuncTest.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2013, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ * @test
+ * @bug 8004476
+ * @summary test XSLT extension functions
+ * @run main/othervm XSLTExFuncTest
+ */
+
+import java.io.StringWriter;
+import java.security.AllPermission;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import javax.xml.transform.*;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamResult;
+import org.xml.sax.InputSource;
+
+/**
+ * test XSLT extension functions
+ *
+ * @author huizhe.wang@oracle.com
+ */
+public class XSLTExFuncTest extends TestBase {
+
+    final static String ENABLE_EXTENSION_FUNCTIONS = "http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions";
+    final static String CLASSNAME = "DocumentBuilderFactoryImpl";
+
+    /**
+     * Creates a new instance of StreamReader
+     */
+    public XSLTExFuncTest(String name) {
+        super(name);
+    }
+    boolean hasSM;
+    String xslFile, xslFileId;
+    String xmlFile, xmlFileId;
+
+    protected void setUp() {
+        super.setUp();
+        xmlFile = filepath + "/tokenize.xml";
+        xslFile = filepath + "/tokenize.xsl";
+
+        /**
+         * On Windows platform it needs triple '/' for valid URL while double '/' is enough on Linux or Solaris.
+         * Here use file:/// directly to make it work on Windows and it will not impact other platforms.
+         */
+        xslFileId = "file:///" + xslFile;
+    }
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        XSLTExFuncTest test = new XSLTExFuncTest("OneTest");
+        test.setUp();
+
+        test.testExtFunc();
+        test.testExtFuncNotAllowed();
+        test.testEnableExtFunc();
+        test.testTemplatesEnableExtFunc();
+        test.tearDown();
+
+    }
+
+    /**
+     * by default, extension function is enabled
+     */
+    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());
+        }
+    }
+
+    /**
+     * Security is enabled, extension function not allowed
+     */
+    public void testExtFuncNotAllowed() {
+        Policy p = new SimplePolicy(new AllPermission());
+        Policy.setPolicy(p);
+        System.setSecurityManager(new SecurityManager());
+        TransformerFactory factory = TransformerFactory.newInstance();
+
+        try {
+            transform(factory);
+        } catch (TransformerConfigurationException e) {
+            fail(e.getMessage());
+        } catch (TransformerException ex) {
+            //expected since extension function is disallowed
+            System.out.println("testExtFuncNotAllowed: OK");
+        } finally {
+            System.setSecurityManager(null);
+        }
+    }
+
+    /**
+     * Security is enabled, use new feature: enableExtensionFunctions
+     */
+    public void testEnableExtFunc() {
+        Policy p = new SimplePolicy(new AllPermission());
+        Policy.setPolicy(p);
+        System.setSecurityManager(new SecurityManager());
+        TransformerFactory factory = TransformerFactory.newInstance();
+
+        /**
+         * Use of the extension function 'http://exslt.org/strings:tokenize' is
+         * not allowed when the secure processing feature is set to true.
+         * Attempt to use the new property to enable extension function
+         */
+        boolean isExtensionSupported = enableExtensionFunction(factory);
+
+        try {
+            transform(factory);
+            System.out.println("testEnableExt: OK");
+        } catch (TransformerConfigurationException e) {
+            fail(e.getMessage());
+        } catch (TransformerException e) {
+            fail(e.getMessage());
+        } finally {
+            System.setSecurityManager(null);
+        }
+    }
+
+    /**
+     * use Templates template = factory.newTemplates(new StreamSource( new
+     * FileInputStream(xslFilename))); // Use the template to create a
+     * transformer Transformer xformer = template.newTransformer();
+     *
+     * @param factory
+     * @return
+     */
+    /**
+     * Security is enabled, use new feature: enableExtensionFunctions Use the
+     * template to create a transformer
+     */
+    public void testTemplatesEnableExtFunc() {
+        Policy p = new SimplePolicy(new AllPermission());
+        Policy.setPolicy(p);
+        System.setSecurityManager(new SecurityManager());
+        TransformerFactory factory = TransformerFactory.newInstance();
+
+        /**
+         * Use of the extension function 'http://exslt.org/strings:tokenize' is
+         * not allowed when the secure processing feature is set to true.
+         * Attempt to use the new property to enable extension function
+         */
+        boolean isExtensionSupported = enableExtensionFunction(factory);
+
+        try {
+            SAXSource xslSource = new SAXSource(new InputSource(xslFile));
+            xslSource.setSystemId(xslFileId);
+            Templates template = factory.newTemplates(xslSource);
+            Transformer transformer = template.newTransformer();
+            StringWriter stringResult = new StringWriter();
+            Result result = new StreamResult(stringResult);
+            transformer.transform(new SAXSource(new InputSource(xmlFile)), result);
+            System.out.println("testTemplatesEnableExtFunc: OK");
+        } catch (TransformerConfigurationException e) {
+            fail(e.getMessage());
+        } catch (TransformerException e) {
+            fail(e.getMessage());
+        } finally {
+            System.setSecurityManager(null);
+        }
+    }
+
+    boolean enableExtensionFunction(TransformerFactory factory) {
+        boolean isSupported = true;
+        try {
+            factory.setFeature(ENABLE_EXTENSION_FUNCTIONS, true);
+        } catch (TransformerConfigurationException ex) {
+            isSupported = false;
+        }
+        return isSupported;
+    }
+
+    void transform(TransformerFactory factory) throws TransformerConfigurationException, TransformerException {
+        SAXSource xslSource = new SAXSource(new InputSource(xslFile));
+        xslSource.setSystemId(xslFileId);
+        Transformer transformer = factory.newTransformer(xslSource);
+        StringWriter stringResult = new StringWriter();
+        Result result = new StreamResult(stringResult);
+        transformer.transform(new SAXSource(new InputSource(xmlFile)), result);
+    }
+
+    class SimplePolicy extends Policy {
+
+        private final Permissions perms;
+
+        public SimplePolicy(Permission... permissions) {
+            perms = new Permissions();
+            for (Permission permission : permissions) {
+                perms.add(permission);
+            }
+        }
+
+        @Override
+        public PermissionCollection getPermissions(CodeSource cs) {
+            return perms;
+        }
+
+        @Override
+        public PermissionCollection getPermissions(ProtectionDomain pd) {
+            return perms;
+        }
+
+        @Override
+        public boolean implies(ProtectionDomain pd, Permission p) {
+            return perms.implies(p);
+        }
+
+        //for older jdk
+        @Override
+        public void refresh() {
+        }
+    }
+}
diff --git a/ojluni/src/test/javax/xml/jaxp/transform/XslSubstringTest.java b/ojluni/src/test/javax/xml/jaxp/transform/XslSubstringTest.java
new file mode 100644
index 0000000..cb3594b
--- /dev/null
+++ b/ojluni/src/test/javax/xml/jaxp/transform/XslSubstringTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8062923 8062924 8074297 8076290
+ * @run testng XslSubstringTest
+ * @summary Test xsl substring function with negative, Inf and
+ * NaN length and few other use cases. Also test proper
+ * processing of supplementary characters by substring function.
+ */
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class XslSubstringTest {
+
+    final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test></test>";
+    final String xslPre = "<xsl:stylesheet version='1.0'"
+            + " xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>"
+            + "<xsl:output method='xml' indent='yes' omit-xml-declaration='yes'/>"
+            + "<xsl:template match='/'><t>";
+    final String xslPost = "</t></xsl:template></xsl:stylesheet>";
+
+    @DataProvider(name = "GeneralTestsData")
+    private Object[][] xmls() {
+        return new Object[][] {
+            { "|<xsl:value-of select=\"substring('asdf',2, 1)\"/>|", "<t>|s|</t>"},
+            { "|<xsl:value-of select=\"substring('asdf',2, 1 div 0)\"/>|", "<t>|sdf|</t>"},
+            { "|<xsl:value-of select=\"substring('asdf',2, -0 div 0)\"/>|", "<t>||</t>" },
+            { "|<xsl:value-of select=\"substring('asdf',2, 1 div 0)\"/>|", "<t>|sdf|</t>" },
+            // 8076290 bug test case
+            { "|<xsl:value-of select=\"substring('123', 0, 3)\"/>|", "<t>|12|</t>"},
+        };
+    }
+
+    @DataProvider(name = "SupplementaryCharactersTestData")
+    private Object[][] dataSupplementaryCharacters() {
+        return new Object[][] {
+            // 8074297 bug test cases
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 3)\"/>|",    "<t>|BC|</t>"},
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 3, 1)\"/>|", "<t>|B|</t>" },
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 2, 2)\"/>|", "<t>|AB|</t>"},
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 3, 2)\"/>|", "<t>|BC|</t>"},
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 3, 4)\"/>|", "<t>|BC|</t>"},
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 1, 1)\"/>|", "<t>|&#131083;|</t>"},
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 2, 1)\"/>|", "<t>|A|</t>"},
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 1, 1 div 0)\"/>|", "<t>|&#131083;ABC|</t>"},
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', -10, 1 div 0)\"/>|", "<t>|&#131083;ABC|</t>"},
+            // 8076290 bug test case
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 0, 2)\"/>|", "<t>|&#131083;|</t>"},
+        };
+    }
+
+    private String testTransform(String xsl) throws Exception {
+        //Prepare sources for transormation
+        Source src = new StreamSource(new StringReader(xml));
+        Source xslsrc = new StreamSource(new StringReader(xslPre + xsl + xslPost));
+        //Create factory, template and transformer
+        TransformerFactory tf = TransformerFactory.newInstance();
+        Templates tmpl = tf.newTemplates(xslsrc);
+        Transformer t = tmpl.newTransformer();
+        //Prepare output stream
+        StringWriter xmlResultString = new StringWriter();
+        StreamResult xmlResultStream = new StreamResult(xmlResultString);
+        //Transform
+        t.transform(src, xmlResultStream);
+        return xmlResultString.toString().trim();
+    }
+
+    @Test
+    public void test8062923() throws Exception {
+        assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2,-1)\"/>|"),
+                "<t>||</t>");
+    }
+
+    @Test
+    public void test8062924() throws Exception {
+        assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2,-1 div 0)\"/>|"),
+                "<t>||</t>");
+    }
+
+    @Test(dataProvider = "GeneralTestsData")
+    public void testGeneralAll(String xsl, String result) throws Exception {
+        assertEquals(testTransform(xsl), result);
+    }
+
+    @Test(dataProvider = "SupplementaryCharactersTestData")
+    public void testSupplementCharacters(String xsl, String result) throws Exception {
+        assertEquals(testTransform(xsl), result);
+    }
+
+}
diff --git a/ojluni/src/test/javax/xml/jaxp/transform/tokenize.xml b/ojluni/src/test/javax/xml/jaxp/transform/tokenize.xml
new file mode 100644
index 0000000..1f97559
--- /dev/null
+++ b/ojluni/src/test/javax/xml/jaxp/transform/tokenize.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<html>
+<a>
+   <b>Is this EXSLT? No. no</b>
+   <c>Is this EXSLT? No. no</c>
+</a>
+</html>
diff --git a/ojluni/src/test/javax/xml/jaxp/transform/tokenize.xsl b/ojluni/src/test/javax/xml/jaxp/transform/tokenize.xsl
new file mode 100644
index 0000000..d090d3b
--- /dev/null
+++ b/ojluni/src/test/javax/xml/jaxp/transform/tokenize.xsl
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+                xmlns:str="http://exslt.org/strings"
+                xmlns:xalan="http://xml.apache.org/xalan"
+                version="1.0">
+<xsl:template match="a">
+   <xsl:apply-templates />
+</xsl:template>
+<xsl:template match="//a/c">
+   <xsl:value-of select="." />
+ -
+      <xsl:value-of select="str:tokenize(string(.), ' ')" />
+   <xsl:value-of select="str:tokenize(string(.), '')" />
+   <xsl:for-each select="str:tokenize(string(.), ' ')">
+      <xsl:value-of select="." />
+   </xsl:for-each>
+   <xsl:apply-templates select="*" />
+</xsl:template>
+<xsl:template match="//a/b">
+   <xsl:value-of select="." />
+ -
+      <xsl:value-of select="xalan:tokenize(string(.), ' ')" />
+   <xsl:value-of select="xalan:tokenize(string(.), '')" />
+   <xsl:for-each select="xalan:tokenize(string(.), ' ')">
+      <xsl:value-of select="." />
+   </xsl:for-each>
+   <xsl:apply-templates select="*" />
+</xsl:template>
+
+</xsl:stylesheet>