From 565e02e3fa8b9a9826319a7a6f483cf44d7d32c7 Mon Sep 17 00:00:00 2001 From: Takakuri Date: Thu, 16 May 2024 19:57:42 +0900 Subject: [PATCH 1/8] Backport 83bce94cc8a7fb45b0604598411fbecc62000dfd --- .../xml/internal/serializer/ToHTMLStream.java | 43 +- .../unittest/transform/SurrogateTest.java | 104 ++++ .../unittest/transform/SurrogateTest1.html | 12 + .../unittest/transform/SurrogateTest1.xml | 4 + .../unittest/transform/SurrogateTest1.xsl | 26 + .../unittest/transform/SurrogateTest2.txt | 4 + .../unittest/transform/SurrogateTest2.xml | 6 + .../test/lib/javax/xml/jaxp/BasePolicy.java | 75 +++ .../test/lib/javax/xml/jaxp/FilePolicy.java | 51 ++ .../lib/javax/xml/jaxp/JAXPPolicyManager.java | 320 +++++++++++ .../lib/javax/xml/jaxp/JAXPTestUtilities.java | 509 ++++++++++++++++++ 11 files changed, 1128 insertions(+), 26 deletions(-) create mode 100644 jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest.java create mode 100644 jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.html create mode 100644 jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.xml create mode 100644 jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.xsl create mode 100644 jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest2.txt create mode 100644 jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest2.xml create mode 100644 test/lib/jdk/test/lib/javax/xml/jaxp/BasePolicy.java create mode 100644 test/lib/jdk/test/lib/javax/xml/jaxp/FilePolicy.java create mode 100644 test/lib/jdk/test/lib/javax/xml/jaxp/JAXPPolicyManager.java create mode 100644 test/lib/jdk/test/lib/javax/xml/jaxp/JAXPTestUtilities.java diff --git a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java index 255bb04e22e..e09887d391a 100644 --- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java +++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one @@ -45,7 +45,7 @@ * because it is used from another package. * * @xsl.usage internal - * @LastModified: July 2021 + * @LastModified: June 2021 */ public final class ToHTMLStream extends ToStream { @@ -1393,32 +1393,23 @@ else if ( } } } - - // The next is kind of a hack to keep from escaping in the case - // of Shift_JIS and the like. - - /* - else if ((ch < m_maxCharacter) && (m_maxCharacter == 0xFFFF) - && (ch != 160)) - { - writer.write(ch); // no escaping in this case - } - else - */ - String outputStringForChar = m_charInfo.getOutputStringForChar(ch); - if (null != outputStringForChar) - { - writer.write(outputStringForChar); - } - else if (escapingNotNeeded(ch)) - { - writer.write(ch); // no escaping in this case - } else { - writer.write("&#"); - writer.write(Integer.toString(ch)); - writer.write(';'); + String outputStringForChar = m_charInfo.getOutputStringForChar(ch); + if (null != outputStringForChar) + { + writer.write(outputStringForChar); + } + else if (escapingNotNeeded(ch)) + { + writer.write(ch); // no escaping in this case + } + else + { + writer.write("&#"); + writer.write(Integer.toString(ch)); + writer.write(';'); + } } } cleanStart = i + 1; diff --git a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest.java b/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest.java new file mode 100644 index 00000000000..3cb1253390a --- /dev/null +++ b/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021, 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. + */ + +package transform; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.InputStream; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import static jdk.test.lib.javax.xml.jaxp.JAXPTestUtilities.compareWithGold; +import static jdk.test.lib.javax.xml.jaxp.JAXPTestUtilities.compareStringWithGold; +import org.testng.Assert; +import org.testng.annotations.Listeners; +import org.testng.annotations.Test; + +/* + * @test + * @bug 8268457 + * @library /test/lib + * @run testng transform.SurrogateTest + * @summary XML Transformer outputs Unicode supplementary character incorrectly to HTML + */ +@Listeners({jdk.test.lib.javax.xml.jaxp.FilePolicy.class}) +public class SurrogateTest { + + final static String TEST_SRC = System.getProperty("test.src", "."); + + @Test + public void toHTMLTest() throws Exception { + String out = "SurrogateTest1out.html"; + String expected = TEST_SRC + File.separator + "SurrogateTest1.html"; + String xsl = TEST_SRC + File.separator + "SurrogateTest1.xsl"; + + try (FileInputStream tFis = new FileInputStream(xsl); + InputStream fis = this.getClass().getResourceAsStream("SurrogateTest1.xml"); + FileOutputStream fos = new FileOutputStream(out)) { + + Source tSrc = new StreamSource(tFis); + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer t = tf.newTransformer(tSrc); + t.setOutputProperty("method", "html"); + + Source src = new StreamSource(fis); + Result res = new StreamResult(fos); + t.transform(src, res); + } + compareWithGold(expected, out); + } + + @Test + public void handlerTest() throws Exception { + File xmlFile = new File(TEST_SRC, "SurrogateTest2.xml"); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + SAXParser sp = spf.newSAXParser(); + TestHandler th = new TestHandler(); + sp.parse(xmlFile, th); + compareStringWithGold(TEST_SRC + File.separator + "SurrogateTest2.txt", th.sb.toString()); + } + + private static class TestHandler extends DefaultHandler { + private StringBuilder sb = new StringBuilder(); + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + sb.append( localName + "@attr:" + attributes.getValue("attr") + '\n'); + } + } +} diff --git a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.html b/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.html new file mode 100644 index 00000000000..e2db93fa3bc --- /dev/null +++ b/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.html @@ -0,0 +1,12 @@ + + + + + + + +
+ +
+ + diff --git a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.xml b/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.xml new file mode 100644 index 00000000000..bb346086b05 --- /dev/null +++ b/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.xml @@ -0,0 +1,4 @@ + + + 𠮟 + diff --git a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.xsl b/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.xsl new file mode 100644 index 00000000000..b7a64d5170b --- /dev/null +++ b/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.xsl @@ -0,0 +1,26 @@ + + + + + + + + + + +
+ + + + + + + +
+
+ + +
+
diff --git a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest2.txt b/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest2.txt new file mode 100644 index 00000000000..0e3ce0062c7 --- /dev/null +++ b/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest2.txt @@ -0,0 +1,4 @@ +root@attr:null +tag1@attr:𠮟 +tag2@attr:𠀋 +tag3@attr:𣱿 diff --git a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest2.xml b/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest2.xml new file mode 100644 index 00000000000..3f91e3c82ae --- /dev/null +++ b/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest2.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/test/lib/jdk/test/lib/javax/xml/jaxp/BasePolicy.java b/test/lib/jdk/test/lib/javax/xml/jaxp/BasePolicy.java new file mode 100644 index 00000000000..d4107c02875 --- /dev/null +++ b/test/lib/jdk/test/lib/javax/xml/jaxp/BasePolicy.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016, 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. + */ +package jdk.test.lib.javax.xml.jaxp; + +import org.testng.ITestContext; +import org.testng.ITestListener; +import org.testng.ITestResult; + +/** + * This policy includes default permissions. + * It should be used as one listener: either TestListener or MethodListener. + */ +public class BasePolicy implements ITestListener { + + @Override + public void onFinish(ITestContext arg0) { + try { + JAXPPolicyManager.teardownPolicyManager(); + } catch (Exception e) { + throw new RuntimeException("Failed to teardown the policy manager", e); + } + } + + @Override + public void onStart(ITestContext arg0) { + // suppose to only run othervm mode + if (isRunWithSecurityManager()) + JAXPPolicyManager.getJAXPPolicyManager(true); + } + + @Override + public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) { + } + + @Override + public void onTestFailure(ITestResult arg0) { + } + + @Override + public void onTestSkipped(ITestResult arg0) { + } + + @Override + public void onTestStart(ITestResult arg0) { + } + + @Override + public void onTestSuccess(ITestResult arg0) { + } + + protected boolean isRunWithSecurityManager() { + final String runSecMngr = JAXPTestUtilities.getSystemProperty("runSecMngr"); + return runSecMngr != null && runSecMngr.equals("true"); + } +} diff --git a/test/lib/jdk/test/lib/javax/xml/jaxp/FilePolicy.java b/test/lib/jdk/test/lib/javax/xml/jaxp/FilePolicy.java new file mode 100644 index 00000000000..ddc212e2369 --- /dev/null +++ b/test/lib/jdk/test/lib/javax/xml/jaxp/FilePolicy.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, 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. + */ +package jdk.test.lib.javax.xml.jaxp; + +import static jdk.test.lib.javax.xml.jaxp.JAXPTestUtilities.getSystemProperty; + +import java.io.FilePermission; + +import org.testng.ITestContext; + +/** + * This policy can access local XML files. + */ +public class FilePolicy extends BasePolicy { + + @Override + public void onStart(ITestContext arg0) { + // suppose to only run othervm mode + if (isRunWithSecurityManager()) { + JAXPPolicyManager policyManager = JAXPPolicyManager.getJAXPPolicyManager(true); + String userdir = getSystemProperty("user.dir"); + policyManager.addPermission(new FilePermission(userdir + "/-", "read,write,delete")); + String testSrc = System.getProperty("test.src"); + // to handle the directory structure of some functional test suite + if (testSrc.endsWith("ptests")) + testSrc = testSrc.substring(0, testSrc.length() - 7); + policyManager.addPermission(new FilePermission(testSrc + "/-", "read")); + policyManager.addPermission(new FilePermission(userdir, "read")); + } + } +} diff --git a/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPPolicyManager.java b/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPPolicyManager.java new file mode 100644 index 00000000000..a23b34c460a --- /dev/null +++ b/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPPolicyManager.java @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2015, 2023, 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. + */ +package jdk.test.lib.javax.xml.jaxp; + + +import java.net.URI; +import java.net.URL; +import java.nio.file.Path; +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.security.SecurityPermission; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.PropertyPermission; +import java.util.Set; +import java.util.StringJoiner; + + +/* + * This is a base class that every test class must extend if it needs to be run + * with security mode. + */ +@SuppressWarnings("removal") +public class JAXPPolicyManager { + /* + * Backing up policy. + */ + private Policy policyBackup; + + /* + * Backing up security manager. + */ + private SecurityManager smBackup; + + /* + * Current policy. + */ + private TestPolicy policy = new TestPolicy(); + + /* + * JAXPPolicyManager singleton. + */ + private static JAXPPolicyManager policyManager = null; + + /* + * Install a SecurityManager along with a default Policy to allow testNG to + * run when there is a security manager. + */ + private JAXPPolicyManager() { + // Backing up policy and security manager for restore + policyBackup = Policy.getPolicy(); + smBackup = System.getSecurityManager(); + + // Set customized policy + setDefaultPermissions(); + Policy.setPolicy(policy); + System.setSecurityManager(new SecurityManager()); + } + + static synchronized JAXPPolicyManager getJAXPPolicyManager(boolean createIfNone) { + if (policyManager == null & createIfNone) + policyManager = new JAXPPolicyManager(); + return policyManager; + } + + private void teardown() throws Exception { + System.setSecurityManager(smBackup); + Policy.setPolicy(policyBackup); + } + + /* + * Restore the original Policy and SecurityManager. + */ + static synchronized void teardownPolicyManager() throws Exception { + if (policyManager != null) { + policyManager.teardown(); + policyManager = null; + } + } + + /* + * Set default permissions, sub-class of JAXPBaseTest should override this + * method. + */ + private void setDefaultPermissions() { + //Permissions to set security manager and policy + addPermission(new SecurityPermission("getPolicy")); + addPermission(new SecurityPermission("setPolicy")); + addPermission(new RuntimePermission("setSecurityManager")); + addPermission(new PropertyPermission("test.src", "read")); + } + + /* + * Add permission to the TestPolicy. + * + * @param permission to be added. + */ + void addPermission(Permission p) { + policy.addPermission(p); + } + + /* + * Add a temporary permission in current thread context. This won't impact + * global policy and doesn't support permission combination. + * + * @param permission + * to add. + * @return index of the added permission. + */ + int addTmpPermission(Permission p) { + return policy.addTmpPermission(p); + } + + /* + * set allowAll in current thread context. + */ + void setAllowAll(boolean allow) { + policy.setAllowAll(allow); + } + + /* + * Remove a temporary permission from current thread context. + * + * @param index to remove. + * + * @throws RuntimeException if no temporary permission list in current + * thread context or no permission correlated to the index. + */ + void removeTmpPermission(int index) { + policy.removeTmpPermission(index); + } + + +} + +/* + * Simple Policy class that supports the required Permissions to validate the + * JAXP concrete classes. + */ +@SuppressWarnings("removal") +class TestPolicy extends Policy { + private final static Set TEST_JARS = new HashSet<>(); + TEST_JARS.add("jtreg.*jar"); + TEST_JARS.add("javatest.*jar"); + TEST_JARS.add("testng.*jar"); + TEST_JARS.add("jcommander.*jar"); + private final PermissionCollection permissions = new Permissions(); + + private ThreadLocal> transientPermissions = new ThreadLocal<>(); + private ThreadLocal allowAll = new ThreadLocal<>(); + + private static Policy defaultPolicy = Policy.getPolicy(); + + /* + * Add permission to this policy. + * + * @param permission to be added. + */ + void addPermission(Permission p) { + permissions.add(p); + } + + /* + * Set all permissions. Caution: this should not called carefully unless + * it's really needed. + * + * private void setAllPermissions() { permissions.add(new AllPermission()); + * } + */ + + /* + * Overloaded methods from the Policy class. + */ + @Override + public String toString() { + StringJoiner sj = new StringJoiner("\n", "policy: ", ""); + Enumeration perms = permissions.elements(); + while (perms.hasMoreElements()) { + sj.add(perms.nextElement().toString()); + } + return sj.toString(); + + } + + @Override + public PermissionCollection getPermissions(ProtectionDomain domain) { + return permissions; + } + + @Override + public PermissionCollection getPermissions(CodeSource codesource) { + return permissions; + } + + private boolean isTestMachineryDomain(ProtectionDomain domain) { + CodeSource cs = (domain == null) ? null : domain.getCodeSource(); + URL loc = (cs == null) ? null : cs.getLocation(); + URI uri = (loc == null) ? null : URI.create(loc.toString()); + String name = (uri == null) ? null : Path.of(uri).getFileName().toString(); + return name != null && TEST_JARS.stream() + .filter(name::matches) + .findAny() + .isPresent(); + } + + @Override + public boolean implies(ProtectionDomain domain, Permission perm) { + if (allowAll()) + return true; + + if (defaultPolicy.implies(domain, perm)) + return true; + + if (permissions.implies(perm)) + return true; + + if (isTestMachineryDomain(domain)) + return true; + + return tmpImplies(perm); + } + + /* + * Add a temporary permission in current thread context. This won't impact + * global policy and doesn't support permission combination. + * + * @param permission to add. + * @return index of the added permission. + */ + int addTmpPermission(Permission p) { + Map tmpPermissions = transientPermissions.get(); + if (tmpPermissions == null) + tmpPermissions = new HashMap<>(); + + int id = tmpPermissions.size(); + tmpPermissions.put(id, p); + transientPermissions.set(tmpPermissions); + return id; + } + + /* + * Remove a temporary permission from current thread context. + * + * @param index to remove. + * + * @throws RuntimeException if no temporary permission list in current + * thread context or no permission correlated to the index. + */ + void removeTmpPermission(int index) { + try { + Map tmpPermissions = transientPermissions.get(); + tmpPermissions.remove(index); + } catch (NullPointerException | IndexOutOfBoundsException e) { + throw new RuntimeException("Tried to delete a non-existent temporary permission", e); + } + } + + /* + * Checks to see if the specified permission is implied by temporary + * permission list in current thread context. + * + * @param permission the Permission object to compare. + * + * @return true if "permission" is implied by any permission in the + * temporary permission list, false if not. + */ + private boolean tmpImplies(Permission perm) { + Map tmpPermissions = transientPermissions.get(); + if (tmpPermissions != null) { + for (Permission p : tmpPermissions.values()) { + if (p.implies(perm)) + return true; + } + } + return false; + } + + /* + * Checks to see if allow all permission requests in current thread context. + */ + private boolean allowAll() { + Boolean allow = allowAll.get(); + if (allow != null) { + return allow; + } + return false; + } + + /* + * set allowAll in current thread context. + */ + void setAllowAll(boolean allow) { + allowAll.set(allow); + } +} diff --git a/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPTestUtilities.java b/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPTestUtilities.java new file mode 100644 index 00000000000..f3a1a6978f9 --- /dev/null +++ b/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPTestUtilities.java @@ -0,0 +1,509 @@ +/* + * Copyright (c) 2014, 2017, 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. + */ +package jdk.test.lib.javax.xml.jaxp; + +import static org.testng.Assert.fail; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.charset.UnsupportedCharsetException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.Permission; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; + +/** + * This is an interface provide basic support for JAXP functional test. + */ +public class JAXPTestUtilities { + /** + * Prefix for error message. + */ + public static final String ERROR_MSG_HEADER = "Unexcepted exception thrown:"; + + /** + * Prefix for error message on clean up block. + */ + public static final String ERROR_MSG_CLEANUP = "Clean up failed on %s"; + + /** + * Force using slash as File separator as we always use cygwin to test in + * Windows platform. + */ + public static final String FILE_SEP = "/"; + + /** + * A map storing every test's current test file pointer. File number should + * be incremental and it's a thread-safe reading on this file number. + */ + private static final ConcurrentHashMap, Integer> currentFileNumber + = new ConcurrentHashMap<>(); + + /** + * BOM table for storing BOM header. + */ + private final static Map bom = new HashMap<>(); + + /** + * Initialize all BOM headers. + */ + static { + bom.put("UTF-8", new byte[]{(byte)0xEF, (byte) 0xBB, (byte) 0xBF}); + bom.put("UTF-16BE", new byte[]{(byte)0xFE, (byte)0xFF}); + bom.put("UTF-16LE", new byte[]{(byte)0xFF, (byte)0xFE}); + bom.put("UTF-32BE", new byte[]{(byte)0x00, (byte)0x00, (byte)0xFE, (byte)0xFF}); + bom.put("UTF-32LE", new byte[]{(byte)0xFF, (byte)0xFE, (byte)0x00, (byte)0x00}); + } + + /** + * Compare contents of golden file with test output file line by line. + * return true if they're identical. + * @param goldfile Golden output file name + * @param outputfile Test output file name + * @return true if two files are identical. + * false if two files are not identical. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read. + */ + public static boolean compareWithGold(String goldfile, String outputfile) + throws IOException { + return compareWithGold(goldfile, outputfile, StandardCharsets.UTF_8); + } + + /** + * Compare contents of golden file with test output file line by line. + * return true if they're identical. + * @param goldfile Golden output file name. + * @param outputfile Test output file name. + * @param cs the charset to use for decoding. + * @return true if two files are identical. + * false if two files are not identical. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read. + */ + public static boolean compareWithGold(String goldfile, String outputfile, + Charset cs) throws IOException { + boolean isSame = Files.readAllLines(Paths.get(goldfile)). + equals(Files.readAllLines(Paths.get(outputfile), cs)); + if (!isSame) { + System.err.println("Golden file " + goldfile + " :"); + Files.readAllLines(Paths.get(goldfile)).forEach(System.err::println); + System.err.println("Output file " + outputfile + " :"); + Files.readAllLines(Paths.get(outputfile), cs).forEach(System.err::println); + } + return isSame; + } + + /** + * Compare contents of golden file with test output list line by line. + * return true if they're identical. + * @param goldfile Golden output file name. + * @param lines test output list. + * @return true if file's content is identical to given list. + * false if file's content is not identical to given list. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read + */ + public static boolean compareLinesWithGold(String goldfile, List lines) + throws IOException { + return Files.readAllLines(Paths.get(goldfile)).equals(lines); + } + + /** + * Compare contents of golden file with a test output string. + * return true if they're identical. + * @param goldfile Golden output file name. + * @param string test string. + * @return true if file's content is identical to given string. + * false if file's content is not identical to given string. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read + */ + public static boolean compareStringWithGold(String goldfile, String string) + throws IOException { + return Files.readAllLines(Paths.get(goldfile)).stream().collect( + Collectors.joining(System.getProperty("line.separator"))) + .equals(string); + } + + /** + * Compare contents of golden file with test output file by their document + * representation. + * Here we ignore the white space and comments. return true if they're + * lexical identical. + * @param goldfile Golden output file name. + * @param resultFile Test output file name. + * @return true if two file's document representation are identical. + * false if two file's document representation are not identical. + * @throws javax.xml.parsers.ParserConfigurationException if the + * implementation is not available or cannot be instantiated. + * @throws SAXException If any parse errors occur. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read . + */ + public static boolean compareDocumentWithGold(String goldfile, String resultFile) + throws ParserConfigurationException, SAXException, IOException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + factory.setCoalescing(true); + factory.setIgnoringElementContentWhitespace(true); + factory.setIgnoringComments(true); + DocumentBuilder db = factory.newDocumentBuilder(); + + Document goldD = db.parse(Paths.get(goldfile).toFile()); + goldD.normalizeDocument(); + Document resultD = db.parse(Paths.get(resultFile).toFile()); + resultD.normalizeDocument(); + return goldD.isEqualNode(resultD); + } + + /** + * Compare contents of golden file with the serialization represent by given + * DOM node. + * Here we ignore the white space and comments. return true if they're + * lexical identical. + * @param goldfile Golden output file name. + * @param node A DOM node instance. + * @return true if file's content is identical to given node's serialization + * represent. + * false if file's content is not identical to given node's + * serialization represent. + * @throws TransformerException If an unrecoverable error occurs during the + * course of the transformation.. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read . + */ + public static boolean compareSerializeDOMWithGold(String goldfile, Node node) + throws TransformerException, IOException { + TransformerFactory factory = TransformerFactory.newInstance(); + // Use identity transformer to serialize + Transformer identityTransformer = factory.newTransformer(); + StringWriter sw = new StringWriter(); + StreamResult streamResult = new StreamResult(sw); + DOMSource nodeSource = new DOMSource(node); + identityTransformer.transform(nodeSource, streamResult); + return compareStringWithGold(goldfile, sw.toString()); + } + + /** + * Convert stream to ByteArrayInputStream by given character set. + * @param charset target character set. + * @param file a file that contains no BOM head content. + * @return a ByteArrayInputStream contains BOM heads and bytes in original + * stream + * @throws IOException I/O operation failed or unsupported character set. + */ + public static InputStream bomStream(String charset, String file) + throws IOException { + String localCharset = charset; + if (charset.equals("UTF-16") || charset.equals("UTF-32")) { + localCharset + += ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN ? "BE" : "LE"; + } + if (!bom.containsKey(localCharset)) + throw new UnsupportedCharsetException("Charset:" + localCharset); + + byte[] content = Files.readAllLines(Paths.get(file)).stream(). + collect(Collectors.joining()).getBytes(localCharset); + byte[] head = bom.get(localCharset); + ByteBuffer bb = ByteBuffer.allocate(content.length + head.length); + bb.put(head); + bb.put(content); + return new ByteArrayInputStream(bb.array()); + } + + /** + * Worker method to detect common absolute URLs. + * + * @param s String path\filename or URL (or any, really) + * @return true if s starts with a common URI scheme (namely + * the ones found in the examples of RFC2396); false otherwise + */ + protected static boolean isCommonURL(String s) { + if (null == s) + return false; + return Pattern.compile("^(file:|http:|ftp:|mailto:|news:|telnet:)") + .matcher(s).matches(); + } + + /** + * Utility method to translate a String filename to URL. + * + * If the name starts with a common URI scheme (namely the ones + * found in the examples of RFC2396), then simply return the + * name as-is (the assumption is that it's already a URL). + * Otherwise we attempt (cheaply) to convert to a file:/ URL. + * + * @param filename local path/filename of a file. + * @return a file:/ URL if filename represent a file, the same string if + * it appears to already be a URL. + */ + public static String filenameToURL(String filename) { + return Paths.get(filename).toUri().toASCIIString(); + } + + /** + * Prints error message if an exception is thrown + * @param ex The exception is thrown by test. + */ + public static void failUnexpected(Throwable ex) { + fail(ERROR_MSG_HEADER, ex); + } + + /** + * Prints error message if an exception is thrown when clean up a file. + * @param ex The exception is thrown in cleaning up a file. + * @param name Cleaning up file name. + */ + public static void failCleanup(IOException ex, String name) { + fail(String.format(ERROR_MSG_CLEANUP, name), ex); + } + + /** + * Retrieve next test output file name. This method is a thread-safe method. + * @param clazz test class. + * @return next test output file name. + */ + public static String getNextFile(Class clazz) { + int nextNumber = currentFileNumber.contains(clazz) + ? currentFileNumber.get(clazz) + 1 : 1; + Integer i = currentFileNumber.putIfAbsent(clazz, nextNumber); + if (i != null) { + do { + nextNumber = currentFileNumber.get(clazz) + 1; + } while (!currentFileNumber.replace(clazz, nextNumber - 1, nextNumber)); + } + return USER_DIR + clazz.getName() + nextNumber + ".out"; + } + + /** + * Acquire a full path string by given class name and relative path string. + * @param clazz Class name for the test. + * @param relativeDir relative path between java source file and expected + * path. + * @return a string represents the full path of accessing path. + */ + public static String getPathByClassName(Class clazz, String relativeDir) { + String javaSourcePath = System.getProperty("test.src").replaceAll("\\" + File.separator, FILE_SEP); + String normalizedPath = Paths.get(javaSourcePath, relativeDir).normalize(). + toAbsolutePath().toString(); + return normalizedPath.replace("\\", FILE_SEP) + FILE_SEP; + } + + + /** + * Run the supplier with all permissions. This won't impact global policy. + * + * @param s + * Supplier to run + */ + public static T runWithAllPerm(Supplier s) { + Optional policyManager = Optional.ofNullable(JAXPPolicyManager + .getJAXPPolicyManager(false)); + policyManager.ifPresent(manager -> manager.setAllowAll(true)); + try { + return s.get(); + } finally { + policyManager.ifPresent(manager -> manager.setAllowAll(false)); + } + } + + /** + * Run the supplier with all permissions. This won't impact global policy. + * + * @param s + * Supplier to run + */ + public static T tryRunWithAllPerm(Callable c) throws Exception { + Optional policyManager = Optional.ofNullable(JAXPPolicyManager + .getJAXPPolicyManager(false)); + policyManager.ifPresent(manager -> manager.setAllowAll(true)); + try { + return c.call(); + } finally { + policyManager.ifPresent(manager -> manager.setAllowAll(false)); + } + } + + /** + * Run the Runnable with all permissions. This won't impact global policy. + * + * @param s + * Supplier to run + */ + public static void runWithAllPerm(Runnable r) { + Optional policyManager = Optional.ofNullable(JAXPPolicyManager + .getJAXPPolicyManager(false)); + policyManager.ifPresent(manager -> manager.setAllowAll(true)); + try { + r.run(); + } finally { + policyManager.ifPresent(manager -> manager.setAllowAll(false)); + } + } + + /** + * Acquire a system property. + * + * @param name + * System property name to be acquired. + * @return property value + */ + public static String getSystemProperty(String name) { + return runWithAllPerm(() -> System.getProperty(name)); + } + + /** + * Set a system property by given system value. + * + * @param name + * System property name to be set. + * @param value + * System property value to be set. + */ + public static void setSystemProperty(String name, String value) { + runWithAllPerm(() -> System.setProperty(name, value)); + } + + /** + * Clear a system property. + * + * @param name + * System property name to be cleared. + */ + public static void clearSystemProperty(String name) { + runWithAllPerm(() -> System.clearProperty(name)); + } + + /** + * Run the runnable with assigning temporary permissions. This won't impact + * global policy. + * + * @param r + * Runnable to run + * @param ps + * assigning permissions to add. + */ + public static void runWithTmpPermission(Runnable r, Permission... ps) { + JAXPPolicyManager policyManager = JAXPPolicyManager.getJAXPPolicyManager(false); + List tmpPermissionIndexes = new ArrayList<>(); + if (policyManager != null) { + for (Permission p : ps) + tmpPermissionIndexes.add(policyManager.addTmpPermission(p)); + } + try { + r.run(); + } finally { + for (int index: tmpPermissionIndexes) + policyManager.removeTmpPermission(index); + } + } + + /** + * Run the supplier with assigning temporary permissions. This won't impact + * global policy. + * + * @param s + * Supplier to run + * @param ps + * assigning permissions to add. + */ + public static T runWithTmpPermission(Supplier s, Permission... ps) { + JAXPPolicyManager policyManager = JAXPPolicyManager.getJAXPPolicyManager(false); + List tmpPermissionIndexes = new ArrayList<>(); + if (policyManager != null) { + for (Permission p : ps) + tmpPermissionIndexes.add(policyManager.addTmpPermission(p)); + } + try { + return s.get(); + } finally { + for (int index: tmpPermissionIndexes) + policyManager.removeTmpPermission(index); + } + } + + /** + * Run the RunnableWithException with assigning temporary permissions. This + * won't impact global policy. + * + * @param r + * RunnableWithException to execute + * @param ps + * assigning permissions to add. + */ + public static void tryRunWithTmpPermission(RunnableWithException r, Permission... ps) throws Exception { + JAXPPolicyManager policyManager = JAXPPolicyManager.getJAXPPolicyManager(false); + List tmpPermissionIndexes = new ArrayList<>(); + if (policyManager != null) { + for (Permission p : ps) + tmpPermissionIndexes.add(policyManager.addTmpPermission(p)); + } + try { + r.run(); + } finally { + for (int index: tmpPermissionIndexes) + policyManager.removeTmpPermission(index); + } + } + + @FunctionalInterface + public interface RunnableWithException { + void run() throws Exception; + } + + /** + * Current test directory. + */ + public static final String USER_DIR = getSystemProperty("user.dir") + FILE_SEP;; + +} From 428c299ec2508f5ac58255a4ecb7309c29c7b049 Mon Sep 17 00:00:00 2001 From: Takakuri Date: Thu, 23 May 2024 21:58:58 +0900 Subject: [PATCH 2/8] Backport 83bce94cc8a7fb45b0604598411fbecc62000dfd --- .../test/lib/javax/xml/jaxp/JAXPPolicyManager.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPPolicyManager.java b/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPPolicyManager.java index a23b34c460a..ea38e50e9a2 100644 --- a/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPPolicyManager.java +++ b/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPPolicyManager.java @@ -25,7 +25,7 @@ import java.net.URI; import java.net.URL; -import java.nio.file.Path; +import java.nio.file.Paths; import java.security.CodeSource; import java.security.Permission; import java.security.PermissionCollection; @@ -33,8 +33,10 @@ import java.security.Policy; import java.security.ProtectionDomain; import java.security.SecurityPermission; +import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.PropertyPermission; import java.util.Set; @@ -164,11 +166,7 @@ void removeTmpPermission(int index) { */ @SuppressWarnings("removal") class TestPolicy extends Policy { - private final static Set TEST_JARS = new HashSet<>(); - TEST_JARS.add("jtreg.*jar"); - TEST_JARS.add("javatest.*jar"); - TEST_JARS.add("testng.*jar"); - TEST_JARS.add("jcommander.*jar"); + private final static Set TEST_JARS = new HashSet(Arrays.asList("jtreg.*jar", "javatest.*jar", "testng.*jar", "jcommander.*jar")); private final PermissionCollection permissions = new Permissions(); private ThreadLocal> transientPermissions = new ThreadLocal<>(); @@ -221,7 +219,7 @@ private boolean isTestMachineryDomain(ProtectionDomain domain) { CodeSource cs = (domain == null) ? null : domain.getCodeSource(); URL loc = (cs == null) ? null : cs.getLocation(); URI uri = (loc == null) ? null : URI.create(loc.toString()); - String name = (uri == null) ? null : Path.of(uri).getFileName().toString(); + String name = (uri == null) ? null : Paths.get(uri).getFileName().toString(); return name != null && TEST_JARS.stream() .filter(name::matches) .findAny() From f5deacedc236482b4e2234e6ff2da481ffa6acf0 Mon Sep 17 00:00:00 2001 From: Takakuri Date: Tue, 28 May 2024 17:39:41 +0900 Subject: [PATCH 3/8] Fix the indent --- .../unittest/transform/SurrogateTest1.html | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.html b/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.html index e2db93fa3bc..203a27a06d2 100644 --- a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.html +++ b/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.html @@ -1,12 +1,12 @@ - - - - - -
- -
- + + + + + +
+ +
+ From 7db72a8e5d69539a897231c881acd8ee6747acba Mon Sep 17 00:00:00 2001 From: Takakuri Date: Tue, 4 Jun 2024 21:17:19 +0900 Subject: [PATCH 4/8] Backport 83bce94cc8a7fb45b0604598411fbecc62000dfd --- .../xml/internal/serializer/ToHTMLStream.java | 2 +- .../8268457}/SurrogateTest.java | 74 ++- .../8268457}/SurrogateTest1.html | 0 .../8268457}/SurrogateTest1.xml | 0 .../8268457}/SurrogateTest1.xsl | 0 .../8268457}/SurrogateTest2.txt | 0 .../8268457}/SurrogateTest2.xml | 0 .../test/lib/javax/xml/jaxp/BasePolicy.java | 75 --- .../test/lib/javax/xml/jaxp/FilePolicy.java | 51 -- .../lib/javax/xml/jaxp/JAXPPolicyManager.java | 318 ----------- .../lib/javax/xml/jaxp/JAXPTestUtilities.java | 509 ------------------ 11 files changed, 67 insertions(+), 962 deletions(-) rename jdk/test/javax/xml/jaxp/{unittest/transform => transform/8268457}/SurrogateTest.java (55%) rename jdk/test/javax/xml/jaxp/{unittest/transform => transform/8268457}/SurrogateTest1.html (100%) rename jdk/test/javax/xml/jaxp/{unittest/transform => transform/8268457}/SurrogateTest1.xml (100%) rename jdk/test/javax/xml/jaxp/{unittest/transform => transform/8268457}/SurrogateTest1.xsl (100%) rename jdk/test/javax/xml/jaxp/{unittest/transform => transform/8268457}/SurrogateTest2.txt (100%) rename jdk/test/javax/xml/jaxp/{unittest/transform => transform/8268457}/SurrogateTest2.xml (100%) delete mode 100644 test/lib/jdk/test/lib/javax/xml/jaxp/BasePolicy.java delete mode 100644 test/lib/jdk/test/lib/javax/xml/jaxp/FilePolicy.java delete mode 100644 test/lib/jdk/test/lib/javax/xml/jaxp/JAXPPolicyManager.java delete mode 100644 test/lib/jdk/test/lib/javax/xml/jaxp/JAXPTestUtilities.java diff --git a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java index e09887d391a..bbad5911263 100644 --- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java +++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java @@ -45,7 +45,7 @@ * because it is used from another package. * * @xsl.usage internal - * @LastModified: June 2021 + * @LastModified: July 2021 */ public final class ToHTMLStream extends ToStream { diff --git a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest.java b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java similarity index 55% rename from jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest.java rename to jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java index 3cb1253390a..f8cd4703f19 100644 --- a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest.java +++ b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java @@ -21,13 +21,14 @@ * questions. */ -package transform; - import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.InputStream; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; @@ -42,8 +43,6 @@ import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; -import static jdk.test.lib.javax.xml.jaxp.JAXPTestUtilities.compareWithGold; -import static jdk.test.lib.javax.xml.jaxp.JAXPTestUtilities.compareStringWithGold; import org.testng.Assert; import org.testng.annotations.Listeners; import org.testng.annotations.Test; @@ -52,15 +51,13 @@ * @test * @bug 8268457 * @library /test/lib - * @run testng transform.SurrogateTest + * @run main/othervm transform.SurrogateTest * @summary XML Transformer outputs Unicode supplementary character incorrectly to HTML */ -@Listeners({jdk.test.lib.javax.xml.jaxp.FilePolicy.class}) public class SurrogateTest { final static String TEST_SRC = System.getProperty("test.src", "."); - @Test public void toHTMLTest() throws Exception { String out = "SurrogateTest1out.html"; String expected = TEST_SRC + File.separator + "SurrogateTest1.html"; @@ -82,7 +79,6 @@ public void toHTMLTest() throws Exception { compareWithGold(expected, out); } - @Test public void handlerTest() throws Exception { File xmlFile = new File(TEST_SRC, "SurrogateTest2.xml"); SAXParserFactory spf = SAXParserFactory.newInstance(); @@ -101,4 +97,66 @@ public void startElement(String uri, String localName, String qName, Attributes sb.append( localName + "@attr:" + attributes.getValue("attr") + '\n'); } } + + /** + * Compare contents of golden file with test output file line by line. + * return true if they're identical. + * @param goldfile Golden output file name + * @param outputfile Test output file name + * @return true if two files are identical. + * false if two files are not identical. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read. + */ + public static boolean compareWithGold(String goldfile, String outputfile) + throws IOException { + return compareWithGold(goldfile, outputfile, StandardCharsets.UTF_8); + } + + /** + * Compare contents of golden file with test output file line by line. + * return true if they're identical. + * @param goldfile Golden output file name. + * @param outputfile Test output file name. + * @param cs the charset to use for decoding. + * @return true if two files are identical. + * false if two files are not identical. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read. + */ + public static boolean compareWithGold(String goldfile, String outputfile, + Charset cs) throws IOException { + boolean isSame = Files.readAllLines(Paths.get(goldfile)). + equals(Files.readAllLines(Paths.get(outputfile), cs)); + if (!isSame) { + System.err.println("Golden file " + goldfile + " :"); + Files.readAllLines(Paths.get(goldfile)).forEach(System.err::println); + System.err.println("Output file " + outputfile + " :"); + Files.readAllLines(Paths.get(outputfile), cs).forEach(System.err::println); + } + return isSame; + } + + /** + * Compare contents of golden file with a test output string. + * return true if they're identical. + * @param goldfile Golden output file name. + * @param string test string. + * @return true if file's content is identical to given string. + * false if file's content is not identical to given string. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read + */ + public static boolean compareStringWithGold(String goldfile, String string) + throws IOException { + return Files.readAllLines(Paths.get(goldfile)).stream().collect( + Collectors.joining(System.getProperty("line.separator"))) + .equals(string); + } + + public static void main(String[] args) throws Exception { + SurrogateTest test = new SurrogateTest(); + test.toHTMLTest(); + test.handlerTest(); + } } diff --git a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.html b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest1.html similarity index 100% rename from jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.html rename to jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest1.html diff --git a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.xml b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest1.xml similarity index 100% rename from jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.xml rename to jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest1.xml diff --git a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.xsl b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest1.xsl similarity index 100% rename from jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest1.xsl rename to jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest1.xsl diff --git a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest2.txt b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest2.txt similarity index 100% rename from jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest2.txt rename to jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest2.txt diff --git a/jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest2.xml b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest2.xml similarity index 100% rename from jdk/test/javax/xml/jaxp/unittest/transform/SurrogateTest2.xml rename to jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest2.xml diff --git a/test/lib/jdk/test/lib/javax/xml/jaxp/BasePolicy.java b/test/lib/jdk/test/lib/javax/xml/jaxp/BasePolicy.java deleted file mode 100644 index d4107c02875..00000000000 --- a/test/lib/jdk/test/lib/javax/xml/jaxp/BasePolicy.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2016, 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. - */ -package jdk.test.lib.javax.xml.jaxp; - -import org.testng.ITestContext; -import org.testng.ITestListener; -import org.testng.ITestResult; - -/** - * This policy includes default permissions. - * It should be used as one listener: either TestListener or MethodListener. - */ -public class BasePolicy implements ITestListener { - - @Override - public void onFinish(ITestContext arg0) { - try { - JAXPPolicyManager.teardownPolicyManager(); - } catch (Exception e) { - throw new RuntimeException("Failed to teardown the policy manager", e); - } - } - - @Override - public void onStart(ITestContext arg0) { - // suppose to only run othervm mode - if (isRunWithSecurityManager()) - JAXPPolicyManager.getJAXPPolicyManager(true); - } - - @Override - public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) { - } - - @Override - public void onTestFailure(ITestResult arg0) { - } - - @Override - public void onTestSkipped(ITestResult arg0) { - } - - @Override - public void onTestStart(ITestResult arg0) { - } - - @Override - public void onTestSuccess(ITestResult arg0) { - } - - protected boolean isRunWithSecurityManager() { - final String runSecMngr = JAXPTestUtilities.getSystemProperty("runSecMngr"); - return runSecMngr != null && runSecMngr.equals("true"); - } -} diff --git a/test/lib/jdk/test/lib/javax/xml/jaxp/FilePolicy.java b/test/lib/jdk/test/lib/javax/xml/jaxp/FilePolicy.java deleted file mode 100644 index ddc212e2369..00000000000 --- a/test/lib/jdk/test/lib/javax/xml/jaxp/FilePolicy.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2016, 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. - */ -package jdk.test.lib.javax.xml.jaxp; - -import static jdk.test.lib.javax.xml.jaxp.JAXPTestUtilities.getSystemProperty; - -import java.io.FilePermission; - -import org.testng.ITestContext; - -/** - * This policy can access local XML files. - */ -public class FilePolicy extends BasePolicy { - - @Override - public void onStart(ITestContext arg0) { - // suppose to only run othervm mode - if (isRunWithSecurityManager()) { - JAXPPolicyManager policyManager = JAXPPolicyManager.getJAXPPolicyManager(true); - String userdir = getSystemProperty("user.dir"); - policyManager.addPermission(new FilePermission(userdir + "/-", "read,write,delete")); - String testSrc = System.getProperty("test.src"); - // to handle the directory structure of some functional test suite - if (testSrc.endsWith("ptests")) - testSrc = testSrc.substring(0, testSrc.length() - 7); - policyManager.addPermission(new FilePermission(testSrc + "/-", "read")); - policyManager.addPermission(new FilePermission(userdir, "read")); - } - } -} diff --git a/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPPolicyManager.java b/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPPolicyManager.java deleted file mode 100644 index ea38e50e9a2..00000000000 --- a/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPPolicyManager.java +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2015, 2023, 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. - */ -package jdk.test.lib.javax.xml.jaxp; - - -import java.net.URI; -import java.net.URL; -import java.nio.file.Paths; -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.security.SecurityPermission; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.PropertyPermission; -import java.util.Set; -import java.util.StringJoiner; - - -/* - * This is a base class that every test class must extend if it needs to be run - * with security mode. - */ -@SuppressWarnings("removal") -public class JAXPPolicyManager { - /* - * Backing up policy. - */ - private Policy policyBackup; - - /* - * Backing up security manager. - */ - private SecurityManager smBackup; - - /* - * Current policy. - */ - private TestPolicy policy = new TestPolicy(); - - /* - * JAXPPolicyManager singleton. - */ - private static JAXPPolicyManager policyManager = null; - - /* - * Install a SecurityManager along with a default Policy to allow testNG to - * run when there is a security manager. - */ - private JAXPPolicyManager() { - // Backing up policy and security manager for restore - policyBackup = Policy.getPolicy(); - smBackup = System.getSecurityManager(); - - // Set customized policy - setDefaultPermissions(); - Policy.setPolicy(policy); - System.setSecurityManager(new SecurityManager()); - } - - static synchronized JAXPPolicyManager getJAXPPolicyManager(boolean createIfNone) { - if (policyManager == null & createIfNone) - policyManager = new JAXPPolicyManager(); - return policyManager; - } - - private void teardown() throws Exception { - System.setSecurityManager(smBackup); - Policy.setPolicy(policyBackup); - } - - /* - * Restore the original Policy and SecurityManager. - */ - static synchronized void teardownPolicyManager() throws Exception { - if (policyManager != null) { - policyManager.teardown(); - policyManager = null; - } - } - - /* - * Set default permissions, sub-class of JAXPBaseTest should override this - * method. - */ - private void setDefaultPermissions() { - //Permissions to set security manager and policy - addPermission(new SecurityPermission("getPolicy")); - addPermission(new SecurityPermission("setPolicy")); - addPermission(new RuntimePermission("setSecurityManager")); - addPermission(new PropertyPermission("test.src", "read")); - } - - /* - * Add permission to the TestPolicy. - * - * @param permission to be added. - */ - void addPermission(Permission p) { - policy.addPermission(p); - } - - /* - * Add a temporary permission in current thread context. This won't impact - * global policy and doesn't support permission combination. - * - * @param permission - * to add. - * @return index of the added permission. - */ - int addTmpPermission(Permission p) { - return policy.addTmpPermission(p); - } - - /* - * set allowAll in current thread context. - */ - void setAllowAll(boolean allow) { - policy.setAllowAll(allow); - } - - /* - * Remove a temporary permission from current thread context. - * - * @param index to remove. - * - * @throws RuntimeException if no temporary permission list in current - * thread context or no permission correlated to the index. - */ - void removeTmpPermission(int index) { - policy.removeTmpPermission(index); - } - - -} - -/* - * Simple Policy class that supports the required Permissions to validate the - * JAXP concrete classes. - */ -@SuppressWarnings("removal") -class TestPolicy extends Policy { - private final static Set TEST_JARS = new HashSet(Arrays.asList("jtreg.*jar", "javatest.*jar", "testng.*jar", "jcommander.*jar")); - private final PermissionCollection permissions = new Permissions(); - - private ThreadLocal> transientPermissions = new ThreadLocal<>(); - private ThreadLocal allowAll = new ThreadLocal<>(); - - private static Policy defaultPolicy = Policy.getPolicy(); - - /* - * Add permission to this policy. - * - * @param permission to be added. - */ - void addPermission(Permission p) { - permissions.add(p); - } - - /* - * Set all permissions. Caution: this should not called carefully unless - * it's really needed. - * - * private void setAllPermissions() { permissions.add(new AllPermission()); - * } - */ - - /* - * Overloaded methods from the Policy class. - */ - @Override - public String toString() { - StringJoiner sj = new StringJoiner("\n", "policy: ", ""); - Enumeration perms = permissions.elements(); - while (perms.hasMoreElements()) { - sj.add(perms.nextElement().toString()); - } - return sj.toString(); - - } - - @Override - public PermissionCollection getPermissions(ProtectionDomain domain) { - return permissions; - } - - @Override - public PermissionCollection getPermissions(CodeSource codesource) { - return permissions; - } - - private boolean isTestMachineryDomain(ProtectionDomain domain) { - CodeSource cs = (domain == null) ? null : domain.getCodeSource(); - URL loc = (cs == null) ? null : cs.getLocation(); - URI uri = (loc == null) ? null : URI.create(loc.toString()); - String name = (uri == null) ? null : Paths.get(uri).getFileName().toString(); - return name != null && TEST_JARS.stream() - .filter(name::matches) - .findAny() - .isPresent(); - } - - @Override - public boolean implies(ProtectionDomain domain, Permission perm) { - if (allowAll()) - return true; - - if (defaultPolicy.implies(domain, perm)) - return true; - - if (permissions.implies(perm)) - return true; - - if (isTestMachineryDomain(domain)) - return true; - - return tmpImplies(perm); - } - - /* - * Add a temporary permission in current thread context. This won't impact - * global policy and doesn't support permission combination. - * - * @param permission to add. - * @return index of the added permission. - */ - int addTmpPermission(Permission p) { - Map tmpPermissions = transientPermissions.get(); - if (tmpPermissions == null) - tmpPermissions = new HashMap<>(); - - int id = tmpPermissions.size(); - tmpPermissions.put(id, p); - transientPermissions.set(tmpPermissions); - return id; - } - - /* - * Remove a temporary permission from current thread context. - * - * @param index to remove. - * - * @throws RuntimeException if no temporary permission list in current - * thread context or no permission correlated to the index. - */ - void removeTmpPermission(int index) { - try { - Map tmpPermissions = transientPermissions.get(); - tmpPermissions.remove(index); - } catch (NullPointerException | IndexOutOfBoundsException e) { - throw new RuntimeException("Tried to delete a non-existent temporary permission", e); - } - } - - /* - * Checks to see if the specified permission is implied by temporary - * permission list in current thread context. - * - * @param permission the Permission object to compare. - * - * @return true if "permission" is implied by any permission in the - * temporary permission list, false if not. - */ - private boolean tmpImplies(Permission perm) { - Map tmpPermissions = transientPermissions.get(); - if (tmpPermissions != null) { - for (Permission p : tmpPermissions.values()) { - if (p.implies(perm)) - return true; - } - } - return false; - } - - /* - * Checks to see if allow all permission requests in current thread context. - */ - private boolean allowAll() { - Boolean allow = allowAll.get(); - if (allow != null) { - return allow; - } - return false; - } - - /* - * set allowAll in current thread context. - */ - void setAllowAll(boolean allow) { - allowAll.set(allow); - } -} diff --git a/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPTestUtilities.java b/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPTestUtilities.java deleted file mode 100644 index f3a1a6978f9..00000000000 --- a/test/lib/jdk/test/lib/javax/xml/jaxp/JAXPTestUtilities.java +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (c) 2014, 2017, 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. - */ -package jdk.test.lib.javax.xml.jaxp; - -import static org.testng.Assert.fail; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.nio.charset.UnsupportedCharsetException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.security.Permission; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Supplier; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; - -/** - * This is an interface provide basic support for JAXP functional test. - */ -public class JAXPTestUtilities { - /** - * Prefix for error message. - */ - public static final String ERROR_MSG_HEADER = "Unexcepted exception thrown:"; - - /** - * Prefix for error message on clean up block. - */ - public static final String ERROR_MSG_CLEANUP = "Clean up failed on %s"; - - /** - * Force using slash as File separator as we always use cygwin to test in - * Windows platform. - */ - public static final String FILE_SEP = "/"; - - /** - * A map storing every test's current test file pointer. File number should - * be incremental and it's a thread-safe reading on this file number. - */ - private static final ConcurrentHashMap, Integer> currentFileNumber - = new ConcurrentHashMap<>(); - - /** - * BOM table for storing BOM header. - */ - private final static Map bom = new HashMap<>(); - - /** - * Initialize all BOM headers. - */ - static { - bom.put("UTF-8", new byte[]{(byte)0xEF, (byte) 0xBB, (byte) 0xBF}); - bom.put("UTF-16BE", new byte[]{(byte)0xFE, (byte)0xFF}); - bom.put("UTF-16LE", new byte[]{(byte)0xFF, (byte)0xFE}); - bom.put("UTF-32BE", new byte[]{(byte)0x00, (byte)0x00, (byte)0xFE, (byte)0xFF}); - bom.put("UTF-32LE", new byte[]{(byte)0xFF, (byte)0xFE, (byte)0x00, (byte)0x00}); - } - - /** - * Compare contents of golden file with test output file line by line. - * return true if they're identical. - * @param goldfile Golden output file name - * @param outputfile Test output file name - * @return true if two files are identical. - * false if two files are not identical. - * @throws IOException if an I/O error occurs reading from the file or a - * malformed or unmappable byte sequence is read. - */ - public static boolean compareWithGold(String goldfile, String outputfile) - throws IOException { - return compareWithGold(goldfile, outputfile, StandardCharsets.UTF_8); - } - - /** - * Compare contents of golden file with test output file line by line. - * return true if they're identical. - * @param goldfile Golden output file name. - * @param outputfile Test output file name. - * @param cs the charset to use for decoding. - * @return true if two files are identical. - * false if two files are not identical. - * @throws IOException if an I/O error occurs reading from the file or a - * malformed or unmappable byte sequence is read. - */ - public static boolean compareWithGold(String goldfile, String outputfile, - Charset cs) throws IOException { - boolean isSame = Files.readAllLines(Paths.get(goldfile)). - equals(Files.readAllLines(Paths.get(outputfile), cs)); - if (!isSame) { - System.err.println("Golden file " + goldfile + " :"); - Files.readAllLines(Paths.get(goldfile)).forEach(System.err::println); - System.err.println("Output file " + outputfile + " :"); - Files.readAllLines(Paths.get(outputfile), cs).forEach(System.err::println); - } - return isSame; - } - - /** - * Compare contents of golden file with test output list line by line. - * return true if they're identical. - * @param goldfile Golden output file name. - * @param lines test output list. - * @return true if file's content is identical to given list. - * false if file's content is not identical to given list. - * @throws IOException if an I/O error occurs reading from the file or a - * malformed or unmappable byte sequence is read - */ - public static boolean compareLinesWithGold(String goldfile, List lines) - throws IOException { - return Files.readAllLines(Paths.get(goldfile)).equals(lines); - } - - /** - * Compare contents of golden file with a test output string. - * return true if they're identical. - * @param goldfile Golden output file name. - * @param string test string. - * @return true if file's content is identical to given string. - * false if file's content is not identical to given string. - * @throws IOException if an I/O error occurs reading from the file or a - * malformed or unmappable byte sequence is read - */ - public static boolean compareStringWithGold(String goldfile, String string) - throws IOException { - return Files.readAllLines(Paths.get(goldfile)).stream().collect( - Collectors.joining(System.getProperty("line.separator"))) - .equals(string); - } - - /** - * Compare contents of golden file with test output file by their document - * representation. - * Here we ignore the white space and comments. return true if they're - * lexical identical. - * @param goldfile Golden output file name. - * @param resultFile Test output file name. - * @return true if two file's document representation are identical. - * false if two file's document representation are not identical. - * @throws javax.xml.parsers.ParserConfigurationException if the - * implementation is not available or cannot be instantiated. - * @throws SAXException If any parse errors occur. - * @throws IOException if an I/O error occurs reading from the file or a - * malformed or unmappable byte sequence is read . - */ - public static boolean compareDocumentWithGold(String goldfile, String resultFile) - throws ParserConfigurationException, SAXException, IOException { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - factory.setCoalescing(true); - factory.setIgnoringElementContentWhitespace(true); - factory.setIgnoringComments(true); - DocumentBuilder db = factory.newDocumentBuilder(); - - Document goldD = db.parse(Paths.get(goldfile).toFile()); - goldD.normalizeDocument(); - Document resultD = db.parse(Paths.get(resultFile).toFile()); - resultD.normalizeDocument(); - return goldD.isEqualNode(resultD); - } - - /** - * Compare contents of golden file with the serialization represent by given - * DOM node. - * Here we ignore the white space and comments. return true if they're - * lexical identical. - * @param goldfile Golden output file name. - * @param node A DOM node instance. - * @return true if file's content is identical to given node's serialization - * represent. - * false if file's content is not identical to given node's - * serialization represent. - * @throws TransformerException If an unrecoverable error occurs during the - * course of the transformation.. - * @throws IOException if an I/O error occurs reading from the file or a - * malformed or unmappable byte sequence is read . - */ - public static boolean compareSerializeDOMWithGold(String goldfile, Node node) - throws TransformerException, IOException { - TransformerFactory factory = TransformerFactory.newInstance(); - // Use identity transformer to serialize - Transformer identityTransformer = factory.newTransformer(); - StringWriter sw = new StringWriter(); - StreamResult streamResult = new StreamResult(sw); - DOMSource nodeSource = new DOMSource(node); - identityTransformer.transform(nodeSource, streamResult); - return compareStringWithGold(goldfile, sw.toString()); - } - - /** - * Convert stream to ByteArrayInputStream by given character set. - * @param charset target character set. - * @param file a file that contains no BOM head content. - * @return a ByteArrayInputStream contains BOM heads and bytes in original - * stream - * @throws IOException I/O operation failed or unsupported character set. - */ - public static InputStream bomStream(String charset, String file) - throws IOException { - String localCharset = charset; - if (charset.equals("UTF-16") || charset.equals("UTF-32")) { - localCharset - += ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN ? "BE" : "LE"; - } - if (!bom.containsKey(localCharset)) - throw new UnsupportedCharsetException("Charset:" + localCharset); - - byte[] content = Files.readAllLines(Paths.get(file)).stream(). - collect(Collectors.joining()).getBytes(localCharset); - byte[] head = bom.get(localCharset); - ByteBuffer bb = ByteBuffer.allocate(content.length + head.length); - bb.put(head); - bb.put(content); - return new ByteArrayInputStream(bb.array()); - } - - /** - * Worker method to detect common absolute URLs. - * - * @param s String path\filename or URL (or any, really) - * @return true if s starts with a common URI scheme (namely - * the ones found in the examples of RFC2396); false otherwise - */ - protected static boolean isCommonURL(String s) { - if (null == s) - return false; - return Pattern.compile("^(file:|http:|ftp:|mailto:|news:|telnet:)") - .matcher(s).matches(); - } - - /** - * Utility method to translate a String filename to URL. - * - * If the name starts with a common URI scheme (namely the ones - * found in the examples of RFC2396), then simply return the - * name as-is (the assumption is that it's already a URL). - * Otherwise we attempt (cheaply) to convert to a file:/ URL. - * - * @param filename local path/filename of a file. - * @return a file:/ URL if filename represent a file, the same string if - * it appears to already be a URL. - */ - public static String filenameToURL(String filename) { - return Paths.get(filename).toUri().toASCIIString(); - } - - /** - * Prints error message if an exception is thrown - * @param ex The exception is thrown by test. - */ - public static void failUnexpected(Throwable ex) { - fail(ERROR_MSG_HEADER, ex); - } - - /** - * Prints error message if an exception is thrown when clean up a file. - * @param ex The exception is thrown in cleaning up a file. - * @param name Cleaning up file name. - */ - public static void failCleanup(IOException ex, String name) { - fail(String.format(ERROR_MSG_CLEANUP, name), ex); - } - - /** - * Retrieve next test output file name. This method is a thread-safe method. - * @param clazz test class. - * @return next test output file name. - */ - public static String getNextFile(Class clazz) { - int nextNumber = currentFileNumber.contains(clazz) - ? currentFileNumber.get(clazz) + 1 : 1; - Integer i = currentFileNumber.putIfAbsent(clazz, nextNumber); - if (i != null) { - do { - nextNumber = currentFileNumber.get(clazz) + 1; - } while (!currentFileNumber.replace(clazz, nextNumber - 1, nextNumber)); - } - return USER_DIR + clazz.getName() + nextNumber + ".out"; - } - - /** - * Acquire a full path string by given class name and relative path string. - * @param clazz Class name for the test. - * @param relativeDir relative path between java source file and expected - * path. - * @return a string represents the full path of accessing path. - */ - public static String getPathByClassName(Class clazz, String relativeDir) { - String javaSourcePath = System.getProperty("test.src").replaceAll("\\" + File.separator, FILE_SEP); - String normalizedPath = Paths.get(javaSourcePath, relativeDir).normalize(). - toAbsolutePath().toString(); - return normalizedPath.replace("\\", FILE_SEP) + FILE_SEP; - } - - - /** - * Run the supplier with all permissions. This won't impact global policy. - * - * @param s - * Supplier to run - */ - public static T runWithAllPerm(Supplier s) { - Optional policyManager = Optional.ofNullable(JAXPPolicyManager - .getJAXPPolicyManager(false)); - policyManager.ifPresent(manager -> manager.setAllowAll(true)); - try { - return s.get(); - } finally { - policyManager.ifPresent(manager -> manager.setAllowAll(false)); - } - } - - /** - * Run the supplier with all permissions. This won't impact global policy. - * - * @param s - * Supplier to run - */ - public static T tryRunWithAllPerm(Callable c) throws Exception { - Optional policyManager = Optional.ofNullable(JAXPPolicyManager - .getJAXPPolicyManager(false)); - policyManager.ifPresent(manager -> manager.setAllowAll(true)); - try { - return c.call(); - } finally { - policyManager.ifPresent(manager -> manager.setAllowAll(false)); - } - } - - /** - * Run the Runnable with all permissions. This won't impact global policy. - * - * @param s - * Supplier to run - */ - public static void runWithAllPerm(Runnable r) { - Optional policyManager = Optional.ofNullable(JAXPPolicyManager - .getJAXPPolicyManager(false)); - policyManager.ifPresent(manager -> manager.setAllowAll(true)); - try { - r.run(); - } finally { - policyManager.ifPresent(manager -> manager.setAllowAll(false)); - } - } - - /** - * Acquire a system property. - * - * @param name - * System property name to be acquired. - * @return property value - */ - public static String getSystemProperty(String name) { - return runWithAllPerm(() -> System.getProperty(name)); - } - - /** - * Set a system property by given system value. - * - * @param name - * System property name to be set. - * @param value - * System property value to be set. - */ - public static void setSystemProperty(String name, String value) { - runWithAllPerm(() -> System.setProperty(name, value)); - } - - /** - * Clear a system property. - * - * @param name - * System property name to be cleared. - */ - public static void clearSystemProperty(String name) { - runWithAllPerm(() -> System.clearProperty(name)); - } - - /** - * Run the runnable with assigning temporary permissions. This won't impact - * global policy. - * - * @param r - * Runnable to run - * @param ps - * assigning permissions to add. - */ - public static void runWithTmpPermission(Runnable r, Permission... ps) { - JAXPPolicyManager policyManager = JAXPPolicyManager.getJAXPPolicyManager(false); - List tmpPermissionIndexes = new ArrayList<>(); - if (policyManager != null) { - for (Permission p : ps) - tmpPermissionIndexes.add(policyManager.addTmpPermission(p)); - } - try { - r.run(); - } finally { - for (int index: tmpPermissionIndexes) - policyManager.removeTmpPermission(index); - } - } - - /** - * Run the supplier with assigning temporary permissions. This won't impact - * global policy. - * - * @param s - * Supplier to run - * @param ps - * assigning permissions to add. - */ - public static T runWithTmpPermission(Supplier s, Permission... ps) { - JAXPPolicyManager policyManager = JAXPPolicyManager.getJAXPPolicyManager(false); - List tmpPermissionIndexes = new ArrayList<>(); - if (policyManager != null) { - for (Permission p : ps) - tmpPermissionIndexes.add(policyManager.addTmpPermission(p)); - } - try { - return s.get(); - } finally { - for (int index: tmpPermissionIndexes) - policyManager.removeTmpPermission(index); - } - } - - /** - * Run the RunnableWithException with assigning temporary permissions. This - * won't impact global policy. - * - * @param r - * RunnableWithException to execute - * @param ps - * assigning permissions to add. - */ - public static void tryRunWithTmpPermission(RunnableWithException r, Permission... ps) throws Exception { - JAXPPolicyManager policyManager = JAXPPolicyManager.getJAXPPolicyManager(false); - List tmpPermissionIndexes = new ArrayList<>(); - if (policyManager != null) { - for (Permission p : ps) - tmpPermissionIndexes.add(policyManager.addTmpPermission(p)); - } - try { - r.run(); - } finally { - for (int index: tmpPermissionIndexes) - policyManager.removeTmpPermission(index); - } - } - - @FunctionalInterface - public interface RunnableWithException { - void run() throws Exception; - } - - /** - * Current test directory. - */ - public static final String USER_DIR = getSystemProperty("user.dir") + FILE_SEP;; - -} From 32b02f5dca5131f558a9098a67671e765901c258 Mon Sep 17 00:00:00 2001 From: Takakuri Date: Tue, 4 Jun 2024 21:20:27 +0900 Subject: [PATCH 5/8] Backport 83bce94cc8a7fb45b0604598411fbecc62000dfd --- .../xml/jaxp/transform/8268457/SurrogateTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java index f8cd4703f19..d2b7fc0e633 100644 --- a/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java +++ b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java @@ -98,6 +98,12 @@ public void startElement(String uri, String localName, String qName, Attributes } } + public static void main(String[] args) throws Exception { + SurrogateTest test = new SurrogateTest(); + test.toHTMLTest(); + test.handlerTest(); + } + /** * Compare contents of golden file with test output file line by line. * return true if they're identical. @@ -153,10 +159,4 @@ public static boolean compareStringWithGold(String goldfile, String string) Collectors.joining(System.getProperty("line.separator"))) .equals(string); } - - public static void main(String[] args) throws Exception { - SurrogateTest test = new SurrogateTest(); - test.toHTMLTest(); - test.handlerTest(); - } } From 4ed1c90ff21fc456cd426ba3443513765b3c0ed5 Mon Sep 17 00:00:00 2001 From: Takakuri Date: Thu, 6 Jun 2024 11:40:40 +0900 Subject: [PATCH 6/8] Backport 83bce94cc8a7fb45b0604598411fbecc62000dfd --- .../javax/xml/jaxp/transform/8268457/SurrogateTest.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java index d2b7fc0e633..c27dadad092 100644 --- a/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java +++ b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java @@ -25,8 +25,10 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; +import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; @@ -43,15 +45,11 @@ import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; -import org.testng.Assert; -import org.testng.annotations.Listeners; -import org.testng.annotations.Test; - /* * @test * @bug 8268457 * @library /test/lib - * @run main/othervm transform.SurrogateTest + * @run main/othervm SurrogateTest * @summary XML Transformer outputs Unicode supplementary character incorrectly to HTML */ public class SurrogateTest { From 671a7c749e3a22238375485689bb1378b4da1ea5 Mon Sep 17 00:00:00 2001 From: Takakuri Date: Thu, 6 Jun 2024 12:54:44 +0900 Subject: [PATCH 7/8] Remove test library --- jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java index c27dadad092..a7b12bf895d 100644 --- a/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java +++ b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java @@ -48,7 +48,6 @@ /* * @test * @bug 8268457 - * @library /test/lib * @run main/othervm SurrogateTest * @summary XML Transformer outputs Unicode supplementary character incorrectly to HTML */ From b03f86e396c2b32369dba2bfc5bbd773b62bad94 Mon Sep 17 00:00:00 2001 From: Takakuri Date: Mon, 10 Jun 2024 17:38:12 +0900 Subject: [PATCH 8/8] Import Collectors --- .../jaxp/transform/8268457/SurrogateTest.java | 35 +++---------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java index a7b12bf895d..79fa503554d 100644 --- a/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java +++ b/jdk/test/javax/xml/jaxp/transform/8268457/SurrogateTest.java @@ -31,6 +31,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.stream.Collectors; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; @@ -101,32 +102,13 @@ public static void main(String[] args) throws Exception { test.handlerTest(); } - /** - * Compare contents of golden file with test output file line by line. - * return true if they're identical. - * @param goldfile Golden output file name - * @param outputfile Test output file name - * @return true if two files are identical. - * false if two files are not identical. - * @throws IOException if an I/O error occurs reading from the file or a - * malformed or unmappable byte sequence is read. - */ + // Compare contents of golden file with test output file line by line. public static boolean compareWithGold(String goldfile, String outputfile) throws IOException { return compareWithGold(goldfile, outputfile, StandardCharsets.UTF_8); } - /** - * Compare contents of golden file with test output file line by line. - * return true if they're identical. - * @param goldfile Golden output file name. - * @param outputfile Test output file name. - * @param cs the charset to use for decoding. - * @return true if two files are identical. - * false if two files are not identical. - * @throws IOException if an I/O error occurs reading from the file or a - * malformed or unmappable byte sequence is read. - */ + // Compare contents of golden file with test output file line by line. public static boolean compareWithGold(String goldfile, String outputfile, Charset cs) throws IOException { boolean isSame = Files.readAllLines(Paths.get(goldfile)). @@ -140,16 +122,7 @@ public static boolean compareWithGold(String goldfile, String outputfile, return isSame; } - /** - * Compare contents of golden file with a test output string. - * return true if they're identical. - * @param goldfile Golden output file name. - * @param string test string. - * @return true if file's content is identical to given string. - * false if file's content is not identical to given string. - * @throws IOException if an I/O error occurs reading from the file or a - * malformed or unmappable byte sequence is read - */ + // Compare contents of golden file with a test output string. public static boolean compareStringWithGold(String goldfile, String string) throws IOException { return Files.readAllLines(Paths.get(goldfile)).stream().collect(