From 3f5e48a44ee77d07dea3d2c4ae52aaf19b8dc7cb Mon Sep 17 00:00:00 2001 From: Richard Reingruber Date: Thu, 23 Jun 2022 05:42:54 +0000 Subject: [PATCH 01/11] 8288781: C1: LIR_OpVisitState::maxNumberOfOperands too small Reviewed-by: shade, mdoerr, thartmann --- src/hotspot/share/c1/c1_LIR.hpp | 2 +- .../compiler/c1/TestManyMethodParameters.java | 57 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 test/hotspot/jtreg/compiler/c1/TestManyMethodParameters.java diff --git a/src/hotspot/share/c1/c1_LIR.hpp b/src/hotspot/share/c1/c1_LIR.hpp index a9dfc6a0264..c50ca261da3 100644 --- a/src/hotspot/share/c1/c1_LIR.hpp +++ b/src/hotspot/share/c1/c1_LIR.hpp @@ -2439,7 +2439,7 @@ class LIR_OpVisitState: public StackObj { typedef enum { inputMode, firstMode = inputMode, tempMode, outputMode, numModes, invalidMode = -1 } OprMode; enum { - maxNumberOfOperands = 20, + maxNumberOfOperands = 21, maxNumberOfInfos = 4 }; diff --git a/test/hotspot/jtreg/compiler/c1/TestManyMethodParameters.java b/test/hotspot/jtreg/compiler/c1/TestManyMethodParameters.java new file mode 100644 index 00000000000..de7fe3fb6be --- /dev/null +++ b/test/hotspot/jtreg/compiler/c1/TestManyMethodParameters.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 SAP SE. 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 8288781 + * @summary Test if a call with 8 integer + 13 float = 21 parameters can can be compiled. + * On ppc all parameters can be passed in registers. + * @author Richard Reingruber + * + * @run main/othervm -Xbatch -XX:CompileCommand=dontinline,*::*dontinline* compiler.c1.TestManyMethodParameters + */ + +package compiler.c1; + +public class TestManyMethodParameters { + public static void main(String[] args) { + for (int i = 30_000; i >= 0; i--) { + double sum = testMethod_01_dontinline(); + if (sum != 127) { + throw new Error("Wrong sum: " + sum); + } + } + } + + public static double testMethod_01_dontinline() { + return testMethod_01_manyArgs(1, 2, 3, 4, 5, 6, 7, 8, + 1.0d, 2.0d, 3.0d, 4.0d, 5.0d, 6.0d, 7.0d, 8.0d, 9.0d, 10.0d, 11.0d, 12.0d, 13.0d); + } + + public static double testMethod_01_manyArgs(long l1, long l2, long l3, long l4, long l5, long l6, long l7, long l8, + double d1, double d2, double d3, double d4, double d5, double d6, double d7, + double d8, double d9, double d10, double d11, double d12, double d13) { + return l1+l2+l3+l4+l5+l6+l7+l8+d1+d2+d3+d4+d5+d6+d7+d8+d9+d10+d11+d12+d13; + } +} From 4c9ea7e66aaf99f42ee2df0b17c6586f57019a19 Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Thu, 23 Jun 2022 16:21:32 +0000 Subject: [PATCH 02/11] 8286580: serviceability/jvmti/vthread/GetSetLocalTest failed with assert: Not supported for heap frames Reviewed-by: lmesnik, rpressler, cjplummer --- src/hotspot/share/prims/jvmtiImpl.cpp | 13 +++++++++- test/hotspot/jtreg/ProblemList.txt | 1 + .../GetSetLocalTest/GetSetLocalTest.java | 22 +++++++++-------- .../GetSetLocalTest/libGetSetLocalTest.cpp | 24 +++++++++++-------- 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/hotspot/share/prims/jvmtiImpl.cpp b/src/hotspot/share/prims/jvmtiImpl.cpp index acbfd97c6ea..9c4325cf7b0 100644 --- a/src/hotspot/share/prims/jvmtiImpl.cpp +++ b/src/hotspot/share/prims/jvmtiImpl.cpp @@ -611,7 +611,7 @@ void VM_BaseGetOrSetLocal::doit() { frame fr = _jvf->fr(); if (_set && _depth != 0 && Continuation::is_frame_in_continuation(_jvf->thread(), fr)) { - _result = JVMTI_ERROR_OPAQUE_FRAME; // deferred locals currently unsupported in continuations + _result = JVMTI_ERROR_OPAQUE_FRAME; // deferred locals are not fully supported in continuations return; } @@ -644,6 +644,17 @@ void VM_BaseGetOrSetLocal::doit() { return; } if (_set) { + if (fr.is_heap_frame()) { // we want this check after the check for JVMTI_ERROR_INVALID_SLOT + assert(Continuation::is_frame_in_continuation(_jvf->thread(), fr), "sanity check"); + // If the topmost frame is a heap frame, then it hasn't been thawed. This can happen + // if we are executing at a return barrier safepoint. The callee frame has been popped, + // but the caller frame has not been thawed. We can't support a JVMTI SetLocal in the callee + // frame at this point, because we aren't truly in the callee yet. + // fr.is_heap_frame() is impossible if a continuation is at a single step or breakpoint. + _result = JVMTI_ERROR_OPAQUE_FRAME; // deferred locals are not fully supported in continuations + return; + } + // Force deoptimization of frame if compiled because it's // possible the compiler emitted some locals as constant values, // meaning they are not mutable. diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 2ae606f04f9..2e9184cfc63 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -111,6 +111,7 @@ serviceability/sa/sadebugd/DebugdConnectTest.java 8239062,8270326 macosx-x64,mac serviceability/sa/TestRevPtrsForInvokeDynamic.java 8241235 generic-all serviceability/jvmti/ModuleAwareAgents/ThreadStart/MAAThreadStart.java 8225354 windows-all +serviceability/jvmti/vthread/GetSetLocalTest/GetSetLocalTest.java 8286836 generic-all serviceability/dcmd/gc/RunFinalizationTest.java 8227120 linux-all,windows-x64 serviceability/sa/ClhsdbCDSCore.java 8269982,8267433 macosx-aarch64,macosx-x64 diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/GetSetLocalTest/GetSetLocalTest.java b/test/hotspot/jtreg/serviceability/jvmti/vthread/GetSetLocalTest/GetSetLocalTest.java index 258cb1f6a8b..57acce70046 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/vthread/GetSetLocalTest/GetSetLocalTest.java +++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/GetSetLocalTest/GetSetLocalTest.java @@ -35,8 +35,7 @@ import java.util.concurrent.*; public class GetSetLocalTest { private static final String agentLib = "GetSetLocalTest"; - static final int MSG_COUNT = 600*1000; - static final SynchronousQueue QUEUE = new SynchronousQueue<>(); + static SynchronousQueue QUEUE; static native boolean completed(); static native void enableEvents(Thread thread); static native void testSuspendedVirtualThreads(Thread thread); @@ -56,19 +55,17 @@ public class GetSetLocalTest { static final Runnable PRODUCER = () -> { try { - for (int i = 0; i < MSG_COUNT; i++) { - if (completed()) { - consumer.interrupt(); - break; - } + while (!completed()) { producer("msg: "); } - } catch (InterruptedException e) { } + consumer.interrupt(); + } catch (InterruptedException e) { + } }; static final Runnable CONSUMER = () -> { try { - for (int i = 0; i < MSG_COUNT; i++) { + while(true) { String s = QUEUE.take(); } } catch (InterruptedException e) { @@ -77,6 +74,7 @@ public class GetSetLocalTest { }; public static void test1() throws Exception { + QUEUE = new SynchronousQueue<>(); producer = Thread.ofVirtual().name("VThread-Producer").start(PRODUCER); consumer = Thread.ofVirtual().name("VThread-Consumer").start(CONSUMER); @@ -101,6 +99,10 @@ public class GetSetLocalTest { } GetSetLocalTest obj = new GetSetLocalTest(); - obj.runTest(); + + for (int i = 0; i < 200; i++) { + obj.runTest(); + } + } } diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/GetSetLocalTest/libGetSetLocalTest.cpp b/test/hotspot/jtreg/serviceability/jvmti/vthread/GetSetLocalTest/libGetSetLocalTest.cpp index 2d82ed48f13..0ed229ad86b 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/vthread/GetSetLocalTest/libGetSetLocalTest.cpp +++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/GetSetLocalTest/libGetSetLocalTest.cpp @@ -232,7 +232,7 @@ test_GetLocal(jvmtiEnv *jvmti, JNIEnv *jni, jthread cthread, jthread vthread, static bool test_SetLocal(jvmtiEnv *jvmti, JNIEnv *jni, jthread cthread, jthread vthread, - int depth, int frame_count, Values *values) { + int depth, int frame_count, Values *values, bool at_event) { jvmtiError err; LOG("test_SetLocal: mounted: %d depth: %d fcount: %d\n", cthread != NULL, depth, frame_count); @@ -288,7 +288,7 @@ test_SetLocal(jvmtiEnv *jvmti, JNIEnv *jni, jthread cthread, jthread vthread, fatal(jni, "JVMTI SetLocalObject for unmounted vthread pr depth > 0failed to return JVMTI_ERROR_OPAQUE_FRAME"); } return false; // skip testing other types for unmounted vthread - } else if (err == JVMTI_ERROR_OPAQUE_FRAME) { + } else if (!at_event && err == JVMTI_ERROR_OPAQUE_FRAME) { LOG("JVMTI SetLocalObject for mounted vthread at depth=0 returned JVMTI_ERROR_OPAQUE_FRAME: %d\n", err); return false; // skip testing other types for compiled frame that can't be deoptimized } @@ -309,7 +309,7 @@ test_SetLocal(jvmtiEnv *jvmti, JNIEnv *jni, jthread cthread, jthread vthread, } static void -test_GetSetLocal(jvmtiEnv *jvmti, JNIEnv* jni, jthread vthread, int depth, int frame_count) { +test_GetSetLocal(jvmtiEnv *jvmti, JNIEnv* jni, jthread vthread, int depth, int frame_count, bool at_event) { Values values0 = { NULL, NULL, 1, 2L, (jfloat)3.2F, (jdouble)4.500000047683716 }; Values values1 = { NULL, NULL, 2, 3L, (jfloat)4.2F, (jdouble)5.500000047683716 }; jthread cthread = get_carrier_thread(jvmti, jni, vthread); @@ -319,8 +319,8 @@ test_GetSetLocal(jvmtiEnv *jvmti, JNIEnv* jni, jthread vthread, int depth, int f LOG("test_GetSetLocal: test_GetLocal with values0\n"); test_GetLocal(jvmti, jni, cthread, vthread, depth, frame_count, &values0); - LOG("test_GetSetLocal: test_SetLocal with values1\n"); - bool success = test_SetLocal(jvmti, jni, cthread, vthread, depth, frame_count, &values1); + LOG("test_GetSetLocal: test_SetLocal at_event: %d with values1\n", at_event); + bool success = test_SetLocal(jvmti, jni, cthread, vthread, depth, frame_count, &values1, at_event); if (!success) { goto End; // skip testing for compiled frame that can't be deoptimized @@ -334,8 +334,8 @@ test_GetSetLocal(jvmtiEnv *jvmti, JNIEnv* jni, jthread vthread, int depth, int f } else { LOG("test_GetSetLocal: test_GetLocal with values1\n"); test_GetLocal(jvmti, jni, cthread, vthread, depth, frame_count, &values1); - LOG("test_GetSetLocal: test_SetLocal with values0 to restore original local values\n"); - test_SetLocal(jvmti, jni, cthread, vthread, depth, frame_count, &values0); + LOG("test_GetSetLocal: test_SetLocal at_event: %d with values0 to restore original local values\n", at_event); + test_SetLocal(jvmti, jni, cthread, vthread, depth, frame_count, &values0, at_event); } End: LOG("test_GetSetLocal: finished\n\n"); @@ -360,7 +360,7 @@ Breakpoint(jvmtiEnv *jvmti, JNIEnv* jni, jthread vthread, { int frame_count = get_frame_count(jvmti, jni, vthread); - test_GetSetLocal(jvmti, jni, vthread, depth, frame_count); + test_GetSetLocal(jvmti, jni, vthread, depth, frame_count, true /* at_event */); } deallocate(jvmti, jni, (void*)mname); deallocate(jvmti, jni, (void*)tname); @@ -470,7 +470,7 @@ Java_GetSetLocalTest_testSuspendedVirtualThreads(JNIEnv *jni, jclass klass, jthr #if 0 print_stack_trace(jvmti, jni, vthread); #endif - test_GetSetLocal(jvmti, jni, vthread, depth, frame_count); + test_GetSetLocal(jvmti, jni, vthread, depth, frame_count, false /* !at_event */); } err = jvmti->ResumeThread(vthread); @@ -487,7 +487,11 @@ Java_GetSetLocalTest_testSuspendedVirtualThreads(JNIEnv *jni, jclass klass, jthr JNIEXPORT jboolean JNICALL Java_GetSetLocalTest_completed(JNIEnv *jni, jclass klass) { - return completed; + if (completed) { + completed = JNI_FALSE; + return JNI_TRUE; + } + return JNI_FALSE; } } // extern "C" From a716f7934b2ce8078c27df4c87e8c1e9cceed000 Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Thu, 23 Jun 2022 17:07:58 +0000 Subject: [PATCH 03/11] 8288589: Files.readString ignores encoding errors for UTF-16 Backport-of: 2728770e3d73bb11c4d6e54b5aff91588a1a780b --- .../share/classes/java/lang/String.java | 41 +++++---- .../jdk/java/lang/String/NewStringNoRepl.java | 50 ----------- test/jdk/java/lang/String/NoReplTest.java | 85 +++++++++++++++++++ .../java/nio/file/Files/ReadWriteString.java | 75 +++++++++++----- 4 files changed, 163 insertions(+), 88 deletions(-) delete mode 100644 test/jdk/java/lang/String/NewStringNoRepl.java create mode 100644 test/jdk/java/lang/String/NoReplTest.java diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index e6243311f70..4d098f58140 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -658,6 +658,8 @@ public final class String // decode using CharsetDecoder int en = scale(length, cd.maxCharsPerByte()); + cd.onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); char[] ca = new char[en]; if (charset.getClass().getClassLoader0() != null && System.getSecurityManager() != null) { @@ -665,7 +667,13 @@ public final class String offset = 0; } - int caLen = decodeWithDecoder(cd, ca, bytes, offset, length); + int caLen; + try { + caLen = decodeWithDecoder(cd, ca, bytes, offset, length); + } catch (CharacterCodingException x) { + // Substitution is enabled, so this shouldn't happen + throw new Error(x); + } if (COMPACT_STRINGS) { byte[] bs = StringUTF16.compress(ca, 0, caLen); if (bs != null) { @@ -791,7 +799,13 @@ public final class String System.getSecurityManager() != null) { src = Arrays.copyOf(src, len); } - int caLen = decodeWithDecoder(cd, ca, src, 0, src.length); + int caLen; + try { + caLen = decodeWithDecoder(cd, ca, src, 0, src.length); + } catch (CharacterCodingException x) { + // throw via IAE + throw new IllegalArgumentException(x); + } if (COMPACT_STRINGS) { byte[] bs = StringUTF16.compress(ca, 0, caLen); if (bs != null) { @@ -1199,23 +1213,16 @@ public final class String return dp; } - private static int decodeWithDecoder(CharsetDecoder cd, char[] dst, byte[] src, int offset, int length) { + private static int decodeWithDecoder(CharsetDecoder cd, char[] dst, byte[] src, int offset, int length) + throws CharacterCodingException { ByteBuffer bb = ByteBuffer.wrap(src, offset, length); CharBuffer cb = CharBuffer.wrap(dst, 0, dst.length); - cd.onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE); - try { - CoderResult cr = cd.decode(bb, cb, true); - if (!cr.isUnderflow()) - cr.throwException(); - cr = cd.flush(cb); - if (!cr.isUnderflow()) - cr.throwException(); - } catch (CharacterCodingException x) { - // Substitution is always enabled, - // so this shouldn't happen - throw new Error(x); - } + CoderResult cr = cd.decode(bb, cb, true); + if (!cr.isUnderflow()) + cr.throwException(); + cr = cd.flush(cb); + if (!cr.isUnderflow()) + cr.throwException(); return cb.position(); } diff --git a/test/jdk/java/lang/String/NewStringNoRepl.java b/test/jdk/java/lang/String/NewStringNoRepl.java deleted file mode 100644 index ae1a26393cc..00000000000 --- a/test/jdk/java/lang/String/NewStringNoRepl.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2022, 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 8286287 - * @summary Verifies newStringNoRepl() does not throw an Error. - */ - -import java.io.IOException; -import java.nio.file.Files; -import java.util.HexFormat; -import static java.nio.charset.StandardCharsets.UTF_16; - -public class NewStringNoRepl { - private final static byte[] MALFORMED_UTF16 = {(byte)0x00, (byte)0x20, (byte)0x00}; - - public static void main(String... args) throws IOException { - var f = Files.createTempFile(null, null); - try (var fos = Files.newOutputStream(f)) { - fos.write(MALFORMED_UTF16); - } - System.out.println("Returned bytes: " + - HexFormat.of() - .withPrefix("x") - .withUpperCase() - .formatHex(Files.readString(f, UTF_16).getBytes(UTF_16))); - Files.delete(f); - } -} diff --git a/test/jdk/java/lang/String/NoReplTest.java b/test/jdk/java/lang/String/NoReplTest.java new file mode 100644 index 00000000000..1817a1ffe73 --- /dev/null +++ b/test/jdk/java/lang/String/NoReplTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022, 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 8286287 8288589 + * @summary Tests for *NoRepl() shared secret methods. + * @run testng NoReplTest + * @modules jdk.charsets + */ + +import java.io.IOException; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.util.HexFormat; +import static java.nio.charset.StandardCharsets.UTF_16; + +import org.testng.annotations.Test; + +@Test +public class NoReplTest { + private final static byte[] MALFORMED_UTF16 = {(byte)0x00, (byte)0x20, (byte)0x00}; + private final static String MALFORMED_WINDOWS_1252 = "\u0080\u041e"; + private final static Charset WINDOWS_1252 = Charset.forName("windows-1252"); + + /** + * Verifies newStringNoRepl() throws a CharacterCodingException. + * The method is invoked by `Files.readString()` method. + */ + @Test + public void newStringNoReplTest() throws IOException { + var f = Files.createTempFile(null, null); + try (var fos = Files.newOutputStream(f)) { + fos.write(MALFORMED_UTF16); + var read = Files.readString(f, UTF_16); + throw new RuntimeException("Exception should be thrown for a malformed input. Bytes read: " + + HexFormat.of() + .withPrefix("x") + .withUpperCase() + .formatHex(read.getBytes(UTF_16))); + } catch (CharacterCodingException cce) { + // success + } finally { + Files.delete(f); + } + } + + /** + * Verifies getBytesNoRepl() throws a CharacterCodingException. + * The method is invoked by `Files.writeString()` method. + */ + @Test + public void getBytesNoReplTest() throws IOException { + var f = Files.createTempFile(null, null); + try { + Files.writeString(f, MALFORMED_WINDOWS_1252, WINDOWS_1252); + throw new RuntimeException("Exception should be thrown"); + } catch (CharacterCodingException cce) { + // success + } finally { + Files.delete(f); + } + } +} diff --git a/test/jdk/java/nio/file/Files/ReadWriteString.java b/test/jdk/java/nio/file/Files/ReadWriteString.java index 37c069c6aa9..885cbb771dc 100644 --- a/test/jdk/java/nio/file/Files/ReadWriteString.java +++ b/test/jdk/java/nio/file/Files/ReadWriteString.java @@ -24,10 +24,12 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.Charset; +import java.nio.charset.CharacterCodingException; import java.nio.charset.MalformedInputException; import java.nio.charset.UnmappableCharacterException; -import static java.nio.charset.StandardCharsets.US_ASCII; import static java.nio.charset.StandardCharsets.ISO_8859_1; +import static java.nio.charset.StandardCharsets.US_ASCII; +import static java.nio.charset.StandardCharsets.UTF_16; import static java.nio.charset.StandardCharsets.UTF_8; import java.nio.file.Files; import java.nio.file.OpenOption; @@ -46,7 +48,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /* @test - * @bug 8201276 8205058 8209576 8287541 + * @bug 8201276 8205058 8209576 8287541 8288589 * @build ReadWriteString PassThroughFileSystem * @run testng ReadWriteString * @summary Unit test for methods for Files readString and write methods. @@ -60,6 +62,8 @@ public class ReadWriteString { final String TEXT_UNICODE = "\u201CHello\u201D"; final String TEXT_ASCII = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n abcdefghijklmnopqrstuvwxyz\n 1234567890\n"; private static final String JA_STRING = "\u65e5\u672c\u8a9e\u6587\u5b57\u5217"; + private static final Charset WINDOWS_1252 = Charset.forName("windows-1252"); + private static final Charset WINDOWS_31J = Charset.forName("windows-31j"); static byte[] data = getData(); @@ -88,14 +92,14 @@ public class ReadWriteString { */ @DataProvider(name = "malformedWrite") public Object[][] getMalformedWrite() throws IOException { - Path path = Files.createTempFile("malformedWrite", null); + Path path = Files.createFile(Path.of("malformedWrite")); return new Object[][]{ {path, "\ud800", null}, //the default Charset is UTF_8 {path, "\u00A0\u00A1", US_ASCII}, {path, "\ud800", UTF_8}, {path, JA_STRING, ISO_8859_1}, - {path, "\u041e", Charset.forName("windows-1252")}, // cyrillic capital letter O - {path, "\u091c", Charset.forName("windows-31j")}, // devanagari letter ja + {path, "\u041e", WINDOWS_1252}, // cyrillic capital letter O + {path, "\u091c", WINDOWS_31J}, // devanagari letter ja }; } @@ -105,13 +109,26 @@ public class ReadWriteString { */ @DataProvider(name = "illegalInput") public Object[][] getIllegalInput() throws IOException { - Path path = Files.createTempFile("illegalInput", null); + Path path = Files.createFile(Path.of("illegalInput")); return new Object[][]{ {path, data, ISO_8859_1, null}, {path, data, ISO_8859_1, UTF_8} }; } + /* + * DataProvider for illegal input bytes test + */ + @DataProvider(name = "illegalInputBytes") + public Object[][] getIllegalInputBytes() throws IOException { + return new Object[][]{ + {new byte[] {(byte)0x00, (byte)0x20, (byte)0x00}, UTF_16, MalformedInputException.class}, + {new byte[] {-50}, UTF_16, MalformedInputException.class}, + {new byte[] {(byte)0x81}, WINDOWS_1252, UnmappableCharacterException.class}, // unused in Cp1252 + {new byte[] {(byte)0x81, (byte)0xff}, WINDOWS_31J, UnmappableCharacterException.class}, // invalid trailing byte + }; + } + /* * DataProvider for writeString test * Writes the data using both the existing and new method and compares the results. @@ -143,16 +160,9 @@ public class ReadWriteString { @BeforeClass void setup() throws IOException { - testFiles[0] = Files.createTempFile("readWriteString", null); - testFiles[1] = Files.createTempFile("writeString_file1", null); - testFiles[2] = Files.createTempFile("writeString_file2", null); - } - - @AfterClass - void cleanup() throws IOException { - for (Path path : testFiles) { - Files.deleteIfExists(path); - } + testFiles[0] = Files.createFile(Path.of("readWriteString")); + testFiles[1] = Files.createFile(Path.of("writeString_file1")); + testFiles[2] = Files.createFile(Path.of("writeString_file2")); } /** @@ -241,11 +251,10 @@ public class ReadWriteString { */ @Test(dataProvider = "malformedWrite", expectedExceptions = UnmappableCharacterException.class) public void testMalformedWrite(Path path, String s, Charset cs) throws IOException { - path.toFile().deleteOnExit(); if (cs == null) { - Files.writeString(path, s, CREATE); + Files.writeString(path, s); } else { - Files.writeString(path, s, cs, CREATE); + Files.writeString(path, s, cs); } } @@ -261,9 +270,8 @@ public class ReadWriteString { */ @Test(dataProvider = "illegalInput", expectedExceptions = MalformedInputException.class) public void testMalformedRead(Path path, byte[] data, Charset csWrite, Charset csRead) throws IOException { - path.toFile().deleteOnExit(); String temp = new String(data, csWrite); - Files.writeString(path, temp, csWrite, CREATE); + Files.writeString(path, temp, csWrite); if (csRead == null) { Files.readString(path); } else { @@ -271,6 +279,31 @@ public class ReadWriteString { } } + /** + * Verifies that IOException is thrown when reading a file containing + * illegal bytes + * + * @param data the data used for the test + * @param csRead the Charset to use for reading the file + * @param expected exception class + * @throws IOException when the Charset used for reading the file is incorrect + */ + @Test(dataProvider = "illegalInputBytes") + public void testMalformedReadBytes(byte[] data, Charset csRead, Class expected) + throws IOException { + Path path = Path.of("illegalInputBytes"); + Files.write(path, data); + try { + Files.readString(path, csRead); + } catch (MalformedInputException | UnmappableCharacterException e) { + if (expected.isInstance(e)) { + // success + return; + } + } + throw new RuntimeException("An instance of " + expected + " should be thrown"); + } + private void checkNullPointerException(Callable c) { try { c.call(); From 1f9521e6cb2f701f8712b4ec941ff1dbb45dad4e Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Thu, 23 Jun 2022 17:12:31 +0000 Subject: [PATCH 04/11] 8287076: Document.normalizeDocument() produces different results Reviewed-by: lancea, iris, naoto --- .../xerces/internal/dom/AttributeMap.java | 10 ++-- .../xerces/internal/dom/DOMNormalizer.java | 13 ++--- .../xerces/internal/dom/NamedNodeMapImpl.java | 10 ++-- .../xml/jaxp/unittest/dom/DocumentTest.java | 56 ++++++++++++++++++- 4 files changed, 69 insertions(+), 20 deletions(-) diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttributeMap.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttributeMap.java index adc78c15039..2b2f98a3205 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttributeMap.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttributeMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -39,7 +39,7 @@ import org.w3c.dom.Node; * * @xerces.internal * - * @LastModified: Oct 2017 + * @LastModified: June 2022 */ public class AttributeMap extends NamedNodeMapImpl { @@ -117,7 +117,7 @@ public class AttributeMap extends NamedNodeMapImpl { } else { i = -1 - i; // Insert point (may be end of list) if (null == nodes) { - nodes = new ArrayList<>(5); + nodes = new ArrayList<>(); } nodes.add(i, arg); } @@ -193,7 +193,7 @@ public class AttributeMap extends NamedNodeMapImpl { } else { i = -1 - i; // Insert point (may be end of list) if (null == nodes) { - nodes = new ArrayList<>(5); + nodes = new ArrayList<>(); } nodes.add(i, arg); } @@ -591,7 +591,7 @@ public class AttributeMap extends NamedNodeMapImpl { else { i = -1 - i; // Insert point (may be end of list) if (null == nodes) { - nodes = new ArrayList<>(5); + nodes = new ArrayList<>(); } nodes.add(i, arg); } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java index 4903448394b..22198efcbb8 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -89,7 +89,7 @@ import org.w3c.dom.Text; * * @author Elena Litani, IBM * @author Neeraj Bajaj, Sun Microsystems, inc. - * @LastModified: Apr 2019 + * @LastModified: June 2022 */ public class DOMNormalizer implements XMLDocumentHandler { @@ -140,9 +140,6 @@ public class DOMNormalizer implements XMLDocumentHandler { /** Stores all namespace bindings on the current element */ protected final NamespaceContext fLocalNSBinder = new NamespaceSupport(); - /** list of attributes */ - protected final List fAttributeList = new ArrayList<>(5); - /** DOM Locator - for namespace fixup algorithm */ protected final DOMLocatorImpl fLocator = new DOMLocatorImpl(); @@ -885,9 +882,9 @@ public class DOMNormalizer implements XMLDocumentHandler { if (attributes != null) { // clone content of the attributes - attributes.cloneMap(fAttributeList); - for (int i = 0; i < fAttributeList.size(); i++) { - Attr attr = (Attr) fAttributeList.get(i); + List attrList = attributes.cloneMap(new ArrayList<>()); + for (int i = 0; i < attrList.size(); i++) { + Attr attr = (Attr) attrList.get(i); fLocator.fRelatedNode = attr; if (DEBUG) { diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NamedNodeMapImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NamedNodeMapImpl.java index 306aefc2432..a2b3e3269a5 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NamedNodeMapImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NamedNodeMapImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -56,7 +56,7 @@ import org.w3c.dom.Node; * @xerces.internal * * @since PR-DOM-Level-1-19980818. - * @LastModified: Jan 2018 + * @LastModified: June 2022 */ public class NamedNodeMapImpl implements NamedNodeMap, Serializable { @@ -197,7 +197,7 @@ public class NamedNodeMapImpl } else { i = -1 - i; // Insert point (may be end of list) if (null == nodes) { - nodes = new ArrayList<>(5); + nodes = new ArrayList<>(); } nodes.add(i, arg); } @@ -247,7 +247,7 @@ public class NamedNodeMapImpl } else { i = -1 - i; // Insert point (may be end of list) if (null == nodes) { - nodes = new ArrayList<>(5); + nodes = new ArrayList<>(); } nodes.add(i, arg); } @@ -562,7 +562,7 @@ public class NamedNodeMapImpl else { i = -1 - i; // Insert point (may be end of list) if (null == nodes) { - nodes = new ArrayList<>(5); + nodes = new ArrayList<>(); } nodes.add(i, arg); } diff --git a/test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java b/test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java index bd8cb264141..e2254f66262 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java +++ b/test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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 @@ -34,15 +34,20 @@ import javax.xml.parsers.DocumentBuilderFactory; import org.testng.Assert; import org.testng.annotations.Listeners; import org.testng.annotations.Test; +import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.events.Event; import org.w3c.dom.events.EventListener; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSInput; +import org.w3c.dom.ls.LSParser; /* * @test - * @bug 8213117 8222743 + * @bug 8213117 8222743 8287076 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @modules java.xml * @modules java.xml/com.sun.org.apache.xerces.internal.dom @@ -56,6 +61,53 @@ public class DocumentTest { static final int DOC1 = 1; static final int DOC2 = 2; + /* + * @bug 8287076 + * Verifies that Document::normalizeDocument returns the same result as that + * prior to JDK 10 (JDK-8181150). + * Attribute Name: + * JDK 9: NS1:wsu and NS2:wsu2 + * After the JDK 10 change: wsu and wsu2 + */ + @Test + public void testNormalizeDocument() throws Exception { + final DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); + final DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); + final LSParser builder = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null); + final LSInput input = impl.createLSInput(); + input.setStringData(""); + final Document document = builder.parse(input); + final Element root = document.getDocumentElement(); + + // Generate a single element + final Element element = document.createElement("token"); + final Attr attr = element.getOwnerDocument().createAttributeNS("http://blah.xsd", "wsu"); + attr.setValue("Id"); + element.setAttributeNodeNS(attr); + + final Attr attr2 = element.getOwnerDocument().createAttributeNS("http://blah2.xsd", "wsu2"); + element.setAttributeNodeNS(attr2); + + final Attr attr3 = element.getOwnerDocument().createAttribute("aa"); + element.setAttributeNodeNS(attr3); + + final Attr attr4 = element.getOwnerDocument().createAttribute("zz"); + element.setAttributeNodeNS(attr4); + + final Attr attr5 = element.getOwnerDocument().createAttribute("tt"); + element.setAttributeNodeNS(attr5); + + root.appendChild(element); + + document.normalizeDocument(); + + Node wsu = element.getAttributes().getNamedItemNS("http://blah.xsd", "wsu"); + Node wsu2 = element.getAttributes().getNamedItemNS("http://blah2.xsd", "wsu2"); + + Assert.assertEquals(wsu.getNodeName(), "NS1:wsu"); + Assert.assertEquals(wsu2.getNodeName(), "NS2:wsu2"); + } + /** * Verifies the adoptNode method. Before a node from a deferred DOM can be * adopted, it needs to be fully expanded. From 651cbebb96fc60e5db48ea68d38cbeb76b007550 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Thu, 23 Jun 2022 22:57:35 +0000 Subject: [PATCH 05/11] 8288080: (fc) FileChannel::map for MemorySegments should state it always throws UOE Backport-of: a9c2ab67c44872ce0247aef6bf972bf4246b44be --- src/java.base/share/classes/java/nio/channels/FileChannel.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/java.base/share/classes/java/nio/channels/FileChannel.java b/src/java.base/share/classes/java/nio/channels/FileChannel.java index 5d8af5239c0..b4cc05441d9 100644 --- a/src/java.base/share/classes/java/nio/channels/FileChannel.java +++ b/src/java.base/share/classes/java/nio/channels/FileChannel.java @@ -997,6 +997,9 @@ public abstract class FileChannel * of mapped memory associated with the returned mapped memory * segment is unspecified and should not be relied upon. * + * @implSpec The default implementation of this method throws + * {@code UnsupportedOperationException}. + * * @param mode * The file mapping mode, see * {@link FileChannel#map(FileChannel.MapMode, long, long)}; From b0db33333a9fbc39e8d9f7d6a0f13d6a1b5dde04 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 24 Jun 2022 04:22:25 +0000 Subject: [PATCH 06/11] 8288528: broken links in java.desktop Reviewed-by: prr, aivanov --- .../java/awt/doc-files/AWTThreadIssues.html | 16 +++------------- .../imageio/plugins/tiff/ExifTIFFTagSet.java | 6 +++--- .../javax/swing/plaf/metal/MetalLookAndFeel.java | 5 ++--- .../swing/plaf/multi/doc-files/multi_tsc.html | 15 +-------------- 4 files changed, 9 insertions(+), 33 deletions(-) diff --git a/src/java.desktop/share/classes/java/awt/doc-files/AWTThreadIssues.html b/src/java.desktop/share/classes/java/awt/doc-files/AWTThreadIssues.html index f5f7d314e87..70f394d460c 100644 --- a/src/java.desktop/share/classes/java/awt/doc-files/AWTThreadIssues.html +++ b/src/java.desktop/share/classes/java/awt/doc-files/AWTThreadIssues.html @@ -5,7 +5,7 @@ AWT Threading Issues