From fd353e38a820eed00b1a5f28e892a4d6baa3f1d1 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 26 Feb 2025 08:29:36 +0000 Subject: [PATCH 001/846] 8350651: Bump update version for OpenJDK: jdk-17.0.16 Reviewed-by: clanger --- .jcheck/conf | 2 +- make/conf/version-numbers.conf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.jcheck/conf b/.jcheck/conf index 70d144818091a..e99bdd2e4165b 100644 --- a/.jcheck/conf +++ b/.jcheck/conf @@ -1,7 +1,7 @@ [general] project=jdk-updates jbs=JDK -version=17.0.15 +version=17.0.16 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf index 29ccfb0801b37..9e08390395aa1 100644 --- a/make/conf/version-numbers.conf +++ b/make/conf/version-numbers.conf @@ -28,12 +28,12 @@ DEFAULT_VERSION_FEATURE=17 DEFAULT_VERSION_INTERIM=0 -DEFAULT_VERSION_UPDATE=15 +DEFAULT_VERSION_UPDATE=16 DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2025-04-15 +DEFAULT_VERSION_DATE=2025-07-15 DEFAULT_VERSION_CLASSFILE_MAJOR=61 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 From e45b98b47543fd9b1684b4b2264fc65777fff115 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Mon, 3 Mar 2025 08:53:20 +0000 Subject: [PATCH 002/846] 8347629: Test FailOverDirectExecutionControlTest.java fails with -Xcomp Backport-of: 981d3c2b6edb8ee8233be07cd1ce682200019d1f --- .../jdk/jshell/FailOverDirectExecutionControlTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/langtools/jdk/jshell/FailOverDirectExecutionControlTest.java b/test/langtools/jdk/jshell/FailOverDirectExecutionControlTest.java index a094ed4a86f3d..99457ea2ce6dc 100644 --- a/test/langtools/jdk/jshell/FailOverDirectExecutionControlTest.java +++ b/test/langtools/jdk/jshell/FailOverDirectExecutionControlTest.java @@ -62,6 +62,7 @@ public class FailOverDirectExecutionControlTest extends ExecutionControlTestBase ClassLoader ccl; ExecutionControlProvider provider; + Logger logger; LogTestHandler hndlr; Map> logged; @@ -95,7 +96,7 @@ public void close() throws SecurityException { @BeforeMethod @Override public void setUp() { - Logger logger = Logger.getLogger("jdk.jshell.execution"); + logger = Logger.getLogger("jdk.jshell.execution"); logger.setLevel(Level.ALL); hndlr = new LogTestHandler(); logger.addHandler(hndlr); @@ -137,8 +138,8 @@ public void setUp() { @Override public void tearDown() { super.tearDown(); - Logger logger = Logger.getLogger("jdk.jshell.execution"); logger.removeHandler(hndlr); + logger = null; Thread.currentThread().setContextClassLoader(ccl); } From 72e90637a1dcd7cecc736ca289dabbaaca39f66b Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Mon, 3 Mar 2025 09:22:08 +0000 Subject: [PATCH 003/846] 8343205: CompileBroker::possibly_add_compiler_threads excessively polls available memory Backport-of: 3087c6c74d742b7b5eaf28e4c886b5dc1811ea6f --- src/hotspot/share/compiler/compileBroker.cpp | 36 ++++++++++++++------ src/hotspot/share/compiler/compileBroker.hpp | 4 ++- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index f54308944e281..b77ab569bdd87 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -1069,18 +1069,34 @@ void CompileBroker::init_compiler_sweeper_threads() { void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) { + int old_c2_count = 0, new_c2_count = 0, old_c1_count = 0, new_c1_count = 0; + const int c2_tasks_per_thread = 2, c1_tasks_per_thread = 4; + + // Quick check if we already have enough compiler threads without taking the lock. + // Numbers may change concurrently, so we read them again after we have the lock. + if (_c2_compile_queue != nullptr) { + old_c2_count = get_c2_thread_count(); + new_c2_count = MIN2(_c2_count, _c2_compile_queue->size() / c2_tasks_per_thread); + } + if (_c1_compile_queue != nullptr) { + old_c1_count = get_c1_thread_count(); + new_c1_count = MIN2(_c1_count, _c1_compile_queue->size() / c1_tasks_per_thread); + } + if (new_c2_count <= old_c2_count && new_c1_count <= old_c1_count) return; + + // Now, we do the more expensive operations. julong available_memory = os::available_memory(); // If SegmentedCodeCache is off, both values refer to the single heap (with type CodeBlobType::All). - size_t available_cc_np = CodeCache::unallocated_capacity(CodeBlobType::MethodNonProfiled), - available_cc_p = CodeCache::unallocated_capacity(CodeBlobType::MethodProfiled); + size_t available_cc_np = CodeCache::unallocated_capacity(CodeBlobType::MethodNonProfiled), + available_cc_p = CodeCache::unallocated_capacity(CodeBlobType::MethodProfiled); - // Only do attempt to start additional threads if the lock is free. + // Only attempt to start additional threads if the lock is free. if (!CompileThread_lock->try_lock()) return; if (_c2_compile_queue != NULL) { - int old_c2_count = _compilers[1]->num_compiler_threads(); - int new_c2_count = MIN4(_c2_count, - _c2_compile_queue->size() / 2, + old_c2_count = get_c2_thread_count(); + new_c2_count = MIN4(_c2_count, + _c2_compile_queue->size() / c2_tasks_per_thread, (int)(available_memory / (200*M)), (int)(available_cc_np / (128*K))); @@ -1114,7 +1130,7 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) { break; } // Check if another thread has beaten us during the Java calls. - if (_compilers[1]->num_compiler_threads() != i) break; + if (get_c2_thread_count() != i) break; jobject thread_handle = JNIHandles::make_global(thread_oop); assert(compiler2_object(i) == NULL, "Old one must be released!"); _compiler2_objects[i] = thread_handle; @@ -1136,9 +1152,9 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) { } if (_c1_compile_queue != NULL) { - int old_c1_count = _compilers[0]->num_compiler_threads(); - int new_c1_count = MIN4(_c1_count, - _c1_compile_queue->size() / 4, + old_c1_count = get_c1_thread_count(); + new_c1_count = MIN4(_c1_count, + _c1_compile_queue->size() / c1_tasks_per_thread, (int)(available_memory / (100*M)), (int)(available_cc_p / (128*K))); diff --git a/src/hotspot/share/compiler/compileBroker.hpp b/src/hotspot/share/compiler/compileBroker.hpp index 0b721f83121f4..adf7a3c6a45ac 100644 --- a/src/hotspot/share/compiler/compileBroker.hpp +++ b/src/hotspot/share/compiler/compileBroker.hpp @@ -88,7 +88,7 @@ class CompileQueue : public CHeapObj { CompileTask* _first_stale; - int _size; + volatile int _size; void purge_stale_tasks(); public: @@ -402,6 +402,8 @@ class CompileBroker: AllStatic { static CompileLog* get_log(CompilerThread* ct); + static int get_c1_thread_count() { return _compilers[0]->num_compiler_threads(); } + static int get_c2_thread_count() { return _compilers[1]->num_compiler_threads(); } static int get_total_compile_count() { return _total_compile_count; } static int get_total_bailout_count() { return _total_bailout_count; } static int get_total_invalidated_count() { return _total_invalidated_count; } From 2c903744a9b7e1c9431b1aa993c9d3e1772459a1 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 4 Mar 2025 15:07:15 +0000 Subject: [PATCH 004/846] 8279884: Use better file for cygwin source permission check Backport-of: 36f41cbe1126c6d9a00b21a1a68cf5f44e2f443f --- make/autoconf/basic.m4 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/make/autoconf/basic.m4 b/make/autoconf/basic.m4 index 3e5e22b53af43..08a54796641fa 100644 --- a/make/autoconf/basic.m4 +++ b/make/autoconf/basic.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -452,7 +452,9 @@ AC_DEFUN([BASIC_CHECK_DIR_ON_LOCAL_DISK], AC_DEFUN_ONCE([BASIC_CHECK_SRC_PERMS], [ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - file_to_test="$TOPDIR/LICENSE" + # The choice of file here is somewhat arbitrary, it just needs to be there + # in the source tree when configure runs + file_to_test="$TOPDIR/Makefile" if test `$STAT -c '%a' "$file_to_test"` -lt 400; then AC_MSG_ERROR([Bad file permissions on src files. This is usually caused by cloning the repositories with a non cygwin hg in a directory not created in cygwin.]) fi From 87810714ac35711fd727158219966eda1349a2e9 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 4 Mar 2025 15:08:28 +0000 Subject: [PATCH 005/846] 8279894: javax/swing/JInternalFrame/8020708/bug8020708.java timeouts on Windows 11 Backport-of: c4a624d46332552e7baca8ee09bfdce0e53eef05 --- .../javax/swing/JInternalFrame/8020708/bug8020708.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/jdk/javax/swing/JInternalFrame/8020708/bug8020708.java b/test/jdk/javax/swing/JInternalFrame/8020708/bug8020708.java index efd13ff768680..8f78178ada62e 100644 --- a/test/jdk/javax/swing/JInternalFrame/8020708/bug8020708.java +++ b/test/jdk/javax/swing/JInternalFrame/8020708/bug8020708.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -41,7 +41,7 @@ * @summary NLS: mnemonics missing in SwingSet2/JInternalFrame demo * @library ../../regtesthelpers * @build Util - * @run main bug8020708 + * @run main/timeout=300 bug8020708 */ public class bug8020708 { @@ -68,6 +68,7 @@ public class bug8020708 { public static void main(String[] args) throws Exception { for (Locale locale : SUPPORTED_LOCALES) { + System.out.println("locale: " + locale); for (String laf : LOOK_AND_FEELS) { Locale.setDefault(locale); if (!installLookAndFeel(laf)) { @@ -80,7 +81,7 @@ public static void main(String[] args) throws Exception { static void testInternalFrameMnemonic(Locale locale) throws Exception { Robot robot = new Robot(); - robot.setAutoDelay(250); + robot.setAutoDelay(100); robot.setAutoWaitForIdle(true); SwingUtilities.invokeAndWait(new Runnable() { @@ -142,6 +143,7 @@ static final boolean installLookAndFeel(String lafName) throws Exception { UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels(); for (UIManager.LookAndFeelInfo info : infos) { if (info.getClassName().contains(lafName)) { + System.out.println("LookAndFeel: " + info.getClassName()); UIManager.setLookAndFeel(info.getClassName()); return true; } From fb0fcb5ac533296d6339d9aaad6f04944525dfc5 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 4 Mar 2025 15:09:44 +0000 Subject: [PATCH 006/846] 8024624: [TEST_BUG] [macosx] CTRL+RIGHT(LEFT) doesn't move selection on next cell in JTable on Aqua L&F Backport-of: 535938722028b86e9d77d3728190f62f42117792 --- .../JTableOrientationNavTest.java | 295 ++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 test/jdk/javax/swing/JTable/JTableOrientationNavTest/JTableOrientationNavTest.java diff --git a/test/jdk/javax/swing/JTable/JTableOrientationNavTest/JTableOrientationNavTest.java b/test/jdk/javax/swing/JTable/JTableOrientationNavTest/JTableOrientationNavTest.java new file mode 100644 index 0000000000000..653ae205993b9 --- /dev/null +++ b/test/jdk/javax/swing/JTable/JTableOrientationNavTest/JTableOrientationNavTest.java @@ -0,0 +1,295 @@ +/* + * 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 8024624 + * @key headful + * @requires (os.family != "mac") + * @summary Tests some of JTable's key navigation + * @run main JTableOrientationNavTest + */ + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.ComponentOrientation; +import java.awt.Rectangle; +import java.awt.Robot; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableModel; + +import static java.awt.event.KeyEvent.VK_CONTROL; +import static java.awt.event.KeyEvent.VK_LEFT; +import static java.awt.event.KeyEvent.VK_PAGE_DOWN; +import static java.awt.event.KeyEvent.VK_PAGE_UP; +import static java.awt.event.KeyEvent.VK_RIGHT; +import static java.awt.event.KeyEvent.VK_SHIFT; + +public class JTableOrientationNavTest { + private static JFrame frame; + private static JTable table; + private static JScrollPane sp; + private static Robot robot; + private static boolean ltr = true; + + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + try { + robot = new Robot(); + robot.setAutoDelay(100); + robot.setAutoWaitForIdle(true); + + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.add(createContentPane()); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + executeTest(); + setupRTL(); + executeTest(); + + System.out.println("Passed"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + SwingUtilities.invokeAndWait(() -> frame.dispose()); + } + } + + private static TableModel getTableModel1() { + String[] columnNames = {"Column 0", "Column 1", "Column 2", + "Column 3", "Column 4"}; + String[][] data = {{"Table 00, 00", "Table 00, 01", "Table 00, 02", + "Table 00, 03", "Table 00, 04"}, + {"Table 01, 00", "Table 01, 01", "Table 01, 02", + "Table 01, 03", "Table 01, 04"}, + {"Table 02, 00", "Table 02, 01", "Table 02, 02", + "Table 02, 03", "Table 02, 04"}, + {"Table 03, 00", "Table 03, 01", "Table 03, 02", + "Table 03, 03", "Table 03, 04"}, + {"Table 04, 00", "Table 04, 01", "Table 04, 02", + "Table 04, 03", "Table 04, 04"}, + {"Table 05, 00", "Table 05, 01", "Table 05, 02", + "Table 05, 03", "Table 05, 04"}}; + + return new DefaultTableModel(data, columnNames); + } + + private static TableModel getTableModel2() { + String[] columnNames = new String[30]; + String[][] data = new String[1][30]; + + for (int i = 0; i < columnNames.length; i++) { + columnNames[i] = "Column " + i; + data[0][i] = "Data " + 1; + } + + return new DefaultTableModel(data, columnNames); + } + + private static Component createContentPane() { + table = new JTable(getTableModel1()); + table.setCellSelectionEnabled(true); + table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + JPanel panel = new JPanel(new BorderLayout()); + sp = new JScrollPane(table); + panel.add(sp); + return panel; + } + + private static void executeTest() throws InterruptedException, InvocationTargetException { + SwingUtilities.invokeAndWait(() -> { + table.setRowSelectionInterval(0, 0); + table.setColumnSelectionInterval(0, 0); + checkSelection(0, 0); + }); + + robot.keyPress(ltr ? VK_RIGHT : VK_LEFT); + robot.keyRelease(ltr ? VK_RIGHT : VK_LEFT); + + SwingUtilities.invokeAndWait(() -> checkSelection(1, 1)); + + robot.keyPress(VK_CONTROL); + robot.keyPress(ltr ? VK_RIGHT : VK_LEFT); + robot.keyRelease(ltr ? VK_RIGHT : VK_LEFT); + robot.keyRelease(VK_CONTROL); + + SwingUtilities.invokeAndWait(() -> { + checkSelection(2, 1); + table.setRowSelectionInterval(0, 0); + table.setColumnSelectionInterval(4, 4); + checkSelection(4, 4); + }); + + robot.keyPress(ltr ? VK_LEFT : VK_RIGHT); + robot.keyRelease(ltr ? VK_LEFT : VK_RIGHT); + + SwingUtilities.invokeAndWait(() -> checkSelection(3, 3)); + + robot.keyPress(VK_CONTROL); + robot.keyPress(ltr ? VK_LEFT : VK_RIGHT); + robot.keyRelease(ltr ? VK_LEFT : VK_RIGHT); + robot.keyRelease(VK_CONTROL); + + SwingUtilities.invokeAndWait(() -> { + checkSelection(2, 3); + table.setColumnSelectionInterval(2, 2); + checkSelection(2, 2); + }); + + robot.keyPress(VK_CONTROL); + robot.keyPress(VK_PAGE_UP); + robot.keyRelease(VK_PAGE_UP); + robot.keyRelease(VK_CONTROL); + + SwingUtilities.invokeAndWait(() -> { + checkSelection(0, 0); + table.setColumnSelectionInterval(2, 2); + checkSelection(2, 2); + }); + + robot.keyPress(VK_CONTROL); + robot.keyPress(VK_PAGE_DOWN); + robot.keyRelease(VK_PAGE_DOWN); + robot.keyRelease(VK_CONTROL); + + SwingUtilities.invokeAndWait(() -> { + checkSelection(4, 4); + table.setColumnSelectionInterval(2, 2); + checkSelection(2, 2); + }); + + robot.keyPress(VK_CONTROL); + robot.keyPress(VK_SHIFT); + robot.keyPress(VK_PAGE_UP); + robot.keyRelease(VK_PAGE_UP); + robot.keyRelease(VK_SHIFT); + robot.keyRelease(VK_CONTROL); + + SwingUtilities.invokeAndWait(() -> { + checkSelection(0, 0, 1, 2); + table.setColumnSelectionInterval(2, 2); + checkSelection(2, 2); + }); + + robot.keyPress(VK_CONTROL); + robot.keyPress(VK_SHIFT); + robot.keyPress(VK_PAGE_DOWN); + robot.keyRelease(VK_PAGE_DOWN); + robot.keyRelease(VK_SHIFT); + robot.keyRelease(VK_CONTROL); + + SwingUtilities.invokeAndWait(() -> { + checkSelection(4, 2, 3, 4); + table.setModel(getTableModel2()); + table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + table.setRowSelectionInterval(0, 0); + table.setColumnSelectionInterval(0, 0); + table.scrollRectToVisible(new Rectangle(ltr ? 0 : table.getWidth(), 0, 1, 1)); + checkSelection(0, 0); + }); + + robot.keyPress(VK_CONTROL); + robot.keyPress(VK_PAGE_DOWN); + robot.keyRelease(VK_PAGE_DOWN); + robot.keyRelease(VK_CONTROL); + + SwingUtilities.invokeAndWait(() -> { + checkSelection(6, 6); + table.setColumnSelectionInterval(29, 29); + table.scrollRectToVisible(new Rectangle(ltr ? table.getWidth() : 0, 0, 1, 1)); + checkSelection(29, 29); + }); + + robot.keyPress(VK_CONTROL); + robot.keyPress(VK_PAGE_UP); + robot.keyRelease(VK_PAGE_UP); + robot.keyRelease(VK_CONTROL); + + SwingUtilities.invokeAndWait(() -> checkSelection(23, 23)); + + System.out.println("Done with ltr: " + ltr); + } + + private static void setupRTL() throws InterruptedException, InvocationTargetException { + ltr = false; + SwingUtilities.invokeAndWait(() -> { + table.setModel(getTableModel1()); + table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); + sp.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); + }); + } + + private static void checkSelection(int col, int... allCols) { + int trow = table.getSelectionModel().getLeadSelectionIndex(); + int[] trows = table.getSelectedRows(); + int tcol = table.getColumnModel().getSelectionModel().getLeadSelectionIndex(); + int[] tcols = table.getSelectedColumns(); + + if (trow != 0) { + throw new RuntimeException("Wrong lead row"); + } + + if (trows.length != 1 || trows[0] != 0) { + throw new RuntimeException("Bad row selection"); + } + + if (col != tcol) { + throw new RuntimeException("Wrong lead col"); + } + + if (allCols == null || allCols.length == 0) { + if (tcols.length != 0) { + throw new RuntimeException("Should be no cols selected"); + } + } else { + Arrays.sort(tcols); + Arrays.sort(allCols); + + for (int c : allCols) { + if (Arrays.binarySearch(tcols, c) < 0) { + throw new RuntimeException("Wrong column selection"); + } + } + + for (int c : tcols) { + if (Arrays.binarySearch(allCols, c) < 0) { + throw new RuntimeException("Wrong column selection"); + } + } + } + } + +} From 82140d5536584ee62f2338f24c33aff6dbbd00c0 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 4 Mar 2025 15:14:03 +0000 Subject: [PATCH 007/846] 8224267: JOptionPane message string with 5000+ newlines produces StackOverflowError Backport-of: 46251bc6e248a19e8d78173ff8d0502c68ee1acb --- .../swing/plaf/basic/BasicOptionPaneUI.java | 11 +++- .../TestOptionPaneStackOverflow.java | 59 +++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 test/jdk/javax/swing/JOptionPane/TestOptionPaneStackOverflow.java diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java index 427823573a6db..19551e4bc278c 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java @@ -89,6 +89,7 @@ public class BasicOptionPaneUI extends OptionPaneUI { public static final int MinimumHeight = 90; private static String newline; + private static int recursionCount; /** * {@code JOptionPane} that the receiver is providing the @@ -460,7 +461,7 @@ protected void addMessageComponents(Container container, @SuppressWarnings("serial") // anonymous class JPanel breakPanel = new JPanel() { public Dimension getPreferredSize() { - Font f = getFont(); + Font f = getFont(); if (f != null) { return new Dimension(1, f.getSize() + 2); @@ -475,8 +476,14 @@ public Dimension getPreferredSize() { addMessageComponents(container, cons, s.substring(0, nl), maxll, false); } + // Prevent recursion of more than + // 200 successive newlines in a message + if (recursionCount++ > 200) { + recursionCount = 0; + return; + } addMessageComponents(container, cons, s.substring(nl + nll), maxll, - false); + false); } else if (len > maxll) { Container c = Box.createVerticalBox(); diff --git a/test/jdk/javax/swing/JOptionPane/TestOptionPaneStackOverflow.java b/test/jdk/javax/swing/JOptionPane/TestOptionPaneStackOverflow.java new file mode 100644 index 0000000000000..f8650c28ac40e --- /dev/null +++ b/test/jdk/javax/swing/JOptionPane/TestOptionPaneStackOverflow.java @@ -0,0 +1,59 @@ +/* + * 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 8224267 + @key headful + @summary Verifies if StackOverflowError is not thrown for multiple newlines + @run main TestOptionPaneStackOverflow + */ + +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; + +public class TestOptionPaneStackOverflow +{ + static JFrame frame; + + public static void main(String[] argv) throws Exception + { + try { + String message = java.nio.CharBuffer.allocate(5000).toString(). + replace('\0','\n'); + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame(); + JOptionPane optionPane = new JOptionPane(); + optionPane.createDialog(frame, null); + optionPane.setMessage(message); + }); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} From 693c56d98db87528744c4008c8f65bd281534691 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 4 Mar 2025 15:24:57 +0000 Subject: [PATCH 008/846] 8290162: Reset recursion counter missed in fix of JDK-8224267 Backport-of: 6e18883d8ffd9a7b7d495da05e9859dc1d1a2677 --- .../classes/javax/swing/plaf/basic/BasicOptionPaneUI.java | 4 ++++ .../javax/swing/JOptionPane/TestOptionPaneStackOverflow.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java index 19551e4bc278c..c916e26016a20 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java @@ -374,6 +374,7 @@ protected Container createMessageArea() { "OptionPane.messageAnchor", GridBagConstraints.CENTER); cons.insets = new Insets(0,0,3,0); + recursionCount = 0; addMessageComponents(body, cons, getMessage(), getMaxCharactersPerLineCount(), false); top.add(realBody, BorderLayout.CENTER); @@ -478,8 +479,11 @@ public Dimension getPreferredSize() { } // Prevent recursion of more than // 200 successive newlines in a message + // and indicate message is truncated via ellipsis if (recursionCount++ > 200) { recursionCount = 0; + addMessageComponents(container, cons, new String("..."), + maxll,false); return; } addMessageComponents(container, cons, s.substring(nl + nll), maxll, diff --git a/test/jdk/javax/swing/JOptionPane/TestOptionPaneStackOverflow.java b/test/jdk/javax/swing/JOptionPane/TestOptionPaneStackOverflow.java index f8650c28ac40e..9cfaea13755cc 100644 --- a/test/jdk/javax/swing/JOptionPane/TestOptionPaneStackOverflow.java +++ b/test/jdk/javax/swing/JOptionPane/TestOptionPaneStackOverflow.java @@ -22,7 +22,7 @@ */ /* @test - @bug 8224267 + @bug 8224267 8290162 @key headful @summary Verifies if StackOverflowError is not thrown for multiple newlines @run main TestOptionPaneStackOverflow From 6e37df10401b55a1944fb5c1007dea979f696e1c Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Tue, 4 Mar 2025 15:36:17 +0000 Subject: [PATCH 009/846] 8349200: [JMH] time.format.ZonedDateTimeFormatterBenchmark fails Backport-of: 9d101b2528f4bb1c4dfb74cdc5e37343b9175580 --- .../java/time/format/ZonedDateTimeFormatterBenchmark.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/micro/org/openjdk/bench/java/time/format/ZonedDateTimeFormatterBenchmark.java b/test/micro/org/openjdk/bench/java/time/format/ZonedDateTimeFormatterBenchmark.java index 00a3729a337ae..93f7e5e1e7719 100644 --- a/test/micro/org/openjdk/bench/java/time/format/ZonedDateTimeFormatterBenchmark.java +++ b/test/micro/org/openjdk/bench/java/time/format/ZonedDateTimeFormatterBenchmark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -40,7 +40,7 @@ public class ZonedDateTimeFormatterBenchmark { private static final DateTimeFormatter df = new DateTimeFormatterBuilder() .appendPattern("yyyy:MM:dd:HH:mm:v") .toFormatter(); - private static final String TEXT = "2015:03:10:12:13:ECT"; + private static final String TEXT = "2015:03:10:12:13:PST"; @Setup public void setUp() { From 2633ee3ddeaa9e5894de37b33c1d2dbdff7b022a Mon Sep 17 00:00:00 2001 From: Richard Reingruber Date: Mon, 10 Mar 2025 08:58:25 +0000 Subject: [PATCH 010/846] 8334560: [PPC64]: postalloc_expand_java_dynamic_call_sched does not copy all fields Backport-of: 13dce296fc3924b269757ce1279c57afe18faeeb --- src/hotspot/cpu/ppc/ppc.ad | 1 + test/jdk/com/sun/jdi/EATests.java | 91 +++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index fab403825e77d..95a2ea6689e4d 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -3507,6 +3507,7 @@ encode %{ call->_oop_map = _oop_map; call->_jvms = _jvms; call->_jvmadj = _jvmadj; + call->_has_ea_local_in_scope = _has_ea_local_in_scope; call->_in_rms = _in_rms; call->_nesting = _nesting; call->_override_symbolic_info = _override_symbolic_info; diff --git a/test/jdk/com/sun/jdi/EATests.java b/test/jdk/com/sun/jdi/EATests.java index 9d02073ee6aea..66c1c38f98640 100644 --- a/test/jdk/com/sun/jdi/EATests.java +++ b/test/jdk/com/sun/jdi/EATests.java @@ -233,6 +233,7 @@ public static void main(String[] args) { // Relocking test cases new EARelockingSimpleTarget() .run(); new EARelockingSimple_2Target() .run(); + new EARelockingSimpleWithAccessInOtherThread_02_DynamicCall_Target() .run(); new EARelockingRecursiveTarget() .run(); new EARelockingNestedInflatedTarget() .run(); new EARelockingNestedInflated_02Target() .run(); @@ -353,6 +354,7 @@ protected void runTests() throws Exception { // Relocking test cases new EARelockingSimple() .run(this); new EARelockingSimple_2() .run(this); + new EARelockingSimpleWithAccessInOtherThread_02_DynamicCall() .run(this); new EARelockingRecursive() .run(this); new EARelockingNestedInflated() .run(this); new EARelockingNestedInflated_02() .run(this); @@ -1812,6 +1814,95 @@ public void dontinline_testMethod() { ///////////////////////////////////////////////////////////////////////////// +// The debugger reads and publishes an object with eliminated locking to an instance field. +// A 2nd thread in the debuggee finds it there and changes its state using a synchronized method. +// Without eager relocking the accesses are unsynchronized which can be observed. +// This is a variant of EARelockingSimpleWithAccessInOtherThread with a dynamic call (not devirtualized). +class EARelockingSimpleWithAccessInOtherThread_02_DynamicCall extends EATestCaseBaseDebugger { + + public void runTestCase() throws Exception { + BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V"); + printStack(bpe.thread()); + String l1ClassName = EARelockingSimpleWithAccessInOtherThread_02_DynamicCall_Target.SyncCounter.class.getName(); + ObjectReference ctr = getLocalRef(bpe.thread().frame(2), l1ClassName, "l1"); + setField(testCase, "sharedCounter", ctr); + terminateEndlessLoop(); + } +} + +class EARelockingSimpleWithAccessInOtherThread_02_DynamicCall_Target extends EATestCaseBaseTarget { + + public static final BrkPtDispatchA[] disp = + {new BrkPtDispatchA(), new BrkPtDispatchB(), new BrkPtDispatchC(), new BrkPtDispatchD()}; + + public static class BrkPtDispatchA { + public EATestCaseBaseTarget testCase; + public void dontinline_brkpt() { testCase.dontinline_brkpt(); } + } + + public static class BrkPtDispatchB extends BrkPtDispatchA { + @Override + public void dontinline_brkpt() { testCase.dontinline_brkpt(); } + } + + public static class BrkPtDispatchC extends BrkPtDispatchA { + @Override + public void dontinline_brkpt() { testCase.dontinline_brkpt(); } + } + + public static class BrkPtDispatchD extends BrkPtDispatchA { + @Override + public void dontinline_brkpt() { + testCase.dontinline_brkpt(); + } + } + + public static class SyncCounter { + private int val; + public synchronized int inc() { return val++; } + } + + public volatile SyncCounter sharedCounter; + + @Override + public void setUp() { + super.setUp(); + testMethodDepth = 2; + for (BrkPtDispatchA d : disp) { + d.testCase = this; + } + doLoop = true; + new Thread(() -> { + while (doLoop) { + SyncCounter ctr = sharedCounter; + if (ctr != null) { + ctr.inc(); + } + } + }).start(); + } + + public int dispCount; + public void dontinline_testMethod() { + SyncCounter l1 = new SyncCounter(); + synchronized (l1) { // Eliminated locking + l1.inc(); + // Use different types for the subsequent call to prevent devirtualization. + BrkPtDispatchA d = disp[(dispCount++) & 3]; + d.dontinline_brkpt(); // Dynamic call. Debugger publishes l1 to sharedCounter. + iResult = l1.inc(); // Changes by the 2nd thread will be observed if l1 + // was not relocked before passing it to the debugger. + } + } + + @Override + public int getExpectedIResult() { + return 1; + } +} + +///////////////////////////////////////////////////////////////////////////// + // Test recursive locking class EARelockingRecursiveTarget extends EATestCaseBaseTarget { From f00607a50acecb3bfd6dd961e4378b4e1697e1e7 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:02:42 +0000 Subject: [PATCH 011/846] 8282863: java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java fails on Windows 10 with HiDPI screen Backport-of: c6e041649514b964f5baaa88880c4d146275db8d --- .../classes/sun/awt/Win32GraphicsDevice.java | 31 ++++++++++++++----- .../FullscreenWindowProps.java | 2 +- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java index d2b0a6764f105..b4d307c646d09 100644 --- a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java +++ b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java @@ -47,6 +47,8 @@ import sun.java2d.opengl.WGLGraphicsConfig; import sun.java2d.windows.WindowsFlags; +import static java.awt.peer.ComponentPeer.SET_BOUNDS; + import static sun.awt.Win32GraphicsEnvironment.debugScaleX; import static sun.awt.Win32GraphicsEnvironment.debugScaleY; @@ -443,6 +445,21 @@ public synchronized void setFullScreenWindow(Window w) { protected native void enterFullScreenExclusive(int screen, WindowPeer w); protected native void exitFullScreenExclusive(int screen, WindowPeer w); + /** + * Reapplies the size of this graphics device to + * the given full-screen window. + * @param w a Window that needs resizing + * @param b new full-screen window bounds + */ + private static void resizeFSWindow(final Window w, final Rectangle b) { + if (w != null) { + WindowPeer peer = AWTAccessor.getComponentAccessor().getPeer(w); + if (peer != null) { + peer.setBounds(b.x, b.y, b.width, b.height, SET_BOUNDS); + } + } + } + @Override public boolean isDisplayChangeSupported() { return (isFullScreenSupported() && getFullScreenWindow() != null); @@ -465,13 +482,9 @@ public synchronized void setDisplayMode(DisplayMode dm) { WWindowPeer peer = AWTAccessor.getComponentAccessor().getPeer(w); configDisplayMode(screen, peer, dm.getWidth(), dm.getHeight(), dm.getBitDepth(), dm.getRefreshRate()); - // resize the fullscreen window to the dimensions of the new - // display mode - Rectangle screenBounds = getDefaultConfiguration().getBounds(); - w.setBounds(screenBounds.x, screenBounds.y, - screenBounds.width, screenBounds.height); - // Note: no call to replaceSurfaceData is required here since - // replacement will be caused by an upcoming display change event + // Note: the full-screen window will get resized to the dimensions of the new + // display mode in the upcoming display change event, when the DPI scales + // would already be correctly set etc. } else { throw new IllegalStateException("Must be in fullscreen mode " + "in order to set display mode"); @@ -531,6 +544,10 @@ public void displayChanged() { defaultConfig = null; configs = null; initScaleFactors(); + + Rectangle screenBounds = getDefaultConfiguration().getBounds(); + resizeFSWindow(getFullScreenWindow(), screenBounds); + // pass on to all top-level windows on this display topLevels.notifyListeners(); } diff --git a/test/jdk/java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java b/test/jdk/java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java index 1160c54bf329c..f5f77d47319d7 100644 --- a/test/jdk/java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java +++ b/test/jdk/java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java @@ -32,7 +32,7 @@ /** * @test - * @bug 8211999 + * @bug 8211999 8282863 * @key headful * @summary verifies the full-screen window bounds and graphics configuration */ From db834e07b74275e0bdc70dbd6a430e212c954831 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:05:39 +0000 Subject: [PATCH 012/846] 5074006: Swing JOptionPane shows tag as a string after newline 8042134: JOptionPane bungles HTML messages Backport-of: 91072ee3934616ab2edc4850a59c0a25fd0de3b4 --- .../swing/plaf/basic/BasicOptionPaneUI.java | 104 +++++++++++------- .../swing/JOptionPane/TestJOptionHTMLTag.java | 68 ++++++++++++ 2 files changed, 132 insertions(+), 40 deletions(-) create mode 100644 test/jdk/javax/swing/JOptionPane/TestJOptionHTMLTag.java diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java index c916e26016a20..318fa88613ae2 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java @@ -456,51 +456,75 @@ protected void addMessageComponents(Container container, } else if ((nl = s.indexOf('\n')) >= 0) { nll = 1; } - if (nl >= 0) { - // break up newlines - if (nl == 0) { - @SuppressWarnings("serial") // anonymous class - JPanel breakPanel = new JPanel() { - public Dimension getPreferredSize() { - Font f = getFont(); - - if (f != null) { - return new Dimension(1, f.getSize() + 2); - } - return new Dimension(0, 0); - } - }; - breakPanel.setName("OptionPane.break"); - addMessageComponents(container, cons, breakPanel, maxll, - true); - } else { - addMessageComponents(container, cons, s.substring(0, nl), - maxll, false); - } - // Prevent recursion of more than - // 200 successive newlines in a message - // and indicate message is truncated via ellipsis - if (recursionCount++ > 200) { - recursionCount = 0; - addMessageComponents(container, cons, new String("..."), - maxll,false); - return; + if (s.contains("")) { + /* line break in html text is done by
tag + * and not by /n so it's incorrect to address newline + * same as non-html text. + * Text between tags are extracted + * and rendered as JLabel text + */ + int index1 = s.indexOf(""); + int index2 = s.indexOf(""); + String str = ""; + if (index2 >= 0) { + str = s.substring(index2 + "".length()); + s = s.substring(index1, index2 + + "".length()); } - addMessageComponents(container, cons, s.substring(nl + nll), maxll, - false); - - } else if (len > maxll) { - Container c = Box.createVerticalBox(); - c.setName("OptionPane.verticalBox"); - burstStringInto(c, s, maxll); - addMessageComponents(container, cons, c, maxll, true ); - - } else { JLabel label; - label = new JLabel( s, JLabel.LEADING ); + label = new JLabel(s, JLabel.LEADING); label.setName("OptionPane.label"); configureMessageLabel(label); addMessageComponents(container, cons, label, maxll, true); + if (!str.isEmpty()) { + addMessageComponents(container, cons, str, maxll, false); + } + } else { + if (nl >= 0) { + // break up newlines + if (nl == 0) { + @SuppressWarnings("serial") // anonymous class + JPanel breakPanel = new JPanel() { + public Dimension getPreferredSize() { + Font f = getFont(); + + if (f != null) { + return new Dimension(1, f.getSize() + 2); + } + return new Dimension(0, 0); + } + }; + breakPanel.setName("OptionPane.break"); + addMessageComponents(container, cons, breakPanel, maxll, + true); + } else { + addMessageComponents(container, cons, s.substring(0, nl), + maxll, false); + } + // Prevent recursion of more than + // 200 successive newlines in a message + // and indicate message is truncated via ellipsis + if (recursionCount++ > 200) { + recursionCount = 0; + addMessageComponents(container, cons, new String("..."), + maxll, false); + return; + } + addMessageComponents(container, cons, s.substring(nl + nll), maxll, + false); + + } else if (len > maxll) { + Container c = Box.createVerticalBox(); + c.setName("OptionPane.verticalBox"); + burstStringInto(c, s, maxll); + addMessageComponents(container, cons, c, maxll, true); + + } else { + JLabel label; + label = new JLabel(s, JLabel.LEADING); + label.setName("OptionPane.label"); + configureMessageLabel(label); + addMessageComponents(container, cons, label, maxll, true); + } } } } diff --git a/test/jdk/javax/swing/JOptionPane/TestJOptionHTMLTag.java b/test/jdk/javax/swing/JOptionPane/TestJOptionHTMLTag.java new file mode 100644 index 0000000000000..94318492bd93d --- /dev/null +++ b/test/jdk/javax/swing/JOptionPane/TestJOptionHTMLTag.java @@ -0,0 +1,68 @@ +/* + * 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 5074006 + * @key headful + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Swing JOptionPane shows tag as a string after newline + * @run main/manual TestJOptionHTMLTag +*/ + +import javax.swing.JDialog; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; + +public class TestJOptionHTMLTag { + static String instructions + = """ + INSTRUCTIONS: + A dialog will be shown. + If it does not contain string, press Pass else press Fail. + """; + static PassFailJFrame passFailJFrame; + + public static void main(String[] args) throws Exception { + + SwingUtilities.invokeAndWait(() -> { + try { + String message = "" + "This is a test\n" + ""; + JOptionPane optionPane = new JOptionPane(); + optionPane.setMessage(message); + optionPane.setMessageType(JOptionPane.INFORMATION_MESSAGE); + JDialog dialog = new JDialog(); + dialog.setContentPane(optionPane); + dialog.pack(); + dialog.setVisible(true); + + passFailJFrame = new PassFailJFrame(instructions); + PassFailJFrame.addTestWindow(dialog); + PassFailJFrame.positionTestWindow(dialog, PassFailJFrame.Position.HORIZONTAL); + } catch (Exception e) { + e.printStackTrace(); + } + }); + passFailJFrame.awaitAndCheck(); + } +} + From 4f1eb59d2d3bb580526b086c7a041cdaa0bd15af Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:09:28 +0000 Subject: [PATCH 013/846] 8296072: CertAttrSet::encode and DerEncoder::derEncode should write into DerOutputStream 8296167: test/langtools/tools/jdeps/jdkinternals/ShowReplacement.java failing after JDK-8296072 Reviewed-by: mbaesken Backport-of: 0d0bd7bd409c0caa5edebe3d1eacf8e5bb48f984 --- .../sun/security/pkcs/PKCS9Attribute.java | 9 ++--- .../classes/sun/security/pkcs/SignerInfo.java | 8 ++--- .../sun/security/pkcs10/PKCS10Attribute.java | 3 +- .../sun/security/pkcs10/PKCS10Attributes.java | 12 +++---- .../classes/sun/security/util/DerEncoder.java | 5 ++- .../sun/security/util/DerOutputStream.java | 3 +- .../share/classes/sun/security/x509/AVA.java | 7 ++-- .../sun/security/x509/AlgorithmId.java | 6 ++-- .../x509/AuthorityInfoAccessExtension.java | 8 ++--- .../x509/AuthorityKeyIdentifierExtension.java | 12 +++---- .../x509/BasicConstraintsExtension.java | 8 ++--- .../x509/CRLDistributionPointsExtension.java | 14 ++++---- .../sun/security/x509/CRLExtensions.java | 15 ++------ .../sun/security/x509/CRLNumberExtension.java | 15 ++++---- .../security/x509/CRLReasonCodeExtension.java | 11 +++--- .../sun/security/x509/CertAttrSet.java | 9 ++--- .../security/x509/CertificateAlgorithmId.java | 11 +++--- .../security/x509/CertificateExtensions.java | 36 +++++++------------ .../x509/CertificateIssuerExtension.java | 12 +++---- .../security/x509/CertificateIssuerName.java | 11 +++--- .../x509/CertificatePoliciesExtension.java | 8 ++--- .../x509/CertificateSerialNumber.java | 11 +++--- .../security/x509/CertificateSubjectName.java | 11 +++--- .../security/x509/CertificateValidity.java | 13 +++---- .../sun/security/x509/CertificateVersion.java | 13 +++---- .../sun/security/x509/CertificateX509Key.java | 13 +++---- .../x509/DeltaCRLIndicatorExtension.java | 8 +++-- .../x509/ExtendedKeyUsageExtension.java | 8 ++--- .../classes/sun/security/x509/Extension.java | 28 +++++++++------ .../security/x509/FreshestCRLExtension.java | 6 ++-- .../x509/InhibitAnyPolicyExtension.java | 9 ++--- .../x509/InvalidityDateExtension.java | 11 +++--- .../x509/IssuerAlternativeNameExtension.java | 10 +++--- .../IssuingDistributionPointExtension.java | 10 +++--- .../sun/security/x509/KeyUsageExtension.java | 11 +++--- .../x509/NameConstraintsExtension.java | 10 +++--- .../x509/NetscapeCertTypeExtension.java | 9 ++--- .../x509/PolicyConstraintsExtension.java | 10 +++--- .../x509/PolicyMappingsExtension.java | 10 +++--- .../x509/PrivateKeyUsageExtension.java | 12 +++---- .../x509/SubjectAlternativeNameExtension.java | 10 +++--- .../x509/SubjectInfoAccessExtension.java | 8 ++--- .../x509/SubjectKeyIdentifierExtension.java | 10 +++--- .../sun/security/x509/X509CRLImpl.java | 2 +- .../sun/security/x509/X509CertImpl.java | 2 +- .../sun/security/x509/X509CertInfo.java | 14 ++++---- .../sun/security/pkcs/pkcs7/SignerOrder.java | 5 ++- .../security/pkcs/pkcs9/UnknownAttribute.java | 18 +++++----- .../tools/keytool/ExtOptionCamelCase.java | 10 +++--- .../util/asn1StringTypes/StringTypes.java | 4 +-- .../jdeps/jdkinternals/src/q/NoRepl.java | 6 ++-- 51 files changed, 210 insertions(+), 315 deletions(-) diff --git a/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java b/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java index 79eaee18862c6..f7a36b1571ad4 100644 --- a/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java +++ b/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java @@ -26,7 +26,6 @@ package sun.security.pkcs; import java.io.IOException; -import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Date; import sun.security.x509.CertificateExtensions; @@ -527,7 +526,7 @@ public PKCS9Attribute(DerValue derVal) throws IOException { * should be encoded as T61Strings. */ @Override - public void derEncode(OutputStream out) throws IOException { + public void derEncode(DerOutputStream out) throws IOException { DerOutputStream temp = new DerOutputStream(); temp.putOID(oid); switch (index) { @@ -648,11 +647,7 @@ public void derEncode(OutputStream out) throws IOException { default: // can't happen } - DerOutputStream derOut = new DerOutputStream(); - derOut.write(DerValue.tag_Sequence, temp.toByteArray()); - - out.write(derOut.toByteArray()); - + out.write(DerValue.tag_Sequence, temp.toByteArray()); } /** diff --git a/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java b/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java index 52b916b5bd639..4e965820fd47c 100644 --- a/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java +++ b/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java @@ -25,7 +25,6 @@ package sun.security.pkcs; -import java.io.OutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CertPathValidatorException; @@ -236,7 +235,7 @@ public void encode(DerOutputStream out) throws IOException { * * @exception IOException on encoding error. */ - public void derEncode(OutputStream out) throws IOException { + public void derEncode(DerOutputStream out) throws IOException { DerOutputStream seq = new DerOutputStream(); seq.putInteger(version); DerOutputStream issuerAndSerialNumber = new DerOutputStream(); @@ -258,10 +257,7 @@ public void derEncode(OutputStream out) throws IOException { if (unauthenticatedAttributes != null) unauthenticatedAttributes.encode((byte)0xA1, seq); - DerOutputStream tmp = new DerOutputStream(); - tmp.write(DerValue.tag_Sequence, seq); - - out.write(tmp.toByteArray()); + out.write(DerValue.tag_Sequence, seq); } /* diff --git a/src/java.base/share/classes/sun/security/pkcs10/PKCS10Attribute.java b/src/java.base/share/classes/sun/security/pkcs10/PKCS10Attribute.java index c7cac3baa259e..b80457f8eb6d4 100644 --- a/src/java.base/share/classes/sun/security/pkcs10/PKCS10Attribute.java +++ b/src/java.base/share/classes/sun/security/pkcs10/PKCS10Attribute.java @@ -25,7 +25,6 @@ package sun.security.pkcs10; -import java.io.OutputStream; import java.io.IOException; import sun.security.pkcs.PKCS9Attribute; @@ -108,7 +107,7 @@ public PKCS10Attribute(PKCS9Attribute attr) { * * @exception IOException on encoding errors. */ - public void derEncode(OutputStream out) throws IOException { + public void derEncode(DerOutputStream out) throws IOException { PKCS9Attribute attr = new PKCS9Attribute(attributeId, attributeValue); attr.derEncode(out); } diff --git a/src/java.base/share/classes/sun/security/pkcs10/PKCS10Attributes.java b/src/java.base/share/classes/sun/security/pkcs10/PKCS10Attributes.java index fefffaf67f7af..c4d3fea6b8a97 100644 --- a/src/java.base/share/classes/sun/security/pkcs10/PKCS10Attributes.java +++ b/src/java.base/share/classes/sun/security/pkcs10/PKCS10Attributes.java @@ -26,7 +26,6 @@ package sun.security.pkcs10; import java.io.IOException; -import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Collection; import java.util.Collections; @@ -92,7 +91,7 @@ public PKCS10Attributes(DerInputStream in) throws IOException { * @param out the OutputStream to marshal the contents to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { + public void encode(DerOutputStream out) throws IOException { derEncode(out); } @@ -103,17 +102,14 @@ public void encode(OutputStream out) throws IOException { * @param out the OutputStream to marshal the contents to. * @exception IOException on encoding errors. */ - public void derEncode(OutputStream out) throws IOException { + public void derEncode(DerOutputStream out) throws IOException { // first copy the elements into an array Collection allAttrs = map.values(); PKCS10Attribute[] attribs = allAttrs.toArray(new PKCS10Attribute[map.size()]); - DerOutputStream attrOut = new DerOutputStream(); - attrOut.putOrderedSetOf(DerValue.createTag(DerValue.TAG_CONTEXT, - true, (byte)0), - attribs); - out.write(attrOut.toByteArray()); + out.putOrderedSetOf( + DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0), attribs); } /** diff --git a/src/java.base/share/classes/sun/security/util/DerEncoder.java b/src/java.base/share/classes/sun/security/util/DerEncoder.java index fadad5fff1998..be418c1d1a715 100644 --- a/src/java.base/share/classes/sun/security/util/DerEncoder.java +++ b/src/java.base/share/classes/sun/security/util/DerEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -26,7 +26,6 @@ package sun.security.util; import java.io.IOException; -import java.io.OutputStream; /** * Interface to an object that knows how to write its own DER @@ -41,7 +40,7 @@ public interface DerEncoder { * * @param out the stream on which the DER encoding is written. */ - public void derEncode(OutputStream out) + public void derEncode(DerOutputStream out) throws IOException; } diff --git a/src/java.base/share/classes/sun/security/util/DerOutputStream.java b/src/java.base/share/classes/sun/security/util/DerOutputStream.java index d7e54a8c5f236..d77e00fbadbe1 100644 --- a/src/java.base/share/classes/sun/security/util/DerOutputStream.java +++ b/src/java.base/share/classes/sun/security/util/DerOutputStream.java @@ -26,7 +26,6 @@ package sun.security.util; import java.io.ByteArrayOutputStream; -import java.io.OutputStream; import java.io.IOException; import java.math.BigInteger; import java.nio.charset.Charset; @@ -583,7 +582,7 @@ public void putTag(byte tagClass, boolean form, byte val) { * * @exception IOException on output error. */ - public void derEncode(OutputStream out) throws IOException { + public void derEncode(DerOutputStream out) throws IOException { out.write(toByteArray()); } diff --git a/src/java.base/share/classes/sun/security/x509/AVA.java b/src/java.base/share/classes/sun/security/x509/AVA.java index 39d7469a38549..03b433a1fefa4 100644 --- a/src/java.base/share/classes/sun/security/x509/AVA.java +++ b/src/java.base/share/classes/sun/security/x509/AVA.java @@ -27,7 +27,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.OutputStream; import java.io.Reader; import java.text.Normalizer; import java.util.*; @@ -638,14 +637,12 @@ public void encode(DerOutputStream out) throws IOException { * * @exception IOException on encoding error. */ - public void derEncode(OutputStream out) throws IOException { + public void derEncode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); - DerOutputStream tmp2 = new DerOutputStream(); tmp.putOID(oid); value.encode(tmp); - tmp2.write(DerValue.tag_Sequence, tmp); - out.write(tmp2.toByteArray()); + out.write(DerValue.tag_Sequence, tmp); } private String toKeyword(int format, Map oidMap) { diff --git a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java index 627fb503ba9c4..db35da16f900f 100644 --- a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java +++ b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java @@ -164,9 +164,8 @@ public final void encode(DerOutputStream out) throws IOException { * @exception IOException on encoding error. */ @Override - public void derEncode (OutputStream out) throws IOException { + public void derEncode (DerOutputStream out) throws IOException { DerOutputStream bytes = new DerOutputStream(); - DerOutputStream tmp = new DerOutputStream(); bytes.putOID(algid); @@ -230,8 +229,7 @@ public void derEncode (OutputStream out) throws IOException { } else { bytes.write(encodedParams); } - tmp.write(DerValue.tag_Sequence, bytes); - out.write(tmp.toByteArray()); + out.write(DerValue.tag_Sequence, bytes); } diff --git a/src/java.base/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java b/src/java.base/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java index 69459fb6ef04b..259d0e3758512 100644 --- a/src/java.base/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java +++ b/src/java.base/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.*; @@ -149,15 +148,14 @@ public String getName() { * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (this.extensionValue == null) { this.extensionId = PKIXExtensions.AuthInfoAccess_Id; this.critical = false; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java b/src/java.base/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java index d3fb3cd5d9f68..0779cc2ffe452 100644 --- a/src/java.base/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java +++ b/src/java.base/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.Enumeration; import sun.security.util.*; @@ -215,18 +214,17 @@ public String toString() { /** * Write the extension to the OutputStream. * - * @param out the OutputStream to write the extension to. + * @param out the DerOutputStream to write the extension to. * @exception IOException on error. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (this.extensionValue == null) { extensionId = PKIXExtensions.AuthorityKey_Id; critical = false; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/BasicConstraintsExtension.java b/src/java.base/share/classes/sun/security/x509/BasicConstraintsExtension.java index 38abaf7cb39be..5d75334f738b1 100644 --- a/src/java.base/share/classes/sun/security/x509/BasicConstraintsExtension.java +++ b/src/java.base/share/classes/sun/security/x509/BasicConstraintsExtension.java @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.Enumeration; import sun.security.util.*; @@ -190,7 +189,8 @@ public String toString() { * * @param out the DerOutputStream to encode the extension to. */ - public void encode(OutputStream out) throws IOException { + @Override + public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { this.extensionId = PKIXExtensions.BasicConstraints_Id; @@ -201,9 +201,7 @@ public void encode(OutputStream out) throws IOException { } encodeThis(); } - super.encode(tmp); - - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/CRLDistributionPointsExtension.java b/src/java.base/share/classes/sun/security/x509/CRLDistributionPointsExtension.java index cb7f106e68592..294039e704413 100644 --- a/src/java.base/share/classes/sun/security/x509/CRLDistributionPointsExtension.java +++ b/src/java.base/share/classes/sun/security/x509/CRLDistributionPointsExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.*; import java.util.Collections; @@ -199,7 +198,8 @@ public String getName() { * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { + @Override + public void encode(DerOutputStream out) throws IOException { encode(out, PKIXExtensions.CRLDistributionPoints_Id, false); } @@ -207,17 +207,15 @@ public void encode(OutputStream out) throws IOException { * Write the extension to the DerOutputStream. * (Also called by the subclass) */ - protected void encode(OutputStream out, ObjectIdentifier extensionId, - boolean isCritical) throws IOException { + protected void encode(DerOutputStream out, ObjectIdentifier extensionId, + boolean isCritical) throws IOException { - DerOutputStream tmp = new DerOutputStream(); if (this.extensionValue == null) { this.extensionId = extensionId; this.critical = isCritical; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/CRLExtensions.java b/src/java.base/share/classes/sun/security/x509/CRLExtensions.java index 1f9c03a9f740c..228dd674bc837 100644 --- a/src/java.base/share/classes/sun/security/x509/CRLExtensions.java +++ b/src/java.base/share/classes/sun/security/x509/CRLExtensions.java @@ -30,7 +30,6 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.security.cert.CRLException; -import java.security.cert.CertificateException; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; @@ -145,16 +144,8 @@ public void encode(OutputStream out, boolean isExplicit) throws CRLException { try { DerOutputStream extOut = new DerOutputStream(); - Collection allExts = map.values(); - Object[] objs = allExts.toArray(); - - for (int i = 0; i < objs.length; i++) { - if (objs[i] instanceof CertAttrSet) - ((CertAttrSet)objs[i]).encode(extOut); - else if (objs[i] instanceof Extension) - ((Extension)objs[i]).encode(extOut); - else - throw new CRLException("Illegal extension object"); + for (Extension ext : map.values()) { + ext.encode(extOut); } DerOutputStream seq = new DerOutputStream(); @@ -170,8 +161,6 @@ else if (objs[i] instanceof Extension) out.write(tmp.toByteArray()); } catch (IOException e) { throw new CRLException("Encoding error: " + e.toString()); - } catch (CertificateException e) { - throw new CRLException("Encoding error: " + e.toString()); } } diff --git a/src/java.base/share/classes/sun/security/x509/CRLNumberExtension.java b/src/java.base/share/classes/sun/security/x509/CRLNumberExtension.java index 9434e613441ac..6b3f0eadf490f 100644 --- a/src/java.base/share/classes/sun/security/x509/CRLNumberExtension.java +++ b/src/java.base/share/classes/sun/security/x509/CRLNumberExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.math.BigInteger; import java.util.Enumeration; @@ -198,7 +197,8 @@ public String toString() { * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { + @Override + public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); encode(out, PKIXExtensions.CRLNumber_Id, true); } @@ -207,18 +207,15 @@ public void encode(OutputStream out) throws IOException { * Write the extension to the DerOutputStream. * (Also called by the subclass) */ - protected void encode(OutputStream out, ObjectIdentifier extensionId, - boolean isCritical) throws IOException { - - DerOutputStream tmp = new DerOutputStream(); + protected void encode(DerOutputStream out, ObjectIdentifier extensionId, + boolean isCritical) throws IOException { if (this.extensionValue == null) { this.extensionId = extensionId; this.critical = isCritical; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/CRLReasonCodeExtension.java b/src/java.base/share/classes/sun/security/x509/CRLReasonCodeExtension.java index d54c35b31beb6..f1d35959f74a4 100644 --- a/src/java.base/share/classes/sun/security/x509/CRLReasonCodeExtension.java +++ b/src/java.base/share/classes/sun/security/x509/CRLReasonCodeExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.security.cert.CRLReason; import java.util.Enumeration; @@ -158,16 +157,14 @@ public String toString() { * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); - + @Override + public void encode(DerOutputStream out) throws IOException { if (this.extensionValue == null) { this.extensionId = PKIXExtensions.ReasonCode_Id; this.critical = false; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/CertAttrSet.java b/src/java.base/share/classes/sun/security/x509/CertAttrSet.java index 8b5f5e6b6c757..2ee443735954b 100644 --- a/src/java.base/share/classes/sun/security/x509/CertAttrSet.java +++ b/src/java.base/share/classes/sun/security/x509/CertAttrSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,8 +25,9 @@ package sun.security.x509; +import sun.security.util.DerOutputStream; + import java.io.IOException; -import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Enumeration; @@ -58,12 +59,12 @@ public interface CertAttrSet { * Encodes the attribute to the output stream in a format * that can be parsed by the decode method. * - * @param out the OutputStream to encode the attribute to. + * @param out the DerOutputStream to encode the attribute to. * * @exception CertificateException on encoding or validity errors. * @exception IOException on other errors. */ - void encode(OutputStream out) + void encode(DerOutputStream out) throws CertificateException, IOException; /** diff --git a/src/java.base/share/classes/sun/security/x509/CertificateAlgorithmId.java b/src/java.base/share/classes/sun/security/x509/CertificateAlgorithmId.java index a7d6e2553e8a0..8b864c3d1bb13 100644 --- a/src/java.base/share/classes/sun/security/x509/CertificateAlgorithmId.java +++ b/src/java.base/share/classes/sun/security/x509/CertificateAlgorithmId.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -27,7 +27,6 @@ import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.util.Enumeration; import sun.security.util.*; @@ -105,11 +104,9 @@ public String toString() { * @param out the DerOutputStream to marshal the contents to. * @exception IOException on errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); - algId.encode(tmp); - - out.write(tmp.toByteArray()); + @Override + public void encode(DerOutputStream out) throws IOException { + algId.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/CertificateExtensions.java b/src/java.base/share/classes/sun/security/x509/CertificateExtensions.java index 4f8022b406710..55f8fdd7ac270 100644 --- a/src/java.base/share/classes/sun/security/x509/CertificateExtensions.java +++ b/src/java.base/share/classes/sun/security/x509/CertificateExtensions.java @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -152,8 +151,9 @@ private void parseExtension(Extension ext) throws IOException { * @exception CertificateException on encoding errors. * @exception IOException on errors. */ - public void encode(OutputStream out) - throws CertificateException, IOException { + @Override + public void encode(DerOutputStream out) + throws CertificateException, IOException { encode(out, false); } @@ -165,33 +165,21 @@ public void encode(OutputStream out) * @exception CertificateException on encoding errors. * @exception IOException on errors. */ - public void encode(OutputStream out, boolean isCertReq) + public void encode(DerOutputStream out, boolean isCertReq) throws CertificateException, IOException { DerOutputStream extOut = new DerOutputStream(); - Collection allExts = map.values(); - Object[] objs = allExts.toArray(); - - for (int i = 0; i < objs.length; i++) { - if (objs[i] instanceof CertAttrSet) - ((CertAttrSet)objs[i]).encode(extOut); - else if (objs[i] instanceof Extension) - ((Extension)objs[i]).encode(extOut); - else - throw new CertificateException("Illegal extension object"); + for (Extension ext : map.values()) { + ext.encode(extOut); } - DerOutputStream seq = new DerOutputStream(); - seq.write(DerValue.tag_Sequence, extOut); - - DerOutputStream tmp; if (!isCertReq) { // certificate - tmp = new DerOutputStream(); - tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)3), + DerOutputStream seq = new DerOutputStream(); + seq.write(DerValue.tag_Sequence, extOut); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)3), seq); - } else - tmp = seq; // pkcs#10 certificateRequest - - out.write(tmp.toByteArray()); + } else { + out.write(DerValue.tag_Sequence, extOut); + } } /** diff --git a/src/java.base/share/classes/sun/security/x509/CertificateIssuerExtension.java b/src/java.base/share/classes/sun/security/x509/CertificateIssuerExtension.java index 0dd8f39642a3b..31bd4506e1714 100644 --- a/src/java.base/share/classes/sun/security/x509/CertificateIssuerExtension.java +++ b/src/java.base/share/classes/sun/security/x509/CertificateIssuerExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,7 +25,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.Enumeration; import sun.security.util.DerValue; @@ -176,18 +175,17 @@ public String toString() { /** * Write the extension to the OutputStream. * - * @param out the OutputStream to write the extension to + * @param out the DerOutputStream to write the extension to * @exception IOException on encoding errors */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (extensionValue == null) { extensionId = PKIXExtensions.CertificateIssuer_Id; critical = true; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/CertificateIssuerName.java b/src/java.base/share/classes/sun/security/x509/CertificateIssuerName.java index 9c82d215e6f62..8d3e9a2370593 100644 --- a/src/java.base/share/classes/sun/security/x509/CertificateIssuerName.java +++ b/src/java.base/share/classes/sun/security/x509/CertificateIssuerName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -27,7 +27,6 @@ import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.util.Enumeration; import javax.security.auth.x500.X500Principal; @@ -107,11 +106,9 @@ public String toString() { * @param out the DerOutputStream to marshal the contents to. * @exception IOException on errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); - dnName.encode(tmp); - - out.write(tmp.toByteArray()); + @Override + public void encode(DerOutputStream out) throws IOException { + dnName.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/CertificatePoliciesExtension.java b/src/java.base/share/classes/sun/security/x509/CertificatePoliciesExtension.java index c2f71b3abc820..2ae2f8b5dd89e 100644 --- a/src/java.base/share/classes/sun/security/x509/CertificatePoliciesExtension.java +++ b/src/java.base/share/classes/sun/security/x509/CertificatePoliciesExtension.java @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.*; import sun.security.util.DerValue; @@ -177,15 +176,14 @@ public String toString() { * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (extensionValue == null) { extensionId = PKIXExtensions.CertificatePolicies_Id; critical = false; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/CertificateSerialNumber.java b/src/java.base/share/classes/sun/security/x509/CertificateSerialNumber.java index 18bfb090960f7..38d2bf2541e28 100644 --- a/src/java.base/share/classes/sun/security/x509/CertificateSerialNumber.java +++ b/src/java.base/share/classes/sun/security/x509/CertificateSerialNumber.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -26,7 +26,6 @@ import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.math.BigInteger; import java.util.Enumeration; import java.util.Random; @@ -117,11 +116,9 @@ public String toString() { * @param out the DerOutputStream to marshal the contents to. * @exception IOException on errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); - serial.encode(tmp); - - out.write(tmp.toByteArray()); + @Override + public void encode(DerOutputStream out) throws IOException { + serial.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/CertificateSubjectName.java b/src/java.base/share/classes/sun/security/x509/CertificateSubjectName.java index 81d344c7dcade..bb5ba5eb98c10 100644 --- a/src/java.base/share/classes/sun/security/x509/CertificateSubjectName.java +++ b/src/java.base/share/classes/sun/security/x509/CertificateSubjectName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -27,7 +27,6 @@ import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.util.Enumeration; import javax.security.auth.x500.X500Principal; @@ -107,11 +106,9 @@ public String toString() { * @param out the DerOutputStream to marshal the contents to. * @exception IOException on errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); - dnName.encode(tmp); - - out.write(tmp.toByteArray()); + @Override + public void encode(DerOutputStream out) throws IOException { + dnName.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/CertificateValidity.java b/src/java.base/share/classes/sun/security/x509/CertificateValidity.java index a5cff7d4bfa55..2b2b7021691c1 100644 --- a/src/java.base/share/classes/sun/security/x509/CertificateValidity.java +++ b/src/java.base/share/classes/sun/security/x509/CertificateValidity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,7 +25,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.security.cert.*; import java.util.Date; import java.util.Enumeration; @@ -144,10 +143,11 @@ public String toString() { /** * Encode the CertificateValidity period in DER form to the stream. * - * @param out the OutputStream to marshal the contents to. + * @param out the DerOutputStream to marshal the contents to. * @exception IOException on errors. */ - public void encode(OutputStream out) throws IOException { + @Override + public void encode(DerOutputStream out) throws IOException { // in cases where default constructor is used check for // null values @@ -167,10 +167,7 @@ public void encode(OutputStream out) throws IOException { } else { pair.putGeneralizedTime(notAfter); } - DerOutputStream seq = new DerOutputStream(); - seq.write(DerValue.tag_Sequence, pair); - - out.write(seq.toByteArray()); + out.write(DerValue.tag_Sequence, pair); } /** diff --git a/src/java.base/share/classes/sun/security/x509/CertificateVersion.java b/src/java.base/share/classes/sun/security/x509/CertificateVersion.java index 7d3cb61e03725..e47dd5b20e5d1 100644 --- a/src/java.base/share/classes/sun/security/x509/CertificateVersion.java +++ b/src/java.base/share/classes/sun/security/x509/CertificateVersion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -27,7 +27,6 @@ import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.util.Enumeration; import sun.security.util.*; @@ -155,10 +154,11 @@ public String toString() { /** * Encode the CertificateVersion period in DER form to the stream. * - * @param out the OutputStream to marshal the contents to. + * @param out the DerOutputStream to marshal the contents to. * @exception IOException on errors. */ - public void encode(OutputStream out) throws IOException { + @Override + public void encode(DerOutputStream out) throws IOException { // Nothing for default if (version == V1) { return; @@ -166,11 +166,8 @@ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); tmp.putInteger(version); - DerOutputStream seq = new DerOutputStream(); - seq.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0), + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0), tmp); - - out.write(seq.toByteArray()); } /** diff --git a/src/java.base/share/classes/sun/security/x509/CertificateX509Key.java b/src/java.base/share/classes/sun/security/x509/CertificateX509Key.java index d78d618a5badb..cab22763dcf25 100644 --- a/src/java.base/share/classes/sun/security/x509/CertificateX509Key.java +++ b/src/java.base/share/classes/sun/security/x509/CertificateX509Key.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -28,7 +28,6 @@ import java.security.PublicKey; import java.io.InputStream; import java.io.IOException; -import java.io.OutputStream; import java.util.Enumeration; import sun.security.util.*; @@ -97,14 +96,12 @@ public String toString() { /** * Encode the key in DER form to the stream. * - * @param out the OutputStream to marshal the contents to. + * @param out the DerOutputStream to marshal the contents to. * @exception IOException on errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); - tmp.write(key.getEncoded()); - - out.write(tmp.toByteArray()); + @Override + public void encode(DerOutputStream out) throws IOException { + out.write(key.getEncoded()); } /** diff --git a/src/java.base/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java b/src/java.base/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java index 10b5a9dc09e95..d16ff142a3d53 100644 --- a/src/java.base/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java +++ b/src/java.base/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -25,8 +25,9 @@ package sun.security.x509; +import sun.security.util.DerOutputStream; + import java.io.IOException; -import java.io.OutputStream; import java.math.BigInteger; import java.util.Enumeration; @@ -109,7 +110,8 @@ public DeltaCRLIndicatorExtension(Boolean critical, Object value) * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { + @Override + public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); super.encode(out, PKIXExtensions.DeltaCRLIndicator_Id, true); } diff --git a/src/java.base/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java b/src/java.base/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java index 55842ed13f5c2..329bc80365674 100644 --- a/src/java.base/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java +++ b/src/java.base/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; @@ -197,15 +196,14 @@ public String toString() { * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (extensionValue == null) { extensionId = PKIXExtensions.ExtendedKeyUsage_Id; critical = false; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/Extension.java b/src/java.base/share/classes/sun/security/x509/Extension.java index 5649d2a12066e..0dd040306af15 100644 --- a/src/java.base/share/classes/sun/security/x509/Extension.java +++ b/src/java.base/share/classes/sun/security/x509/Extension.java @@ -141,22 +141,28 @@ public static Extension newExtension(ObjectIdentifier extensionId, return ext; } - public void encode(OutputStream out) throws IOException { + /** + * Implementing {@link java.security.cert.Extension#encode(OutputStream)}. + * This implementation is made final to make sure all {@code encode()} + * methods in child classes are actually implementations of + * {@link #encode(DerOutputStream)} below. + * + * @param out the output stream + * @throws IOException + */ + @Override + public final void encode(OutputStream out) throws IOException { if (out == null) { throw new NullPointerException(); } - DerOutputStream dos1 = new DerOutputStream(); - DerOutputStream dos2 = new DerOutputStream(); - - dos1.putOID(extensionId); - if (critical) { - dos1.putBoolean(critical); + if (out instanceof DerOutputStream dos) { + encode(dos); + } else { + DerOutputStream dos = new DerOutputStream(); + encode(dos); + out.write(dos.toByteArray()); } - dos1.putOctetString(extensionValue); - - dos2.write(DerValue.tag_Sequence, dos1); - out.write(dos2.toByteArray()); } /** diff --git a/src/java.base/share/classes/sun/security/x509/FreshestCRLExtension.java b/src/java.base/share/classes/sun/security/x509/FreshestCRLExtension.java index 84dcb284cab03..3d2be346fcd96 100644 --- a/src/java.base/share/classes/sun/security/x509/FreshestCRLExtension.java +++ b/src/java.base/share/classes/sun/security/x509/FreshestCRLExtension.java @@ -25,8 +25,9 @@ package sun.security.x509; +import sun.security.util.DerOutputStream; + import java.io.IOException; -import java.io.OutputStream; import java.math.BigInteger; import java.util.Enumeration; import java.util.List; @@ -93,7 +94,8 @@ public FreshestCRLExtension(Boolean critical, Object value) * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { + @Override + public void encode(DerOutputStream out) throws IOException { super.encode(out, PKIXExtensions.FreshestCRL_Id, false); } } diff --git a/src/java.base/share/classes/sun/security/x509/InhibitAnyPolicyExtension.java b/src/java.base/share/classes/sun/security/x509/InhibitAnyPolicyExtension.java index 6fa2ae16729fd..381c63702d94b 100644 --- a/src/java.base/share/classes/sun/security/x509/InhibitAnyPolicyExtension.java +++ b/src/java.base/share/classes/sun/security/x509/InhibitAnyPolicyExtension.java @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.Enumeration; import sun.security.util.*; @@ -160,16 +159,14 @@ public String toString() { * * @param out the DerOutputStream to encode the extension to. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (extensionValue == null) { this.extensionId = PKIXExtensions.InhibitAnyPolicy_Id; critical = true; encodeThis(); } - super.encode(tmp); - - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/InvalidityDateExtension.java b/src/java.base/share/classes/sun/security/x509/InvalidityDateExtension.java index 7fac65f3ee592..e4e48563e5f68 100644 --- a/src/java.base/share/classes/sun/security/x509/InvalidityDateExtension.java +++ b/src/java.base/share/classes/sun/security/x509/InvalidityDateExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.Date; import java.util.Enumeration; @@ -177,16 +176,14 @@ public String toString() { * @param out the DerOutputStream to write the extension to * @exception IOException on encoding errors */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); - + @Override + public void encode(DerOutputStream out) throws IOException { if (this.extensionValue == null) { this.extensionId = PKIXExtensions.InvalidityDate_Id; this.critical = false; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/IssuerAlternativeNameExtension.java b/src/java.base/share/classes/sun/security/x509/IssuerAlternativeNameExtension.java index da7dde9a9b8dc..7ace854df0dd1 100644 --- a/src/java.base/share/classes/sun/security/x509/IssuerAlternativeNameExtension.java +++ b/src/java.base/share/classes/sun/security/x509/IssuerAlternativeNameExtension.java @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.Enumeration; import sun.security.util.*; @@ -159,18 +158,17 @@ public String toString() { /** * Write the extension to the OutputStream. * - * @param out the OutputStream to write the extension to. + * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding error. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (extensionValue == null) { extensionId = PKIXExtensions.IssuerAlternativeName_Id; critical = false; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/IssuingDistributionPointExtension.java b/src/java.base/share/classes/sun/security/x509/IssuingDistributionPointExtension.java index bc0df11a8a231..9f8a6b1b5b86d 100644 --- a/src/java.base/share/classes/sun/security/x509/IssuingDistributionPointExtension.java +++ b/src/java.base/share/classes/sun/security/x509/IssuingDistributionPointExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.*; @@ -234,15 +233,14 @@ public String getName() { * @param out the output stream. * @exception IOException on encoding error. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (this.extensionValue == null) { this.extensionId = PKIXExtensions.IssuingDistributionPoint_Id; this.critical = false; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/KeyUsageExtension.java b/src/java.base/share/classes/sun/security/x509/KeyUsageExtension.java index f02d8eeb636cd..69235647e13d7 100644 --- a/src/java.base/share/classes/sun/security/x509/KeyUsageExtension.java +++ b/src/java.base/share/classes/sun/security/x509/KeyUsageExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.Enumeration; import sun.security.util.*; @@ -318,16 +317,14 @@ public String toString() { * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); - + @Override + public void encode(DerOutputStream out) throws IOException { if (this.extensionValue == null) { this.extensionId = PKIXExtensions.KeyUsage_Id; this.critical = true; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/NameConstraintsExtension.java b/src/java.base/share/classes/sun/security/x509/NameConstraintsExtension.java index e595fbd68111b..ae4d0cc1565fe 100644 --- a/src/java.base/share/classes/sun/security/x509/NameConstraintsExtension.java +++ b/src/java.base/share/classes/sun/security/x509/NameConstraintsExtension.java @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.*; @@ -233,18 +232,17 @@ public String toString() { /** * Write the extension to the OutputStream. * - * @param out the OutputStream to write the extension to. + * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (this.extensionValue == null) { this.extensionId = PKIXExtensions.NameConstraints_Id; this.critical = true; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java b/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java index d455f00f8a8fd..2c297aee92721 100644 --- a/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java +++ b/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.*; import sun.security.util.*; @@ -264,16 +263,14 @@ public String toString() { * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); - + @Override + public void encode(DerOutputStream out) throws IOException { if (this.extensionValue == null) { this.extensionId = NetscapeCertType_Id; this.critical = true; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java b/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java index eca45828aa638..a02c13581e314 100644 --- a/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java +++ b/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.Enumeration; import sun.security.util.*; @@ -201,15 +200,14 @@ public String toString() { * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (extensionValue == null) { extensionId = PKIXExtensions.PolicyConstraints_Id; critical = true; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/PolicyMappingsExtension.java b/src/java.base/share/classes/sun/security/x509/PolicyMappingsExtension.java index ed931a2119bc0..31b4ade1b63d1 100644 --- a/src/java.base/share/classes/sun/security/x509/PolicyMappingsExtension.java +++ b/src/java.base/share/classes/sun/security/x509/PolicyMappingsExtension.java @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.*; import sun.security.util.*; @@ -146,18 +145,17 @@ public String toString() { /** * Write the extension to the OutputStream. * - * @param out the OutputStream to write the extension to. + * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (extensionValue == null) { extensionId = PKIXExtensions.PolicyMappings_Id; critical = true; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/PrivateKeyUsageExtension.java b/src/java.base/share/classes/sun/security/x509/PrivateKeyUsageExtension.java index b4cc22e789ddf..cbfa5b8cb445f 100644 --- a/src/java.base/share/classes/sun/security/x509/PrivateKeyUsageExtension.java +++ b/src/java.base/share/classes/sun/security/x509/PrivateKeyUsageExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.security.cert.CertificateException; import java.security.cert.CertificateParsingException; import java.security.cert.CertificateExpiredException; @@ -237,18 +236,17 @@ public void valid(Date now) /** * Write the extension to the OutputStream. * - * @param out the OutputStream to write the extension to. + * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (extensionValue == null) { extensionId = PKIXExtensions.PrivateKeyUsage_Id; critical = false; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/SubjectAlternativeNameExtension.java b/src/java.base/share/classes/sun/security/x509/SubjectAlternativeNameExtension.java index 95eb67e0dd127..7e9487f372a36 100644 --- a/src/java.base/share/classes/sun/security/x509/SubjectAlternativeNameExtension.java +++ b/src/java.base/share/classes/sun/security/x509/SubjectAlternativeNameExtension.java @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.Enumeration; import sun.security.util.*; @@ -161,18 +160,17 @@ public String toString() { /** * Write the extension to the OutputStream. * - * @param out the OutputStream to write the extension to. + * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (extensionValue == null) { extensionId = PKIXExtensions.SubjectAlternativeName_Id; critical = false; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/SubjectInfoAccessExtension.java b/src/java.base/share/classes/sun/security/x509/SubjectInfoAccessExtension.java index 0acdf96057f84..f04fd9432f278 100644 --- a/src/java.base/share/classes/sun/security/x509/SubjectInfoAccessExtension.java +++ b/src/java.base/share/classes/sun/security/x509/SubjectInfoAccessExtension.java @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.Collections; import java.util.*; @@ -154,15 +153,14 @@ public String getName() { * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (this.extensionValue == null) { this.extensionId = PKIXExtensions.SubjectInfoAccess_Id; this.critical = false; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/SubjectKeyIdentifierExtension.java b/src/java.base/share/classes/sun/security/x509/SubjectKeyIdentifierExtension.java index b3dd2132407e9..cc9f1d121b118 100644 --- a/src/java.base/share/classes/sun/security/x509/SubjectKeyIdentifierExtension.java +++ b/src/java.base/share/classes/sun/security/x509/SubjectKeyIdentifierExtension.java @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.util.Enumeration; import sun.security.util.*; @@ -122,18 +121,17 @@ public String toString() { /** * Write the extension to the OutputStream. * - * @param out the OutputStream to write the extension to. + * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ - public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); + @Override + public void encode(DerOutputStream out) throws IOException { if (extensionValue == null) { extensionId = PKIXExtensions.SubjectKey_Id; critical = false; encodeThis(); } - super.encode(tmp); - out.write(tmp.toByteArray()); + super.encode(out); } /** diff --git a/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java b/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java index 1523cde227d38..e9c0e434c97d6 100644 --- a/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java +++ b/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java @@ -1260,7 +1260,7 @@ private X500Principal getCertIssuer(X509CRLEntryImpl entry, } @Override - public void derEncode(OutputStream out) throws IOException { + public void derEncode(DerOutputStream out) throws IOException { if (signedCRL == null) throw new IOException("Null CRL to encode"); out.write(signedCRL.clone()); diff --git a/src/java.base/share/classes/sun/security/x509/X509CertImpl.java b/src/java.base/share/classes/sun/security/x509/X509CertImpl.java index 5a296bf9494f5..e6ab259d7ff32 100644 --- a/src/java.base/share/classes/sun/security/x509/X509CertImpl.java +++ b/src/java.base/share/classes/sun/security/x509/X509CertImpl.java @@ -332,7 +332,7 @@ public void encode(OutputStream out) * * @exception IOException on encoding error. */ - public void derEncode(OutputStream out) throws IOException { + public void derEncode(DerOutputStream out) throws IOException { if (signedCert == null) throw new IOException("Null certificate to encode"); out.write(signedCert.clone()); diff --git a/src/java.base/share/classes/sun/security/x509/X509CertInfo.java b/src/java.base/share/classes/sun/security/x509/X509CertInfo.java index 5fbc9a08f54fe..d169617a2f401 100644 --- a/src/java.base/share/classes/sun/security/x509/X509CertInfo.java +++ b/src/java.base/share/classes/sun/security/x509/X509CertInfo.java @@ -26,7 +26,6 @@ package sun.security.x509; import java.io.IOException; -import java.io.OutputStream; import java.security.cert.*; import java.util.*; @@ -179,14 +178,15 @@ public X509CertInfo(DerValue derVal) throws CertificateParsingException { * @exception CertificateException on encoding errors. * @exception IOException on other errors. */ - public void encode(OutputStream out) - throws CertificateException, IOException { + @Override + public void encode(DerOutputStream out) + throws CertificateException, IOException { if (rawCertInfo == null) { - DerOutputStream tmp = new DerOutputStream(); - emit(tmp); - rawCertInfo = tmp.toByteArray(); + emit(out); + rawCertInfo = out.toByteArray(); + } else { + out.write(rawCertInfo.clone()); } - out.write(rawCertInfo.clone()); } /** diff --git a/test/jdk/sun/security/pkcs/pkcs7/SignerOrder.java b/test/jdk/sun/security/pkcs/pkcs7/SignerOrder.java index 37db7fe4e8f76..7ce01c0813ec7 100644 --- a/test/jdk/sun/security/pkcs/pkcs7/SignerOrder.java +++ b/test/jdk/sun/security/pkcs/pkcs7/SignerOrder.java @@ -32,7 +32,6 @@ * @run main SignerOrder default 1024 * @run main SignerOrder Sha256 2048 */ -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.KeyPair; @@ -117,7 +116,7 @@ public static void main(String[] args) throws Exception { } static void printSignerInfos(SignerInfo signerInfo) throws IOException { - ByteArrayOutputStream strm = new ByteArrayOutputStream(); + DerOutputStream strm = new DerOutputStream(); signerInfo.derEncode(strm); System.out.println("SignerInfo, length: " + strm.toByteArray().length); @@ -127,7 +126,7 @@ static void printSignerInfos(SignerInfo signerInfo) throws IOException { } static void printSignerInfos(SignerInfo[] signerInfos) throws IOException { - ByteArrayOutputStream strm = new ByteArrayOutputStream(); + DerOutputStream strm = new DerOutputStream(); for (int i = 0; i < signerInfos.length; i++) { signerInfos[i].derEncode(strm); System.out.println("SignerInfo[" + i + "], length: " diff --git a/test/jdk/sun/security/pkcs/pkcs9/UnknownAttribute.java b/test/jdk/sun/security/pkcs/pkcs9/UnknownAttribute.java index 333550d2ace9d..3a3ba5e908297 100644 --- a/test/jdk/sun/security/pkcs/pkcs9/UnknownAttribute.java +++ b/test/jdk/sun/security/pkcs/pkcs9/UnknownAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -30,10 +30,10 @@ * java.base/sun.security.util */ -import java.io.*; import java.util.Arrays; import sun.security.pkcs.PKCS9Attribute; +import sun.security.util.DerOutputStream; import sun.security.util.DerValue; import sun.security.util.ObjectIdentifier; import jdk.test.lib.hexdump.HexPrinter; @@ -57,10 +57,10 @@ public static void main(String[] args) throws Exception { if (p2.isKnown()) { throw new Exception(); } - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - p2.derEncode(bout); - HexPrinter.simple().dest(System.err).format(bout.toByteArray()); - if (!Arrays.equals(data, bout.toByteArray())) { + DerOutputStream dout = new DerOutputStream(); + p2.derEncode(dout); + HexPrinter.simple().dest(System.err).format(dout.toByteArray()); + if (!Arrays.equals(data, dout.toByteArray())) { throw new Exception(); } // Unknown attr from value @@ -75,9 +75,9 @@ public static void main(String[] args) throws Exception { if (p3.isKnown()) { throw new Exception(); } - bout = new ByteArrayOutputStream(); - p3.derEncode(bout); - if (!Arrays.equals(data, bout.toByteArray())) { + dout = new DerOutputStream(); + p3.derEncode(dout); + if (!Arrays.equals(data, dout.toByteArray())) { throw new Exception(); } } diff --git a/test/jdk/sun/security/tools/keytool/ExtOptionCamelCase.java b/test/jdk/sun/security/tools/keytool/ExtOptionCamelCase.java index c14b019d798d8..5e3c7bd80c765 100644 --- a/test/jdk/sun/security/tools/keytool/ExtOptionCamelCase.java +++ b/test/jdk/sun/security/tools/keytool/ExtOptionCamelCase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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,6 +34,7 @@ */ import sun.security.tools.keytool.Main; +import sun.security.util.DerOutputStream; import sun.security.util.DerValue; import sun.security.x509.BasicConstraintsExtension; import sun.security.x509.CertificateExtensions; @@ -41,7 +42,6 @@ import sun.security.x509.KeyIdentifier; import sun.security.x509.KeyUsageExtension; -import java.io.ByteArrayOutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -203,9 +203,9 @@ static void testCreate(String option, Class clazz, // ATTENTION: the extensions created above might contain raw // extensions (not of a subtype) and we need to store and reload // it to resolve them to subtypes. - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - exts.encode(bout); - exts = new CertificateExtensions(new DerValue(bout.toByteArray()).data); + DerOutputStream dout = new DerOutputStream(); + exts.encode(dout); + exts = new CertificateExtensions(new DerValue(dout.toByteArray()).data); if (clazz == null) { throw new Exception("Should fail"); diff --git a/test/jdk/sun/security/util/asn1StringTypes/StringTypes.java b/test/jdk/sun/security/util/asn1StringTypes/StringTypes.java index be067a89fdb1a..ed74f89a0ca5e 100644 --- a/test/jdk/sun/security/util/asn1StringTypes/StringTypes.java +++ b/test/jdk/sun/security/util/asn1StringTypes/StringTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -63,7 +63,7 @@ public static void main(String[] args) throws Exception { derOut.putT61String(s); derOut.putBMPString(s); - derOut.derEncode(fout); + fout.write(derOut.toByteArray()); fout.close(); FileInputStream fis = new FileInputStream(fileName); diff --git a/test/langtools/tools/jdeps/jdkinternals/src/q/NoRepl.java b/test/langtools/tools/jdeps/jdkinternals/src/q/NoRepl.java index 16731f55b26af..6fa175193a0f5 100644 --- a/test/langtools/tools/jdeps/jdkinternals/src/q/NoRepl.java +++ b/test/langtools/tools/jdeps/jdkinternals/src/q/NoRepl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -24,11 +24,11 @@ package q; import java.io.IOException; -import java.io.OutputStream; import sun.security.util.DerEncoder; +import sun.security.util.DerOutputStream; public class NoRepl implements DerEncoder { - public void derEncode(OutputStream out) throws IOException { + public void derEncode(DerOutputStream out) throws IOException { throw new IOException(); } } From 04a1b0d3a69f42c8fb3541ec58ea08dcc3fcc8d0 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:15:07 +0000 Subject: [PATCH 014/846] 8297173: usageTicks and totalTicks should be volatile to ensure that different threads get the latest ticks Backport-of: dd18d76b4c1dfa79707634bcd4df4f8e7cfb8b70 --- .../com/sun/management/internal/OperatingSystemImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jdk.management/unix/classes/com/sun/management/internal/OperatingSystemImpl.java b/src/jdk.management/unix/classes/com/sun/management/internal/OperatingSystemImpl.java index 85e9aa9f119c5..795d662b9af0e 100644 --- a/src/jdk.management/unix/classes/com/sun/management/internal/OperatingSystemImpl.java +++ b/src/jdk.management/unix/classes/com/sun/management/internal/OperatingSystemImpl.java @@ -49,8 +49,8 @@ class OperatingSystemImpl extends BaseOperatingSystemImpl private ContainerCpuTicks processLoadTicks = new ProcessCpuTicks(); private abstract class ContainerCpuTicks { - private long usageTicks = 0; - private long totalTicks = 0; + private volatile long usageTicks; + private volatile long totalTicks; private double getUsageDividesTotal(long usageTicks, long totalTicks) { // If cpu quota or cpu shares are in effect. Calculate the cpu load From 4c124374ee5a2498af7c9cfa283d46bbe0aa5129 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:16:32 +0000 Subject: [PATCH 015/846] 8298147: Clang warns about pointless comparisons Backport-of: 1c2a093988c69ae0b2c0030835d11469fa9fb852 --- .../os/linux/cgroupV1Subsystem_linux.cpp | 3 --- .../os/linux/cgroupV2Subsystem_linux.cpp | 24 ------------------- 2 files changed, 27 deletions(-) diff --git a/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp index e380319e78980..2f72bcc9c3d0a 100644 --- a/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp @@ -287,9 +287,6 @@ int CgroupV1Subsystem::cpu_shares() { char* CgroupV1Subsystem::pids_max_val() { GET_CONTAINER_INFO_CPTR(cptr, _pids, "/pids.max", "Maximum number of tasks is: %s", "%s %*d", pidsmax, 1024); - if (pidsmax == NULL) { - return NULL; - } return os::strdup(pidsmax); } diff --git a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp index 2456385af7abd..eb90714f57f84 100644 --- a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp @@ -92,27 +92,18 @@ int CgroupV2Subsystem::cpu_quota() { char * CgroupV2Subsystem::cpu_cpuset_cpus() { GET_CONTAINER_INFO_CPTR(cptr, _unified, "/cpuset.cpus", "cpuset.cpus is: %s", "%1023s", cpus, 1024); - if (cpus == NULL) { - return NULL; - } return os::strdup(cpus); } char* CgroupV2Subsystem::cpu_quota_val() { GET_CONTAINER_INFO_CPTR(cptr, _unified, "/cpu.max", "Raw value for CPU quota is: %s", "%s %*d", quota, 1024); - if (quota == NULL) { - return NULL; - } return os::strdup(quota); } char * CgroupV2Subsystem::cpu_cpuset_memory_nodes() { GET_CONTAINER_INFO_CPTR(cptr, _unified, "/cpuset.mems", "cpuset.mems is: %s", "%1023s", mems, 1024); - if (mems == NULL) { - return NULL; - } return os::strdup(mems); } @@ -151,9 +142,6 @@ jlong CgroupV2Subsystem::memory_max_usage_in_bytes() { char* CgroupV2Subsystem::mem_soft_limit_val() { GET_CONTAINER_INFO_CPTR(cptr, _unified, "/memory.low", "Memory Soft Limit is: %s", "%s", mem_soft_limit_str, 1024); - if (mem_soft_limit_str == NULL) { - return NULL; - } return os::strdup(mem_soft_limit_str); } @@ -176,9 +164,6 @@ jlong CgroupV2Subsystem::memory_and_swap_limit_in_bytes() { char* CgroupV2Subsystem::mem_swp_limit_val() { GET_CONTAINER_INFO_CPTR(cptr, _unified, "/memory.swap.max", "Memory and Swap Limit is: %s", "%s", mem_swp_limit_str, 1024); - if (mem_swp_limit_str == NULL) { - return NULL; - } return os::strdup(mem_swp_limit_str); } @@ -186,9 +171,6 @@ char* CgroupV2Subsystem::mem_swp_limit_val() { char* CgroupV2Subsystem::mem_swp_current_val() { GET_CONTAINER_INFO_CPTR(cptr, _unified, "/memory.swap.current", "Swap currently used is: %s", "%s", mem_swp_current_str, 1024); - if (mem_swp_current_str == NULL) { - return NULL; - } return os::strdup(mem_swp_current_str); } @@ -216,9 +198,6 @@ jlong CgroupV2Subsystem::read_memory_limit_in_bytes() { char* CgroupV2Subsystem::mem_limit_val() { GET_CONTAINER_INFO_CPTR(cptr, _unified, "/memory.max", "Raw value for memory limit is: %s", "%s", mem_limit_str, 1024); - if (mem_limit_str == NULL) { - return NULL; - } return os::strdup(mem_limit_str); } @@ -245,9 +224,6 @@ char* CgroupV2Controller::construct_path(char* mount_path, char *cgroup_path) { char* CgroupV2Subsystem::pids_max_val() { GET_CONTAINER_INFO_CPTR(cptr, _unified, "/pids.max", "Maximum number of tasks is: %s", "%s %*d", pidsmax, 1024); - if (pidsmax == NULL) { - return NULL; - } return os::strdup(pidsmax); } From 09354055ccee652ce01c569849eb962634e4ec0c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:18:03 +0000 Subject: [PATCH 016/846] 8218474: JComboBox display issue with GTKLookAndFeel Backport-of: c4449224bbb70d1a0256ebf19297450ab0f98d4b --- .../java/swing/plaf/gtk/GTKLookAndFeel.java | 1 + .../swing/plaf/synth/SynthComboBoxUI.java | 28 ++++ .../native/libawt_xawt/awt/gtk3_interface.c | 2 +- .../TestComboBoxComponentRendering.java | 151 ++++++++++++++++++ .../swing/JComboBox/TestComboBoxHeight.java | 2 +- 5 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 test/jdk/javax/swing/JComboBox/TestComboBoxComponentRendering.java diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java index 40d713123c734..62c7a07d047b8 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java @@ -577,6 +577,7 @@ public Object createValue(UIDefaults table) { }), "ComboBox.font", new FontLazyValue(Region.COMBO_BOX), "ComboBox.isEnterSelectablePopup", Boolean.TRUE, + "ComboBox.squareButton", Boolean.FALSE, "EditorPane.caretForeground", caretColor, diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java index a4b389d4b6a6a..3f6e091afd64c 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java @@ -357,6 +357,34 @@ public void update(Graphics g, JComponent c) { paint(context, g); } + /** + * The minimum size is the size of the display area plus insets plus the button. + */ + @Override + public Dimension getMinimumSize( JComponent c ) { + if ( !isMinimumSizeDirty ) { + return new Dimension(cachedMinimumSize); + } + Dimension size = getDisplaySize(); + Insets insets = getInsets(); + Insets arrowInsets = arrowButton.getInsets(); + //calculate the width and height of the button + int buttonHeight = size.height; + int buttonWidth = squareButton ? + buttonHeight : + arrowButton.getPreferredSize().width; + //adjust the size based on the button width + size.height += insets.top + insets.bottom + arrowInsets.top + + arrowInsets.bottom; + size.width += insets.left + insets.right + arrowInsets.left + + arrowInsets.right + buttonWidth; + + cachedMinimumSize.setSize( size.width, size.height ); + isMinimumSizeDirty = false; + + return new Dimension(size); + } + /** * Paints the specified component according to the Look and Feel. *

This method is not used by Synth Look and Feel. diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c index 112b1b28f5777..3573ac82464ef 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c +++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c @@ -1525,7 +1525,7 @@ static void gtk3_paint_arrow(WidgetType widget_type, GtkStateType state_type, break; case COMBO_BOX_ARROW_BUTTON: - s = (int)(0.3 * height + 0.5) + 1; + s = (int)(0.3 * MIN(height, width) + 0.5) + 1; a = G_PI; break; diff --git a/test/jdk/javax/swing/JComboBox/TestComboBoxComponentRendering.java b/test/jdk/javax/swing/JComboBox/TestComboBoxComponentRendering.java new file mode 100644 index 0000000000000..0e176a911a39c --- /dev/null +++ b/test/jdk/javax/swing/JComboBox/TestComboBoxComponentRendering.java @@ -0,0 +1,151 @@ +/* + * 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 8218474 + * @key headful + * @requires (os.family == "linux") + * @summary Verifies if combobox components are rendered correctly. + * @run main TestComboBoxComponentRendering + */ + +import java.awt.Color; +import java.awt.Component; +import java.awt.image.BufferedImage; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.io.File; +import javax.imageio.ImageIO; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.ListCellRenderer; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +public class TestComboBoxComponentRendering { + private static JFrame frame; + private static JComboBox cb; + private static Robot robot; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + robot.setAutoDelay(100); + + for (UIManager.LookAndFeelInfo laf : + UIManager.getInstalledLookAndFeels()) { + if (!laf.getClassName().contains("MotifLookAndFeel") && + !laf.getClassName().contains("MetalLookAndFeel")) { + System.out.println("Testing LAF: " + laf.getClassName()); + SwingUtilities.invokeAndWait(() -> setLookAndFeel(laf)); + doTesting(laf); + } + } + } + + private static void setLookAndFeel(UIManager.LookAndFeelInfo laf) { + try { + UIManager.setLookAndFeel(laf.getClassName()); + } catch (UnsupportedLookAndFeelException ignored) { + System.out.println("Unsupported LAF: " + laf.getClassName()); + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + private static void doTesting(UIManager.LookAndFeelInfo laf) + throws Exception { + try { + SwingUtilities.invokeAndWait(() -> { + createAndShowUI(); + }); + boolean passed = false; + robot.waitForIdle(); + robot.delay(1000); + + Point pt = cb.getLocationOnScreen(); + BufferedImage img = robot.createScreenCapture( + new Rectangle(pt.x, pt.y, cb.getWidth(), cb.getHeight())); + for (int x = 20; x < img.getWidth()-20; ++x) { + for (int y = 20; y < img.getHeight()-20; ++y) { + if (img.getRGB(x,y) == Color.RED.getRGB()) { + passed = true; + break; + } + } + if (passed) + break; + } + + if (passed) { + System.out.println("Passed"); + } else { + ImageIO.write(img, "png", + new File("ComboBox.png")); + throw new RuntimeException("ComboBox components not rendered" + + " correctly for: " + laf.getClassName()); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + String[] petStrings = { "Bird", "Cat", "Dog", "Rabbit", "Pig" }; + frame = new JFrame(); + cb = new JComboBox(petStrings); + cb.setRenderer(new ComboBoxCustomRenderer()); + frame.pack(); + frame.add(cb); + frame.setSize(200,250); + frame.setLocationRelativeTo(null); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setVisible(true); + } +} + +class ComboBoxCustomRenderer extends JLabel + implements ListCellRenderer { + + public ComboBoxCustomRenderer() { + setOpaque(true); + setHorizontalAlignment(CENTER); + setVerticalAlignment(CENTER); + } + + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + setText(value.toString()); + setForeground(Color.RED); + return this; + } +} diff --git a/test/jdk/javax/swing/JComboBox/TestComboBoxHeight.java b/test/jdk/javax/swing/JComboBox/TestComboBoxHeight.java index 5cd5edcbbcc65..b06dcdce3e9c0 100644 --- a/test/jdk/javax/swing/JComboBox/TestComboBoxHeight.java +++ b/test/jdk/javax/swing/JComboBox/TestComboBoxHeight.java @@ -24,7 +24,7 @@ /* * @test * @key headful - * @bug 4517214 + * @bug 4517214 8218474 * @summary Tests that comboBox is not doubleheight if editable and has TitledBorder */ From 2354a029906a52dfbfc5b00b6d19bb76a8dee0f3 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:19:24 +0000 Subject: [PATCH 017/846] 8315876: Open source several Swing CSS related tests Backport-of: 833a82872c0b2517c7f4ae5d512cff3a428a071c --- .../javax/swing/text/html/CSS/bug4174871.java | 101 +++++++++++++++++ .../javax/swing/text/html/CSS/bug4174874.java | 100 ++++++++++++++++ .../javax/swing/text/html/CSS/bug4284162.java | 96 ++++++++++++++++ .../javax/swing/text/html/CSS/bug4764897.java | 107 ++++++++++++++++++ .../text/html/HTMLDocument/bug4209280.java | 39 +++++++ 5 files changed, 443 insertions(+) create mode 100644 test/jdk/javax/swing/text/html/CSS/bug4174871.java create mode 100644 test/jdk/javax/swing/text/html/CSS/bug4174874.java create mode 100644 test/jdk/javax/swing/text/html/CSS/bug4284162.java create mode 100644 test/jdk/javax/swing/text/html/CSS/bug4764897.java create mode 100644 test/jdk/javax/swing/text/html/HTMLDocument/bug4209280.java diff --git a/test/jdk/javax/swing/text/html/CSS/bug4174871.java b/test/jdk/javax/swing/text/html/CSS/bug4174871.java new file mode 100644 index 0000000000000..7ae27150be5fa --- /dev/null +++ b/test/jdk/javax/swing/text/html/CSS/bug4174871.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2003, 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. + */ + +import java.awt.Robot; +import java.awt.Shape; +import javax.swing.JFrame; +import javax.swing.JTextPane; +import javax.swing.SwingUtilities; +import javax.swing.text.View; + +/* + * @test + * @bug 4174871 + * @key headful + * @summary Tests if CELLSPACING attribute in HTML table is rendered. + */ + +public class bug4174871 { + private static JFrame frame; + private static JTextPane pane; + private static volatile boolean passed = false; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + + SwingUtilities.invokeAndWait(bug4174871::createAndShowUI); + robot.waitForIdle(); + robot.delay(500); + + SwingUtilities.invokeAndWait(bug4174871::testUI); + + if (!passed) { + throw new RuntimeException("Test failed!!" + + " CELLSPACING attribute in HTML table is NOT rendered"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public static void createAndShowUI() { + pane = new JTextPane(); + pane.setContentType("text/html"); + pane.setText("" + + "" + + "" + + "
onetwothree
"); + + frame = new JFrame("Table CellSpacing Test"); + frame.getContentPane().add(pane); + frame.setSize(600, 200); + frame.setVisible(true); + } + + private static void testUI() { + int tableWidth = 0; + Shape r = pane.getBounds(); + View v = pane.getUI().getRootView(pane); + + while (!(v instanceof javax.swing.text.html.ParagraphView)) { + int n = v.getViewCount(); + Shape sh = v.getChildAllocation(n - 1, r); + String viewName = v.getClass().getName(); + if (viewName.endsWith("TableView")) { + tableWidth = r.getBounds().width; + } + v = v.getView(n - 1); + if (sh != null) { + r = sh; + } + } + // tableWidth should be the sum of TD's widths (300) + // and cellspacings (80) + passed = (tableWidth >= 380); + } +} diff --git a/test/jdk/javax/swing/text/html/CSS/bug4174874.java b/test/jdk/javax/swing/text/html/CSS/bug4174874.java new file mode 100644 index 0000000000000..b6ba85014dafc --- /dev/null +++ b/test/jdk/javax/swing/text/html/CSS/bug4174874.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2003, 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. + */ + +import javax.swing.JFrame; +import javax.swing.JTextPane; +import javax.swing.SwingUtilities; +import javax.swing.text.View; +import java.awt.Robot; +import java.awt.Shape; + +/* + * @test + * @bug 4174874 + * @key headful + * @summary Tests if borders in HTML table are rendered + */ + +public class bug4174874 { + private static JFrame frame; + private static JTextPane pane; + private static volatile boolean passed = false; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + + SwingUtilities.invokeAndWait(bug4174874::createAndShowUI); + robot.waitForIdle(); + robot.delay(500); + + SwingUtilities.invokeAndWait(bug4174874::testUI); + + if (!passed) { + throw new RuntimeException("Test failed!!" + + " Borders of HTML table not rendered correctly"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public static void createAndShowUI() { + pane = new JTextPane(); + pane.setContentType("text/html"); + pane.setText("" + + "" + + "" + + "
onetwothree
"); + + frame = new JFrame("Table Border Test"); + frame.getContentPane().add(pane); + frame.setSize(600, 200); + frame.setVisible(true); + } + + private static void testUI() { + Shape r = pane.getBounds(); + View v = pane.getUI().getRootView(pane); + int tableWidth = 0; + while (!(v instanceof javax.swing.text.html.ParagraphView)) { + int n = v.getViewCount(); + Shape sh = v.getChildAllocation(n - 1, r); + String viewName = v.getClass().getName(); + if (viewName.endsWith("TableView")) { + tableWidth = r.getBounds().width; + } + v = v.getView(n - 1); + if (sh != null) { + r = sh; + } + } + // tableWidth should be the sum of TD's widths (300) + // and border width * 2 (40) + passed = tableWidth >= 340; + } +} diff --git a/test/jdk/javax/swing/text/html/CSS/bug4284162.java b/test/jdk/javax/swing/text/html/CSS/bug4284162.java new file mode 100644 index 0000000000000..e1f7116c0a82a --- /dev/null +++ b/test/jdk/javax/swing/text/html/CSS/bug4284162.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2003, 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. + */ + +import java.awt.Robot; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.text.AttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.View; +import javax.swing.text.html.HTMLEditorKit; + + +/* + * @test + * @bug 4284162 + * @key headful + * @summary Tests if css text-indent attribute is supported with negative values. + */ + +public class bug4284162 { + private static JEditorPane jep; + private static JFrame frame; + private static volatile boolean passed = false; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + + SwingUtilities.invokeAndWait(bug4284162::createAndShowUI); + robot.waitForIdle(); + robot.delay(500); + + SwingUtilities.invokeAndWait(bug4284162::testUI); + + if (!passed) { + throw new RuntimeException("Test failed!!" + + " CSS Text-indent attribute doesn't support negative values"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public static void createAndShowUI() { + String text ="" + + "

paragraph"; + + frame = new JFrame("CSS Text-Indent Test"); + jep = new JEditorPane(); + jep.setEditorKit(new HTMLEditorKit()); + jep.setEditable(false); + + jep.setText(text); + + frame.getContentPane().add(jep); + frame.setSize(200, 200); + frame.setVisible(true); + } + + private static void testUI() { + View v = jep.getUI().getRootView(jep); + while (!(v instanceof javax.swing.text.html.ParagraphView)) { + int n = v.getViewCount(); + v = v.getView(n - 1); + } + + AttributeSet attrs = v.getAttributes(); + Object attr = attrs.getAttribute(StyleConstants.FirstLineIndent); + passed = (attr.toString().startsWith("-")); + } +} diff --git a/test/jdk/javax/swing/text/html/CSS/bug4764897.java b/test/jdk/javax/swing/text/html/CSS/bug4764897.java new file mode 100644 index 0000000000000..68de9b1bb847f --- /dev/null +++ b/test/jdk/javax/swing/text/html/CSS/bug4764897.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2003, 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. + */ + +import java.awt.Robot; +import java.awt.Shape; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.JTextPane; +import javax.swing.SwingUtilities; +import javax.swing.text.View; + +/* + * @test + * @bug 4764897 + * @key headful + * @summary Tests if text and borders in HTML table doesn't run over right edge + */ + +public class bug4764897 { + private static JEditorPane pane; + private static JFrame frame; + private static volatile boolean passed = false; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + + SwingUtilities.invokeAndWait(bug4764897::createAndShowUI); + robot.waitForIdle(); + robot.delay(500); + + SwingUtilities.invokeAndWait(bug4764897::testUI); + + if (!passed) { + throw new RuntimeException("Test failed!!" + + " Text and Borders of HTML table run over the right edge"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public static void createAndShowUI() { + pane = new JTextPane(); + pane.setContentType("text/html"); + pane.setText("" + + "" + + "" + + "" + + "
one ThisIsAnExtraWideWord" + + "This is text that won't get displayed correctly.
"); + + frame = new JFrame("Table Border & Text Test"); + frame.getContentPane().add(pane); + frame.setSize(600, 200); + frame.setVisible(true); + } + + private static void testUI() { + Shape r = pane.getBounds(); + View v = pane.getUI().getRootView(pane); + int tableWidth = 0; + int cellsWidth = 0; + while (!(v instanceof javax.swing.text.html.ParagraphView)) { + int n = v.getViewCount(); + Shape sh = v.getChildAllocation(n - 1, r); + String viewName = v.getClass().getName(); + if (viewName.endsWith("TableView")) { + tableWidth = r.getBounds().width; + } + + if (viewName.endsWith("CellView")) { + cellsWidth = r.getBounds().x + r.getBounds().width; + } + + v = v.getView(n - 1); + if (sh != null) { + r = sh; + } + } + passed = cellsWidth <= tableWidth; + } +} diff --git a/test/jdk/javax/swing/text/html/HTMLDocument/bug4209280.java b/test/jdk/javax/swing/text/html/HTMLDocument/bug4209280.java new file mode 100644 index 0000000000000..e9170d8cf2dad --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLDocument/bug4209280.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1999, 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. + */ + +import javax.swing.JLabel; + +/* + * @test + * @bug 4209280 + * @summary Tests that no exception is thrown on unknown HTML tag + */ + +public class bug4209280 { + + public static void main(String[] args) throws Exception { + String html = "Foo"; + // The following line should throw no exceptions + new JLabel(html); + } +} From 45820299006a3fdaa2a7872742205bc0e48eca26 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:21:20 +0000 Subject: [PATCH 018/846] 8077371: Binary files in JAXP test should be removed Backport-of: 40106422bd2ae3da98d028bdbab2c240a71081e3 --- .../GregorianCalAndDurSerDataTemplate.java | 70 ++++++ .../GregorianCalAndDurSerDataUtil.java | 141 +++++++++++ .../GregorianCalendarAndDurationSerData.java | 33 +++ ...K6GregorianCalendarAndDurationSerData.java | 129 ++++++++++ .../jaxp/datatype/8033980/JDK6_Duration.ser | Bin 290 -> 0 bytes .../8033980/JDK6_XMLGregorianCalendar.ser | Bin 521 -> 0 bytes ...K7GregorianCalendarAndDurationSerData.java | 127 ++++++++++ .../jaxp/datatype/8033980/JDK7_Duration.ser | Bin 145 -> 0 bytes .../8033980/JDK7_XMLGregorianCalendar.ser | Bin 521 -> 0 bytes ...K8GregorianCalendarAndDurationSerData.java | 128 ++++++++++ .../jaxp/datatype/8033980/JDK8_Duration.ser | Bin 145 -> 0 bytes .../8033980/JDK8_XMLGregorianCalendar.ser | Bin 521 -> 0 bytes ...K9GregorianCalendarAndDurationSerData.java | 127 ++++++++++ .../jaxp/datatype/8033980/JDK9_Duration.ser | Bin 290 -> 0 bytes .../8033980/JDK9_XMLGregorianCalendar.ser | Bin 1208 -> 0 bytes .../datatype/8033980/SerializationTest.java | 225 ++++++++---------- 16 files changed, 860 insertions(+), 120 deletions(-) create mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/GregorianCalAndDurSerDataTemplate.java create mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/GregorianCalAndDurSerDataUtil.java create mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/GregorianCalendarAndDurationSerData.java create mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/JDK6GregorianCalendarAndDurationSerData.java delete mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/JDK6_Duration.ser delete mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/JDK6_XMLGregorianCalendar.ser create mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/JDK7GregorianCalendarAndDurationSerData.java delete mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/JDK7_Duration.ser delete mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/JDK7_XMLGregorianCalendar.ser create mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/JDK8GregorianCalendarAndDurationSerData.java delete mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/JDK8_Duration.ser delete mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/JDK8_XMLGregorianCalendar.ser create mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/JDK9GregorianCalendarAndDurationSerData.java delete mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/JDK9_Duration.ser delete mode 100644 test/jdk/javax/xml/jaxp/datatype/8033980/JDK9_XMLGregorianCalendar.ser diff --git a/test/jdk/javax/xml/jaxp/datatype/8033980/GregorianCalAndDurSerDataTemplate.java b/test/jdk/javax/xml/jaxp/datatype/8033980/GregorianCalAndDurSerDataTemplate.java new file mode 100644 index 0000000000000..dfb12c4c0e960 --- /dev/null +++ b/test/jdk/javax/xml/jaxp/datatype/8033980/GregorianCalAndDurSerDataTemplate.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 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. + */ + +/** + * This class provide the template for JDK version specific GregorianCalendarAndDurationSerData.java src file. + */ +public class GregorianCalAndDurSerDataTemplate { + public static final String ORACLE_COPY_RIGHT = """ + /* + * Copyright (c) %s, 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. + */ + \s + /** + * Mechanically generated %s specific serialization bytes for XMLGregorianCalendar and Duration data type. + * Do not edit this file. + */"""; + public static final String GREGO_CAL_DUR_SER_CLASS = """ + public class %sGregorianCalendarAndDurationSerData extends GregorianCalendarAndDurationSerData { + %s + %s + @Override + public byte[] getGregorianCalendarByteArray() { + return gregorianCalendarBytes; + } + \s + @Override + public byte[] getDurationBytes() { + return durationBytes; + } + };"""; +} diff --git a/test/jdk/javax/xml/jaxp/datatype/8033980/GregorianCalAndDurSerDataUtil.java b/test/jdk/javax/xml/jaxp/datatype/8033980/GregorianCalAndDurSerDataUtil.java new file mode 100644 index 0000000000000..323ba4a802bf6 --- /dev/null +++ b/test/jdk/javax/xml/jaxp/datatype/8033980/GregorianCalAndDurSerDataUtil.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 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. + */ + +/** + * @test + * @summary utility to generate Gregorian Calendar and Duration serialized data java classes. + * @run junit/manual GregorianCalAndDurSerDataUtil + */ + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.LocalDate; +import java.util.Formatter; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.Duration; +import javax.xml.datatype.XMLGregorianCalendar; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +/** + * Utility to generate the java source file for Gregorian Calendar and Duration serialized data + * for specific version of JDK to be added in SerializationTest. Execute this test with desired version + * of JDK to generate the java source file. + */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class GregorianCalAndDurSerDataUtil { + static String JDK = "JDK" + System.getProperty("java.version"); + static String testsrc = System.getProperty("test.src"); + final static String EXPECTED_CAL = "0001-01-01T00:00:00.0000000-05:00"; + final static String EXPECTED_DURATION = "P1Y1M1DT1H1M1S"; + String srcFilePrefix = JDK.toUpperCase().replace("-", "_"); + + + /** + * Create the serialized Bytes array and serialized bytes base64 string for GregorianCalender and Duration + * with jdk under test and generate the java source file. + * @throws DatatypeConfigurationException Unexpected. + * @throws IOException Unexpected. + */ + @BeforeAll + public void setup() throws DatatypeConfigurationException, IOException { + DatatypeFactory dtf = DatatypeFactory.newInstance(); + XMLGregorianCalendar xmlGregorianCalendar = dtf.newXMLGregorianCalendar(EXPECTED_CAL); + Duration duration = dtf.newDuration(EXPECTED_DURATION); + String copyRightStr = GregorianCalAndDurSerDataTemplate.ORACLE_COPY_RIGHT; + String classStr = GregorianCalAndDurSerDataTemplate.GREGO_CAL_DUR_SER_CLASS; + try(ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); + ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); ObjectOutputStream oos2 = new ObjectOutputStream(baos2)) { + //Serialize the given xmlGregorianCalendar + oos.writeObject(xmlGregorianCalendar); + //Serialize the given xml Duration + oos2.writeObject(duration); + Files.deleteIfExists(Path.of(testsrc,srcFilePrefix+"GregorianCalendarAndDurationSerData.java")); + + copyRightStr = String.format(copyRightStr, LocalDate.now().getYear(), JDK); + classStr = String.format(classStr, srcFilePrefix, generatePseudoCodeForGregCalSerBytes(baos), + generatePseudoCodeForDurationSerBytes(baos2)); + String srcStr = copyRightStr + "\n" + classStr; + Files.writeString(Path.of(testsrc,srcFilePrefix+"GregorianCalendarAndDurationSerData.java"), srcStr); + } + } + + /** + * Verify that Java source file is created. + */ + @Test + void testFileCreated() { + assertTrue(Files.exists(Path.of(testsrc,srcFilePrefix+"GregorianCalendarAndDurationSerData.java"))); + } + + /** + * Generates the Java Pseudo code for serialized Gregorian Calendar byte array. + * @param baos Serialized GregorianCalendar ByteArrayOutputStream. + * @return pseudocode String for serialized Gregorian Calendar byte array. + */ + public static String generatePseudoCodeForGregCalSerBytes(ByteArrayOutputStream baos) { + byte [] bytes = baos.toByteArray(); + StringBuilder sb = new StringBuilder(bytes.length * 5); + sb.append("private final byte[] gregorianCalendarBytes = {"); + return generatePseudoCode(sb, bytes); + } + + /** + * Generates the Java Pseudo code for serialized Duration byte array. + * @param baos Serialized Duration ByteArrayOutputStream. + * @return pseudocode String for serialized Duration byte array. + */ + public static String generatePseudoCodeForDurationSerBytes(ByteArrayOutputStream baos) { + byte [] bytesdur = baos.toByteArray(); + StringBuilder sb = new StringBuilder(bytesdur.length * 5); + sb.append("private final byte[] durationBytes = {"); + return generatePseudoCode(sb, bytesdur); + } + + private static String generatePseudoCode(StringBuilder sb, byte [] bytes) { + final int linelen = 8; +// HexFormat hex = HexFormat.of().withPrefix(" (byte) 0x").withSuffix(","); +// for (int i = 0; i < bytes.length; i += linelen) { +// sb.append("\n"); +// sb.append(hex.formatHex(bytes, i, Math.min(i + linelen, bytes.length))); +// } +// sb.append("};"); + Formatter fmt = new Formatter(sb); + for (int i = 0; i ykm6IAWOs#%z%inFnL#Y`CBc!a0z~foj4#3CSxlc2g#CF`UNa_dn?+GmY?Fvw}v$ m#&dOsyueNm^rY5PuAc6vkSA}S)%m<_kNXXI=ibQ}!wcITiM`!!+`QVZQiG~JBsHu_i zAN&9xkRPC;0f7>HA&4T|c;wyLnc2Y`R8s>y(2}K@V%kIu6AU`Uaxwv>Oejl6Va&Ri zCoDvZwwDk)Iq>%lMcN2dyBL!S(Qui>@LQ!a)HqZ^>~Wau=*)2Nq)?e94ppg@?YNJW z0|N`(3=m9f`KH(-0ANP9idOAC}Jz23BZit2Nm%GrLED zkQmqV#Q7;rO%=}skH@3e0w*r|YN5dj4dyhay!Ol5@#oF&N4DZSS6WRHh?b8JJ-%nf5^{>qecrN^zu)8`_mP5@! zpHx&FXXRX&)Hb#1lhKWyC8xn*Db`n%+7{V{a0D+Ek;>#L)Fehq*eoOq<3Z5I|=Iv9s_D*0ZFx-9jOPur`)M9AcLINM7sS^*9=!Jl*0q2( zDPWx=recvYnFnLzVz{DAc6vkSA}S)%m<_kNXXI=ibQ}!wcITiM`!!+`QVZQiG~JBsHu_i zAN&9xkRPC;0f7>HA&4T|c;wyLnc2Y`R8s>y(2}K@V%kIu6AU`Uaxwv>Oejl6Va&Ri zCoDvZwwDk)Iq>%lMcN2dyBL!S(Qui>@LQ!a)HqZ^>~Wau=*)2Nq)?e94ppg@?YNJW z0|N`(3=m9f`KH(-0ANP9idOAC}Jz23BZit2Nm%GrLED zkQmqV#Q7;rO%=}skH@3e0w*r|YN5dj4dyhay!Ol5@#oF&N4DZSS6WRHh?b8JJ-%nf5^{>qecrN^zu)8`_mP5@! zpHx&FXXRX&)Hb#1lhKWyC8xn*Db`n%+7{V{a0D+Ek;>#L)Fehq*eoOq<3Z5I|=Iv9s_D*0ZFx-9jOPur`)M9AcLINM7sS^*9=!Jl*0q2( zDPWx=recvYnFnLzVz{DAc6vkSA}S)%m<_kNXXI=ibQ}!wcITiM`!!+`QVZQiG~JBsHu_i zAN&9xkRPC;0f7>HA&4T|c;wyLnc2Y`R8s>y(2}K@V%kIu6AU`Uaxwv>Oejl6Va&Ri zCoDvZwwDk)Iq>%lMcN2dyBL!S(Qui>@LQ!a)HqZ^>~Wau=*)2Nq)?e94ppg@?YNJW z0|N`(3=m9f`KH(-0ANP9idOAC}Jz23BZit2Nm%GrLED zkQmqV#Q7;rO%=}skH@3e0w*r|YN5dj4dyhay!Ol5@#oF&N4DZSS6WRHh?b8JJ-%nf5^{>qecrN^zu)8`_mP5@! zpHx&FXXRX&)Hb#1lhKWyC8xn*Db`n%+7{V{a0D+Ek;>#L)Fehq*eoOq<ykm6IAWOs#%z%inFnL#Y`CBc!a0z~foj4#3CSxlc2g#CF`UNa_dn?+GmY?Fvw}v$ m#&dOsyueNm^rY5PuQbhPuMYL4T16+4OLY9_LBm$%qXtF!mbF{V>uQ%+aK%$|6 z66(~E?mc(`9w0A3MFRreVSDeC;y_eT;bzAk&&>CEf78#k}r+9+J3wQ;c#=vGMEKucaua-w--b_DiZ@j;J8v%r|>nq(C4&MDZzjrbG zzTJh`nLiSCSJ%pN7`QMYmHWrpIu@p~ds>~5(W8kaH-p3VLcgTS?vot}R}fbsSG7EZ zfy7)1TW4e;Ivh1#V{d-7W-gq0`?c};>6g1-ensU<%*Lh1^lwuvX{-$0f?>%c)9;BbHjMV``@&&r=izl8C(aQff% MAJi34OaGMdPe_7~{Qv*} diff --git a/test/jdk/javax/xml/jaxp/datatype/8033980/SerializationTest.java b/test/jdk/javax/xml/jaxp/datatype/8033980/SerializationTest.java index c8fa0d41d2821..89fd6e050cb57 100644 --- a/test/jdk/javax/xml/jaxp/datatype/8033980/SerializationTest.java +++ b/test/jdk/javax/xml/jaxp/datatype/8033980/SerializationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -25,160 +25,145 @@ * @test * @bug 8033980 * @summary verify serialization compatibility for XMLGregorianCalendar and Duration - * @run main SerializationTest read + * @run junit SerializationTest */ -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.stream.Stream; + import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.Duration; import javax.xml.datatype.XMLGregorianCalendar; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + /** - * use "read" to test compatibility - * SerializationTest read - * - * use "write" to create test files - * SerializationTest write javaVersion - * where javaVersion is 6, 7, 8, or 9 - * + * Verify serialization compatibility for XMLGregorianCalendar and Duration * @author huizhe.wang@oracle.com */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class SerializationTest { - final String FILENAME_CAL = "_XMLGregorianCalendar.ser"; - final String FILENAME_DURATION = "_Duration.ser"; - String filePath; - - { - filePath = System.getProperty("test.src"); - if (filePath == null) { - //current directory - filePath = System.getProperty("user.dir"); - } - filePath += File.separator; - } final String EXPECTED_CAL = "0001-01-01T00:00:00.0000000-05:00"; final String EXPECTED_DURATION = "P1Y1M1DT1H1M1S"; - static String[] JDK = {"JDK6", "JDK7", "JDK8", "JDK9"}; - - public static void main(String[] args) { - SerializationTest test = new SerializationTest(); - - if (args[0].equalsIgnoreCase("read")) { - test.testReadCal(); - test.testReadDuration(); - test.report(); - } else { - int ver = Integer.valueOf(args[1]).intValue(); - test.createTestFile(JDK[ver - 6]); - } + static String[] JDK = {System.getProperty("java.version"), "JDK6", "JDK7", "JDK8", "JDK9"}; - } + // If needed to add serialized data of more JDK versions, serialized data source file can be generated using + // GregorianCalAndDurSerDataUtil class. + private GregorianCalendarAndDurationSerData[] gregorianCalendarAndDurationSerData = {null, new JDK6GregorianCalendarAndDurationSerData(), + new JDK7GregorianCalendarAndDurationSerData(), new JDK8GregorianCalendarAndDurationSerData(), new JDK9GregorianCalendarAndDurationSerData()}; - public void testReadCal() { - try { - for (String javaVersion : JDK) { - XMLGregorianCalendar d1 = (XMLGregorianCalendar) fromFile( - javaVersion + FILENAME_CAL); - if (!d1.toString().equalsIgnoreCase(EXPECTED_CAL)) { - fail("Java version: " + javaVersion - + "\nExpected: " + EXPECTED_CAL - + "\nActual: " + d1.toString()); - } else { - success("testReadCal: read " + javaVersion + " serialized file, passed."); + /** + * Create the serialized Bytes array and serialized bytes base64 string for GregorianCalender and Duration + * with jdk under test. + * @throws DatatypeConfigurationException Unexpected. + * @throws IOException Unexpected. + */ + @BeforeAll + public void setup() throws DatatypeConfigurationException, IOException { + DatatypeFactory dtf = DatatypeFactory.newInstance(); + XMLGregorianCalendar xmlGregorianCalendar = dtf.newXMLGregorianCalendar(EXPECTED_CAL); + Duration duration = dtf.newDuration(EXPECTED_DURATION); + try(ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); + ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); ObjectOutputStream oos2 = new ObjectOutputStream(baos2)) { + //Serialize the given xmlGregorianCalendar + oos.writeObject(xmlGregorianCalendar); + //Serialize the given xml Duration + oos2.writeObject(duration); + // Create the Data for JDK under test. + gregorianCalendarAndDurationSerData[0] = new GregorianCalendarAndDurationSerData() { + @Override + public byte[] getGregorianCalendarByteArray() { + return baos.toByteArray(); } - } - } catch (ClassNotFoundException ex) { - fail("testReadCal: " + ex.getMessage()); - } catch (IOException ex) { - fail("testReadCal: " + ex.getMessage()); - } - } - public void testReadDuration() { - try { - for (String javaVersion : JDK) { - Duration d1 = (Duration) fromFile( - javaVersion + FILENAME_DURATION); - if (!d1.toString().equalsIgnoreCase(EXPECTED_DURATION)) { - fail("Java version: " + javaVersion - + "\nExpected: " + EXPECTED_DURATION - + "\nActual: " + d1.toString()); - } else { - success("testReadDuration: read " + javaVersion + " serialized file, passed."); + @Override + public byte[] getDurationBytes() { + return baos2.toByteArray(); } - } - } catch (ClassNotFoundException ex) { - fail("testReadDuration: " + ex.getMessage()); - } catch (IOException ex) { - fail("testReadDuration: " + ex.getMessage()); + }; } } /** - * Create test files - * - * @param javaVersion JDK version + * Provide data for JDK version and Gregorian Calendar serialized bytes. + * @return A Stream of arguments where each element is an array of size three. First element contain JDK version, + * second element contain object reference to GregorianCalendarAndDurationSerData specific to JDK version + * and third element contain expected Gregorian Calendar as string. */ - public void createTestFile(String javaVersion) { - try { - DatatypeFactory dtf = DatatypeFactory.newInstance(); - XMLGregorianCalendar c = dtf.newXMLGregorianCalendar(EXPECTED_CAL); - Duration d = dtf.newDuration(EXPECTED_DURATION); - toFile((Serializable) c, filePath + javaVersion + FILENAME_CAL); - toFile((Serializable) d, filePath + javaVersion + FILENAME_DURATION); - } catch (Exception e) { - fail(e.getMessage()); - } + + public Stream gregorianCalendarDataBytes() { + return Stream.of( + Arguments.of(JDK[0], gregorianCalendarAndDurationSerData[0], EXPECTED_CAL), + Arguments.of(JDK[1], gregorianCalendarAndDurationSerData[1], EXPECTED_CAL), + Arguments.of(JDK[2], gregorianCalendarAndDurationSerData[2], EXPECTED_CAL), + Arguments.of(JDK[3], gregorianCalendarAndDurationSerData[3], EXPECTED_CAL), + Arguments.of(JDK[4], gregorianCalendarAndDurationSerData[4], EXPECTED_CAL) + ); } /** - * Read the object from a file. + * Provide data for JDK version and Duration serialized bytes. + * @return A Stream of arguments where each element is an array of size three. First element contain JDK version, + * second element contain object reference to GregorianCalendarAndDurationSerData specific to JDK version + * and third element contain expected Duration as string. */ - private static Object fromFile(String filePath) throws IOException, - ClassNotFoundException { - InputStream streamIn = SerializationTest.class.getResourceAsStream( - filePath); - ObjectInputStream objectinputstream = new ObjectInputStream(streamIn); - Object o = objectinputstream.readObject(); - return o; + + public Stream durationData() { + return Stream.of(Arguments.of(JDK[0], gregorianCalendarAndDurationSerData[0], EXPECTED_DURATION), + Arguments.of(JDK[1], gregorianCalendarAndDurationSerData[1], EXPECTED_DURATION), + Arguments.of(JDK[2], gregorianCalendarAndDurationSerData[2], EXPECTED_DURATION), + Arguments.of(JDK[3], gregorianCalendarAndDurationSerData[3], EXPECTED_DURATION), + Arguments.of(JDK[4], gregorianCalendarAndDurationSerData[4], EXPECTED_DURATION)); } /** - * Write the object to a file. + * Verify that GregorianCalendar serialized with different old JDK versions can be deserialized correctly with + * JDK under test. + * @param javaVersion JDK version used to GregorianCalendar serialization. + * @param gcsd JDK version specific GregorianCalendarAndDurationSerData. + * @param gregorianDate String representation of GregorianCalendar Date. + * @throws IOException Unexpected. + * @throws ClassNotFoundException Unexpected. */ - private static void toFile(Serializable o, String filePath) throws IOException { - FileOutputStream fout = new FileOutputStream(filePath, true); - ObjectOutputStream oos = new ObjectOutputStream(fout); - oos.writeObject(o); - oos.close(); - } - - static String errMessage; - int passed = 0, failed = 0; - - void fail(String errMsg) { - if (errMessage == null) { - errMessage = errMsg; - } else { - errMessage = errMessage + "\n" + errMsg; - } - failed++; - } - void success(String msg) { - passed++; - System.out.println(msg); + @ParameterizedTest + @MethodSource("gregorianCalendarDataBytes") + public void testReadCalBytes(String javaVersion, GregorianCalendarAndDurationSerData gcsd, String gregorianDate) throws IOException, + ClassNotFoundException { + final ByteArrayInputStream bais = new ByteArrayInputStream(gcsd.getGregorianCalendarByteArray()); + final ObjectInputStream ois = new ObjectInputStream(bais); + final XMLGregorianCalendar xgc = (XMLGregorianCalendar) ois.readObject(); + assertEquals(gregorianDate, xgc.toString()); } - public void report() { - - System.out.println("\nNumber of tests passed: " + passed); - System.out.println("Number of tests failed: " + failed + "\n"); + /** + * Verify that Duration serialized with different old JDK versions can be deserialized correctly with + * JDK under test. + * @param javaVersion JDK version used to GregorianCalendar serialization. + * @param gcsd JDK version specific GregorianCalendarAndDurationSerData. + * @param duration String representation of Duration. + * @throws IOException Unexpected. + * @throws ClassNotFoundException Unexpected. + */ - if (errMessage != null) { - throw new RuntimeException(errMessage); - } + @ParameterizedTest + @MethodSource("durationData") + public void testReadDurationBytes(String javaVersion, GregorianCalendarAndDurationSerData gcsd, String duration) throws IOException, + ClassNotFoundException { + final ByteArrayInputStream bais = new ByteArrayInputStream(gcsd.getDurationBytes()); + final ObjectInputStream ois = new ObjectInputStream(bais); + final Duration d1 = (Duration) ois.readObject(); + assertEquals(duration, d1.toString().toUpperCase()); } } From 574e1ad734409bdcf1b78f0c6b53a7196b3b0d66 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:22:43 +0000 Subject: [PATCH 019/846] 8316497: ColorConvertOp - typo for non-ICC conversions needs one-line fix Backport-of: dadd9cd1e8434cffaafc7406a864eaa55954cfb8 --- .../java/awt/image/ColorConvertOp.java | 8 +- test/jdk/java/awt/color/NonICCFilterTest.java | 151 ++++++++++++++++++ 2 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 test/jdk/java/awt/color/NonICCFilterTest.java diff --git a/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java b/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java index 023b376d73d80..a32cb925e5cce 100644 --- a/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java +++ b/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -811,7 +811,7 @@ private BufferedImage nonICCBIFilter(BufferedImage src, } float[] srcMinVal = new float[iccSrcNumComp]; float[] srcInvDiffMinMax = new float[iccSrcNumComp]; - for (int i = 0; i < srcNumComp; i++) { + for (int i = 0; i < iccSrcNumComp; i++) { srcMinVal[i] = cs.getMinValue(i); srcInvDiffMinMax[i] = maxNum / (cs.getMaxValue(i) - srcMinVal[i]); } @@ -825,7 +825,7 @@ private BufferedImage nonICCBIFilter(BufferedImage src, } float[] dstMinVal = new float[iccDstNumComp]; float[] dstDiffMinMax = new float[iccDstNumComp]; - for (int i = 0; i < dstNumComp; i++) { + for (int i = 0; i < iccDstNumComp; i++) { dstMinVal[i] = cs.getMinValue(i); dstDiffMinMax[i] = (cs.getMaxValue(i) - dstMinVal[i]) / maxNum; } @@ -878,7 +878,7 @@ private BufferedImage nonICCBIFilter(BufferedImage src, dstDiffMinMax[i] + dstMinVal[i]; } if (nonICCDst) { - color = srcColorSpace.fromCIEXYZ(dstColor); + color = dstColorSpace.fromCIEXYZ(dstColor); for (int i = 0; i < dstNumComp; i++) { dstColor[i] = color[i]; } diff --git a/test/jdk/java/awt/color/NonICCFilterTest.java b/test/jdk/java/awt/color/NonICCFilterTest.java new file mode 100644 index 0000000000000..bddd89ed6b355 --- /dev/null +++ b/test/jdk/java/awt/color/NonICCFilterTest.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Color; +import java.awt.GradientPaint; +import java.awt.Graphics2D; +import java.awt.Transparency; +import java.awt.color.ColorSpace; +import java.awt.image.BufferedImage; +import java.awt.image.ColorConvertOp; +import java.awt.image.ComponentColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.WritableRaster; + +/* + * @test + * @bug 8316497 + * @summary Verifies Color filter on non-ICC profile + */ +public final class NonICCFilterTest { + private static final int WIDTH = 100; + private static final int HEIGHT = 100; + + private enum ColorSpaceSelector { + GRAY, + RGB, + PYCC, + WRAPPED_GRAY, + WRAPPED_RGB, + WRAPPED_PYCC + } + + private static final class TestColorSpace extends ColorSpace { + + private final ColorSpace cs; + + TestColorSpace(ColorSpace cs) { + super(cs.getType(), cs.getNumComponents()); + this.cs = cs; + } + + @Override + public float[] toRGB(float[] colorvalue) { + return cs.toRGB(colorvalue); + } + + @Override + public float[] fromRGB(float[] rgbvalue) { + return cs.fromRGB(rgbvalue); + } + + @Override + public float[] toCIEXYZ(float[] colorvalue) { + return cs.toCIEXYZ(colorvalue); + } + + @Override + public float[] fromCIEXYZ(float[] xyzvalue) { + return cs.fromCIEXYZ(xyzvalue); + } + } + + private static BufferedImage createTestImage(final ColorSpace cs) { + ComponentColorModel cm = new ComponentColorModel(cs, false, false, + Transparency.OPAQUE, DataBuffer.TYPE_BYTE); + WritableRaster raster = cm.createCompatibleWritableRaster(WIDTH, HEIGHT); + BufferedImage img = new BufferedImage(cm, raster, false, null); + + Graphics2D g = img.createGraphics(); + GradientPaint gp = new GradientPaint(0, 0, Color.GREEN, + raster.getWidth(), raster.getHeight(), Color.BLUE); + g.setPaint(gp); + g.fillRect(0, 0, raster.getWidth(), raster.getHeight()); + g.dispose(); + + return img; + } + + private static ColorSpace createCS(ColorSpaceSelector selector) { + return switch (selector) { + case GRAY -> ColorSpace.getInstance(ColorSpace.CS_GRAY); + case WRAPPED_GRAY -> new TestColorSpace(ColorSpace.getInstance(ColorSpace.CS_GRAY)); + + case RGB -> ColorSpace.getInstance(ColorSpace.CS_sRGB); + case WRAPPED_RGB -> new TestColorSpace(ColorSpace.getInstance(ColorSpace.CS_sRGB)); + + case PYCC -> ColorSpace.getInstance(ColorSpace.CS_PYCC); + case WRAPPED_PYCC -> new TestColorSpace(ColorSpace.getInstance(ColorSpace.CS_PYCC)); + }; + } + + private static boolean areImagesEqual(BufferedImage destTest, BufferedImage destGold) { + for (int x = 0; x < destTest.getWidth(); x++) { + for (int y = 0; y < destTest.getHeight(); y++) { + int rgb1 = destTest.getRGB(x, y); + int rgb2 = destGold.getRGB(x, y); + if (rgb1 != rgb2) { + System.err.println("x = " + x + ", y = " + y); + System.err.println("rgb1 = " + Integer.toHexString(rgb1)); + System.err.println("rgb2 = " + Integer.toHexString(rgb2)); + return false; + } + } + } + return true; + } + + public static void main(String[] args) { + BufferedImage srcTest = createTestImage(createCS(ColorSpaceSelector.WRAPPED_GRAY)); + BufferedImage destTest = createTestImage(createCS(ColorSpaceSelector.WRAPPED_RGB)); + + BufferedImage srcGold = createTestImage(createCS(ColorSpaceSelector.GRAY)); + BufferedImage destGold = createTestImage(createCS(ColorSpaceSelector.RGB)); + + ColorConvertOp gold = new ColorConvertOp(createCS(ColorSpaceSelector.PYCC), null); + gold.filter(srcTest, destTest); + gold.filter(srcGold, destGold); + + if (!areImagesEqual(destTest, destGold)) { + throw new RuntimeException("ICC test failed"); + } + + ColorConvertOp test = new ColorConvertOp(createCS(ColorSpaceSelector.WRAPPED_PYCC), null); + test.filter(srcTest, destTest); + test.filter(srcGold, destGold); + + if (!areImagesEqual(destTest, destGold)) { + throw new RuntimeException("Wrapper test failed"); + } + } +} From 8dec85c10f7490183fcc024b0739cc43bf49dfc9 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:26:09 +0000 Subject: [PATCH 020/846] 8325435: [macos] Menu or JPopupMenu not closed when main window is resized Backport-of: 1c514b34c0260823e70f209996ac933a76ac34c2 --- .../native/libawt_lwawt/awt/AWTWindow.m | 6 +- test/jdk/javax/swing/JMenu/TestUngrab.java | 120 ++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 test/jdk/javax/swing/JMenu/TestUngrab.java diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m index 79c5abdbc2c9e..30d41ec1cf25f 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m @@ -1022,7 +1022,11 @@ - (void)sendEvent:(NSEvent *)event { NSRect contentRect = [self.nsWindow contentRectForFrameRect:frame]; // Check if the click happened in the non-client area (title bar) - if (p.y >= (frame.origin.y + contentRect.size.height)) { + // Also, non-client area includes the edges at left, right and botton of frame + if ((p.y >= (frame.origin.y + contentRect.size.height)) || + (p.x >= (frame.origin.x + contentRect.size.width - 3)) || + (fabs(frame.origin.x - p.x) < 3) || + (fabs(frame.origin.y - p.y) < 3)) { JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; jobject platformWindow = (*env)->NewLocalRef(env, self.javaPlatformWindow); if (platformWindow != NULL) { diff --git a/test/jdk/javax/swing/JMenu/TestUngrab.java b/test/jdk/javax/swing/JMenu/TestUngrab.java new file mode 100644 index 0000000000000..64326009c6c77 --- /dev/null +++ b/test/jdk/javax/swing/JMenu/TestUngrab.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 8267374 + * @key headful + * @requires (os.family == "mac") + * @summary Verifies menu closes when main window is resized + * @run main TestUngrab + */ + +import java.awt.Point; +import java.awt.Dimension; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.SwingUtilities; + +public class TestUngrab { + /** + * Menu (JMenuBar and JPopupMenu) not hidden when resizing the window. + * -> UngrabEvent not sent. + */ + static JMenu menu; + static JFrame frame; + static volatile Point loc; + static volatile Point point; + static volatile Dimension dim; + static volatile int width; + static volatile int height; + static volatile boolean popupVisible; + + private static void createAndShowGUI() { + frame = new JFrame(); + JMenuBar mb = new JMenuBar(); + menu = new JMenu("Menu"); + menu.add(new JMenuItem("Item 1")); + menu.add(new JMenuItem("Item 2")); + mb.add(menu); + + frame.setJMenuBar(mb); + frame.setSize(300, 300); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoDelay(100); + SwingUtilities.invokeAndWait(() -> createAndShowGUI()); + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + point = menu.getLocationOnScreen(); + dim = menu.getSize(); + }); + robot.mouseMove(point.x + dim.width / 2, point.y + dim.height / 2); + robot.waitForIdle(); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + + SwingUtilities.invokeAndWait(() -> { + loc = frame.getLocationOnScreen(); + width = frame.getWidth(); + height = frame.getHeight(); + }); + robot.mouseMove(loc.x + width, loc.y + height); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + popupVisible = menu.isPopupMenuVisible(); + }); + System.out.println("isPopupMenuVisible " + popupVisible); + if (popupVisible) { + throw new RuntimeException("popup menu not closed on resize"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + +} From 1b1c92e75ebfb43c8f9940b03bc52358c3e8669d Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:27:48 +0000 Subject: [PATCH 021/846] 8340560: Open Source several AWT/2D font and rendering tests Backport-of: ade17ecb6cb5125d048401a878b557e5afefc08c --- test/jdk/sun/awt/font/CacheFlushTest.java | 106 ++++++++++ test/jdk/sun/awt/font/TestArabicHebrew.java | 215 ++++++++++++++++++++ test/jdk/sun/awt/font/TestDevTransform.java | 155 ++++++++++++++ test/jdk/sun/awt/windows/TestPen.java | 102 ++++++++++ 4 files changed, 578 insertions(+) create mode 100644 test/jdk/sun/awt/font/CacheFlushTest.java create mode 100644 test/jdk/sun/awt/font/TestArabicHebrew.java create mode 100644 test/jdk/sun/awt/font/TestDevTransform.java create mode 100644 test/jdk/sun/awt/windows/TestPen.java diff --git a/test/jdk/sun/awt/font/CacheFlushTest.java b/test/jdk/sun/awt/font/CacheFlushTest.java new file mode 100644 index 0000000000000..f3b3293127530 --- /dev/null +++ b/test/jdk/sun/awt/font/CacheFlushTest.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4286726 + * @summary Java2D raster printing: large text may overflow glyph cache. + * Draw a large glyphvector, the 'A' glyph should appear and not get flushed. +*/ + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.geom.Point2D; +import java.awt.image.BufferedImage; +import java.util.HashMap; + +/** + * Draw a very large glyphvector on a surface. + * If the cache was flushed the first glyph is not rendered. + * Note: the implementation no longer uses glyphs for rendering large text, + * but in principle the test is still useful. + */ +public class CacheFlushTest { + + static final int WIDTH = 400, HEIGHT = 600; + static final int FONTSIZE = 250; + static final String TEST = "ABCDEFGHIJKLMNOP"; + static final HashMap HINTS = new HashMap<>(); + + static { + HINTS.put(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + HINTS.put(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + HINTS.put(RenderingHints.KEY_FRACTIONALMETRICS, + RenderingHints.VALUE_FRACTIONALMETRICS_ON); + } + + public static void main(String args[]) { + BufferedImage bi = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); + + Graphics2D g2d = bi.createGraphics(); + g2d.addRenderingHints(HINTS); + g2d.setColor(Color.white); + g2d.fillRect(0, 0, WIDTH, HEIGHT); + g2d.setColor(Color.black); + + FontRenderContext frc = g2d.getFontRenderContext(); + Font font = new Font(Font.DIALOG, Font.PLAIN, 250); + GlyphVector gv = font.createGlyphVector(frc, TEST); + + /* Set the positions of all but the first glyph to be offset vertically but + * FONTSIZE pixels. So if the first glyph "A" is not flushed we can tell this + * by checking for non-white pixels in the range for the default y offset of 0 + * from the specified y location. + */ + Point2D.Float pt = new Point2D.Float(20f, FONTSIZE); + for (int i = 1; i < gv.getNumGlyphs(); ++i) { + gv.setGlyphPosition(i, pt); + pt.x += 25f; + pt.y = FONTSIZE; + } + g2d.drawGlyphVector(gv, 20, FONTSIZE); + /* Now expect to find at least one black pixel in the rect (0,0) -> (WIDTH, FONTSIZE) */ + boolean found = false; + int blackPixel = Color.black.getRGB(); + for (int y = 0; y < FONTSIZE; y++) { + for (int x = 0; x < WIDTH; x++) { + if (bi.getRGB(x, y) == blackPixel) { + found = true; + break; + } + } + if (found == true) { + break; + } + } + if (!found) { + throw new RuntimeException("NO BLACK PIXELS"); + } + } +} diff --git a/test/jdk/sun/awt/font/TestArabicHebrew.java b/test/jdk/sun/awt/font/TestArabicHebrew.java new file mode 100644 index 0000000000000..61cbe931c32c4 --- /dev/null +++ b/test/jdk/sun/awt/font/TestArabicHebrew.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4198081 + * @key headful + * @summary Arabic characters should appear instead of boxes and be correctly shaped. + * Hebrew characters should appear instead of boxes. + * Test is made headful so there's no excuse for test systems not having the fonts. + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridLayout; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.geom.Rectangle2D; + +public class TestArabicHebrew extends Panel { + + static volatile Frame frame; + static volatile Font font = new Font(Font.DIALOG, Font.PLAIN, 36); + + static void createUI() { + frame = new Frame("Test Arabic/Hebrew"); + frame.setLayout(new BorderLayout()); + TestArabicHebrew panel = new TestArabicHebrew(); + frame.add(panel, BorderLayout.CENTER); + frame.pack(); + frame.setVisible(true); + } + + public static void main(String args[]) throws Exception { + EventQueue.invokeAndWait(TestArabicHebrew::createUI); + try { + checkStrings(); + } finally { + if (frame != null && args.length == 0) { + EventQueue.invokeAndWait(frame::dispose); + } + } + } + + static void checkString(String script, String str) { + int index = font.canDisplayUpTo(str); + if (index != -1) { + throw new RuntimeException("Cannot display char " + index + " for " + script); + } + } + + static void checkStrings() { + checkString("Arabic", arabic); + checkString("Hebrew", hebrew); + checkString("Latin-1 Supplement", latin1sup); + } + + // Table of arabic unicode characters - minimal support level + // Includes arabic chars from basic block up to 0652 and + // corresponding shaped characters from the arabic + // extended-B block from fe80 to fefc (does include lam-alef + // ligatures). + // Does not include arabic-indic digits nor "arabic extended" + // range. + + static final String arabic = + "\u060c\u061b\u061f\u0621\u0622\u0623\u0624\u0625\u0626\u0627" + + "\u0628\u0629\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631" + + "\u0632\u0633\u0634\u0635\u0636\u0637\u0638\u0639\u063a\u0640" + + "\u0641\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064a" + + "\u064b\u064c\u064d\u064e\u064f\u0650\u0651\u0652\ufe80\ufe81" + + "\ufe82\ufe83\ufe84\ufe85\ufe86\ufe87\ufe88\ufe89\ufe8a\ufe8b" + + "\ufe8c\ufe8d\ufe8e\ufe8f\ufe90\ufe91\ufe92\ufe93\ufe94\ufe95" + + "\ufe96\ufe97\ufe98\ufe99\ufe9a\ufe9b\ufe9c\ufe9d\ufe9e\ufe9f" + + "\ufea0\ufea1\ufea2\ufea3\ufea4\ufea5\ufea6\ufea7\ufea8\ufea9" + + "\ufeaa\ufeab\ufeac\ufead\ufeae\ufeaf\ufeb0\ufeb1\ufeb2\ufeb3" + + "\ufeb4\ufeb5\ufeb6\ufeb7\ufeb8\ufeb9\ufeba\ufebb\ufebc\ufebd" + + "\ufebe\ufebf\ufec0\ufec1\ufec2\ufec3\ufec4\ufec5\ufec6\ufec7" + + "\ufec8\ufec9\ufeca\ufecb\ufecc\ufecd\ufece\ufecf\ufed0\ufed1" + + "\ufed2\ufed3\ufed4\ufed5\ufed6\ufed7\ufed8\ufed9\ufeda\ufedb" + + "\ufedc\ufedd\ufede\ufedf\ufee0\ufee1\ufee2\ufee3\ufee4\ufee5" + + "\ufee6\ufee7\ufee8\ufee9\ufeea\ufeeb\ufeec\ufeed\ufeee\ufeef" + + "\ufef0\ufef1\ufef2\ufef3\ufef4\ufef5\ufef6\ufef7\ufef8\ufef9" + + "\ufefa\ufefb\ufefc"; + + // hebrew table includes all characters in hebrew block + + static final String hebrew = + "\u0591\u0592\u0593\u0594\u0595\u0596\u0597\u0598\u0599\u059a" + + "\u059b\u059c\u059d\u059e\u059f\u05a0\u05a1\u05a3\u05a4\u05a5" + + "\u05a6\u05a7\u05a8\u05a9\u05aa\u05ab\u05ac\u05ad\u05ae\u05af" + + "\u05b0\u05b1\u05b2\u05b3\u05b4\u05b5\u05b6\u05b7\u05b8\u05b9" + + "\u05bb\u05bc\u05bd\u05be\u05bf\u05c0\u05c1\u05c2\u05c3\u05c4" + + "\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9" + + "\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3" + + "\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\u05f0\u05f1\u05f2" + + "\u05f3\u05f4"; + + // latin 1 supplement table includes all non-control characters + // in this range. Included because of comment in code that claims + // some problems displaying this range with some SJIS fonts. + + static final String latin1sup = + "\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7" + + "\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u00b0\u00b1" + + "\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb" + + "\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5" + + "\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf" + + "\u00d0\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9" + + "\u00da\u00db\u00dc\u00dd\u00de\u00df\u00e0\u00e1\u00e2\u00e3" + + "\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed" + + "\u00ee\u00ef\u00f0\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7" + + "\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u00fe\u00ff"; + + public TestArabicHebrew() { + setLayout(new GridLayout(3, 1)); + + FontRenderContext frc = new FontRenderContext(null, false, false); + add(new SubGlyphPanel("Arabic", arabic, font, frc)); + add(new SubGlyphPanel("Hebrew", hebrew, font, frc)); + add(new SubGlyphPanel("Latin-1 Supplement", latin1sup, font, frc)); + } + + static class SubGlyphPanel extends Panel { + String title; + Dimension extent; + GlyphVector[] vectors; + + static final int kGlyphsPerLine = 20; + + SubGlyphPanel(String title, String chars, Font font, FontRenderContext frc) { + + this.title = title; + setBackground(Color.white); + + double width = 0; + double height = 0; + + int max = chars.length(); + vectors = new GlyphVector[(max + kGlyphsPerLine - 1) / kGlyphsPerLine]; + for (int i = 0; i < vectors.length; i++) { + int start = i * 20; + int limit = Math.min(max, (i + 1) * kGlyphsPerLine); + String substr = ""; + for (int j = start; j < limit; ++j) { + substr = substr.concat(chars.charAt(j) + " "); + } + GlyphVector gv = font.createGlyphVector(frc, substr); + vectors[i] = gv; + Rectangle2D bounds = gv.getLogicalBounds(); + + width = Math.max(width, bounds.getWidth()); + height += bounds.getHeight(); + } + + extent = new Dimension((int)(width + 1), (int)(height + 1 + 30)); // room for title + + setSize(getPreferredSize()); + } + + public Dimension getPreferredSize() { + return new Dimension(extent); + } + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + public Dimension getMaximumSize() { + return getPreferredSize(); + } + + public void paint(Graphics g) { + Graphics2D g2d = (Graphics2D)g; + + g.drawString(title, 10, 20); + + float x = 10; + float y = 30; + for (int i = 0; i < vectors.length; ++i) { + GlyphVector gv = vectors[i]; + Rectangle2D bounds = gv.getLogicalBounds(); + g2d.drawGlyphVector(gv, x, (float)(y - bounds.getY())); + y += bounds.getHeight(); + } + } + } +} diff --git a/test/jdk/sun/awt/font/TestDevTransform.java b/test/jdk/sun/awt/font/TestDevTransform.java new file mode 100644 index 0000000000000..035cb0b13d73a --- /dev/null +++ b/test/jdk/sun/awt/font/TestDevTransform.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4269775 + * @summary Check that different text rendering APIs agree + */ + +/** + * Draw into an image rendering the same text string nine different + * ways: as a TextLayout, a simple String, and a GlyphVector, each + * with three different x scale factors. The expectation is that each + * set of three strings would appear the same although offset in y to + * avoid overlap. The bug was that the y positions of the individual characters + * of the TextLayout and GlyphVector were wrong, so the strings appeared + * to be rendered at different angles. + */ + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.util.HashMap; + +public class TestDevTransform { + + static HashMap hints = new HashMap<>(); + + static { + hints.put(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + hints.put(RenderingHints.KEY_FRACTIONALMETRICS, + RenderingHints.VALUE_FRACTIONALMETRICS_ON); + } + + static String test = "This is only a test"; + static double angle = Math.PI / 6.0; // Rotate 30 degrees + static final int W = 400, H = 400; + + static void draw(Graphics2D g2d, TextLayout layout, + float x, float y, float scalex) { + AffineTransform saveTransform = g2d.getTransform(); + g2d.translate(x, y); + g2d.rotate(angle); + g2d.scale(scalex, 1f); + layout.draw(g2d, 0f, 0f); + g2d.setTransform(saveTransform); + } + + static void draw(Graphics2D g2d, String string, + float x, float y, float scalex) { + AffineTransform saveTransform = g2d.getTransform(); + g2d.translate(x, y); + g2d.rotate(angle); + g2d.scale(scalex, 1f); + g2d.drawString(string, 0f, 0f); + g2d.setTransform(saveTransform); + } + + static void draw(Graphics2D g2d, GlyphVector gv, + float x, float y, float scalex) { + AffineTransform saveTransform = g2d.getTransform(); + g2d.translate(x, y); + g2d.rotate(angle); + g2d.scale(scalex, 1f); + g2d.drawGlyphVector(gv, 0f, 0f); + g2d.setTransform(saveTransform); + } + + static void init(Graphics2D g2d) { + g2d.setColor(Color.white); + g2d.fillRect(0, 0, W, H); + g2d.setColor(Color.black); + g2d.scale(1.481f, 1.481); // Convert to 108 dpi + g2d.addRenderingHints(hints); + Font font = new Font(Font.DIALOG, Font.PLAIN, 12); + g2d.setFont(font); + } + + static void compare(BufferedImage bi1, BufferedImage bi2) { + for (int x = 0; x < bi1.getWidth(); x++) { + for (int y = 0; y < bi1.getHeight(); y++) { + if (bi1.getRGB(x, y) != bi2.getRGB(x, y)) { + throw new RuntimeException("Different rendering"); + } + } + } + } + + public static void main(String args[]) { + + BufferedImage tl_Image = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB); + { + Graphics2D tl_g2d = tl_Image.createGraphics(); + init(tl_g2d); + FontRenderContext frc = tl_g2d.getFontRenderContext(); + // Specify font from graphics to be sure it is the same as the other cases. + TextLayout tl = new TextLayout(test, tl_g2d.getFont(), frc); + draw(tl_g2d, tl, 10f, 12f, 3.0f); + draw(tl_g2d, tl, 10f, 24f, 1.0f); + draw(tl_g2d, tl, 10f, 36f, 0.33f); + } + + BufferedImage st_Image = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB); + { + Graphics2D st_g2d = st_Image.createGraphics(); + init(st_g2d); + draw(st_g2d, test, 10f, 12f, 3.0f); + draw(st_g2d, test, 10f, 24f, 1.0f); + draw(st_g2d, test, 10f, 36f, .33f); + } + + BufferedImage gv_Image = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB); + { + Graphics2D gv_g2d = gv_Image.createGraphics(); + init(gv_g2d); + FontRenderContext frc = gv_g2d.getFontRenderContext(); + GlyphVector gv = gv_g2d.getFont().createGlyphVector(frc, test); + draw(gv_g2d, gv, 10f, 12f, 3.0f); + draw(gv_g2d, gv, 10f, 24f, 1.0f); + draw(gv_g2d, gv, 10f, 36f, .33f); + } + + compare(tl_Image, st_Image); + compare(gv_Image, st_Image); + } +} diff --git a/test/jdk/sun/awt/windows/TestPen.java b/test/jdk/sun/awt/windows/TestPen.java new file mode 100644 index 0000000000000..25b7304bdc862 --- /dev/null +++ b/test/jdk/sun/awt/windows/TestPen.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4277201 + * @summary verifies that invoking a fill on a brand new Graphics object + * does not stroke the shape in addition to filling it + * @key headful + */ + +/* + * This test case tests for a problem with initializing GDI graphics + * contexts (HDCs) where a pen is left installed in the graphics object + * even though the AWT believes that there is no Pen installed. The + * result is that when you try to fill a shape, GDI will both fill and + * stroke it. +*/ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; + +public class TestPen extends Panel { + + static volatile TestPen pen; + static volatile Frame frame; + + public TestPen() { + setForeground(Color.black); + setBackground(Color.white); + } + + public Dimension getPreferredSize() { + return new Dimension(200, 200); + } + + public void paint(Graphics g) { + g.setColor(Color.green); + g.fillOval(50, 50, 100, 100); + } + + static void createUI() { + frame = new Frame(); + pen = new TestPen(); + frame.add(pen); + frame.pack(); + frame.setVisible(true); + } + + public static void main(String argv[]) throws Exception { + try { + EventQueue.invokeAndWait(TestPen::createUI); + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(2000); + Point p = pen.getLocationOnScreen(); + Dimension d = pen.getSize(); + Rectangle r = new Rectangle(p.x + 1, p.y + 1, d.width - 2, d.height - 2); + BufferedImage bi = robot.createScreenCapture(r); + int blackPixel = Color.black.getRGB(); + for (int y = 0; y < bi.getHeight(); y++ ) { + for (int x = 0; x < bi.getWidth(); x++ ) { + if (bi.getRGB(x, y) == blackPixel) { + throw new RuntimeException("Black pixel !"); + } + } + } + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + } + } +} From f91d7d34ae29b6ccd8fc9682c5a49b08e522ba51 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:31:03 +0000 Subject: [PATCH 022/846] 8341170: Open source several Choice related tests (part 2) Backport-of: 52eded4a9ce612a978ae15d5b606784bcf671c69 --- .../awt/Choice/ChoiceDragEventsInside.java | 210 ++++++++++++++++++ .../java/awt/Choice/ChoiceMouseEventTest.java | 123 ++++++++++ .../jdk/java/awt/Choice/ChoiceRemoveTest.java | 111 +++++++++ .../awt/Choice/PopupMenuOnChoiceArea.java | 106 +++++++++ .../java/awt/Choice/ScrollbarFlickers.java | 85 +++++++ 5 files changed, 635 insertions(+) create mode 100644 test/jdk/java/awt/Choice/ChoiceDragEventsInside.java create mode 100644 test/jdk/java/awt/Choice/ChoiceMouseEventTest.java create mode 100644 test/jdk/java/awt/Choice/ChoiceRemoveTest.java create mode 100644 test/jdk/java/awt/Choice/PopupMenuOnChoiceArea.java create mode 100644 test/jdk/java/awt/Choice/ScrollbarFlickers.java diff --git a/test/jdk/java/awt/Choice/ChoiceDragEventsInside.java b/test/jdk/java/awt/Choice/ChoiceDragEventsInside.java new file mode 100644 index 0000000000000..dde773f19289c --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceDragEventsInside.java @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6251983 6722236 + * @summary MouseDragged events not triggered for Choice when dragging it with left mouse button + * @key headful + * @run main ChoiceDragEventsInside + */ + +import java.awt.Choice; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.lang.reflect.InvocationTargetException; + +public class ChoiceDragEventsInside extends Frame { + Robot robot; + Choice choice1; + Point pt; + Dimension size; + volatile boolean mouseDragged = false; + volatile boolean mouseDraggedOutside = false; + + public void setupUI() { + setTitle("Choce Drag Events Inside"); + choice1 = new Choice(); + for (int i = 1; i < 50; i++) { + choice1.add("item-0" + i); + } + choice1.setForeground(Color.red); + choice1.setBackground(Color.red); + choice1.addMouseMotionListener(new MouseMotionAdapter() { + public void mouseMoved(MouseEvent me) { + System.out.println(me); + } + + public void mouseDragged(MouseEvent me) { + System.out.println(me); + mouseDragged = true; + if (me.getY() < 0) { + mouseDraggedOutside = true; + } + } + } + ); + add(choice1); + setLayout(new FlowLayout()); + setSize(200, 200); + setLocationRelativeTo(null); + setVisible(true); + validate(); + } + + public void start() { + try { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.delay(100); + EventQueue.invokeAndWait(() -> { + pt = choice1.getLocationOnScreen(); + size = choice1.getSize(); + }); + testDragInsideChoice(InputEvent.BUTTON1_MASK); + testDragInsideChoiceList(InputEvent.BUTTON1_MASK); + testDragOutsideChoice(InputEvent.BUTTON1_MASK); + } catch (Throwable e) { + throw new RuntimeException("Test failed. Exception thrown: " + e); + } + } + + public void testDragInsideChoice(int button) { + robot.mouseMove(pt.x + size.width / 2, pt.y + size.height / 2); + robot.delay(100); + robot.mousePress(button); + robot.mouseRelease(button); + robot.delay(200); + robot.mousePress(button); + robot.mouseRelease(button); + robot.delay(200); + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + + robot.mouseMove(pt.x + size.width / 4, pt.y + size.height / 2); + robot.mousePress(button); + + dragMouse(pt.x + size.width / 4, pt.y + size.height / 2, + pt.x + size.width * 3 / 4, pt.y + size.height / 2); + robot.mouseRelease(button); + robot.delay(200); + if (!mouseDragged) { + throw new RuntimeException("Test failed. Choice should generate MouseDragged events inside Choice itself"); + } else { + System.out.println("Stage 1 passed. Choice generates MouseDragged events inside Choice itself"); + } + mouseDragged = false; + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + } + + public void testDragInsideChoiceList(int button) { + robot.mouseMove(pt.x + size.width / 2, pt.y + size.height / 2); + robot.delay(100); + robot.mousePress(button); + robot.mouseRelease(button); + robot.delay(200); + + robot.mouseMove(pt.x + size.width / 2, pt.y + 5 * size.height); + robot.delay(200); + robot.mousePress(button); + + dragMouse(pt.x + size.width / 2, pt.y + 5 * size.height, + pt.x + size.width / 2, pt.y + 8 * size.height); + robot.mouseRelease(button); + robot.delay(200); + if (mouseDragged) { + throw new RuntimeException("Test failed. Choice shouldn't generate MouseDragged events inside Choice's list"); + } else { + System.out.println("Stage 2 passed. Choice doesn't generate MouseDragged events inside Choice's list"); + } + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + mouseDragged = false; + } + + public void testDragOutsideChoice(int button) { + pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + size.width / 2, pt.y + size.height / 2); + robot.delay(100); + + robot.mousePress(button); + //drag mouse outside of Choice + dragMouse(pt.x + size.width / 2, pt.y + size.height / 2, + pt.x + size.width / 2, pt.y - 3 * size.height); + robot.mouseRelease(button); + robot.delay(200); + if (!mouseDragged || !mouseDraggedOutside) { + throw new RuntimeException("Test failed. Choice should generate MouseDragged events outside Choice"); + } else { + System.out.println("Stage 3 passed. Choice generates MouseDragged events outside Choice"); + } + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + mouseDragged = false; + } + + public void dragMouse(int x0, int y0, int x1, int y1) { + int curX = x0; + int curY = y0; + int dx = x0 < x1 ? 1 : -1; + int dy = y0 < y1 ? 1 : -1; + + while (curX != x1) { + curX += dx; + robot.mouseMove(curX, curY); + } + while (curY != y1) { + curY += dy; + robot.mouseMove(curX, curY); + } + } + + public static void main(final String[] args) throws InterruptedException, + InvocationTargetException { + ChoiceDragEventsInside app = new ChoiceDragEventsInside(); + try { + EventQueue.invokeAndWait(app::setupUI); + app.start(); + } finally { + EventQueue.invokeAndWait(app::dispose); + } + } +} diff --git a/test/jdk/java/awt/Choice/ChoiceMouseEventTest.java b/test/jdk/java/awt/Choice/ChoiceMouseEventTest.java new file mode 100644 index 0000000000000..9603d5c763de4 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceMouseEventTest.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4319246 + * @summary Tests that MouseReleased, MouseClicked and MouseDragged are triggered on choice + * @key headful + * @run main ChoiceMouseEventTest + */ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Choice; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.lang.reflect.InvocationTargetException; + + +public class ChoiceMouseEventTest extends Frame { + static volatile boolean mousePressed = false; + static volatile boolean mouseReleased = false; + static volatile boolean mouseClicked = false; + Choice choice = new Choice(); + static Point location; + static Dimension size; + + public void setupGUI() { + setTitle("Choice Mouse Event Test"); + this.setLayout(new BorderLayout()); + choice.add("item-1"); + choice.add("item-2"); + choice.add("item-3"); + choice.add("item-4"); + add("Center", choice); + choice.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + mouseClicked = true; + } + + @Override + public void mousePressed(MouseEvent e) { + mousePressed = true; + } + + @Override + public void mouseReleased(MouseEvent e) { + mouseReleased = true; + } + }); + setLocationRelativeTo(null); + setSize(400, 200); + setVisible(true); + } + + public Point _location() { + return choice.getLocationOnScreen(); + } + + public Dimension _size() { + return choice.getSize(); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + ChoiceMouseEventTest test = new ChoiceMouseEventTest(); + try { + EventQueue.invokeAndWait(test::setupGUI); + Robot robot = new Robot(); + robot.setAutoDelay(50); + robot.delay(1000); + robot.waitForIdle(); + EventQueue.invokeAndWait(() -> { + location = test._location(); + size = test._size(); + }); + robot.waitForIdle(); + robot.mouseMove(location.x + size.width - 10, location.y + (size.height / 2)); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(2000); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(2000); + robot.waitForIdle(); + if (!mouseClicked || !mousePressed || !mouseReleased) { + throw new RuntimeException(String.format("One of the events not arrived: " + + "mouseClicked = %b, mousePressed = %b, mouseReleased = %b", + mouseClicked, mousePressed, mouseReleased)); + } + } finally { + if (test != null) { + EventQueue.invokeAndWait(test::dispose); + } + } + } +} + diff --git a/test/jdk/java/awt/Choice/ChoiceRemoveTest.java b/test/jdk/java/awt/Choice/ChoiceRemoveTest.java new file mode 100644 index 0000000000000..6de66db936276 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceRemoveTest.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4079027 + * @summary Removing an item dynamically from a Choice object breaks lower items. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ChoiceRemoveTest + */ + +import java.awt.Choice; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Label; +import java.awt.Panel; +import java.awt.event.ItemEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.lang.reflect.InvocationTargetException; + +public class ChoiceRemoveTest extends Frame { + Choice selector; + static final String INSTRUCTIONS = """ + After window 'Choice Remove Test' appears wait for three seconds + and then click on the choice. In popup there should be no + 'Choice A' variant. Try selecting each variant with mouse + and verify by the log that the correct variant gets selected. + If after selecting item in the list the correct item gets selected + and correct item name appears in the log press Pass otherwise press Fail. + """; + + public static void main(String[] argv) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Test Instructions") + .testUI(ChoiceRemoveTest::new) + .instructions(INSTRUCTIONS) + .columns(40) + .logArea() + .build() + .awaitAndCheck(); + } + + public ChoiceRemoveTest() { + super("Choice Remove Test"); + Panel p; + Label prompt; + + addWindowListener(new WindowAdapter() { + @Override + public void windowOpened(WindowEvent e) { + super.windowOpened(e); + new Thread(() -> { + try { + Thread.sleep(2000); + } catch (InterruptedException ignore) { + } + removeFirst(); + }).start(); + } + }); + + setLayout(new GridLayout()); + p = new Panel(); + + prompt = new Label("Select different items including the last one"); + p.add(prompt); + + selector = new Choice(); + selector.add("Choice A"); + selector.add("Choice B"); + selector.add("Choice C"); + selector.add("Choice D"); + selector.add("Choice E"); + selector.addItemListener(e -> { + if (e.getStateChange() == ItemEvent.SELECTED) { + Object selected = e.getItem(); + PassFailJFrame.log(selected.toString()); + } + }); + p.add(selector); + add(p); + pack(); + } + + public void removeFirst() { + selector.remove("Choice A"); + } +} diff --git a/test/jdk/java/awt/Choice/PopupMenuOnChoiceArea.java b/test/jdk/java/awt/Choice/PopupMenuOnChoiceArea.java new file mode 100644 index 0000000000000..2a56d7281ee44 --- /dev/null +++ b/test/jdk/java/awt/Choice/PopupMenuOnChoiceArea.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6240046 + * @summary REG:Choice's Drop-down does not disappear when clicking somewhere, after popup menu is disposed-XTkt + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual PopupMenuOnChoiceArea + */ + + +import java.awt.CheckboxMenuItem; +import java.awt.Choice; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.PopupMenu; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.lang.reflect.InvocationTargetException; + +public class PopupMenuOnChoiceArea extends Frame { + static final String INSTRUCTIONS = """ + You would see a window named 'Popup menu on choice area' + with Choice in it. Move the mouse pointer to the choice. + Click right mouse button on it. + You should see a popup menu with 'File' in it. + Close this popup menu by pressing Esc. + Click the left mouse button on the Choice. + You should see a Choice drop-down menu. + Move mouse pointer into drop-down menu. + Click right mouse button on any item in it. + If you see a 'File' popup menu press Fail. + If Choice drop-down closes instead press Pass. + """; + + public PopupMenuOnChoiceArea() { + super("Popup menu on choice area"); + this.setLayout(new FlowLayout()); + Choice choice = new Choice(); + choice.add("item-1"); + choice.add("item-2"); + choice.add("item-3"); + choice.add("item-4"); + add("Center", choice); + Menu fileMenu = new Menu("File"); + Menu open = new Menu("Open"); + Menu save = new Menu("save"); + CheckboxMenuItem exit = new CheckboxMenuItem("Exit"); + fileMenu.add(open); + fileMenu.add(save); + fileMenu.add(exit); + final PopupMenu pop = new PopupMenu(); + pop.setLabel("This is a popup menu"); + pop.setName("a menu"); + pop.add(fileMenu); + choice.add(pop); + choice.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + if (me.isPopupTrigger()) { + pop.show(me.getComponent(), me.getX(), me.getY()); + } + } + + public void mouseReleased(MouseEvent me) { + if (me.isPopupTrigger()) { + pop.show(me.getComponent(), me.getX(), me.getY()); + } + } + }); + setSize(200, 200); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Test Instructions") + .testUI(PopupMenuOnChoiceArea::new) + .instructions(INSTRUCTIONS) + .columns(40) + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/java/awt/Choice/ScrollbarFlickers.java b/test/jdk/java/awt/Choice/ScrollbarFlickers.java new file mode 100644 index 0000000000000..c35d4900134fa --- /dev/null +++ b/test/jdk/java/awt/Choice/ScrollbarFlickers.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6405707 + * @summary Choice popup & scrollbar gets Flickering when mouse is pressed & drag on the scrollbar + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ScrollbarFlickers + */ + +import java.awt.BorderLayout; +import java.awt.Choice; +import java.awt.Frame; +import java.lang.reflect.InvocationTargetException; + +public class ScrollbarFlickers extends Frame { + static final String INSTRUCTIONS = """ + Open the choice popup. Select any item in it and + drag it with the mouse above or below the choice. + Keep the choice opened. + Continue dragging the mouse outside of the choice + making content of the popup scroll. + If you see that scrollbar flickers press Fail. + Otherwise press Pass. + """; + + public ScrollbarFlickers() { + super("Scrollbar Flickering Test"); + Choice ch = new Choice(); + setLayout(new BorderLayout()); + ch.add("Praveen"); + ch.add("Mohan"); + ch.add("Rakesh"); + ch.add("Menon"); + ch.add("Girish"); + ch.add("Ramachandran"); + ch.add("Elancheran"); + ch.add("Subramanian"); + ch.add("Raju"); + ch.add("Pallath"); + ch.add("Mayank"); + ch.add("Joshi"); + ch.add("Sundar"); + ch.add("Srinivas"); + ch.add("Mandalika"); + ch.add("Suresh"); + ch.add("Chandar"); + add(ch); + setSize(200, 200); + validate(); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Test Instructions") + .testUI(ScrollbarFlickers::new) + .instructions(INSTRUCTIONS) + .columns(40) + .build() + .awaitAndCheck(); + } +} From 6288b3d1222f289ba84fbb9cc697766a1067eb04 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:34:18 +0000 Subject: [PATCH 023/846] 8341535: sun/awt/font/TestDevTransform.java fails with RuntimeException: Different rendering Backport-of: 593c27e69703875115e6db5843a3743ba9bd8c18 --- test/jdk/sun/awt/font/TestDevTransform.java | 31 +++++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/test/jdk/sun/awt/font/TestDevTransform.java b/test/jdk/sun/awt/font/TestDevTransform.java index 035cb0b13d73a..2783401c0f2db 100644 --- a/test/jdk/sun/awt/font/TestDevTransform.java +++ b/test/jdk/sun/awt/font/TestDevTransform.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4269775 + * @bug 4269775 8341535 * @summary Check that different text rendering APIs agree */ @@ -46,6 +46,8 @@ import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; +import java.io.File; import java.util.HashMap; public class TestDevTransform { @@ -105,17 +107,34 @@ static void init(Graphics2D g2d) { g2d.setFont(font); } - static void compare(BufferedImage bi1, BufferedImage bi2) { + static void compare(BufferedImage bi1, String name1, BufferedImage bi2, String name2) throws Exception { + int nonWhite1 = 0; + int nonWhite2 = 0; + int differences = 0; + int whitePixel = Color.white.getRGB(); for (int x = 0; x < bi1.getWidth(); x++) { for (int y = 0; y < bi1.getHeight(); y++) { + int pix1 = bi1.getRGB(x, y); + int pix2 = bi2.getRGB(x, y); + if (pix1 != whitePixel) { nonWhite1++; } + if (pix2 != whitePixel) { nonWhite2++; } if (bi1.getRGB(x, y) != bi2.getRGB(x, y)) { - throw new RuntimeException("Different rendering"); + differences++; } } } + int nonWhite = (nonWhite1 < nonWhite2) ? nonWhite1 : nonWhite2; + if (differences > 0 && ((nonWhite / differences) < 20)) { + ImageIO.write(bi1, "png", new File(name1 + ".png")); + ImageIO.write(bi2, "png", new File(name2 + ".png")); + System.err.println("nonWhite image 1 = " + nonWhite1); + System.err.println("nonWhite image 2 = " + nonWhite2); + System.err.println("Number of non-white differing pixels=" + differences); + throw new RuntimeException("Different rendering: " + differences + " pixels differ."); + } } - public static void main(String args[]) { + public static void main(String args[]) throws Exception { BufferedImage tl_Image = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB); { @@ -149,7 +168,7 @@ public static void main(String args[]) { draw(gv_g2d, gv, 10f, 36f, .33f); } - compare(tl_Image, st_Image); - compare(gv_Image, st_Image); + compare(tl_Image, "textlayout", st_Image, "string"); + compare(gv_Image, "glyphvector", st_Image, "string"); } } From 11f91c35954821353d7186bf6c76f8e2ee8ba43e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:38:23 +0000 Subject: [PATCH 024/846] 8347911: Limit the length of inflated text chunks Backport-of: 398a580518b4e7961bdddf733e0a89ff25bc437a --- .../classes/com/sun/imageio/plugins/png/PNGImageReader.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java index 8cb93eaf727e6..b96a8216a5ca8 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -141,6 +141,7 @@ public class PNGImageReader extends ImageReader { static final int tRNS_TYPE = 0x74524e53; static final int zTXt_TYPE = 0x7a545874; + static final int MAX_INFLATED_TEXT_LENGTH = 262144; static final int PNG_COLOR_GRAY = 0; static final int PNG_COLOR_RGB = 2; static final int PNG_COLOR_PALETTE = 3; @@ -669,7 +670,7 @@ private void parse_tRNS_chunk(int chunkLength) throws IOException { private static byte[] inflate(byte[] b) throws IOException { InputStream bais = new ByteArrayInputStream(b); try (InputStream iis = new InflaterInputStream(bais)) { - return iis.readAllBytes(); + return iis.readNBytes(MAX_INFLATED_TEXT_LENGTH); } } From 8da895be39f28fbf325e3e591b40d8d6e5161e61 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:39:39 +0000 Subject: [PATCH 025/846] 8348299: Update List/ItemEventTest/ItemEventTest.java Use thread-safe StringBuffer to track selecting/deselecting items. Use auto waitForIdle for all events. Log handleEvent and ItemListener. Take screenshot of the list on failure; Optionally take screenshot after each mouse press+release. Backport-of: 605b53e4f8857c58a72fa361f8787c563d6dab90 --- .../awt/List/ItemEventTest/ItemEventTest.java | 144 +++++++++++------- 1 file changed, 90 insertions(+), 54 deletions(-) diff --git a/test/jdk/java/awt/List/ItemEventTest/ItemEventTest.java b/test/jdk/java/awt/List/ItemEventTest/ItemEventTest.java index c5d4537990563..ea0f339c92b62 100644 --- a/test/jdk/java/awt/List/ItemEventTest/ItemEventTest.java +++ b/test/jdk/java/awt/List/ItemEventTest/ItemEventTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -27,8 +27,13 @@ * @bug 8033936 8172510 * @summary Verify that correct ItemEvent is received while selection & * deselection of multi select List items. + * @library /test/lib + * @build jdk.test.lib.Platform + * @run main ItemEventTest */ +// Pass -save to the test to enable screenshots at each select/deselect + import java.awt.AWTException; import java.awt.Event; import java.awt.FlowLayout; @@ -37,26 +42,30 @@ import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; -import java.awt.event.KeyEvent; import java.awt.event.InputEvent; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; - -public class ItemEventTest extends Frame -{ - List list; - final String expectedSelectionOrder; - StringBuilder actualSelectionOrder; - Robot robot; - - public ItemEventTest() - { - try { - robot = new Robot(); - } catch(AWTException e) { - throw new RuntimeException(e.getMessage()); - } - expectedSelectionOrder = "01230123"; +import java.awt.event.KeyEvent; +import java.awt.image.RenderedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import jdk.test.lib.Platform; + +public final class ItemEventTest extends Frame { + private static final String expectedSelectionOrder = "01230123"; + + private static boolean saveScreenshots; + + private final StringBuffer actualSelectionOrder + = new StringBuffer(expectedSelectionOrder.length()); + + private final List list; + private final Robot robot; + + private ItemEventTest() throws AWTException { + robot = new Robot(); + robot.setAutoWaitForIdle(true); list = new List(4, true); list.add("0"); @@ -65,71 +74,76 @@ public ItemEventTest() list.add("3"); add(list); + setSize(400,400); setLayout(new FlowLayout()); pack(); + setLocationRelativeTo(null); setVisible(true); robot.waitForIdle(); } @Override + @SuppressWarnings("deprecation") public boolean handleEvent(Event e) { - if (e.target instanceof List) { - if (e.id == Event.LIST_DESELECT || e.id == Event.LIST_SELECT) { - actualSelectionOrder.append(e.arg); - } + if ((e.target instanceof List) + && (e.id == Event.LIST_DESELECT + || e.id == Event.LIST_SELECT)) { + logEvent("handleEvent: ", e.arg); } return true; } - void testHandleEvent() { + private void logEvent(String method, Object listItem) { + actualSelectionOrder.append(listItem); + System.out.println(method + listItem); + } + + private void testHandleEvent() { // When no ItemListener is added to List, parent's handleEvent is // called with ItemEvent. performTest(); } - void testItemListener() { - list.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent ie) { - actualSelectionOrder.append(ie.getItem()); - } - }); + private void testItemListener() { + list.addItemListener(ie + -> logEvent("testItemListener: ", ie.getItem())); performTest(); } - void performTest() { - actualSelectionOrder = new StringBuilder(); - Point loc = list.getLocationOnScreen(); - Rectangle rect = list.getBounds(); - int dY = rect.height / list.getItemCount(); - loc = new Point(loc.x + 10, loc.y + 5); + private void performTest() { + actualSelectionOrder.setLength(0); + + final Rectangle rect = getListBoundsOnScreen(); + final int dY = rect.height / list.getItemCount(); + final Point loc = new Point(rect.x + rect.width / 2, + rect.y + dY / 2); - String osName = System.getProperty("os.name"); - boolean isMac = osName.contains("Mac") || osName.contains("mac"); - if(isMac) { + if (Platform.isOSX()) { robot.keyPress(KeyEvent.VK_META); - robot.waitForIdle(); } // First loop to select & Second loop to deselect the list items. for (int j = 0; j < 2; ++j) { for (int i = 0; i < list.getItemCount(); ++i) { robot.mouseMove(loc.x, loc.y + i * dY); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); robot.waitForIdle(); - robot.mousePress(InputEvent.BUTTON1_MASK); - robot.waitForIdle(); - robot.mouseRelease(InputEvent.BUTTON1_MASK); - robot.waitForIdle(); + + if (saveScreenshots) { + saveImage(robot.createScreenCapture(rect)); + } } } - if(isMac) { + if (Platform.isOSX()) { robot.keyRelease(KeyEvent.VK_META); } - if (!expectedSelectionOrder.equals(actualSelectionOrder.toString())) { - dispose(); + if (!expectedSelectionOrder.contentEquals(actualSelectionOrder)) { + saveImage(robot.createScreenCapture(rect)); + throw new RuntimeException("ItemEvent for selection & deselection" + " of multi select List's item is not correct" + " Expected : " + expectedSelectionOrder @@ -137,10 +151,32 @@ void performTest() { } } - public static void main(String args[]) { - ItemEventTest test = new ItemEventTest(); - test.testHandleEvent(); - test.testItemListener(); - test.dispose(); + private Rectangle getListBoundsOnScreen() { + return new Rectangle(list.getLocationOnScreen(), + list.getSize()); + } + + private static int imageNo = 0; + + private static void saveImage(RenderedImage image) { + try { + ImageIO.write(image, + "png", + new File(String.format("image-%02d.png", + ++imageNo))); + } catch (IOException ignored) { + } + } + + public static void main(String[] args) throws AWTException { + saveScreenshots = args.length > 0 && "-save".equals(args[0]); + + ItemEventTest test = new ItemEventTest(); + try { + test.testHandleEvent(); + test.testItemListener(); + } finally { + test.dispose(); + } } } From 0048246a334ee4e55a3d8aa2a89bb040daacaa03 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:43:12 +0000 Subject: [PATCH 026/846] 8348600: Update PipeWire to 1.3.81 Backport-of: add3cd1ca470be8fd5e5e1930d7f789318eb8e6d --- src/java.desktop/unix/legal/pipewire.md | 7 +- .../libpipewire/include/pipewire/context.h | 61 +++- .../libpipewire/include/pipewire/core.h | 195 ++++++++--- .../libpipewire/include/pipewire/keys.h | 77 +++- .../libpipewire/include/pipewire/loop.h | 127 +++++-- .../libpipewire/include/pipewire/port.h | 51 ++- .../libpipewire/include/pipewire/properties.h | 45 ++- .../libpipewire/include/pipewire/protocol.h | 7 +- .../libpipewire/include/pipewire/proxy.h | 4 +- .../libpipewire/include/pipewire/stream.h | 271 +++++++++++--- .../libpipewire/include/pipewire/type.h | 45 +++ .../libpipewire/include/pipewire/utils.h | 12 + .../libpipewire/include/spa/buffer/buffer.h | 29 +- .../libpipewire/include/spa/buffer/meta.h | 53 ++- .../include/spa/buffer/type-info.h | 18 + .../libpipewire/include/spa/control/control.h | 9 +- .../include/spa/control/type-info.h | 1 + .../libpipewire/include/spa/debug/types.h | 28 +- .../native/libpipewire/include/spa/node/io.h | 140 ++++++-- .../libpipewire/include/spa/node/type-info.h | 1 + .../include/spa/param/audio/aac-types.h | 5 + .../libpipewire/include/spa/param/audio/aac.h | 5 + .../include/spa/param/audio/amr-types.h | 5 + .../libpipewire/include/spa/param/audio/amr.h | 5 + .../include/spa/param/audio/iec958-types.h | 21 ++ .../include/spa/param/audio/mp3-types.h | 5 + .../libpipewire/include/spa/param/audio/mp3.h | 5 + .../include/spa/param/audio/raw-types.h | 28 ++ .../libpipewire/include/spa/param/audio/raw.h | 10 +- .../include/spa/param/audio/wma-types.h | 5 + .../libpipewire/include/spa/param/audio/wma.h | 5 + .../include/spa/param/bluetooth/audio.h | 6 + .../include/spa/param/bluetooth/type-info.h | 5 + .../include/spa/param/buffers-types.h | 1 + .../libpipewire/include/spa/param/buffers.h | 7 +- .../include/spa/param/format-utils.h | 10 +- .../libpipewire/include/spa/param/format.h | 2 + .../libpipewire/include/spa/param/latency.h | 44 ++- .../include/spa/param/param-types.h | 6 + .../libpipewire/include/spa/param/param.h | 1 + .../include/spa/param/profiler-types.h | 1 + .../libpipewire/include/spa/param/profiler.h | 26 +- .../include/spa/param/props-types.h | 10 +- .../libpipewire/include/spa/param/props.h | 21 +- .../include/spa/param/route-types.h | 4 +- .../libpipewire/include/spa/param/tag-types.h | 39 +++ .../libpipewire/include/spa/param/tag.h | 46 +++ .../libpipewire/include/spa/param/type-info.h | 1 + .../include/spa/param/video/dsp-utils.h | 27 +- .../include/spa/param/video/format-utils.h | 15 +- .../include/spa/param/video/h264-utils.h | 16 +- .../include/spa/param/video/mjpg-utils.h | 16 +- .../include/spa/param/video/multiview.h | 9 +- .../include/spa/param/video/raw-types.h | 20 +- .../include/spa/param/video/raw-utils.h | 31 +- .../libpipewire/include/spa/param/video/raw.h | 11 +- .../libpipewire/include/spa/pod/builder.h | 94 ++--- .../libpipewire/include/spa/pod/event.h | 2 +- .../native/libpipewire/include/spa/pod/iter.h | 142 ++++---- .../libpipewire/include/spa/pod/parser.h | 70 ++-- .../libpipewire/include/spa/support/loop.h | 331 ++++++++++++------ .../libpipewire/include/spa/support/system.h | 145 ++++++-- .../libpipewire/include/spa/utils/cleanup.h | 124 +++++++ .../libpipewire/include/spa/utils/defs.h | 91 ++++- .../libpipewire/include/spa/utils/dict.h | 27 +- .../libpipewire/include/spa/utils/endian.h | 26 ++ .../include/spa/utils/enum-types.h | 8 +- .../libpipewire/include/spa/utils/hook.h | 114 +++++- .../libpipewire/include/spa/utils/list.h | 20 +- .../libpipewire/include/spa/utils/string.h | 46 ++- .../libpipewire/include/spa/utils/type-info.h | 5 +- .../libpipewire/include/spa/utils/type.h | 51 +++ 72 files changed, 2310 insertions(+), 641 deletions(-) create mode 100644 src/java.desktop/unix/native/libpipewire/include/pipewire/type.h create mode 100644 src/java.desktop/unix/native/libpipewire/include/spa/param/tag-types.h create mode 100644 src/java.desktop/unix/native/libpipewire/include/spa/param/tag.h create mode 100644 src/java.desktop/unix/native/libpipewire/include/spa/utils/cleanup.h create mode 100644 src/java.desktop/unix/native/libpipewire/include/spa/utils/endian.h diff --git a/src/java.desktop/unix/legal/pipewire.md b/src/java.desktop/unix/legal/pipewire.md index 88389a74e69dd..8275928e27150 100644 --- a/src/java.desktop/unix/legal/pipewire.md +++ b/src/java.desktop/unix/legal/pipewire.md @@ -1,4 +1,4 @@ -## PipeWire 0.3.68 +## PipeWire 1.3.81 ### PipeWire license: @@ -39,3 +39,8 @@ spa/include/spa/utils/string.h ``` Copyright © 2021 Red Hat, Inc. ``` + +spa/utils/cleanup.h: +``` +Copyright © 2023 PipeWire authors +``` diff --git a/src/java.desktop/unix/native/libpipewire/include/pipewire/context.h b/src/java.desktop/unix/native/libpipewire/include/pipewire/context.h index b02baf6c4c55f..7e1a2b29b9498 100644 --- a/src/java.desktop/unix/native/libpipewire/include/pipewire/context.h +++ b/src/java.desktop/unix/native/libpipewire/include/pipewire/context.h @@ -43,6 +43,7 @@ struct pw_context; struct pw_global; struct pw_impl_client; +struct pw_impl_node; #include #include @@ -50,7 +51,7 @@ struct pw_impl_client; /** context events emitted by the context object added with \ref pw_context_add_listener */ struct pw_context_events { -#define PW_VERSION_CONTEXT_EVENTS 0 +#define PW_VERSION_CONTEXT_EVENTS 1 uint32_t version; /** The context is being destroyed */ @@ -63,12 +64,24 @@ struct pw_context_events { void (*global_added) (void *data, struct pw_global *global); /** a global object was removed */ void (*global_removed) (void *data, struct pw_global *global); + + /** a driver was added, since 0.3.75 version:1 */ + void (*driver_added) (void *data, struct pw_impl_node *node); + /** a driver was removed, since 0.3.75 version:1 */ + void (*driver_removed) (void *data, struct pw_impl_node *node); }; -/** Make a new context object for a given main_loop. Ownership of the properties is taken */ -struct pw_context * pw_context_new(struct pw_loop *main_loop, /**< a main loop to run in */ - struct pw_properties *props, /**< extra properties */ - size_t user_data_size /**< extra user data size */); +/** Make a new context object for a given main_loop. Ownership of the properties is taken, even + * if the function returns NULL. + * + * \param main_loop A main loop to run in. This must stay alive unil pw_context_destroy() is called. + * \param props extra properties + * \param user_data_size extra user data size + * \return The context object on success, or NULL on failure, in which case errno is set. + * */ +struct pw_context * pw_context_new(struct pw_loop *main_loop, + struct pw_properties *props, + size_t user_data_size); /** destroy a context object, all resources except the main_loop will be destroyed */ void pw_context_destroy(struct pw_context *context); @@ -113,15 +126,27 @@ int pw_context_conf_section_match_rules(struct pw_context *context, const char * /** Get the context support objects */ const struct spa_support *pw_context_get_support(struct pw_context *context, uint32_t *n_support); -/** get the context main loop */ +/** Get the context main loop. Returns the value passed to pw_context_new(). */ struct pw_loop *pw_context_get_main_loop(struct pw_context *context); -/** get the context data loop. Since 0.3.56 */ +/** Get the context data loop. This loop runs on the realtime thread. This + * acquires a loop from the generic data.rt class. Use pw_context_acquire_loop() instead. + * Since 0.3.56 */ struct pw_data_loop *pw_context_get_data_loop(struct pw_context *context); +/** Get a data-loop. + * Since 1.1.0 */ +struct pw_loop *pw_context_acquire_loop(struct pw_context *context, const struct spa_dict *props); +/** Release a data-loop. + * Since 1.1.0 */ +void pw_context_release_loop(struct pw_context *context, struct pw_loop *loop); + /** Get the work queue from the context: Since 0.3.26 */ struct pw_work_queue *pw_context_get_work_queue(struct pw_context *context); +/** Get the memory pool from the context: Since 0.3.74 */ +struct pw_mempool *pw_context_get_mempool(struct pw_context *context); + /** Iterate the globals of the context. The callback should return * 0 to fetch the next item, any other value stops the iteration and returns * the value. When all callbacks return 0, this function returns 0 when all @@ -130,7 +155,10 @@ int pw_context_for_each_global(struct pw_context *context, int (*callback) (void *data, struct pw_global *global), void *data); -/** Find a context global by id */ +/** Find a context global by id. + * + * \return The global on success, or NULL on failure. If id is \ref PW_ID_CORE, + * this function will always return a non-NULL value. */ struct pw_global *pw_context_find_global(struct pw_context *context, /**< the context */ uint32_t id /**< the global id */); @@ -140,6 +168,7 @@ int pw_context_add_spa_lib(struct pw_context *context, const char *factory_regex /** find the library name for a spa factory */ const char * pw_context_find_spa_lib(struct pw_context *context, const char *factory_name); +/** Load a SPA handle from a context. On failure returns NULL and sets errno. */ struct spa_handle *pw_context_load_spa_handle(struct pw_context *context, const char *factory_name, const struct spa_dict *info); @@ -160,9 +189,21 @@ int pw_context_register_export_type(struct pw_context *context, struct pw_export /** find information about registered export type */ const struct pw_export_type *pw_context_find_export_type(struct pw_context *context, const char *type); -/** add an object to the context */ +/** add an object to the context + * + * \param context The context. + * \param type The type of the object, usually a `TYPE_INTERFACE_` value. + * \param value The object value. Must last as long as the context and must + * be of the type corresponding to the type. + * \return A negative number on failure (out of memory). + * */ int pw_context_set_object(struct pw_context *context, const char *type, void *value); -/** get an object from the context */ +/** get an object from the context + * + * \param context The context. + * \param type The string corresponding to the object's interface. + * \return The object, or NULL if the object does not exist. + * */ void *pw_context_get_object(struct pw_context *context, const char *type); /** diff --git a/src/java.desktop/unix/native/libpipewire/include/pipewire/core.h b/src/java.desktop/unix/native/libpipewire/include/pipewire/core.h index 23a9e16dfbf86..1acfded4b07ad 100644 --- a/src/java.desktop/unix/native/libpipewire/include/pipewire/core.h +++ b/src/java.desktop/unix/native/libpipewire/include/pipewire/core.h @@ -14,6 +14,8 @@ extern "C" { #include +#include + /** \defgroup pw_core Core * * \brief The core global object. @@ -34,11 +36,20 @@ extern "C" { #define PW_TYPE_INTERFACE_Core PW_TYPE_INFO_INTERFACE_BASE "Core" #define PW_TYPE_INTERFACE_Registry PW_TYPE_INFO_INTERFACE_BASE "Registry" +#define PW_CORE_PERM_MASK PW_PERM_R|PW_PERM_X|PW_PERM_M + #define PW_VERSION_CORE 4 struct pw_core; #define PW_VERSION_REGISTRY 3 struct pw_registry; +#ifndef PW_API_CORE_IMPL +#define PW_API_CORE_IMPL static inline +#endif +#ifndef PW_API_REGISTRY_IMPL +#define PW_API_REGISTRY_IMPL static inline +#endif + /** The default remote name to connect to */ #define PW_DEFAULT_REMOTE "pipewire-0" @@ -67,11 +78,13 @@ struct pw_core_info { #include #include -/** Update an existing \ref pw_core_info with \a update with reset */ +/** Update an existing \ref pw_core_info with \a update with reset. When info is NULL, + * a new one will be allocated. Returns NULL on failure. */ struct pw_core_info * pw_core_info_update(struct pw_core_info *info, const struct pw_core_info *update); -/** Update an existing \ref pw_core_info with \a update */ +/** Update an existing \ref pw_core_info with \a update. When info is NULL, a new one + * will be allocated. Returns NULL on failure */ struct pw_core_info * pw_core_info_merge(struct pw_core_info *info, const struct pw_core_info *update, bool reset); @@ -162,6 +175,9 @@ struct pw_core_events { * global ID. It is emitted before the global becomes visible in the * registry. * + * The bound_props event is an enhanced version of this event that + * also contains the extra global properties. + * * \param id bound object ID * \param global_id the global id bound to */ @@ -190,6 +206,21 @@ struct pw_core_events { */ void (*remove_mem) (void *data, uint32_t id); + /** + * Notify an object binding + * + * This event is emitted when a local object ID is bound to a + * global ID. It is emitted before the global becomes visible in the + * registry. + * + * This is an enhanced version of the bound_id event. + * + * \param id bound object ID + * \param global_id the global id bound to + * \param props The properties of the new global object. + * + * Since version 4:1 + */ void (*bound_props) (void *data, uint32_t id, uint32_t global_id, const struct spa_dict *props); }; @@ -223,6 +254,8 @@ struct pw_core_methods { * Start a conversation with the server. This will send * the core info and will destroy all resources for the client * (except the core and client resource). + * + * This requires X permissions on the core. */ int (*hello) (void *object, uint32_t version); /** @@ -235,6 +268,8 @@ struct pw_core_methods { * methods and the resulting events have been handled. * * \param seq the seq number passed to the done event + * + * This requires X permissions on the core. */ int (*sync) (void *object, uint32_t id, int seq); /** @@ -243,6 +278,8 @@ struct pw_core_methods { * Reply to the server ping event with the same seq. * * \param seq the seq number received in the ping event + * + * This requires X permissions on the core. */ int (*pong) (void *object, uint32_t id, int seq); /** @@ -257,9 +294,11 @@ struct pw_core_methods { * This method is usually also emitted on the resource object with * \a id. * - * \param id object where the error occurred + * \param id resource id where the error occurred * \param res error code * \param message error description + * + * This requires X permissions on the core. */ int (*error) (void *object, uint32_t id, int seq, int res, const char *message); /** @@ -269,6 +308,8 @@ struct pw_core_methods { * the global objects available from the PipeWire server * \param version the client version * \param user_data_size extra size + * + * This requires X permissions on the core. */ struct pw_registry * (*get_registry) (void *object, uint32_t version, size_t user_data_size); @@ -281,6 +322,8 @@ struct pw_core_methods { * \param version the version of the interface * \param props extra properties * \param user_data_size extra size + * + * This requires X permissions on the core. */ void * (*create_object) (void *object, const char *factory_name, @@ -294,27 +337,57 @@ struct pw_core_methods { * Destroy the server resource for the given proxy. * * \param obj the proxy to destroy + * + * This requires X permissions on the core. */ int (*destroy) (void *object, void *proxy); }; -#define pw_core_method(o,method,version,...) \ -({ \ - int _res = -ENOTSUP; \ - spa_interface_call_res((struct spa_interface*)o, \ - struct pw_core_methods, _res, \ - method, version, ##__VA_ARGS__); \ - _res; \ -}) -#define pw_core_add_listener(c,...) pw_core_method(c,add_listener,0,__VA_ARGS__) -#define pw_core_hello(c,...) pw_core_method(c,hello,0,__VA_ARGS__) -#define pw_core_sync(c,...) pw_core_method(c,sync,0,__VA_ARGS__) -#define pw_core_pong(c,...) pw_core_method(c,pong,0,__VA_ARGS__) -#define pw_core_error(c,...) pw_core_method(c,error,0,__VA_ARGS__) - - -static inline +/** \copydoc pw_core_methods.add_listener + * \sa pw_core_methods.add_listener */ +PW_API_CORE_IMPL int pw_core_add_listener(struct pw_core *object, + struct spa_hook *listener, + const struct pw_core_events *events, + void *data) +{ + return spa_api_method_r(int, -ENOTSUP, + pw_core, (struct spa_interface*)object, add_listener, 0, + listener, events, data); +} +/** \copydoc pw_core_methods.hello + * \sa pw_core_methods.hello */ +PW_API_CORE_IMPL int pw_core_hello(struct pw_core *object, uint32_t version) +{ + return spa_api_method_r(int, -ENOTSUP, + pw_core, (struct spa_interface*)object, hello, 0, + version); +} +/** \copydoc pw_core_methods.sync + * \sa pw_core_methods.sync */ +PW_API_CORE_IMPL int pw_core_sync(struct pw_core *object, uint32_t id, int seq) +{ + return spa_api_method_r(int, -ENOTSUP, + pw_core, (struct spa_interface*)object, sync, 0, + id, seq); +} +/** \copydoc pw_core_methods.pong + * \sa pw_core_methods.pong */ +PW_API_CORE_IMPL int pw_core_pong(struct pw_core *object, uint32_t id, int seq) +{ + return spa_api_method_r(int, -ENOTSUP, + pw_core, (struct spa_interface*)object, pong, 0, + id, seq); +} +/** \copydoc pw_core_methods.error + * \sa pw_core_methods.error */ +PW_API_CORE_IMPL int pw_core_error(struct pw_core *object, uint32_t id, int seq, int res, const char *message) +{ + return spa_api_method_r(int, -ENOTSUP, + pw_core, (struct spa_interface*)object, error, 0, + id, seq, res, message); +} +PW_API_CORE_IMPL SPA_PRINTF_FUNC(5, 0) int pw_core_errorv(struct pw_core *core, uint32_t id, int seq, int res, const char *message, va_list args) @@ -325,7 +398,7 @@ pw_core_errorv(struct pw_core *core, uint32_t id, int seq, return pw_core_error(core, id, seq, res, buffer); } -static inline +PW_API_CORE_IMPL SPA_PRINTF_FUNC(5, 6) int pw_core_errorf(struct pw_core *core, uint32_t id, int seq, int res, const char *message, ...) @@ -338,17 +411,18 @@ pw_core_errorf(struct pw_core *core, uint32_t id, int seq, return r; } -static inline struct pw_registry * +/** \copydoc pw_core_methods.get_registry + * \sa pw_core_methods.get_registry */ +PW_API_CORE_IMPL struct pw_registry * pw_core_get_registry(struct pw_core *core, uint32_t version, size_t user_data_size) { - struct pw_registry *res = NULL; - spa_interface_call_res((struct spa_interface*)core, - struct pw_core_methods, res, - get_registry, 0, version, user_data_size); - return res; + return spa_api_method_r(struct pw_registry*, NULL, + pw_core, (struct spa_interface*)core, get_registry, 0, + version, user_data_size); } - -static inline void * +/** \copydoc pw_core_methods.create_object + * \sa pw_core_methods.create_object */ +PW_API_CORE_IMPL void * pw_core_create_object(struct pw_core *core, const char *factory_name, const char *type, @@ -356,15 +430,18 @@ pw_core_create_object(struct pw_core *core, const struct spa_dict *props, size_t user_data_size) { - void *res = NULL; - spa_interface_call_res((struct spa_interface*)core, - struct pw_core_methods, res, - create_object, 0, factory_name, - type, version, props, user_data_size); - return res; + return spa_api_method_r(void*, NULL, + pw_core, (struct spa_interface*)core, create_object, 0, + factory_name, type, version, props, user_data_size); +} +/** \copydoc pw_core_methods.destroy + * \sa pw_core_methods.destroy */ +PW_API_CORE_IMPL void +pw_core_destroy(struct pw_core *core, void *proxy) +{ + spa_api_method_v(pw_core, (struct spa_interface*)core, destroy, 0, + proxy); } - -#define pw_core_destroy(c,...) pw_core_method(c,destroy,0,__VA_ARGS__) /** * \} @@ -474,36 +551,44 @@ struct pw_registry_methods { * * Try to destroy the global object. * - * \param id the global id to destroy + * \param id the global id to destroy. The client needs X permissions + * on the global. */ int (*destroy) (void *object, uint32_t id); }; -#define pw_registry_method(o,method,version,...) \ -({ \ - int _res = -ENOTSUP; \ - spa_interface_call_res((struct spa_interface*)o, \ - struct pw_registry_methods, _res, \ - method, version, ##__VA_ARGS__); \ - _res; \ -}) /** Registry */ -#define pw_registry_add_listener(p,...) pw_registry_method(p,add_listener,0,__VA_ARGS__) - -static inline void * +/** \copydoc pw_registry_methods.add_listener + * \sa pw_registry_methods.add_listener */ +PW_API_REGISTRY_IMPL int pw_registry_add_listener(struct pw_registry *registry, + struct spa_hook *listener, + const struct pw_registry_events *events, + void *data) +{ + return spa_api_method_r(int, -ENOTSUP, + pw_registry, (struct spa_interface*)registry, add_listener, 0, + listener, events, data); +} +/** \copydoc pw_registry_methods.bind + * \sa pw_registry_methods.bind */ +PW_API_REGISTRY_IMPL void * pw_registry_bind(struct pw_registry *registry, uint32_t id, const char *type, uint32_t version, size_t user_data_size) { - void *res = NULL; - spa_interface_call_res((struct spa_interface*)registry, - struct pw_registry_methods, res, - bind, 0, id, type, version, user_data_size); - return res; + return spa_api_method_r(void*, NULL, + pw_registry, (struct spa_interface*)registry, bind, 0, + id, type, version, user_data_size); +} +/** \copydoc pw_registry_methods.destroy + * \sa pw_registry_methods.destroy */ +PW_API_REGISTRY_IMPL int +pw_registry_destroy(struct pw_registry *registry, uint32_t id) +{ + return spa_api_method_r(int, -ENOTSUP, + pw_registry, (struct spa_interface*)registry, destroy, 0, id); } - -#define pw_registry_destroy(p,...) pw_registry_method(p,destroy,0,__VA_ARGS__) /** * \} diff --git a/src/java.desktop/unix/native/libpipewire/include/pipewire/keys.h b/src/java.desktop/unix/native/libpipewire/include/pipewire/keys.h index b7de764657a94..67ea3f9cce229 100644 --- a/src/java.desktop/unix/native/libpipewire/include/pipewire/keys.h +++ b/src/java.desktop/unix/native/libpipewire/include/pipewire/keys.h @@ -38,6 +38,14 @@ extern "C" { #define PW_KEY_SEC_GID "pipewire.sec.gid" /**< client gid, set by protocol*/ #define PW_KEY_SEC_LABEL "pipewire.sec.label" /**< client security label, set by protocol*/ +#define PW_KEY_SEC_SOCKET "pipewire.sec.socket" /**< client socket name, set by protocol */ + +#define PW_KEY_SEC_ENGINE "pipewire.sec.engine" /**< client secure context engine, set by protocol. + * This can also be set by a client when making a + * new security context. */ +#define PW_KEY_SEC_APP_ID "pipewire.sec.app-id" /**< client secure application id */ +#define PW_KEY_SEC_INSTANCE_ID "pipewire.sec.instance-id" /**< client secure instance id */ + #define PW_KEY_LIBRARY_NAME_SYSTEM "library.name.system" /**< name of the system library to use */ #define PW_KEY_LIBRARY_NAME_LOOP "library.name.loop" /**< name of the loop library to use */ #define PW_KEY_LIBRARY_NAME_DBUS "library.name.dbus" /**< name of the dbus library to use */ @@ -52,7 +60,8 @@ extern "C" { #define PW_KEY_OBJECT_LINGER "object.linger" /**< the object lives on even after the client * that created it has been destroyed */ #define PW_KEY_OBJECT_REGISTER "object.register" /**< If the object should be registered. */ - +#define PW_KEY_OBJECT_EXPORT "object.export" /**< If the object should be exported, + * since 0.3.72 */ /* config */ #define PW_KEY_CONFIG_PREFIX "config.prefix" /**< a config prefix directory */ @@ -60,6 +69,12 @@ extern "C" { #define PW_KEY_CONFIG_OVERRIDE_PREFIX "config.override.prefix" /**< a config override prefix directory */ #define PW_KEY_CONFIG_OVERRIDE_NAME "config.override.name" /**< a config override file name */ +/* loop */ +#define PW_KEY_LOOP_NAME "loop.name" /**< the name of a loop */ +#define PW_KEY_LOOP_CLASS "loop.class" /**< the classes this loop handles, array of strings */ +#define PW_KEY_LOOP_RT_PRIO "loop.rt-prio" /**< realtime priority of the loop */ +#define PW_KEY_LOOP_CANCEL "loop.cancel" /**< if the loop can be canceled */ + /* context */ #define PW_KEY_CONTEXT_PROFILE_MODULES "context.profile.modules" /**< a context profile for modules, deprecated */ #define PW_KEY_USER_NAME "context.user-name" /**< The user name that runs pipewire */ @@ -87,7 +102,9 @@ extern "C" { /* remote keys */ #define PW_KEY_REMOTE_NAME "remote.name" /**< The name of the remote to connect to, * default pipewire-0, overwritten by - * env(PIPEWIRE_REMOTE) */ + * env(PIPEWIRE_REMOTE). May also be + * a SPA-JSON array of sockets, to be tried + * in order. */ #define PW_KEY_REMOTE_INTENTION "remote.intention" /**< The intention of the remote connection, * "generic", "screencast" */ @@ -132,7 +149,14 @@ extern "C" { #define PW_KEY_NODE_SESSION "node.session" /**< the session id this node is part of */ #define PW_KEY_NODE_GROUP "node.group" /**< the group id this node is part of. Nodes * in the same group are always scheduled - * with the same driver. */ + * with the same driver. Can be an array of + * group names. */ +#define PW_KEY_NODE_SYNC_GROUP "node.sync-group" /**< the sync group this node is part of. Nodes + * in the same sync group are always scheduled + * together with the same driver when the sync + * is active. Can be an array of sync names. */ +#define PW_KEY_NODE_SYNC "node.sync" /**< if the sync-group is active or not */ +#define PW_KEY_NODE_TRANSPORT "node.transport" /**< if the transport is active or not */ #define PW_KEY_NODE_EXCLUSIVE "node.exclusive" /**< node wants exclusive access to resources */ #define PW_KEY_NODE_AUTOCONNECT "node.autoconnect" /**< node wants to be automatically connected * to a compatible node */ @@ -163,7 +187,23 @@ extern "C" { #define PW_KEY_NODE_SUSPEND_ON_IDLE "node.suspend-on-idle" /**< suspend the node when idle */ #define PW_KEY_NODE_CACHE_PARAMS "node.cache-params" /**< cache the node params */ #define PW_KEY_NODE_TRANSPORT_SYNC "node.transport.sync" /**< the node handles transport sync */ -#define PW_KEY_NODE_DRIVER "node.driver" /**< node can drive the graph */ +#define PW_KEY_NODE_DRIVER "node.driver" /**< node can drive the graph. When the node is + * selected as the driver, it needs to start + * the graph periodically. */ +#define PW_KEY_NODE_SUPPORTS_LAZY "node.supports-lazy" /**< the node can be a lazy driver. It will listen + * to RequestProcess commands and take them into + * account when deciding to start the graph. + * A value of 0 disables support, a value of > 0 + * enables with increasing preference. */ +#define PW_KEY_NODE_SUPPORTS_REQUEST "node.supports-request" /**< The node supports emiting RequestProcess events + * when it wants the graph to be scheduled. + * A value of 0 disables support, a value of > 0 + * enables with increasing preference. */ +#define PW_KEY_NODE_DRIVER_ID "node.driver-id" /**< the node id of the node assigned as driver + * for this node */ +#define PW_KEY_NODE_ASYNC "node.async" /**< the node wants async scheduling */ +#define PW_KEY_NODE_LOOP_NAME "node.loop.name" /**< the loop name fnmatch pattern to run in */ +#define PW_KEY_NODE_LOOP_CLASS "node.loop.class" /**< the loop class fnmatch pattern to run in */ #define PW_KEY_NODE_STREAM "node.stream" /**< node is a stream, the server side should * add a converter */ #define PW_KEY_NODE_VIRTUAL "node.virtual" /**< the node is some sort of virtual @@ -172,17 +212,20 @@ extern "C" { * on output/input/all ports when the value is * "out"/"in"/"true" respectively */ #define PW_KEY_NODE_LINK_GROUP "node.link-group" /**< the node is internally linked to - * nodes with the same link-group */ + * nodes with the same link-group. Can be an + * array of group names. */ #define PW_KEY_NODE_NETWORK "node.network" /**< the node is on a network */ #define PW_KEY_NODE_TRIGGER "node.trigger" /**< the node is not scheduled automatically * based on the dependencies in the graph * but it will be triggered explicitly. */ -#define PW_KEY_NODE_CHANNELNAMES "node.channel-names" /**< names of node's - * channels (unrelated to positions) */ -#define PW_KEY_NODE_DEVICE_PORT_NAME_PREFIX "node.device-port-name-prefix" /** override - * port name prefix for device ports, like capture and playback - * or disable the prefix completely if an empty string is provided */ - +#define PW_KEY_NODE_CHANNELNAMES "node.channel-names" /**< names of node's + * channels (unrelated to positions) */ +#define PW_KEY_NODE_DEVICE_PORT_NAME_PREFIX \ + "node.device-port-name-prefix" /**< override port name prefix for + * device ports, like capture and + * playback or disable the prefix + * completely if an empty string + * is provided */ /** Port keys */ #define PW_KEY_PORT_ID "port.id" /**< port id */ #define PW_KEY_PORT_NAME "port.name" /**< port name */ @@ -197,6 +240,8 @@ extern "C" { #define PW_KEY_PORT_EXTRA "port.extra" /**< api specific extra port info, API name * should be prefixed. "jack:flags:56" */ #define PW_KEY_PORT_PASSIVE "port.passive" /**< the ports wants passive links, since 0.3.67 */ +#define PW_KEY_PORT_IGNORE_LATENCY "port.ignore-latency" /**< latency ignored by peers, since 0.3.71 */ +#define PW_KEY_PORT_GROUP "port.group" /**< the port group of the port 1.2.0 */ /** link properties */ #define PW_KEY_LINK_ID "link.id" /**< a link id */ @@ -210,6 +255,7 @@ extern "C" { #define PW_KEY_LINK_FEEDBACK "link.feedback" /**< indicate that a link is a feedback * link and the target will receive data * in the next cycle */ +#define PW_KEY_LINK_ASYNC "link.async" /**< the link is using async io */ /** device properties */ #define PW_KEY_DEVICE_ID "device.id" /**< device id */ @@ -260,6 +306,7 @@ extern "C" { #define PW_KEY_MODULE_USAGE "module.usage" /**< a human readable usage description of * the module's arguments. */ #define PW_KEY_MODULE_VERSION "module.version" /**< a version string for the module. */ +#define PW_KEY_MODULE_DEPRECATED "module.deprecated" /**< the module is deprecated with this message */ /** Factory properties */ #define PW_KEY_FACTORY_ID "factory.id" /**< the factory id */ @@ -274,7 +321,10 @@ extern "C" { #define PW_KEY_STREAM_LATENCY_MAX "stream.latency.max" /**< The maximum latency of the stream */ #define PW_KEY_STREAM_MONITOR "stream.monitor" /**< Indicates that the stream is monitoring * and might select a less accurate but faster - * conversion algorithm. */ + * conversion algorithm. Monitor streams are also + * ignored when calculating the latency of their peer + * ports (since 0.3.71). + */ #define PW_KEY_STREAM_DONT_REMIX "stream.dont-remix" /**< don't remix channels */ #define PW_KEY_STREAM_CAPTURE_SINK "stream.capture.sink" /**< Try to capture the sink output instead of * source output */ @@ -292,6 +342,7 @@ extern "C" { #define PW_KEY_MEDIA_NAME "media.name" /**< media name. Ex: "Pink Floyd: Time" */ #define PW_KEY_MEDIA_TITLE "media.title" /**< title. Ex: "Time" */ #define PW_KEY_MEDIA_ARTIST "media.artist" /**< artist. Ex: "Pink Floyd" */ +#define PW_KEY_MEDIA_ALBUM "media.album" /**< album. Ex: "Dark Side of the Moon" */ #define PW_KEY_MEDIA_COPYRIGHT "media.copyright" /**< copyright string */ #define PW_KEY_MEDIA_SOFTWARE "media.software" /**< generator software */ #define PW_KEY_MEDIA_LANGUAGE "media.language" /**< language in POSIX format. Ex: en_GB */ @@ -327,9 +378,11 @@ extern "C" { # ifdef PW_ENABLE_DEPRECATED # define PW_KEY_PRIORITY_MASTER "priority.master" /**< deprecated, use priority.driver */ # define PW_KEY_NODE_TARGET "node.target" /**< deprecated since 0.3.64, use target.object. */ +# define PW_KEY_LOOP_RETRY_TIMEOUT "loop.retry-timeout" /**< deprecated since 1.3.0 */ # else # define PW_KEY_PRIORITY_MASTER PW_DEPRECATED("priority.master") # define PW_KEY_NODE_TARGET PW_DEPRECATED("node.target") +# define PW_KEY_LOOP_RETRY_TIMEOUT PW_DEPRECATED("loop.retry-timeout") # endif /* PW_ENABLE_DEPRECATED */ #endif /* PW_REMOVE_DEPRECATED */ diff --git a/src/java.desktop/unix/native/libpipewire/include/pipewire/loop.h b/src/java.desktop/unix/native/libpipewire/include/pipewire/loop.h index b3a5c55b83edb..94b2dc2780b3b 100644 --- a/src/java.desktop/unix/native/libpipewire/include/pipewire/loop.h +++ b/src/java.desktop/unix/native/libpipewire/include/pipewire/loop.h @@ -17,6 +17,8 @@ extern "C" { * PipeWire loop object provides an implementation of * the spa loop interfaces. It can be used to implement various * event loops. + * + * The members of \ref pw_loop are read-only. */ /** @@ -29,35 +31,118 @@ struct pw_loop { struct spa_loop *loop; /**< wrapped loop */ struct spa_loop_control *control; /**< loop control */ struct spa_loop_utils *utils; /**< loop utils */ + const char *name; }; +#ifndef PW_API_LOOP_IMPL +#define PW_API_LOOP_IMPL static inline +#endif + struct pw_loop * pw_loop_new(const struct spa_dict *props); void pw_loop_destroy(struct pw_loop *loop); -#define pw_loop_add_source(l,...) spa_loop_add_source((l)->loop,__VA_ARGS__) -#define pw_loop_update_source(l,...) spa_loop_update_source((l)->loop,__VA_ARGS__) -#define pw_loop_remove_source(l,...) spa_loop_remove_source((l)->loop,__VA_ARGS__) -#define pw_loop_invoke(l,...) spa_loop_invoke((l)->loop,__VA_ARGS__) - -#define pw_loop_get_fd(l) spa_loop_control_get_fd((l)->control) -#define pw_loop_add_hook(l,...) spa_loop_control_add_hook((l)->control,__VA_ARGS__) -#define pw_loop_enter(l) spa_loop_control_enter((l)->control) -#define pw_loop_iterate(l,...) spa_loop_control_iterate((l)->control,__VA_ARGS__) -#define pw_loop_leave(l) spa_loop_control_leave((l)->control) - -#define pw_loop_add_io(l,...) spa_loop_utils_add_io((l)->utils,__VA_ARGS__) -#define pw_loop_update_io(l,...) spa_loop_utils_update_io((l)->utils,__VA_ARGS__) -#define pw_loop_add_idle(l,...) spa_loop_utils_add_idle((l)->utils,__VA_ARGS__) -#define pw_loop_enable_idle(l,...) spa_loop_utils_enable_idle((l)->utils,__VA_ARGS__) -#define pw_loop_add_event(l,...) spa_loop_utils_add_event((l)->utils,__VA_ARGS__) -#define pw_loop_signal_event(l,...) spa_loop_utils_signal_event((l)->utils,__VA_ARGS__) -#define pw_loop_add_timer(l,...) spa_loop_utils_add_timer((l)->utils,__VA_ARGS__) -#define pw_loop_update_timer(l,...) spa_loop_utils_update_timer((l)->utils,__VA_ARGS__) -#define pw_loop_add_signal(l,...) spa_loop_utils_add_signal((l)->utils,__VA_ARGS__) -#define pw_loop_destroy_source(l,...) spa_loop_utils_destroy_source((l)->utils,__VA_ARGS__) +int pw_loop_set_name(struct pw_loop *loop, const char *name); + +PW_API_LOOP_IMPL int pw_loop_add_source(struct pw_loop *object, struct spa_source *source) +{ + return spa_loop_add_source(object->loop, source); +} +PW_API_LOOP_IMPL int pw_loop_update_source(struct pw_loop *object, struct spa_source *source) +{ + return spa_loop_update_source(object->loop, source); +} +PW_API_LOOP_IMPL int pw_loop_remove_source(struct pw_loop *object, struct spa_source *source) +{ + return spa_loop_remove_source(object->loop, source); +} +PW_API_LOOP_IMPL int pw_loop_invoke(struct pw_loop *object, + spa_invoke_func_t func, uint32_t seq, const void *data, + size_t size, bool block, void *user_data) +{ + return spa_loop_invoke(object->loop, func, seq, data, size, block, user_data); +} + +PW_API_LOOP_IMPL int pw_loop_get_fd(struct pw_loop *object) +{ + return spa_loop_control_get_fd(object->control); +} +PW_API_LOOP_IMPL void pw_loop_add_hook(struct pw_loop *object, + struct spa_hook *hook, const struct spa_loop_control_hooks *hooks, + void *data) +{ + spa_loop_control_add_hook(object->control, hook, hooks, data); +} +PW_API_LOOP_IMPL void pw_loop_enter(struct pw_loop *object) +{ + spa_loop_control_enter(object->control); +} +PW_API_LOOP_IMPL void pw_loop_leave(struct pw_loop *object) +{ + spa_loop_control_leave(object->control); +} +PW_API_LOOP_IMPL int pw_loop_iterate(struct pw_loop *object, + int timeout) +{ + return spa_loop_control_iterate_fast(object->control, timeout); +} + +PW_API_LOOP_IMPL struct spa_source * +pw_loop_add_io(struct pw_loop *object, int fd, uint32_t mask, + bool close, spa_source_io_func_t func, void *data) +{ + return spa_loop_utils_add_io(object->utils, fd, mask, close, func, data); +} +PW_API_LOOP_IMPL int pw_loop_update_io(struct pw_loop *object, + struct spa_source *source, uint32_t mask) +{ + return spa_loop_utils_update_io(object->utils, source, mask); +} +PW_API_LOOP_IMPL struct spa_source * +pw_loop_add_idle(struct pw_loop *object, bool enabled, + spa_source_idle_func_t func, void *data) +{ + return spa_loop_utils_add_idle(object->utils, enabled, func, data); +} +PW_API_LOOP_IMPL int pw_loop_enable_idle(struct pw_loop *object, + struct spa_source *source, bool enabled) +{ + return spa_loop_utils_enable_idle(object->utils, source, enabled); +} +PW_API_LOOP_IMPL struct spa_source * +pw_loop_add_event(struct pw_loop *object, spa_source_event_func_t func, void *data) +{ + return spa_loop_utils_add_event(object->utils, func, data); +} +PW_API_LOOP_IMPL int pw_loop_signal_event(struct pw_loop *object, + struct spa_source *source) +{ + return spa_loop_utils_signal_event(object->utils, source); +} +PW_API_LOOP_IMPL struct spa_source * +pw_loop_add_timer(struct pw_loop *object, spa_source_timer_func_t func, void *data) +{ + return spa_loop_utils_add_timer(object->utils, func, data); +} +PW_API_LOOP_IMPL int pw_loop_update_timer(struct pw_loop *object, + struct spa_source *source, struct timespec *value, + struct timespec *interval, bool absolute) +{ + return spa_loop_utils_update_timer(object->utils, source, value, interval, absolute); +} +PW_API_LOOP_IMPL struct spa_source * +pw_loop_add_signal(struct pw_loop *object, int signal_number, + spa_source_signal_func_t func, void *data) +{ + return spa_loop_utils_add_signal(object->utils, signal_number, func, data); +} +PW_API_LOOP_IMPL void pw_loop_destroy_source(struct pw_loop *object, + struct spa_source *source) +{ + return spa_loop_utils_destroy_source(object->utils, source); +} /** * \} diff --git a/src/java.desktop/unix/native/libpipewire/include/pipewire/port.h b/src/java.desktop/unix/native/libpipewire/include/pipewire/port.h index bb58cab97f53b..ef48c67c004d5 100644 --- a/src/java.desktop/unix/native/libpipewire/include/pipewire/port.h +++ b/src/java.desktop/unix/native/libpipewire/include/pipewire/port.h @@ -29,9 +29,15 @@ extern "C" { #define PW_TYPE_INTERFACE_Port PW_TYPE_INFO_INTERFACE_BASE "Port" +#define PW_PORT_PERM_MASK PW_PERM_R|PW_PERM_X|PW_PERM_M + #define PW_VERSION_PORT 3 struct pw_port; +#ifndef PW_API_PORT_IMPL +#define PW_API_PORT_IMPL static inline +#endif + /** The direction of a port */ #define pw_direction spa_direction #define PW_DIRECTION_INPUT SPA_DIRECTION_INPUT @@ -115,6 +121,8 @@ struct pw_port_methods { * * \param ids an array of param ids * \param n_ids the number of ids in \a ids + * + * This requires X permissions on the port. */ int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids); @@ -129,24 +137,43 @@ struct pw_port_methods { * \param start the start index or 0 for the first param * \param num the maximum number of params to retrieve * \param filter a param filter or NULL + * + * This requires X permissions on the port. */ int (*enum_params) (void *object, int seq, uint32_t id, uint32_t start, uint32_t num, const struct spa_pod *filter); }; -#define pw_port_method(o,method,version,...) \ -({ \ - int _res = -ENOTSUP; \ - spa_interface_call_res((struct spa_interface*)o, \ - struct pw_port_methods, _res, \ - method, version, ##__VA_ARGS__); \ - _res; \ -}) - -#define pw_port_add_listener(c,...) pw_port_method(c,add_listener,0,__VA_ARGS__) -#define pw_port_subscribe_params(c,...) pw_port_method(c,subscribe_params,0,__VA_ARGS__) -#define pw_port_enum_params(c,...) pw_port_method(c,enum_params,0,__VA_ARGS__) +/** \copydoc pw_port_methods.add_listener + * \sa pw_port_methods.add_listener */ +PW_API_PORT_IMPL int pw_port_add_listener(struct pw_port *object, + struct spa_hook *listener, + const struct pw_port_events *events, + void *data) +{ + return spa_api_method_r(int, -ENOTSUP, + pw_port, (struct spa_interface*)object, add_listener, 0, + listener, events, data); +} +/** \copydoc pw_port_methods.subscribe_params + * \sa pw_port_methods.subscribe_params */ +PW_API_PORT_IMPL int pw_port_subscribe_params(struct pw_port *object, uint32_t *ids, uint32_t n_ids) +{ + return spa_api_method_r(int, -ENOTSUP, + pw_port, (struct spa_interface*)object, subscribe_params, 0, + ids, n_ids); +} +/** \copydoc pw_port_methods.enum_params + * \sa pw_port_methods.enum_params */ +PW_API_PORT_IMPL int pw_port_enum_params(struct pw_port *object, + int seq, uint32_t id, uint32_t start, uint32_t num, + const struct spa_pod *filter) +{ + return spa_api_method_r(int, -ENOTSUP, + pw_port, (struct spa_interface*)object, enum_params, 0, + seq, id, start, num, filter); +} /** * \} diff --git a/src/java.desktop/unix/native/libpipewire/include/pipewire/properties.h b/src/java.desktop/unix/native/libpipewire/include/pipewire/properties.h index 3966be417bcb7..de67f33a50174 100644 --- a/src/java.desktop/unix/native/libpipewire/include/pipewire/properties.h +++ b/src/java.desktop/unix/native/libpipewire/include/pipewire/properties.h @@ -11,9 +11,14 @@ extern "C" { #include +#include #include #include +#ifndef PW_API_PROPERTIES +#define PW_API_PROPERTIES static inline +#endif + /** \defgroup pw_properties Properties * * Properties are used to pass around arbitrary key/value pairs. @@ -40,6 +45,10 @@ pw_properties_new_dict(const struct spa_dict *dict); struct pw_properties * pw_properties_new_string(const char *args); +struct pw_properties * +pw_properties_new_string_checked(const char *args, size_t size, + struct spa_error_location *loc); + struct pw_properties * pw_properties_copy(const struct pw_properties *properties); @@ -51,10 +60,14 @@ int pw_properties_update_ignore(struct pw_properties *props, /* Update props with all key/value pairs from dict */ int pw_properties_update(struct pw_properties *props, const struct spa_dict *dict); + /* Update props with all key/value pairs from str */ int pw_properties_update_string(struct pw_properties *props, const char *str, size_t size); +int pw_properties_update_string_checked(struct pw_properties *props, + const char *str, size_t size, struct spa_error_location *loc); + int pw_properties_add(struct pw_properties *oldprops, const struct spa_dict *dict); int pw_properties_add_keys(struct pw_properties *oldprops, @@ -92,7 +105,7 @@ pw_properties_fetch_int64(const struct pw_properties *properties, const char *ke int pw_properties_fetch_bool(const struct pw_properties *properties, const char *key, bool *value); -static inline uint32_t +PW_API_PROPERTIES uint32_t pw_properties_get_uint32(const struct pw_properties *properties, const char *key, uint32_t deflt) { uint32_t val = deflt; @@ -100,7 +113,7 @@ pw_properties_get_uint32(const struct pw_properties *properties, const char *key return val; } -static inline int32_t +PW_API_PROPERTIES int32_t pw_properties_get_int32(const struct pw_properties *properties, const char *key, int32_t deflt) { int32_t val = deflt; @@ -108,7 +121,7 @@ pw_properties_get_int32(const struct pw_properties *properties, const char *key, return val; } -static inline uint64_t +PW_API_PROPERTIES uint64_t pw_properties_get_uint64(const struct pw_properties *properties, const char *key, uint64_t deflt) { uint64_t val = deflt; @@ -116,7 +129,7 @@ pw_properties_get_uint64(const struct pw_properties *properties, const char *key return val; } -static inline int64_t +PW_API_PROPERTIES int64_t pw_properties_get_int64(const struct pw_properties *properties, const char *key, int64_t deflt) { int64_t val = deflt; @@ -125,7 +138,7 @@ pw_properties_get_int64(const struct pw_properties *properties, const char *key, } -static inline bool +PW_API_PROPERTIES bool pw_properties_get_bool(const struct pw_properties *properties, const char *key, bool deflt) { bool val = deflt; @@ -136,34 +149,38 @@ pw_properties_get_bool(const struct pw_properties *properties, const char *key, const char * pw_properties_iterate(const struct pw_properties *properties, void **state); -#define PW_PROPERTIES_FLAG_NL (1<<0) +#define PW_PROPERTIES_FLAG_NL (1<<0) +#define PW_PROPERTIES_FLAG_RECURSE (1<<1) +#define PW_PROPERTIES_FLAG_ENCLOSE (1<<2) +#define PW_PROPERTIES_FLAG_ARRAY (1<<3) +#define PW_PROPERTIES_FLAG_COLORS (1<<4) int pw_properties_serialize_dict(FILE *f, const struct spa_dict *dict, uint32_t flags); -static inline bool pw_properties_parse_bool(const char *value) { +PW_API_PROPERTIES bool pw_properties_parse_bool(const char *value) { return spa_atob(value); } -static inline int pw_properties_parse_int(const char *value) { +PW_API_PROPERTIES int pw_properties_parse_int(const char *value) { int v; return spa_atoi32(value, &v, 0) ? v: 0; } -static inline int64_t pw_properties_parse_int64(const char *value) { +PW_API_PROPERTIES int64_t pw_properties_parse_int64(const char *value) { int64_t v; return spa_atoi64(value, &v, 0) ? v : 0; } -static inline uint64_t pw_properties_parse_uint64(const char *value) { +PW_API_PROPERTIES uint64_t pw_properties_parse_uint64(const char *value) { uint64_t v; return spa_atou64(value, &v, 0) ? v : 0; } -static inline float pw_properties_parse_float(const char *value) { +PW_API_PROPERTIES float pw_properties_parse_float(const char *value) { float v; return spa_atof(value, &v) ? v : 0.0f; } -static inline double pw_properties_parse_double(const char *value) { +PW_API_PROPERTIES double pw_properties_parse_double(const char *value) { double v; return spa_atod(value, &v) ? v : 0.0; } @@ -172,6 +189,10 @@ static inline double pw_properties_parse_double(const char *value) { * \} */ +SPA_DEFINE_AUTOPTR_CLEANUP(pw_properties, struct pw_properties, { + spa_clear_ptr(*thing, pw_properties_free); +}) + #ifdef __cplusplus } #endif diff --git a/src/java.desktop/unix/native/libpipewire/include/pipewire/protocol.h b/src/java.desktop/unix/native/libpipewire/include/pipewire/protocol.h index f119a31b5db46..f306979877a11 100644 --- a/src/java.desktop/unix/native/libpipewire/include/pipewire/protocol.h +++ b/src/java.desktop/unix/native/libpipewire/include/pipewire/protocol.h @@ -81,7 +81,7 @@ struct pw_protocol_marshal { }; struct pw_protocol_implementation { -#define PW_VERSION_PROTOCOL_IMPLEMENTATION 0 +#define PW_VERSION_PROTOCOL_IMPLEMENTATION 1 uint32_t version; struct pw_protocol_client * (*new_client) (struct pw_protocol *protocol, @@ -90,6 +90,10 @@ struct pw_protocol_implementation { struct pw_protocol_server * (*add_server) (struct pw_protocol *protocol, struct pw_impl_core *core, const struct spa_dict *props); + struct pw_protocol_server * (*add_fd_server) (struct pw_protocol *protocol, + struct pw_impl_core *core, + int listen_fd, int close_fd, + const struct spa_dict *props); }; struct pw_protocol_events { @@ -101,6 +105,7 @@ struct pw_protocol_events { #define pw_protocol_new_client(p,...) (pw_protocol_get_implementation(p)->new_client(p,__VA_ARGS__)) #define pw_protocol_add_server(p,...) (pw_protocol_get_implementation(p)->add_server(p,__VA_ARGS__)) +#define pw_protocol_add_fd_server(p,...) (pw_protocol_get_implementation(p)->add_fd_server(p,__VA_ARGS__)) #define pw_protocol_ext(p,type,method,...) (((type*)pw_protocol_get_extension(p))->method( __VA_ARGS__)) struct pw_protocol *pw_protocol_new(struct pw_context *context, const char *name, size_t user_data_size); diff --git a/src/java.desktop/unix/native/libpipewire/include/pipewire/proxy.h b/src/java.desktop/unix/native/libpipewire/include/pipewire/proxy.h index ecd8038a2c0f6..ca7f324c285c1 100644 --- a/src/java.desktop/unix/native/libpipewire/include/pipewire/proxy.h +++ b/src/java.desktop/unix/native/libpipewire/include/pipewire/proxy.h @@ -12,6 +12,8 @@ extern "C" { #include /** \page page_proxy Proxy + * + * \see \ref pw_proxy * * \section sec_page_proxy_overview Overview * @@ -76,7 +78,7 @@ extern "C" { * invoked by the client to PipeWire messages. Events will call the handlers * set in listener. * - * See \ref page_proxy + * \see \ref page_proxy */ /** diff --git a/src/java.desktop/unix/native/libpipewire/include/pipewire/stream.h b/src/java.desktop/unix/native/libpipewire/include/pipewire/stream.h index 90096056a0c57..dca13d22669c4 100644 --- a/src/java.desktop/unix/native/libpipewire/include/pipewire/stream.h +++ b/src/java.desktop/unix/native/libpipewire/include/pipewire/stream.h @@ -10,6 +10,8 @@ extern "C" { #endif /** \page page_streams Streams + * + * \see \ref pw_stream * * \section sec_overview Overview * @@ -56,11 +58,15 @@ extern "C" { * \li PW_DIRECTION_INPUT for a stream that *consumes* data. This can be a * stream that captures from a Source or a when the stream is used to - * implement a Sink. + * implement a Sink. An application will use a \ref PW_DIRECTION_INPUT + * stream to record data. A virtual sound card will use a + * \ref PW_DIRECTION_INPUT stream to implement audio playback. * * \li PW_DIRECTION_OUTPUT for a stream that *produces* data. This can be a * stream that plays to a Sink or when the stream is used to implement - * a Source. + * a Source. An application will use a \ref PW_DIRECTION_OUTPUT + * stream to produce data. A virtual sound card or camera will use a + * \ref PW_DIRECTION_OUTPUT stream to implement audio or video recording. * * \subsection ssec_stream_target Stream target * @@ -127,8 +133,25 @@ extern "C" { * When the buffer has been processed, call \ref pw_stream_queue_buffer() * to let PipeWire reuse the buffer. * + * Although not strictly required, it is recommended to call \ref + * pw_stream_dequeue_buffer() and pw_stream_queue_buffer() from the + * process() callback to minimize the amount of buffering and + * maximize the amount of buffer reuse in the stream. + * + * It is also possible to dequeue the buffer from the process event, + * then process and queue the buffer from a helper thread. It is also + * possible to dequeue, process and queue a buffer from a helper thread + * after receiving the process event. + * * \subsection ssec_produce Produce data * + * The process event is emitted when a new buffer should be queued. + * + * When the PW_STREAM_FLAG_RT_PROCESS flag was given, this function will be + * called from a realtime thread and it is not safe to call non-reatime + * functions such as doing file operations, blocking operations or any of + * the PipeWire functions that are not explicitly marked as being RT safe. + * * \ref pw_stream_dequeue_buffer() gives an empty buffer that can be filled. * * The buffer is owned by the stream and stays alive until the @@ -136,8 +159,45 @@ extern "C" { * * Filled buffers should be queued with \ref pw_stream_queue_buffer(). * - * The process event is emitted when PipeWire has emptied a buffer that - * can now be refilled. + * Although not strictly required, it is recommended to call \ref + * pw_stream_dequeue_buffer() and pw_stream_queue_buffer() from the + * process() callback to minimize the amount of buffering and + * maximize the amount of buffer reuse in the stream. + * + * Buffers that are queued after the process event completes will be delayed + * to the next processing cycle. + * + * \section sec_stream_driving Driving the graph + * + * Starting in 0.3.34, it is possible for a stream to drive the graph. + * This allows interrupt-driven scheduling for drivers implemented as + * PipeWire streams, without having to reimplement the stream as a SPA + * plugin. + * + * A stream cannot drive the graph unless it is in the + * \ref PW_STREAM_STATE_STREAMING state and \ref pw_stream_is_driving() returns + * true. It must then use pw_stream_trigger_process() to start the graph + * cycle. + * + * \ref pw_stream_trigger_process() will result in a process event, where a buffer + * should be dequeued, and queued again. This is the recommended behaviour that + * minimizes buffering and maximized buffer reuse. + * + * Producers of data that drive the graph can also dequeue a buffer in a helper + * thread, fill it with data and then call \ref pw_stream_trigger_process() to + * start the graph cycle. In the process event they will then queue the filled + * buffer and dequeue a new empty buffer to fill again in the helper thread, + * + * Consumers of data that drive the graph (pull based scheduling) will use + * \ref pw_stream_trigger_process() to start the graph and will dequeue, process + * and queue the buffers in the process event. + * + * \section sec_stream_process_requests Request processing + * + * A stream that is not driving the graph can request a new graph cycle by doing + * \ref pw_stream_trigger_process(). This will result in a RequestProcess command + * in the driver stream. If the driver supports this, it can then perform + * \ref pw_stream_trigger_process() to start the actual graph cycle. * * \section sec_stream_disconnect Disconnect * @@ -151,6 +211,9 @@ extern "C" { * * \section sec_stream_environment Environment Variables * + * The environment variable PIPEWIRE_AUTOCONNECT can be used to override the + * flag and force apps to autoconnect or not. + * */ /** \defgroup pw_stream Stream * @@ -159,7 +222,7 @@ extern "C" { * The stream object provides a convenient way to send and * receive data streams from/to PipeWire. * - * See also \ref page_streams and \ref api_pw_core + * \see \ref page_streams, \ref api_pw_core */ /** @@ -171,6 +234,7 @@ struct pw_stream; #include #include #include +#include /** \enum pw_stream_state The state of a stream */ enum pw_stream_state { @@ -182,19 +246,29 @@ enum pw_stream_state { }; /** a buffer structure obtained from pw_stream_dequeue_buffer(). The size of this - * structure can grow as more field are added in the future */ + * structure can grow as more fields are added in the future */ struct pw_buffer { struct spa_buffer *buffer; /**< the spa buffer */ - void *user_data; /**< user data attached to the buffer */ + void *user_data; /**< user data attached to the buffer. The user of + * the stream can set custom data associated with the + * buffer, typically in the add_buffer event. Any + * cleanup should be performed in the remove_buffer + * event. The user data is returned unmodified each + * time a buffer is dequeued. */ uint64_t size; /**< This field is set by the user and the sum of - * all queued buffer is returned in the time info. + * all queued buffers is returned in the time info. * For audio, it is advised to use the number of - * samples in the buffer for this field. */ + * frames in the buffer for this field. */ uint64_t requested; /**< For playback streams, this field contains the * suggested amount of data to provide. For audio - * streams this will be the amount of samples + * streams this will be the amount of frames * required by the resampler. This field is 0 * when no suggestion is provided. Since 0.3.49 */ + uint64_t time; /**< For capture streams, this field contains the + * cycle time in nanoseconds when this buffer was + * queued in the stream. It can be compared against + * the pw_time values or pw_stream_get_nsec() + * Since 1.0.5 */ }; struct pw_stream_control { @@ -223,25 +297,33 @@ struct pw_stream_control { * value, and pw_time.ticks, were captured at pw_time.now and can be extrapolated * to the current time like this: * - * struct timespec ts; - * clock_gettime(CLOCK_MONOTONIC, &ts); - * int64_t diff = SPA_TIMESPEC_TO_NSEC(&ts) - pw_time.now; + *\code{.c} + * uint64_t now = pw_stream_get_nsec(stream); + * int64_t diff = now - pw_time.now; * int64_t elapsed = (pw_time.rate.denom * diff) / (pw_time.rate.num * SPA_NSEC_PER_SEC); + *\endcode * * pw_time.delay contains the total delay that a signal will travel through the * graph. This includes the delay caused by filters in the graph as well as delays * caused by the hardware. The delay is usually quite stable and should only change when * the topology, quantum or samplerate of the graph changes. * + * The delay requires the application to send the stream early relative to other synchronized + * streams in order to arrive at the edge of the graph in time. This is usually done by + * delaying the other streams with the given delay. + * + * Note that the delay can be negative. A negative delay means that this stream should be + * delayed with the (positive) delay relative to other streams. + * * pw_time.queued and pw_time.buffered is expressed in the time domain of the stream, * or the format that is used for the buffers of this stream. * * pw_time.queued is the sum of all the pw_buffer.size fields of the buffers that are * currently queued in the stream but not yet processed. The application can choose - * the units of this value, for example, time, samples or bytes (below expressed - * as app.rate). + * the units of this value, for example, time, samples, frames or bytes (below + * expressed as app.rate). * - * pw_time.buffered is format dependent, for audio/raw it contains the number of samples + * pw_time.buffered is format dependent, for audio/raw it contains the number of frames * that are buffered inside the resampler/converter. * * The total delay of data in a stream is the sum of the queued and buffered data @@ -252,15 +334,21 @@ struct pw_stream_control { * in milliseconds for the first sample in the newly queued buffer to be played * by the hardware can be calculated as: * + *\code{.unparsed} * (pw_time.buffered * 1000 / stream.samplerate) + * (pw_time.queued * 1000 / app.rate) + * ((pw_time.delay - elapsed) * 1000 * pw_time.rate.num / pw_time.rate.denom) + *\endcode * * The current extrapolated time (in ms) in the source or sink can be calculated as: * + *\code{.unparsed} * (pw_time.ticks + elapsed) * 1000 * pw_time.rate.num / pw_time.rate.denom + *\endcode * + * Below is an overview of the different timing values: * + *\code{.unparsed} * stream time domain graph time domain * /-----------------------\/-----------------------------\ * @@ -272,14 +360,15 @@ struct pw_stream_control { * latency latency * \--------/\-------------/\-----------------------------/ * queued buffered delay + *\endcode */ struct pw_time { - int64_t now; /**< the monotonic time in nanoseconds. This is the time - * when this time report was updated. It is usually - * updated every graph cycle. You can use the current - * monotonic time to calculate the elapsed time between - * this report and the current state and calculate - * updated ticks and delay values. */ + int64_t now; /**< the time in nanoseconds. This is the time when this + * time report was updated. It is usually updated every + * graph cycle. You can use pw_stream_get_nsec() to + * calculate the elapsed time between this report and + * the current time and calculate updated ticks and delay + * values. */ struct spa_fraction rate; /**< the rate of \a ticks and delay. This is usually * expressed in 1/. */ uint64_t ticks; /**< the ticks at \a now. This is the current time that @@ -298,10 +387,14 @@ struct pw_time { * of the size fields in the pw_buffer that are * currently queued */ uint64_t buffered; /**< for audio/raw streams, this contains the extra - * number of samples buffered in the resampler. + * number of frames buffered in the resampler. * Since 0.3.50. */ - uint32_t queued_buffers; /**< The number of buffers that are queued. Since 0.3.50 */ - uint32_t avail_buffers; /**< The number of buffers that can be dequeued. Since 0.3.50 */ + uint32_t queued_buffers; /**< the number of buffers that are queued. Since 0.3.50 */ + uint32_t avail_buffers; /**< the number of buffers that can be dequeued. Since 0.3.50 */ + uint64_t size; /**< for audio/raw playback streams, this contains the number of + * samples requested by the resampler for the current + * quantum. for audio/raw capture streams this will be the number + * of samples available for the current quantum. Since 1.1.0 */ }; #include @@ -342,7 +435,10 @@ struct pw_stream_events { /** A command notify, Since 0.3.39:1 */ void (*command) (void *data, const struct spa_command *command); - /** a trigger_process completed. Since version 0.3.40:2 */ + /** a trigger_process completed. Since version 0.3.40:2. + * This is normally called from the mainloop but since 1.1.0 it + * can also be called directly from the realtime data + * thread if the user is prepared to deal with this. */ void (*trigger_done) (void *data); }; @@ -357,7 +453,8 @@ enum pw_stream_flags { PW_STREAM_FLAG_INACTIVE = (1 << 1), /**< start the stream inactive, * pw_stream_set_active() needs to be * called explicitly */ - PW_STREAM_FLAG_MAP_BUFFERS = (1 << 2), /**< mmap the buffers except DmaBuf */ + PW_STREAM_FLAG_MAP_BUFFERS = (1 << 2), /**< mmap the buffers except DmaBuf that is not + * explicitly marked as mappable. */ PW_STREAM_FLAG_DRIVER = (1 << 3), /**< be a driver */ PW_STREAM_FLAG_RT_PROCESS = (1 << 4), /**< call process from the realtime * thread. You MUST use RT safe functions @@ -375,9 +472,24 @@ enum pw_stream_flags { * needs to be called. This can be used * when the output of the stream depends * on input from other streams. */ + PW_STREAM_FLAG_ASYNC = (1 << 10), /**< Buffers will not be dequeued/queued from + * the realtime process() function. This is + * assumed when RT_PROCESS is unset but can + * also be the case when the process() function + * does a trigger_process() that will then + * dequeue/queue a buffer from another process() + * function. since 0.3.73 */ + PW_STREAM_FLAG_EARLY_PROCESS = (1 << 11), /**< Call process as soon as there is a buffer + * to dequeue. This is only relevant for + * playback and when not using RT_PROCESS. It + * can be used to keep the maximum number of + * buffers queued. Since 0.3.81 */ + PW_STREAM_FLAG_RT_TRIGGER_DONE = (1 << 12), /**< Call trigger_done from the realtime + * thread. You MUST use RT safe functions + * in the trigger_done callback. Since 1.1.0 */ }; -/** Create a new unconneced \ref pw_stream +/** Create a new unconnected \ref pw_stream * \return a newly allocated \ref pw_stream */ struct pw_stream * pw_stream_new(struct pw_core *core, /**< a \ref pw_core */ @@ -385,7 +497,7 @@ pw_stream_new(struct pw_core *core, /**< a \ref pw_core */ struct pw_properties *props /**< stream properties, ownership is taken */); struct pw_stream * -pw_stream_new_simple(struct pw_loop *loop, /**< a \ref pw_loop to use */ +pw_stream_new_simple(struct pw_loop *loop, /**< a \ref pw_loop to use as the main loop */ const char *name, /**< a stream media name */ struct pw_properties *props,/**< stream properties, ownership is taken */ const struct pw_stream_events *events, /**< stream events */ @@ -447,45 +559,62 @@ int pw_stream_set_error(struct pw_stream *stream, /**< a \ref pw_stream */ const char *error, /**< an error message */ ...) SPA_PRINTF_FUNC(3, 4); -/** Complete the negotiation process with result code \a res - * - * This function should be called after notification of the format. - - * When \a res indicates success, \a params contain the parameters for the - * allocation state. */ +/** Update the param exposed on the stream. */ int pw_stream_update_params(struct pw_stream *stream, /**< a \ref pw_stream */ - const struct spa_pod **params, /**< an array of params. The params should - * ideally contain parameters for doing - * buffer allocation. */ + const struct spa_pod **params, /**< an array of params. */ uint32_t n_params /**< number of elements in \a params */); +/** + * Set a parameter on the stream. This is like pw_stream_set_control() but with + * a complete spa_pod param. It can also be called from the param_changed event handler + * to intercept and modify the param for the adapter. Since 0.3.70 */ +int pw_stream_set_param(struct pw_stream *stream, /**< a \ref pw_stream */ + uint32_t id, /**< the id of the param */ + const struct spa_pod *param /**< the params to set */); + /** Get control values */ const struct pw_stream_control *pw_stream_get_control(struct pw_stream *stream, uint32_t id); /** Set control values */ int pw_stream_set_control(struct pw_stream *stream, uint32_t id, uint32_t n_values, float *values, ...); -/** Query the time on the stream */ +/** Query the time on the stream, RT safe */ int pw_stream_get_time_n(struct pw_stream *stream, struct pw_time *time, size_t size); +/** Get the current time in nanoseconds. This value can be compared with + * the \ref pw_time.now value. RT safe. Since 1.1.0 */ +uint64_t pw_stream_get_nsec(struct pw_stream *stream); + +/** Get the data loop that is doing the processing of this stream. This loop + * is assigned after pw_stream_connect(). * Since 1.1.0 */ +struct pw_loop *pw_stream_get_data_loop(struct pw_stream *stream); + /** Query the time on the stream, deprecated since 0.3.50, - * use pw_stream_get_time_n() to get the fields added since 0.3.50. */ + * use pw_stream_get_time_n() to get the fields added since 0.3.50. RT safe. */ SPA_DEPRECATED int pw_stream_get_time(struct pw_stream *stream, struct pw_time *time); /** Get a buffer that can be filled for playback streams or consumed - * for capture streams. */ + * for capture streams. RT safe. */ struct pw_buffer *pw_stream_dequeue_buffer(struct pw_stream *stream); -/** Submit a buffer for playback or recycle a buffer for capture. */ +/** Submit a buffer for playback or recycle a buffer for capture. RT safe. */ int pw_stream_queue_buffer(struct pw_stream *stream, struct pw_buffer *buffer); +/** Return a buffer to the queue without using it. This makes the buffer + * immediately available to dequeue again. RT safe. */ +int pw_stream_return_buffer(struct pw_stream *stream, struct pw_buffer *buffer); + /** Activate or deactivate the stream */ int pw_stream_set_active(struct pw_stream *stream, bool active); /** Flush a stream. When \a drain is true, the drained callback will - * be called when all data is played or recorded */ + * be called when all data is played or recorded. The stream can be resumed + * after the drain by setting it active again with + * \ref pw_stream_set_active(). A flush without a drain is mostly useful afer + * a state change to PAUSED, to flush any remaining data from the queues and + * the converters. RT safe. */ int pw_stream_flush(struct pw_stream *stream, bool drain); /** Check if the stream is driving. The stream needs to have the @@ -494,10 +623,64 @@ int pw_stream_flush(struct pw_stream *stream, bool drain); * available (output) or needed (input). Since 0.3.34 */ bool pw_stream_is_driving(struct pw_stream *stream); +/** Check if the graph is using lazy scheduling. If the stream is + * driving according to \ref pw_stream_is_driving(), then it should + * consider taking into account the RequestProcess commands when + * driving the graph. + * + * If the stream is not driving, it should send out RequestProcess + * events with \ref pw_stream_emit_event() or indirectly with + * \ref pw_stream_trigger_process() to suggest a new graph cycle + * to the driver. + * + * It is not a requirement that all RequestProcess events/commands + * need to start a graph cycle. + * Since 1.4.0 */ +bool pw_stream_is_lazy(struct pw_stream *stream); + /** Trigger a push/pull on the stream. One iteration of the graph will - * scheduled and process() will be called. Since 0.3.34 */ + * be scheduled when the stream is driving according to + * \ref pw_stream_is_driving(). If it successfully finishes, process() + * will be called and the trigger_done event will be emitted. It is + * possible for the graph iteration to not finish, so + * pw_stream_trigger_process() needs to be called again even if process() + * and trigger_done is not called. + * + * If there is a deadline after which the stream will have xrun, + * pw_stream_trigger_process() should be called then, whether or not + * process()/trigger_done has been called. Sound hardware will xrun if + * there is any delay in audio processing, so the ALSA plugin triggers the + * graph every quantum to ensure audio keeps flowing. Drivers that + * do not have a deadline, such as the freewheel driver, should + * use a timeout to ensure that forward progress keeps being made. + * A reasonable choice of deadline is three times the quantum: if + * the graph is taking 3x longer than normal, it is likely that it + * is hung and should be retriggered. + * + * Streams that are not drivers according to \ref pw_stream_is_driving() + * can also call this method. The result is that a RequestProcess event + * is sent to the driver. If the graph is lazy scheduling according to + * \ref pw_stream_is_lazy(), this might result in a graph cycle by the + * driver. If the graph is not lazy scheduling and the stream is not a + * driver, this method will have no effect. + * + * RT safe. + * + * Since 0.3.34 */ int pw_stream_trigger_process(struct pw_stream *stream); +/** Emit an event from this stream. RT safe. + * Since 1.2.6 */ +int pw_stream_emit_event(struct pw_stream *stream, const struct spa_event *event); + +/** Adjust the rate of the stream. + * When the stream is using an adaptive resampler, adjust the resampler rate. + * When there is no resampler, -ENOTSUP is returned. Activating the adaptive + * resampler will add a small amount of delay to the samples, you can deactivate + * it again by setting a value <= 0.0. RT safe. + * Since 1.4.0 */ +int pw_stream_set_rate(struct pw_stream *stream, double rate); + /** * \} */ diff --git a/src/java.desktop/unix/native/libpipewire/include/pipewire/type.h b/src/java.desktop/unix/native/libpipewire/include/pipewire/type.h new file mode 100644 index 0000000000000..2035811666ea3 --- /dev/null +++ b/src/java.desktop/unix/native/libpipewire/include/pipewire/type.h @@ -0,0 +1,45 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef PIPEWIRE_TYPE_H +#define PIPEWIRE_TYPE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** \defgroup pw_type Type info + * Type information + */ + +/** + * \addtogroup pw_type + * \{ + */ + +enum { + PW_TYPE_FIRST = SPA_TYPE_VENDOR_PipeWire, +}; + +#define PW_TYPE_INFO_BASE "PipeWire:" + +#define PW_TYPE_INFO_Object PW_TYPE_INFO_BASE "Object" +#define PW_TYPE_INFO_OBJECT_BASE PW_TYPE_INFO_Object ":" + +#define PW_TYPE_INFO_Interface PW_TYPE_INFO_BASE "Interface" +#define PW_TYPE_INFO_INTERFACE_BASE PW_TYPE_INFO_Interface ":" + +const struct spa_type_info * pw_type_info(void); + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_TYPE_H */ diff --git a/src/java.desktop/unix/native/libpipewire/include/pipewire/utils.h b/src/java.desktop/unix/native/libpipewire/include/pipewire/utils.h index 19110db81a4a8..c584320487549 100644 --- a/src/java.desktop/unix/native/libpipewire/include/pipewire/utils.h +++ b/src/java.desktop/unix/native/libpipewire/include/pipewire/utils.h @@ -15,11 +15,13 @@ extern "C" { #ifndef _POSIX_C_SOURCE # include #endif +#include #ifndef ENODATA #define ENODATA 9919 #endif +#include #include #include @@ -45,6 +47,12 @@ pw_split_strv(const char *str, const char *delimiter, int max_tokens, int *n_tok int pw_split_ip(char *str, const char *delimiter, int max_tokens, char *tokens[]); +char **pw_strv_parse(const char *val, size_t len, int max_tokens, int *n_tokens); + +int pw_strv_find(char **a, const char *b); + +int pw_strv_find_common(char **a, char **b); + void pw_free_strv(char **str); @@ -92,6 +100,10 @@ void* pw_reallocarray(void *ptr, size_t nmemb, size_t size); * \} */ +SPA_DEFINE_AUTO_CLEANUP(pw_strv, char **, { + spa_clear_ptr(*thing, pw_free_strv); +}) + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/buffer/buffer.h b/src/java.desktop/unix/native/libpipewire/include/spa/buffer/buffer.h index a5e2ac7ffff40..b287a76dec138 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/buffer/buffer.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/buffer/buffer.h @@ -12,6 +12,14 @@ extern "C" { #include #include +#ifndef SPA_API_BUFFER + #ifdef SPA_API_IMPL + #define SPA_API_BUFFER SPA_API_IMPL + #else + #define SPA_API_BUFFER static inline + #endif +#endif + /** \defgroup spa_buffer Buffers * * Buffers describe the data and metadata that is exchanged between @@ -27,9 +35,15 @@ enum spa_data_type { SPA_DATA_Invalid, SPA_DATA_MemPtr, /**< pointer to memory, the data field in * struct spa_data is set. */ - SPA_DATA_MemFd, /**< generic fd, mmap to get to memory */ - SPA_DATA_DmaBuf, /**< fd to dmabuf memory */ - SPA_DATA_MemId, /**< memory is identified with an id */ + SPA_DATA_MemFd, /**< memfd, mmap to get to memory. */ + SPA_DATA_DmaBuf, /**< fd to dmabuf memory. This might not be readily + * mappable (unless the MAPPABLE flag is set) and should + * normally be handled with DMABUF apis. */ + SPA_DATA_MemId, /**< memory is identified with an id. The actual memory + * can be obtained in some other way and can be identified + * with this id. */ + SPA_DATA_SyncObj, /**< a syncobj, usually requires a spa_meta_sync_timeline metadata + * with timeline points. */ _SPA_DATA_LAST, /**< not part of ABI */ }; @@ -65,9 +79,12 @@ struct spa_data { #define SPA_DATA_FLAG_WRITABLE (1u<<1) /**< data is writable */ #define SPA_DATA_FLAG_DYNAMIC (1u<<2) /**< data pointer can be changed */ #define SPA_DATA_FLAG_READWRITE (SPA_DATA_FLAG_READABLE|SPA_DATA_FLAG_WRITABLE) +#define SPA_DATA_FLAG_MAPPABLE (1u<<3) /**< data is mappable with simple mmap/munmap. Some memory + * types are not simply mappable (DmaBuf) unless explicitly + * specified with this flag. */ uint32_t flags; /**< data flags */ int64_t fd; /**< optional fd for data */ - uint32_t mapoffset; /**< offset to map fd at */ + uint32_t mapoffset; /**< offset to map fd at, this is page aligned */ uint32_t maxsize; /**< max size of data */ void *data; /**< optional data pointer */ struct spa_chunk *chunk; /**< valid chunk of memory */ @@ -82,7 +99,7 @@ struct spa_buffer { }; /** Find metadata in a buffer */ -static inline struct spa_meta *spa_buffer_find_meta(const struct spa_buffer *b, uint32_t type) +SPA_API_BUFFER struct spa_meta *spa_buffer_find_meta(const struct spa_buffer *b, uint32_t type) { uint32_t i; @@ -93,7 +110,7 @@ static inline struct spa_meta *spa_buffer_find_meta(const struct spa_buffer *b, return NULL; } -static inline void *spa_buffer_find_meta_data(const struct spa_buffer *b, uint32_t type, size_t size) +SPA_API_BUFFER void *spa_buffer_find_meta_data(const struct spa_buffer *b, uint32_t type, size_t size) { struct spa_meta *m; if ((m = spa_buffer_find_meta(b, type)) && m->size >= size) diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/buffer/meta.h b/src/java.desktop/unix/native/libpipewire/include/spa/buffer/meta.h index bf67f12b7f156..dbb452b56d70b 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/buffer/meta.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/buffer/meta.h @@ -12,6 +12,14 @@ extern "C" { #include #include +#ifndef SPA_API_META + #ifdef SPA_API_IMPL + #define SPA_API_META SPA_API_IMPL + #else + #define SPA_API_META static inline + #endif +#endif + /** * \addtogroup spa_buffer * \{ @@ -28,6 +36,7 @@ enum spa_meta_type { * associated with the data */ SPA_META_Busy, /**< don't write to buffer when count > 0 */ SPA_META_VideoTransform, /**< struct spa_meta_transform */ + SPA_META_SyncTimeline, /**< struct spa_meta_sync_timeline */ _SPA_META_LAST, /**< not part of ABI/API */ }; @@ -45,14 +54,13 @@ struct spa_meta { void *data; /**< pointer to metadata */ }; -static inline void *spa_meta_first(const struct spa_meta *m) { +SPA_API_META void *spa_meta_first(const struct spa_meta *m) { return m->data; } -#define spa_meta_first spa_meta_first -static inline void *spa_meta_end(const struct spa_meta *m) { + +SPA_API_META void *spa_meta_end(const struct spa_meta *m) { return SPA_PTROFF(m->data,m->size,void); } -#define spa_meta_end spa_meta_end #define spa_meta_check(p,m) (SPA_PTROFF(p,sizeof(*(p)),void) <= spa_meta_end(m)) /** @@ -79,19 +87,16 @@ struct spa_meta_region { struct spa_region region; }; -static inline bool spa_meta_region_is_valid(const struct spa_meta_region *m) { +SPA_API_META bool spa_meta_region_is_valid(const struct spa_meta_region *m) { return m->region.size.width != 0 && m->region.size.height != 0; } -#define spa_meta_region_is_valid spa_meta_region_is_valid /** iterate all the items in a metadata */ #define spa_meta_for_each(pos,meta) \ - for ((pos) = (__typeof(pos))spa_meta_first(meta); \ + for ((pos) = (__typeof(pos))spa_meta_first(meta); \ spa_meta_check(pos, meta); \ (pos)++) -#define spa_meta_bitmap_is_valid(m) ((m)->format != 0) - /** * Bitmap information * @@ -111,7 +116,9 @@ struct spa_meta_bitmap { * info. */ }; -#define spa_meta_cursor_is_valid(m) ((m)->id != 0) +SPA_API_META bool spa_meta_bitmap_is_valid(const struct spa_meta_bitmap *m) { + return m->format != 0; +} /** * Cursor information @@ -131,6 +138,10 @@ struct spa_meta_cursor { * struct spa_meta_bitmap at the offset. */ }; +SPA_API_META bool spa_meta_cursor_is_valid(const struct spa_meta_cursor *m) { + return m->id != 0; +} + /** a timed set of events associated with the buffer */ struct spa_meta_control { struct spa_pod_sequence sequence; @@ -149,7 +160,7 @@ enum spa_meta_videotransform_value { SPA_META_TRANSFORMATION_270, /**< 270 degree counter-clockwise */ SPA_META_TRANSFORMATION_Flipped, /**< 180 degree flipped around the vertical axis. Equivalent * to a reflexion through the vertical line splitting the - * bufffer in two equal sized parts */ + * buffer in two equal sized parts */ SPA_META_TRANSFORMATION_Flipped90, /**< flip then rotate around 90 degree counter-clockwise */ SPA_META_TRANSFORMATION_Flipped180, /**< flip then rotate around 180 degree counter-clockwise */ SPA_META_TRANSFORMATION_Flipped270, /**< flip then rotate around 270 degree counter-clockwise */ @@ -161,6 +172,26 @@ struct spa_meta_videotransform { * one of enum spa_meta_videotransform_value */ }; +/** + * A timeline point for explicit sync + * + * Metadata to describe the time on the timeline when the buffer + * can be acquired and when it can be reused. + * + * This metadata will require negotiation of 2 extra fds for the acquire + * and release timelines respectively. One way to achieve this is to place + * this metadata as SPA_PARAM_BUFFERS_metaType when negotiating a buffer + * layout with 2 extra fds. + */ +struct spa_meta_sync_timeline { + uint32_t flags; + uint32_t padding; + uint64_t acquire_point; /**< the timeline acquire point, this is when the data + * can be accessed. */ + uint64_t release_point; /**< the timeline release point, this timeline point should + * be signaled when the data is no longer accessed. */ +}; + /** * \} */ diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/buffer/type-info.h b/src/java.desktop/unix/native/libpipewire/include/spa/buffer/type-info.h index a5208c0b944da..2a9c43c3a421d 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/buffer/type-info.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/buffer/type-info.h @@ -35,6 +35,7 @@ static const struct spa_type_info spa_type_data_type[] = { { SPA_DATA_MemFd, SPA_TYPE_Int, SPA_TYPE_INFO_DATA_FD_BASE "MemFd", NULL }, { SPA_DATA_DmaBuf, SPA_TYPE_Int, SPA_TYPE_INFO_DATA_FD_BASE "DmaBuf", NULL }, { SPA_DATA_MemId, SPA_TYPE_Int, SPA_TYPE_INFO_DATA_BASE "MemId", NULL }, + { SPA_DATA_SyncObj, SPA_TYPE_Int, SPA_TYPE_INFO_DATA_BASE "SyncObj", NULL }, { 0, 0, NULL, NULL }, }; @@ -50,6 +51,22 @@ static const struct spa_type_info spa_type_data_type[] = { #define SPA_TYPE_INFO_META_ARRAY_Region SPA_TYPE_INFO_META_ARRAY_BASE "Region" #define SPA_TYPE_INFO_META_ARRAY_REGION_BASE SPA_TYPE_INFO_META_ARRAY_Region ":" +/* VideoTransform meta */ +#define SPA_TYPE_INFO_META_Transformation SPA_TYPE_INFO_ENUM_BASE "Meta:Transformation" +#define SPA_TYPE_INFO_META_TRANSFORMATION_BASE SPA_TYPE_INFO_META_Transformation ":" + +static const struct spa_type_info spa_type_meta_videotransform_type[] = { + { SPA_META_TRANSFORMATION_None, SPA_TYPE_Int, SPA_TYPE_INFO_META_TRANSFORMATION_BASE "None", NULL }, + { SPA_META_TRANSFORMATION_90, SPA_TYPE_Int, SPA_TYPE_INFO_META_TRANSFORMATION_BASE "90", NULL }, + { SPA_META_TRANSFORMATION_180, SPA_TYPE_Int, SPA_TYPE_INFO_META_TRANSFORMATION_BASE "180", NULL }, + { SPA_META_TRANSFORMATION_270, SPA_TYPE_Int, SPA_TYPE_INFO_META_TRANSFORMATION_BASE "270", NULL }, + { SPA_META_TRANSFORMATION_Flipped, SPA_TYPE_Int, SPA_TYPE_INFO_META_TRANSFORMATION_BASE "Flipped", NULL }, + { SPA_META_TRANSFORMATION_Flipped90, SPA_TYPE_Int, SPA_TYPE_INFO_META_TRANSFORMATION_BASE "Flipped90", NULL }, + { SPA_META_TRANSFORMATION_Flipped180, SPA_TYPE_Int, SPA_TYPE_INFO_META_TRANSFORMATION_BASE "Flipped180", NULL }, + { SPA_META_TRANSFORMATION_Flipped270, SPA_TYPE_Int, SPA_TYPE_INFO_META_TRANSFORMATION_BASE "Flipped270", NULL }, + { 0, 0, NULL, NULL }, +}; + static const struct spa_type_info spa_type_meta_type[] = { { SPA_META_Invalid, SPA_TYPE_Pointer, SPA_TYPE_INFO_META_BASE "Invalid", NULL }, { SPA_META_Header, SPA_TYPE_Pointer, SPA_TYPE_INFO_META_BASE "Header", NULL }, @@ -60,6 +77,7 @@ static const struct spa_type_info spa_type_meta_type[] = { { SPA_META_Control, SPA_TYPE_Pointer, SPA_TYPE_INFO_META_BASE "Control", NULL }, { SPA_META_Busy, SPA_TYPE_Pointer, SPA_TYPE_INFO_META_BASE "Busy", NULL }, { SPA_META_VideoTransform, SPA_TYPE_Pointer, SPA_TYPE_INFO_META_BASE "VideoTransform", NULL }, + { SPA_META_SyncTimeline, SPA_TYPE_Pointer, SPA_TYPE_INFO_META_BASE "SyncTimeline", NULL }, { 0, 0, NULL, NULL }, }; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/control/control.h b/src/java.desktop/unix/native/libpipewire/include/spa/control/control.h index ed04c7e5b9683..43877eef9cc08 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/control/control.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/control/control.h @@ -24,9 +24,12 @@ extern "C" { /** Different Control types */ enum spa_control_type { SPA_CONTROL_Invalid, - SPA_CONTROL_Properties, /**< data contains a SPA_TYPE_OBJECT_Props */ - SPA_CONTROL_Midi, /**< data contains a spa_pod_bytes with raw midi data */ - SPA_CONTROL_OSC, /**< data contains a spa_pod_bytes with an OSC packet */ + SPA_CONTROL_Properties, /**< SPA_TYPE_OBJECT_Props */ + SPA_CONTROL_Midi, /**< spa_pod_bytes with raw midi data (deprecated, use SPA_CONTROL_UMP) */ + SPA_CONTROL_OSC, /**< spa_pod_bytes with an OSC packet */ + SPA_CONTROL_UMP, /**< spa_pod_bytes with raw UMP (universal MIDI packet) + * data. The UMP 32 bit words are stored in native endian + * format. */ _SPA_CONTROL_LAST, /**< not part of ABI */ }; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/control/type-info.h b/src/java.desktop/unix/native/libpipewire/include/spa/control/type-info.h index a3a61a153c7b2..3db937ec616f0 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/control/type-info.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/control/type-info.h @@ -27,6 +27,7 @@ static const struct spa_type_info spa_type_control[] = { { SPA_CONTROL_Properties, SPA_TYPE_Int, SPA_TYPE_INFO_CONTROL_BASE "Properties", NULL }, { SPA_CONTROL_Midi, SPA_TYPE_Int, SPA_TYPE_INFO_CONTROL_BASE "Midi", NULL }, { SPA_CONTROL_OSC, SPA_TYPE_Int, SPA_TYPE_INFO_CONTROL_BASE "OSC", NULL }, + { SPA_CONTROL_UMP, SPA_TYPE_Int, SPA_TYPE_INFO_CONTROL_BASE "UMP", NULL }, { 0, 0, NULL, NULL }, }; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/debug/types.h b/src/java.desktop/unix/native/libpipewire/include/spa/debug/types.h index dda912e7c04e0..b32fd28ed9c7e 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/debug/types.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/debug/types.h @@ -18,7 +18,16 @@ extern "C" { #include -static inline const struct spa_type_info *spa_debug_type_find(const struct spa_type_info *info, uint32_t type) +#ifndef SPA_API_DEBUG_TYPES + #ifdef SPA_API_IMPL + #define SPA_API_DEBUG_TYPES SPA_API_IMPL + #else + #define SPA_API_DEBUG_TYPES static inline + #endif +#endif + + +SPA_API_DEBUG_TYPES const struct spa_type_info *spa_debug_type_find(const struct spa_type_info *info, uint32_t type) { const struct spa_type_info *res; @@ -37,22 +46,19 @@ static inline const struct spa_type_info *spa_debug_type_find(const struct spa_t return NULL; } -static inline const char *spa_debug_type_short_name(const char *name) +SPA_API_DEBUG_TYPES const char *spa_debug_type_short_name(const char *name) { - const char *h; - if ((h = strrchr(name, ':')) != NULL) - name = h + 1; - return name; + return spa_type_short_name(name); } -static inline const char *spa_debug_type_find_name(const struct spa_type_info *info, uint32_t type) +SPA_API_DEBUG_TYPES const char *spa_debug_type_find_name(const struct spa_type_info *info, uint32_t type) { if ((info = spa_debug_type_find(info, type)) == NULL) return NULL; return info->name; } -static inline const char *spa_debug_type_find_short_name(const struct spa_type_info *info, uint32_t type) +SPA_API_DEBUG_TYPES const char *spa_debug_type_find_short_name(const struct spa_type_info *info, uint32_t type) { const char *str; if ((str = spa_debug_type_find_name(info, type)) == NULL) @@ -60,7 +66,7 @@ static inline const char *spa_debug_type_find_short_name(const struct spa_type_i return spa_debug_type_short_name(str); } -static inline uint32_t spa_debug_type_find_type(const struct spa_type_info *info, const char *name) +SPA_API_DEBUG_TYPES uint32_t spa_debug_type_find_type(const struct spa_type_info *info, const char *name) { if (info == NULL) info = SPA_TYPE_ROOT; @@ -76,7 +82,7 @@ static inline uint32_t spa_debug_type_find_type(const struct spa_type_info *info return SPA_ID_INVALID; } -static inline const struct spa_type_info *spa_debug_type_find_short(const struct spa_type_info *info, const char *name) +SPA_API_DEBUG_TYPES const struct spa_type_info *spa_debug_type_find_short(const struct spa_type_info *info, const char *name) { while (info && info->name) { if (strcmp(spa_debug_type_short_name(info->name), name) == 0) @@ -90,7 +96,7 @@ static inline const struct spa_type_info *spa_debug_type_find_short(const struct return NULL; } -static inline uint32_t spa_debug_type_find_type_short(const struct spa_type_info *info, const char *name) +SPA_API_DEBUG_TYPES uint32_t spa_debug_type_find_type_short(const struct spa_type_info *info, const char *name) { if ((info = spa_debug_type_find_short(info, name)) == NULL) return SPA_ID_INVALID; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/node/io.h b/src/java.desktop/unix/native/libpipewire/include/spa/node/io.h index a25c8fd11c5a5..fffde5bb27bbd 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/node/io.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/node/io.h @@ -31,14 +31,16 @@ extern "C" { enum spa_io_type { SPA_IO_Invalid, SPA_IO_Buffers, /**< area to exchange buffers, struct spa_io_buffers */ - SPA_IO_Range, /**< expected byte range, struct spa_io_range */ + SPA_IO_Range, /**< expected byte range, struct spa_io_range (currently not used in PipeWire) */ SPA_IO_Clock, /**< area to update clock information, struct spa_io_clock */ - SPA_IO_Latency, /**< latency reporting, struct spa_io_latency */ + SPA_IO_Latency, /**< latency reporting, struct spa_io_latency (currently not used in + * PipeWire). \see spa_param_latency */ SPA_IO_Control, /**< area for control messages, struct spa_io_sequence */ SPA_IO_Notify, /**< area for notify messages, struct spa_io_sequence */ SPA_IO_Position, /**< position information in the graph, struct spa_io_position */ SPA_IO_RateMatch, /**< rate matching between nodes, struct spa_io_rate_match */ - SPA_IO_Memory, /**< memory pointer, struct spa_io_memory */ + SPA_IO_Memory, /**< memory pointer, struct spa_io_memory (currently not used in PipeWire) */ + SPA_IO_AsyncBuffers, /**< async area to exchange buffers, struct spa_io_async_buffers */ }; /** @@ -108,29 +110,52 @@ struct spa_io_range { * * The clock counts the elapsed time according to the clock provider * since the provider was last started. + * + * Driver nodes are supposed to update the contents of \ref SPA_IO_Clock before + * signaling the start of a graph cycle. These updated clock values become + * visible to other nodes in \ref SPA_IO_Position. Non-driver nodes do + * not need to update the contents of their \ref SPA_IO_Clock. + * + * The host generally gives each node a separate \ref spa_io_clock in \ref + * SPA_IO_Clock, so that updates made by the driver are not visible in the + * contents of \ref SPA_IO_Clock of other nodes. Instead, \ref SPA_IO_Position + * is used to look up the current graph time. + * + * A node is a driver when \ref spa_io_clock.id in \ref SPA_IO_Clock and + * \ref spa_io_position.clock.id in \ref SPA_IO_Position are the same. */ struct spa_io_clock { -#define SPA_IO_CLOCK_FLAG_FREEWHEEL (1u<<0) - uint32_t flags; /**< clock flags */ - uint32_t id; /**< unique clock id, set by application */ - char name[64]; /**< clock name prefixed with API, set by node. The clock name - * is unique per clock and can be used to check if nodes - * share the same clock. */ - uint64_t nsec; /**< time in nanoseconds against monotonic clock */ - struct spa_fraction rate; /**< rate for position/duration/delay */ - uint64_t position; /**< current position */ - uint64_t duration; /**< duration of current cycle */ - int64_t delay; /**< delay between position and hardware, - * positive for capture, negative for playback */ - double rate_diff; /**< rate difference between clock and monotonic time */ - uint64_t next_nsec; /**< estimated next wakeup time in nanoseconds */ +#define SPA_IO_CLOCK_FLAG_FREEWHEEL (1u<<0) /* graph is freewheeling */ +#define SPA_IO_CLOCK_FLAG_XRUN_RECOVER (1u<<1) /* recovering from xrun */ +#define SPA_IO_CLOCK_FLAG_LAZY (1u<<2) /* lazy scheduling */ +#define SPA_IO_CLOCK_FLAG_NO_RATE (1u<<3) /* the rate of the clock is only approximately. + * it is recommended to use the nsec as a clock source. + * The rate_diff contains the measured inaccuracy. */ + uint32_t flags; /**< Clock flags */ + uint32_t id; /**< Unique clock id, set by host application */ + char name[64]; /**< Clock name prefixed with API, set by node when it receives + * \ref SPA_IO_Clock. The clock name is unique per clock and + * can be used to check if nodes share the same clock. */ + uint64_t nsec; /**< Time in nanoseconds against monotonic clock + * (CLOCK_MONOTONIC). This fields reflects a real time instant + * in the past. The value may have jitter. */ + struct spa_fraction rate; /**< Rate for position/duration/delay/xrun */ + uint64_t position; /**< Current position, in samples @ \ref rate */ + uint64_t duration; /**< Duration of current cycle, in samples @ \ref rate */ + int64_t delay; /**< Delay between position and hardware, in samples @ \ref rate */ + double rate_diff; /**< Rate difference between clock and monotonic time, as a ratio of + * clock speeds. */ + uint64_t next_nsec; /**< Estimated next wakeup time in nanoseconds. + * This time is a logical start time of the next cycle, and + * is not necessarily in the future. + */ - struct spa_fraction target_rate; /**< target rate of next cycle */ - uint64_t target_duration; /**< target duration of next cycle */ - uint32_t target_seq; /**< seq counter. must be equal at start and + struct spa_fraction target_rate; /**< Target rate of next cycle */ + uint64_t target_duration; /**< Target duration of next cycle */ + uint32_t target_seq; /**< Seq counter. must be equal at start and * end of read and lower bit must be 0 */ - - uint32_t padding[3]; + uint32_t cycle; /**< incremented each time the graph is started */ + uint64_t xrun; /**< Estimated accumulated xrun duration */ }; /* the size of the video in this cycle */ @@ -145,7 +170,11 @@ struct spa_io_video_size { uint32_t padding[4]; }; -/** latency reporting */ +/** + * Latency reporting + * + * Currently not used in PipeWire. Instead, \see spa_param_latency + */ struct spa_io_latency { struct spa_fraction rate; /**< rate for min/max */ uint64_t min; /**< min latency */ @@ -166,7 +195,9 @@ struct spa_io_segment_bar { float signature_denom; /**< time signature denominator */ double bpm; /**< beats per minute */ double beat; /**< current beat in segment */ - uint32_t padding[8]; + double bar_start_tick; + double ticks_per_beat; + uint32_t padding[4]; }; /** video frame segment */ @@ -245,8 +276,13 @@ enum spa_io_position_state { /** * The position information adds extra meaning to the raw clock times. * - * It is set on all nodes and the clock id will contain the clock of the - * driving node in the graph. + * It is set on all nodes in \ref SPA_IO_Position, and the contents of \ref + * spa_io_position.clock contain the clock updates made by the driving node in + * the graph in its \ref SPA_IO_Clock. Also, \ref spa_io_position.clock.id + * will contain the clock id of the driving node in the graph. + * + * The position clock indicates the logical start time of the current graph + * cycle. * * The position information contains 1 or more segments that convert the * raw clock times to a stream time. They are sorted based on their @@ -269,14 +305,56 @@ struct spa_io_position { struct spa_io_segment segments[SPA_IO_POSITION_MAX_SEGMENTS]; /**< segments */ }; -/** rate matching */ +/** + * Rate matching. + * + * It is usually set on the nodes that process resampled data, by + * the component (audioadapter) that handles resampling between graph + * and node rates. The \a flags and \a rate fields may be modified by the node. + * + * The node can request a correction to the resampling rate in its process(), by setting + * \ref SPA_IO_RATE_MATCH_ACTIVE on \a flags, and setting \a rate to the desired rate + * correction. Usually the rate is obtained from DLL or other adaptive mechanism that + * e.g. drives the node buffer fill level toward a specific value. + * + * When resampling to (graph->node) direction, the number of samples produced + * by the resampler varies on each cycle, as the rates are not commensurate. + * + * When resampling to (node->graph) direction, the number of samples consumed by the + * resampler varies. Node output ports in process() should produce \a size number of + * samples to match what the resampler needs to produce one graph quantum of output + * samples. + * + * Resampling filters introduce processing delay, given by \a delay and \a delay_frac, in + * samples at node rate. The delay varies on each cycle e.g. when resampling between + * noncommensurate rates. + * + * The first sample output (graph->node) or consumed (node->graph) by the resampler is + * offset by \a delay + \a delay_frac / 1e9 node samples relative to the nominal graph + * cycle start position: + * + * \code{.unparsed} + * first_resampled_sample_nsec = + * first_original_sample_nsec + * - (rate_match->delay * SPA_NSEC_PER_SEC + rate_match->delay_frac) / node_rate + * \endcode + */ struct spa_io_rate_match { - uint32_t delay; /**< extra delay in samples for resampler */ + uint32_t delay; /**< resampling delay, in samples at + * node rate */ uint32_t size; /**< requested input size for resampler */ - double rate; /**< rate for resampler */ + double rate; /**< rate for resampler (set by node) */ #define SPA_IO_RATE_MATCH_FLAG_ACTIVE (1 << 0) - uint32_t flags; /**< extra flags */ - uint32_t padding[7]; + uint32_t flags; /**< extra flags (set by node) */ + int32_t delay_frac; /**< resampling delay fractional part, + * in units of nanosamples (1/10^9 sample) at node rate */ + uint32_t padding[6]; +}; + +/** async buffers */ +struct spa_io_async_buffers { + struct spa_io_buffers buffers[2]; /**< async buffers, writers write to current (cycle+1)&1, + * readers read from (cycle)&1 */ }; /** diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/node/type-info.h b/src/java.desktop/unix/native/libpipewire/include/spa/node/type-info.h index 3d3d7908519c0..ab4dbdedfb767 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/node/type-info.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/node/type-info.h @@ -34,6 +34,7 @@ static const struct spa_type_info spa_type_io[] = { { SPA_IO_Position, SPA_TYPE_Int, SPA_TYPE_INFO_IO_BASE "Position", NULL }, { SPA_IO_RateMatch, SPA_TYPE_Int, SPA_TYPE_INFO_IO_BASE "RateMatch", NULL }, { SPA_IO_Memory, SPA_TYPE_Int, SPA_TYPE_INFO_IO_BASE "Memory", NULL }, + { SPA_IO_AsyncBuffers, SPA_TYPE_Int, SPA_TYPE_INFO_IO_BASE "AsyncBuffers", NULL }, { 0, 0, NULL, NULL }, }; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/aac-types.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/aac-types.h index 26c80bfa9db1c..e941250ff96b5 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/aac-types.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/aac-types.h @@ -12,6 +12,11 @@ extern "C" { #include #include +/** + * \addtogroup spa_param + * \{ + */ + #define SPA_TYPE_INFO_AudioAACStreamFormat SPA_TYPE_INFO_ENUM_BASE "AudioAACStreamFormat" #define SPA_TYPE_INFO_AUDIO_AAC_STREAM_FORMAT_BASE SPA_TYPE_INFO_AudioAACStreamFormat ":" diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/aac.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/aac.h index dc5257c2dfd3d..164eaf7de8bd2 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/aac.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/aac.h @@ -11,6 +11,11 @@ extern "C" { #include +/** + * \addtogroup spa_param + * \{ + */ + enum spa_audio_aac_stream_format { SPA_AUDIO_AAC_STREAM_FORMAT_UNKNOWN, /* Raw AAC frames */ diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/amr-types.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/amr-types.h index 5e07a784524c0..34281c85763ab 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/amr-types.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/amr-types.h @@ -12,6 +12,11 @@ extern "C" { #include #include +/** + * \addtogroup spa_param + * \{ + */ + #define SPA_TYPE_INFO_AudioAMRBandMode SPA_TYPE_INFO_ENUM_BASE "AudioAMRBandMode" #define SPA_TYPE_INFO_AUDIO_AMR_BAND_MODE_BASE SPA_TYPE_INFO_AudioAMRBandMode ":" diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/amr.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/amr.h index 88b2c4cbcf3ef..aece0ab119eea 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/amr.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/amr.h @@ -11,6 +11,11 @@ extern "C" { #include +/** + * \addtogroup spa_param + * \{ + */ + enum spa_audio_amr_band_mode { SPA_AUDIO_AMR_BAND_MODE_UNKNOWN, SPA_AUDIO_AMR_BAND_MODE_NB, diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/iec958-types.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/iec958-types.h index fc8243a769b78..6e2e3f028a5bd 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/iec958-types.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/iec958-types.h @@ -12,6 +12,19 @@ extern "C" { #include #include +/** + * \addtogroup spa_param + * \{ + */ + +#ifndef SPA_API_AUDIO_IEC958_TYPES + #ifdef SPA_API_IMPL + #define SPA_API_AUDIO_IEC958_TYPES SPA_API_IMPL + #else + #define SPA_API_AUDIO_IEC958_TYPES static inline + #endif +#endif + #define SPA_TYPE_INFO_AudioIEC958Codec SPA_TYPE_INFO_ENUM_BASE "AudioIEC958Codec" #define SPA_TYPE_INFO_AUDIO_IEC958_CODEC_BASE SPA_TYPE_INFO_AudioIEC958Codec ":" @@ -28,6 +41,14 @@ static const struct spa_type_info spa_type_audio_iec958_codec[] = { { 0, 0, NULL, NULL }, }; +SPA_API_AUDIO_IEC958_TYPES uint32_t spa_type_audio_iec958_codec_from_short_name(const char *name) +{ + return spa_type_from_short_name(name, spa_type_audio_iec958_codec, SPA_AUDIO_IEC958_CODEC_UNKNOWN); +} +SPA_API_AUDIO_IEC958_TYPES const char * spa_type_audio_iec958_codec_to_short_name(uint32_t type) +{ + return spa_type_to_short_name(type, spa_type_audio_iec958_codec, "UNKNOWN"); +} /** * \} */ diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/mp3-types.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/mp3-types.h index 6907090faaf6a..8974f1efb336b 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/mp3-types.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/mp3-types.h @@ -12,6 +12,11 @@ extern "C" { #include #include +/** + * \addtogroup spa_param + * \{ + */ + #define SPA_TYPE_INFO_AudioMP3ChannelMode SPA_TYPE_INFO_ENUM_BASE "AudioMP3ChannelMode" #define SPA_TYPE_INFO_AUDIO_MP3_CHANNEL_MODE_BASE SPA_TYPE_INFO_AudioMP3ChannelMode ":" diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/mp3.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/mp3.h index 51f4c2eaf75e5..bfe61aaea54ae 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/mp3.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/mp3.h @@ -11,6 +11,11 @@ extern "C" { #include +/** + * \addtogroup spa_param + * \{ + */ + enum spa_audio_mp3_channel_mode { SPA_AUDIO_MP3_CHANNEL_MODE_UNKNOWN, SPA_AUDIO_MP3_CHANNEL_MODE_MONO, diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/raw-types.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/raw-types.h index 50a42157602d9..06b8cc4a7d38d 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/raw-types.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/raw-types.h @@ -15,8 +15,17 @@ extern "C" { */ #include +#include #include +#ifndef SPA_API_AUDIO_RAW_TYPES + #ifdef SPA_API_IMPL + #define SPA_API_AUDIO_RAW_TYPES SPA_API_IMPL + #else + #define SPA_API_AUDIO_RAW_TYPES static inline + #endif +#endif + #define SPA_TYPE_INFO_AudioFormat SPA_TYPE_INFO_ENUM_BASE "AudioFormat" #define SPA_TYPE_INFO_AUDIO_FORMAT_BASE SPA_TYPE_INFO_AudioFormat ":" @@ -128,6 +137,15 @@ static const struct spa_type_info spa_type_audio_format[] = { { 0, 0, NULL, NULL }, }; +SPA_API_AUDIO_RAW_TYPES uint32_t spa_type_audio_format_from_short_name(const char *name) +{ + return spa_type_from_short_name(name, spa_type_audio_format, SPA_AUDIO_FORMAT_UNKNOWN); +} +SPA_API_AUDIO_RAW_TYPES const char * spa_type_audio_format_to_short_name(uint32_t type) +{ + return spa_type_to_short_name(type, spa_type_audio_format, "UNKNOWN"); +} + #define SPA_TYPE_INFO_AudioFlags SPA_TYPE_INFO_FLAGS_BASE "AudioFlags" #define SPA_TYPE_INFO_AUDIO_FLAGS_BASE SPA_TYPE_INFO_AudioFlags ":" @@ -247,6 +265,16 @@ static const struct spa_type_info spa_type_audio_channel[] = { { 0, 0, NULL, NULL }, }; +SPA_API_AUDIO_RAW_TYPES uint32_t spa_type_audio_channel_from_short_name(const char *name) +{ + return spa_type_from_short_name(name, spa_type_audio_channel, SPA_AUDIO_CHANNEL_UNKNOWN); +} +SPA_API_AUDIO_RAW_TYPES const char * spa_type_audio_channel_to_short_name(uint32_t type) +{ + return spa_type_to_short_name(type, spa_type_audio_channel, "UNK"); +} + + /** * \} */ diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/raw.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/raw.h index 54052f75311a9..462cf58a13ca6 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/raw.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/raw.h @@ -11,15 +11,7 @@ extern "C" { #include -#if !defined(__FreeBSD__) && !defined(__MidnightBSD__) && !defined(AIX) -#include -#endif - -#if defined(AIX) -#include -#define __BIG_ENDIAN BIG_ENDIAN -#define __BYTE_ORDER BIG_ENDIAN -#endif +#include /** * \addtogroup spa_param diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/wma-types.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/wma-types.h index 0309223ac7008..78ce1b987738d 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/wma-types.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/wma-types.h @@ -12,6 +12,11 @@ extern "C" { #include #include +/** + * \addtogroup spa_param + * \{ + */ + #define SPA_TYPE_INFO_AudioWMAProfile SPA_TYPE_INFO_ENUM_BASE "AudioWMAProfile" #define SPA_TYPE_INFO_AUDIO_WMA_PROFILE_BASE SPA_TYPE_INFO_AudioWMAProfile ":" diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/wma.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/wma.h index 84a78a7e12d05..4f86efe84b70e 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/wma.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/audio/wma.h @@ -11,6 +11,11 @@ extern "C" { #include +/** + * \addtogroup spa_param + * \{ + */ + enum spa_audio_wma_profile { SPA_AUDIO_WMA_PROFILE_UNKNOWN, diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/bluetooth/audio.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/bluetooth/audio.h index 8561a00aebdbe..13590545ed73d 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/bluetooth/audio.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/bluetooth/audio.h @@ -21,6 +21,7 @@ enum spa_bluetooth_audio_codec { SPA_BLUETOOTH_AUDIO_CODEC_SBC_XQ, SPA_BLUETOOTH_AUDIO_CODEC_MPEG, SPA_BLUETOOTH_AUDIO_CODEC_AAC, + SPA_BLUETOOTH_AUDIO_CODEC_AAC_ELD, SPA_BLUETOOTH_AUDIO_CODEC_APTX, SPA_BLUETOOTH_AUDIO_CODEC_APTX_HD, SPA_BLUETOOTH_AUDIO_CODEC_LDAC, @@ -34,13 +35,18 @@ enum spa_bluetooth_audio_codec { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_71, SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_DUPLEX, SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_PRO, + SPA_BLUETOOTH_AUDIO_CODEC_OPUS_G, /* HFP */ SPA_BLUETOOTH_AUDIO_CODEC_CVSD = 0x100, SPA_BLUETOOTH_AUDIO_CODEC_MSBC, + SPA_BLUETOOTH_AUDIO_CODEC_LC3_SWB, /* BAP */ SPA_BLUETOOTH_AUDIO_CODEC_LC3 = 0x200, + + /* ASHA */ + SPA_BLUETOOTH_AUDIO_CODEC_G722 = 0x300, }; /** diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/bluetooth/type-info.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/bluetooth/type-info.h index a7ce08246c27b..2affa465b458e 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/bluetooth/type-info.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/bluetooth/type-info.h @@ -25,6 +25,7 @@ static const struct spa_type_info spa_type_bluetooth_audio_codec[] = { { SPA_BLUETOOTH_AUDIO_CODEC_SBC_XQ, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "sbc_xq", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_MPEG, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "mpeg", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_AAC, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "aac", NULL }, + { SPA_BLUETOOTH_AUDIO_CODEC_AAC_ELD, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "aac_eld", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_APTX, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "aptx", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_APTX_HD, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "aptx_hd", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_LDAC, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "ldac", NULL }, @@ -38,12 +39,16 @@ static const struct spa_type_info spa_type_bluetooth_audio_codec[] = { { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_71, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "opus_05_71", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_DUPLEX, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "opus_05_duplex", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_PRO, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "opus_05_pro", NULL }, + { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_G, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "opus_g", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_CVSD, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "cvsd", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_MSBC, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "msbc", NULL }, + { SPA_BLUETOOTH_AUDIO_CODEC_LC3_SWB, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "lc3_swb", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_LC3, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "lc3", NULL }, + { SPA_BLUETOOTH_AUDIO_CODEC_G722, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "g722", NULL }, + { 0, 0, NULL, NULL }, }; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/buffers-types.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/buffers-types.h index 987d75a1669f6..a963193a60c01 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/buffers-types.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/buffers-types.h @@ -56,6 +56,7 @@ static const struct spa_type_info spa_type_param_buffers[] = { { SPA_PARAM_BUFFERS_stride, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_BLOCK_INFO_BASE "stride", NULL }, { SPA_PARAM_BUFFERS_align, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_BLOCK_INFO_BASE "align", NULL }, { SPA_PARAM_BUFFERS_dataType, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_BLOCK_INFO_BASE "dataType", NULL }, + { SPA_PARAM_BUFFERS_metaType, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_BLOCK_INFO_BASE "metaType", NULL }, { 0, 0, NULL, NULL }, }; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/buffers.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/buffers.h index 6834c6e5e390a..eb8c107337ebd 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/buffers.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/buffers.h @@ -24,14 +24,15 @@ enum spa_param_buffers { SPA_PARAM_BUFFERS_size, /**< size of a data block memory (Int)*/ SPA_PARAM_BUFFERS_stride, /**< stride of data block memory (Int) */ SPA_PARAM_BUFFERS_align, /**< alignment of data block memory (Int) */ - SPA_PARAM_BUFFERS_dataType, /**< possible memory types (Int, mask of enum spa_data_type) */ + SPA_PARAM_BUFFERS_dataType, /**< possible memory types (flags choice Int, mask of enum spa_data_type) */ + SPA_PARAM_BUFFERS_metaType, /**< required meta data types (Int, mask of enum spa_meta_type) */ }; /** properties for SPA_TYPE_OBJECT_ParamMeta */ enum spa_param_meta { SPA_PARAM_META_START, - SPA_PARAM_META_type, /**< the metadata, one of enum spa_meta_type (Id enum spa_meta_type) */ - SPA_PARAM_META_size, /**< the expected maximum size the meta (Int) */ + SPA_PARAM_META_type, /**< the metadata, one of enum spa_meta_type (Id enum spa_meta_type) */ + SPA_PARAM_META_size, /**< the expected maximum size the meta (Int) */ }; /** properties for SPA_TYPE_OBJECT_ParamIO */ diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/format-utils.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/format-utils.h index b4edb6f6efe4c..b829209351d1e 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/format-utils.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/format-utils.h @@ -18,7 +18,15 @@ extern "C" { #include #include -static inline int +#ifndef SPA_API_FORMAT_UTILS + #ifdef SPA_API_IMPL + #define SPA_API_FORMAT_UTILS SPA_API_IMPL + #else + #define SPA_API_FORMAT_UTILS static inline + #endif +#endif + +SPA_API_FORMAT_UTILS int spa_format_parse(const struct spa_pod *format, uint32_t *media_type, uint32_t *media_subtype) { return spa_pod_parse_object(format, diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/format.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/format.h index a7b425465239a..7de2775ca4417 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/format.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/format.h @@ -141,6 +141,8 @@ enum spa_format { SPA_FORMAT_START_Stream = 0x50000, /* Application Format keys */ SPA_FORMAT_START_Application = 0x60000, + SPA_FORMAT_CONTROL_types, /**< possible control types (flags choice Int, + * mask of enum spa_control_type) */ }; #define SPA_KEY_FORMAT_DSP "format.dsp" /**< a predefined DSP format, diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/latency.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/latency.h index 5fa40b59b9f65..2d567f79eb21b 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/latency.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/latency.h @@ -16,14 +16,31 @@ extern "C" { #include -/** properties for SPA_TYPE_OBJECT_ParamLatency */ +/** + * Properties for SPA_TYPE_OBJECT_ParamLatency + * + * The latency indicates: + * + * - for playback: time delay between start of a graph cycle, and the rendering of + * the first sample of that cycle in audio output. + * + * - for capture: time delay between start of a graph cycle, and the first sample + * of that cycle having occurred in audio input. + * + * For physical output/input, the latency is intended to correspond to the + * rendering/capture of physical audio, including hardware internal rendering delay. + * + * The latency values are adjusted by \ref SPA_PROP_latencyOffsetNsec or + * SPA_PARAM_ProcessLatency, if present. (e.g. for ALSA this is used to adjust for + * the internal hardware latency). + */ enum spa_param_latency { SPA_PARAM_LATENCY_START, SPA_PARAM_LATENCY_direction, /**< direction, input/output (Id enum spa_direction) */ SPA_PARAM_LATENCY_minQuantum, /**< min latency relative to quantum (Float) */ SPA_PARAM_LATENCY_maxQuantum, /**< max latency relative to quantum (Float) */ - SPA_PARAM_LATENCY_minRate, /**< min latency (Int) relative to rate */ - SPA_PARAM_LATENCY_maxRate, /**< max latency (Int) relative to rate */ + SPA_PARAM_LATENCY_minRate, /**< min latency (Int) relative to graph rate */ + SPA_PARAM_LATENCY_maxRate, /**< max latency (Int) relative to graph rate */ SPA_PARAM_LATENCY_minNs, /**< min latency (Long) in nanoseconds */ SPA_PARAM_LATENCY_maxNs, /**< max latency (Long) in nanoseconds */ }; @@ -33,27 +50,32 @@ struct spa_latency_info { enum spa_direction direction; float min_quantum; float max_quantum; - uint32_t min_rate; - uint32_t max_rate; - uint64_t min_ns; - uint64_t max_ns; + int32_t min_rate; + int32_t max_rate; + int64_t min_ns; + int64_t max_ns; }; #define SPA_LATENCY_INFO(dir,...) ((struct spa_latency_info) { .direction = (dir), ## __VA_ARGS__ }) -/** properties for SPA_TYPE_OBJECT_ParamProcessLatency */ +/** + * Properties for SPA_TYPE_OBJECT_ParamProcessLatency + * + * The processing latency indicates logical time delay between a sample in an input port, + * and a corresponding sample in an output port, relative to the graph time. + */ enum spa_param_process_latency { SPA_PARAM_PROCESS_LATENCY_START, SPA_PARAM_PROCESS_LATENCY_quantum, /**< latency relative to quantum (Float) */ - SPA_PARAM_PROCESS_LATENCY_rate, /**< latency (Int) relative to rate */ + SPA_PARAM_PROCESS_LATENCY_rate, /**< latency (Int) relative to graph rate */ SPA_PARAM_PROCESS_LATENCY_ns, /**< latency (Long) in nanoseconds */ }; /** Helper structure for managing process latency objects */ struct spa_process_latency_info { float quantum; - uint32_t rate; - uint64_t ns; + int32_t rate; + int64_t ns; }; #define SPA_PROCESS_LATENCY_INFO_INIT(...) ((struct spa_process_latency_info) { __VA_ARGS__ }) diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/param-types.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/param-types.h index ff2ddde1cd953..b996666d2b2c5 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/param-types.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/param-types.h @@ -40,6 +40,7 @@ static const struct spa_type_info spa_type_param[] = { { SPA_PARAM_Control, SPA_TYPE_Sequence, SPA_TYPE_INFO_PARAM_ID_BASE "Control", NULL }, { SPA_PARAM_Latency, SPA_TYPE_OBJECT_ParamLatency, SPA_TYPE_INFO_PARAM_ID_BASE "Latency", NULL }, { SPA_PARAM_ProcessLatency, SPA_TYPE_OBJECT_ParamProcessLatency, SPA_TYPE_INFO_PARAM_ID_BASE "ProcessLatency", NULL }, + { SPA_PARAM_Tag, SPA_TYPE_OBJECT_ParamTag, SPA_TYPE_INFO_PARAM_ID_BASE "Tag", NULL }, { 0, 0, NULL, NULL }, }; @@ -54,6 +55,11 @@ static const struct spa_type_info spa_type_prop_float_array[] = { { 0, 0, NULL, NULL }, }; +static const struct spa_type_info spa_type_prop_int_array[] = { + { SPA_PROP_START, SPA_TYPE_Int, SPA_TYPE_INFO_BASE "intArray", NULL, }, + { 0, 0, NULL, NULL }, +}; + static const struct spa_type_info spa_type_prop_channel_map[] = { { SPA_PROP_START, SPA_TYPE_Id, SPA_TYPE_INFO_BASE "channelMap", spa_type_audio_channel, }, { 0, 0, NULL, NULL }, diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/param.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/param.h index 48e7d9349d58d..aac55b7359163 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/param.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/param.h @@ -39,6 +39,7 @@ enum spa_param_type { SPA_PARAM_Control, /**< Control parameter, a SPA_TYPE_Sequence */ SPA_PARAM_Latency, /**< latency reporting, a SPA_TYPE_OBJECT_ParamLatency */ SPA_PARAM_ProcessLatency, /**< processing latency, a SPA_TYPE_OBJECT_ParamProcessLatency */ + SPA_PARAM_Tag, /**< tag reporting, a SPA_TYPE_OBJECT_ParamTag. Since 0.3.79 */ }; /** information about a parameter */ diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/profiler-types.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/profiler-types.h index a1abc02a130c4..b87a125a41692 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/profiler-types.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/profiler-types.h @@ -26,6 +26,7 @@ static const struct spa_type_info spa_type_profiler[] = { { SPA_PROFILER_clock, SPA_TYPE_Struct, SPA_TYPE_INFO_PROFILER_BASE "clock", NULL, }, { SPA_PROFILER_driverBlock, SPA_TYPE_Struct, SPA_TYPE_INFO_PROFILER_BASE "driverBlock", NULL, }, { SPA_PROFILER_followerBlock, SPA_TYPE_Struct, SPA_TYPE_INFO_PROFILER_BASE "followerBlock", NULL, }, + { SPA_PROFILER_followerClock, SPA_TYPE_Struct, SPA_TYPE_INFO_PROFILER_BASE "followerClock", NULL, }, { 0, 0, NULL, NULL }, }; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/profiler.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/profiler.h index e65835a1a8525..97e5431a7de58 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/profiler.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/profiler.h @@ -39,7 +39,10 @@ enum spa_profiler { * Long : clock duration, * Long : clock delay, * Double : clock rate_diff, - * Long : clock next_nsec)) */ + * Long : clock next_nsec, + * Int : transport_state, + * Int : clock cycle, + * Long : xrun duration)) */ SPA_PROFILER_driverBlock, /**< generic driver info block * (Struct( * Int : driver_id, @@ -48,8 +51,9 @@ enum spa_profiler { * Long : driver signal, * Long : driver awake, * Long : driver finish, - * Int : driver status), - * Fraction : latency)) */ + * Int : driver status, + * Fraction : latency, + * Int : xrun_count)) */ SPA_PROFILER_START_Follower = 0x20000, /**< follower related profiler properties */ SPA_PROFILER_followerBlock, /**< generic follower info block @@ -61,8 +65,20 @@ enum spa_profiler { * Long : awake, * Long : finish, * Int : status, - * Fraction : latency)) */ - + * Fraction : latency, + * Int : xrun_count)) */ + SPA_PROFILER_followerClock, /**< follower clock information + * (Struct( + * Int : clock id, + * String: clock name, + * Long : clock nsec, + * Fraction : clock rate, + * Long : clock position, + * Long : clock duration, + * Long : clock delay, + * Double : clock rate_diff, + * Long : clock next_nsec, + * Long : xrun duration)) */ SPA_PROFILER_START_CUSTOM = 0x1000000, }; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/props-types.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/props-types.h index 5e4e0a0c9d6f1..e52f6c9a228ec 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/props-types.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/props-types.h @@ -64,14 +64,14 @@ static const struct spa_type_info spa_type_props[] = { { SPA_PROP_volumeRampStepTime, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "volumeRampStepTime", NULL }, { SPA_PROP_volumeRampScale, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "volumeRampScale", NULL }, - { SPA_PROP_brightness, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "brightness", NULL }, - { SPA_PROP_contrast, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "contrast", NULL }, - { SPA_PROP_saturation, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "saturation", NULL }, + { SPA_PROP_brightness, SPA_TYPE_Float, SPA_TYPE_INFO_PROPS_BASE "brightness", NULL }, + { SPA_PROP_contrast, SPA_TYPE_Float, SPA_TYPE_INFO_PROPS_BASE "contrast", NULL }, + { SPA_PROP_saturation, SPA_TYPE_Float, SPA_TYPE_INFO_PROPS_BASE "saturation", NULL }, { SPA_PROP_hue, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "hue", NULL }, { SPA_PROP_gamma, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "gamma", NULL }, { SPA_PROP_exposure, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "exposure", NULL }, - { SPA_PROP_gain, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "gain", NULL }, - { SPA_PROP_sharpness, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "sharpness", NULL }, + { SPA_PROP_gain, SPA_TYPE_Float, SPA_TYPE_INFO_PROPS_BASE "gain", NULL }, + { SPA_PROP_sharpness, SPA_TYPE_Float, SPA_TYPE_INFO_PROPS_BASE "sharpness", NULL }, { SPA_PROP_params, SPA_TYPE_Struct, SPA_TYPE_INFO_PROPS_BASE "params", NULL }, { 0, 0, NULL, NULL }, diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/props.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/props.h index 8ecf6f69bc49c..2656c1087c7d7 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/props.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/props.h @@ -59,24 +59,31 @@ enum spa_prop { SPA_PROP_START_Audio = 0x10000, /**< audio related properties */ SPA_PROP_waveType, SPA_PROP_frequency, - SPA_PROP_volume, /**< a volume (Float), 0.0 silence, 1.0 normal */ + SPA_PROP_volume, /**< a volume (Float), 0.0 silence, 1.0 no attenutation */ SPA_PROP_mute, /**< mute (Bool) */ SPA_PROP_patternType, SPA_PROP_ditherType, SPA_PROP_truncate, - SPA_PROP_channelVolumes, /**< a volume array, one volume per - * channel (Array of Float) */ + SPA_PROP_channelVolumes, /**< a volume array, one (linear) volume per channel + * (Array of Float). 0.0 is silence, 1.0 is + * without attenuation. This is the effective + * volume that is applied. It can result + * in a hardware volume and software volume + * (see softVolumes) */ SPA_PROP_volumeBase, /**< a volume base (Float) */ SPA_PROP_volumeStep, /**< a volume step (Float) */ SPA_PROP_channelMap, /**< a channelmap array * (Array (Id enum spa_audio_channel)) */ SPA_PROP_monitorMute, /**< mute (Bool) */ - SPA_PROP_monitorVolumes, /**< a volume array, one volume per + SPA_PROP_monitorVolumes, /**< a volume array, one (linear) volume per * channel (Array of Float) */ SPA_PROP_latencyOffsetNsec, /**< delay adjustment */ - SPA_PROP_softMute, /**< mute (Bool) */ - SPA_PROP_softVolumes, /**< a volume array, one volume per - * channel (Array of Float) */ + SPA_PROP_softMute, /**< mute (Bool) applied in software */ + SPA_PROP_softVolumes, /**< a volume array, one (linear) volume per channel + * (Array of Float). 0.0 is silence, 1.0 is without + * attenuation. This is the volume applied in + * software, there might be a part applied in + * hardware. */ SPA_PROP_iec958Codecs, /**< enabled IEC958 (S/PDIF) codecs, * (Array (Id enum spa_audio_iec958_codec) */ diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/route-types.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/route-types.h index 8eb839d3f7b5a..d7f2bf96b47e7 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/route-types.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/route-types.h @@ -32,9 +32,9 @@ static const struct spa_type_info spa_type_param_route[] = { { SPA_PARAM_ROUTE_priority, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_ROUTE_BASE "priority", NULL, }, { SPA_PARAM_ROUTE_available, SPA_TYPE_Id, SPA_TYPE_INFO_PARAM_ROUTE_BASE "available", spa_type_param_availability, }, { SPA_PARAM_ROUTE_info, SPA_TYPE_Struct, SPA_TYPE_INFO_PARAM_ROUTE_BASE "info", NULL, }, - { SPA_PARAM_ROUTE_profiles, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_ROUTE_BASE "profiles", NULL, }, + { SPA_PARAM_ROUTE_profiles, SPA_TYPE_Array, SPA_TYPE_INFO_PARAM_ROUTE_BASE "profiles", spa_type_prop_int_array, }, { SPA_PARAM_ROUTE_props, SPA_TYPE_OBJECT_Props, SPA_TYPE_INFO_PARAM_ROUTE_BASE "props", NULL, }, - { SPA_PARAM_ROUTE_devices, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_ROUTE_BASE "devices", NULL, }, + { SPA_PARAM_ROUTE_devices, SPA_TYPE_Array, SPA_TYPE_INFO_PARAM_ROUTE_BASE "devices", spa_type_prop_int_array, }, { SPA_PARAM_ROUTE_profile, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_ROUTE_BASE "profile", NULL, }, { SPA_PARAM_ROUTE_save, SPA_TYPE_Bool, SPA_TYPE_INFO_PARAM_ROUTE_BASE "save", NULL, }, { 0, 0, NULL, NULL }, diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/tag-types.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/tag-types.h new file mode 100644 index 0000000000000..0a473ef90996f --- /dev/null +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/tag-types.h @@ -0,0 +1,39 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_PARAM_TAG_TYPES_H +#define SPA_PARAM_TAG_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_param + * \{ + */ + +#include +#include +#include + +#define SPA_TYPE_INFO_PARAM_Tag SPA_TYPE_INFO_PARAM_BASE "Tag" +#define SPA_TYPE_INFO_PARAM_TAG_BASE SPA_TYPE_INFO_PARAM_Tag ":" + +static const struct spa_type_info spa_type_param_tag[] = { + { SPA_PARAM_TAG_START, SPA_TYPE_Id, SPA_TYPE_INFO_PARAM_TAG_BASE, spa_type_param, }, + { SPA_PARAM_TAG_direction, SPA_TYPE_Id, SPA_TYPE_INFO_PARAM_TAG_BASE "direction", spa_type_direction, }, + { SPA_PARAM_TAG_info, SPA_TYPE_Struct, SPA_TYPE_INFO_PARAM_TAG_BASE "info", NULL, }, + { 0, 0, NULL, NULL }, +}; + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_PARAM_TAG_TYPES_H */ diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/tag.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/tag.h new file mode 100644 index 0000000000000..558da087dc7aa --- /dev/null +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/tag.h @@ -0,0 +1,46 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_PARAM_TAG_H +#define SPA_PARAM_TAG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_param + * \{ + */ + +#include + +/** properties for SPA_TYPE_OBJECT_ParamTag */ +enum spa_param_tag { + SPA_PARAM_TAG_START, + SPA_PARAM_TAG_direction, /**< direction, input/output (Id enum spa_direction) */ + SPA_PARAM_TAG_info, /**< Struct( + * Int: n_items + * (String: key + * String: value)* + * ) */ +}; + +/** helper structure for managing tag objects */ +struct spa_tag_info { + enum spa_direction direction; + const struct spa_pod *info; +}; + +#define SPA_TAG_INFO(dir,...) ((struct spa_tag_info) { .direction = (dir), ## __VA_ARGS__ }) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_PARAM_TAG_H */ diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/type-info.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/type-info.h index 730a1f53607f2..fee2d030a0a42 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/type-info.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/type-info.h @@ -14,5 +14,6 @@ #include #include #include +#include #endif /* SPA_PARAM_TYPE_INFO_H */ diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/dsp-utils.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/dsp-utils.h index 2d4a83c2928b5..d8f075901e343 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/dsp-utils.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/dsp-utils.h @@ -18,13 +18,24 @@ extern "C" { #include #include -static inline int +#ifndef SPA_API_VIDEO_DSP_UTILS + #ifdef SPA_API_IMPL + #define SPA_API_VIDEO_DSP_UTILS SPA_API_IMPL + #else + #define SPA_API_VIDEO_DSP_UTILS static inline + #endif +#endif + +SPA_API_VIDEO_DSP_UTILS int spa_format_video_dsp_parse(const struct spa_pod *format, struct spa_video_info_dsp *info) { info->flags = SPA_VIDEO_FLAG_NONE; - if (spa_pod_find_prop (format, NULL, SPA_FORMAT_VIDEO_modifier)) { + const struct spa_pod_prop *mod_prop; + if ((mod_prop = spa_pod_find_prop (format, NULL, SPA_FORMAT_VIDEO_modifier)) != NULL) { info->flags |= SPA_VIDEO_FLAG_MODIFIER; + if ((mod_prop->flags & SPA_POD_PROP_FLAG_DONT_FIXATE) == SPA_POD_PROP_FLAG_DONT_FIXATE) + info->flags |= SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED; } return spa_pod_parse_object(format, @@ -33,9 +44,9 @@ spa_format_video_dsp_parse(const struct spa_pod *format, SPA_FORMAT_VIDEO_modifier, SPA_POD_OPT_Long(&info->modifier)); } -static inline struct spa_pod * +SPA_API_VIDEO_DSP_UTILS struct spa_pod * spa_format_video_dsp_build(struct spa_pod_builder *builder, uint32_t id, - struct spa_video_info_dsp *info) + const struct spa_video_info_dsp *info) { struct spa_pod_frame f; spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id); @@ -46,9 +57,11 @@ spa_format_video_dsp_build(struct spa_pod_builder *builder, uint32_t id, if (info->format != SPA_VIDEO_FORMAT_UNKNOWN) spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_format, SPA_POD_Id(info->format), 0); - if (info->modifier != 0 || info->flags & SPA_VIDEO_FLAG_MODIFIER) - spa_pod_builder_add(builder, - SPA_FORMAT_VIDEO_modifier, SPA_POD_Long(info->modifier), 0); + if (info->modifier != 0 || info->flags & SPA_VIDEO_FLAG_MODIFIER) { + spa_pod_builder_prop(builder, + SPA_FORMAT_VIDEO_modifier, SPA_POD_PROP_FLAG_MANDATORY); + spa_pod_builder_long(builder, info->modifier); + } return (struct spa_pod*)spa_pod_builder_pop(builder, &f); } diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/format-utils.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/format-utils.h index 31d33101774bc..13495a473a330 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/format-utils.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/format-utils.h @@ -16,7 +16,15 @@ extern "C" { #include #include -static inline int +#ifndef SPA_API_VIDEO_FORMAT_UTILS + #ifdef SPA_API_IMPL + #define SPA_API_VIDEO_FORMAT_UTILS SPA_API_IMPL + #else + #define SPA_API_VIDEO_FORMAT_UTILS static inline + #endif +#endif + +SPA_API_VIDEO_FORMAT_UTILS int spa_format_video_parse(const struct spa_pod *format, struct spa_video_info *info) { int res; @@ -40,8 +48,9 @@ spa_format_video_parse(const struct spa_pod *format, struct spa_video_info *info return -ENOTSUP; } -static inline struct spa_pod * -spa_format_video_build(struct spa_pod_builder *builder, uint32_t id, struct spa_video_info *info) +SPA_API_VIDEO_FORMAT_UTILS struct spa_pod * +spa_format_video_build(struct spa_pod_builder *builder, uint32_t id, + const struct spa_video_info *info) { switch (info->media_subtype) { case SPA_MEDIA_SUBTYPE_raw: diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/h264-utils.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/h264-utils.h index 89c73c98f7ef0..d15b4a0ee68df 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/h264-utils.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/h264-utils.h @@ -18,7 +18,15 @@ extern "C" { #include #include -static inline int +#ifndef SPA_API_VIDEO_H264_UTILS + #ifdef SPA_API_IMPL + #define SPA_API_VIDEO_H264_UTILS SPA_API_IMPL + #else + #define SPA_API_VIDEO_H264_UTILS static inline + #endif +#endif + +SPA_API_VIDEO_H264_UTILS int spa_format_video_h264_parse(const struct spa_pod *format, struct spa_video_info_h264 *info) { @@ -31,9 +39,9 @@ spa_format_video_h264_parse(const struct spa_pod *format, SPA_FORMAT_VIDEO_H264_alignment, SPA_POD_OPT_Id(&info->alignment)); } -static inline struct spa_pod * +SPA_API_VIDEO_H264_UTILS struct spa_pod * spa_format_video_h264_build(struct spa_pod_builder *builder, uint32_t id, - struct spa_video_info_h264 *info) + const struct spa_video_info_h264 *info) { struct spa_pod_frame f; spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id); @@ -49,7 +57,7 @@ spa_format_video_h264_build(struct spa_pod_builder *builder, uint32_t id, SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&info->framerate), 0); if (info->max_framerate.denom != 0) spa_pod_builder_add(builder, - SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_Fraction(info->max_framerate), 0); + SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_Fraction(&info->max_framerate), 0); if (info->stream_format != 0) spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_H264_streamFormat, SPA_POD_Id(info->stream_format), 0); diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/mjpg-utils.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/mjpg-utils.h index 5cb323e8077d6..af362360755c8 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/mjpg-utils.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/mjpg-utils.h @@ -18,7 +18,15 @@ extern "C" { #include #include -static inline int +#ifndef SPA_API_VIDEO_MJPG_UTILS + #ifdef SPA_API_IMPL + #define SPA_API_VIDEO_MJPG_UTILS SPA_API_IMPL + #else + #define SPA_API_VIDEO_MJPG_UTILS static inline + #endif +#endif + +SPA_API_VIDEO_MJPG_UTILS int spa_format_video_mjpg_parse(const struct spa_pod *format, struct spa_video_info_mjpg *info) { @@ -29,9 +37,9 @@ spa_format_video_mjpg_parse(const struct spa_pod *format, SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_OPT_Fraction(&info->max_framerate)); } -static inline struct spa_pod * +SPA_API_VIDEO_MJPG_UTILS struct spa_pod * spa_format_video_mjpg_build(struct spa_pod_builder *builder, uint32_t id, - struct spa_video_info_mjpg *info) + const struct spa_video_info_mjpg *info) { struct spa_pod_frame f; spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id); @@ -47,7 +55,7 @@ spa_format_video_mjpg_build(struct spa_pod_builder *builder, uint32_t id, SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&info->framerate), 0); if (info->max_framerate.denom != 0) spa_pod_builder_add(builder, - SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_Fraction(info->max_framerate), 0); + SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_Fraction(&info->max_framerate), 0); return (struct spa_pod*)spa_pod_builder_pop(builder, &f); } diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/multiview.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/multiview.h index 10a19323f4407..7ee6a152f64ce 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/multiview.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/multiview.h @@ -59,12 +59,11 @@ enum spa_video_multiview_mode { * sequence. This method only applies to * raw video buffers at the moment. * Specific view identification is via - * \ref spa_video_multiview_meta on raw - * video buffers. */ + * metadata on raw video buffers. */ SPA_VIDEO_MULTIVIEW_MODE_SEPARATED, /**< Multiple views are provided as separate * \ref spa_data framebuffers attached * to each \ref spa_buffer, described - * by the \ref spa_video_multiview_meta */ + * by the metadata */ /* future expansion for annotated modes */ }; @@ -97,9 +96,7 @@ enum spa_video_multiview_flags { SPA_VIDEO_MULTIVIEW_FLAGS_MIXED_MONO = (1 << 15), /**< The video stream contains both * mono and multiview portions, * signalled on each buffer by the - * absence or presence of the - * \ref SPA_VIDEO_BUFFER_FLAG_MULTIPLE_VIEW - * buffer flag. */ + * absence or presence of a buffer flag. */ }; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw-types.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw-types.h index 743dd4cd1a5ce..b216250eda6b3 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw-types.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw-types.h @@ -16,11 +16,20 @@ extern "C" { #include #include +#ifndef SPA_API_VIDEO_RAW_TYPES + #ifdef SPA_API_IMPL + #define SPA_API_VIDEO_RAW_TYPES SPA_API_IMPL + #else + #define SPA_API_VIDEO_RAW_TYPES static inline + #endif +#endif + #define SPA_TYPE_INFO_VideoFormat SPA_TYPE_INFO_ENUM_BASE "VideoFormat" #define SPA_TYPE_INFO_VIDEO_FORMAT_BASE SPA_TYPE_INFO_VideoFormat ":" static const struct spa_type_info spa_type_video_format[] = { - { SPA_VIDEO_FORMAT_ENCODED, SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "encoded", NULL }, + { SPA_VIDEO_FORMAT_UNKNOWN, SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "UNKNOWN", NULL }, + { SPA_VIDEO_FORMAT_ENCODED, SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "ENCODED", NULL }, { SPA_VIDEO_FORMAT_I420, SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "I420", NULL }, { SPA_VIDEO_FORMAT_YV12, SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "YV12", NULL }, { SPA_VIDEO_FORMAT_YUY2, SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "YUY2", NULL }, @@ -110,6 +119,15 @@ static const struct spa_type_info spa_type_video_format[] = { { 0, 0, NULL, NULL }, }; +SPA_API_VIDEO_RAW_TYPES uint32_t spa_type_video_format_from_short_name(const char *name) +{ + return spa_type_from_short_name(name, spa_type_video_format, SPA_VIDEO_FORMAT_UNKNOWN); +} +SPA_API_VIDEO_RAW_TYPES const char * spa_type_video_format_to_short_name(uint32_t type) +{ + return spa_type_to_short_name(type, spa_type_video_format, "UNKNOWN"); +} + #define SPA_TYPE_INFO_VideoFlags SPA_TYPE_INFO_FLAGS_BASE "VideoFlags" #define SPA_TYPE_INFO_VIDEO_FLAGS_BASE SPA_TYPE_INFO_VideoFlags ":" diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw-utils.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw-utils.h index e39c430136d1d..424c04004cc06 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw-utils.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw-utils.h @@ -18,13 +18,24 @@ extern "C" { #include #include -static inline int +#ifndef SPA_API_VIDEO_RAW_UTILS + #ifdef SPA_API_IMPL + #define SPA_API_VIDEO_RAW_UTILS SPA_API_IMPL + #else + #define SPA_API_VIDEO_RAW_UTILS static inline + #endif +#endif + +SPA_API_VIDEO_RAW_UTILS int spa_format_video_raw_parse(const struct spa_pod *format, struct spa_video_info_raw *info) { info->flags = SPA_VIDEO_FLAG_NONE; - if (spa_pod_find_prop (format, NULL, SPA_FORMAT_VIDEO_modifier)) { + const struct spa_pod_prop *mod_prop; + if ((mod_prop = spa_pod_find_prop (format, NULL, SPA_FORMAT_VIDEO_modifier)) != NULL) { info->flags |= SPA_VIDEO_FLAG_MODIFIER; + if ((mod_prop->flags & SPA_POD_PROP_FLAG_DONT_FIXATE) == SPA_POD_PROP_FLAG_DONT_FIXATE) + info->flags |= SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED; } return spa_pod_parse_object(format, @@ -46,9 +57,9 @@ spa_format_video_raw_parse(const struct spa_pod *format, SPA_FORMAT_VIDEO_colorPrimaries, SPA_POD_OPT_Id(&info->color_primaries)); } -static inline struct spa_pod * +SPA_API_VIDEO_RAW_UTILS struct spa_pod * spa_format_video_raw_build(struct spa_pod_builder *builder, uint32_t id, - struct spa_video_info_raw *info) + const struct spa_video_info_raw *info) { struct spa_pod_frame f; spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id); @@ -65,12 +76,14 @@ spa_format_video_raw_build(struct spa_pod_builder *builder, uint32_t id, if (info->framerate.denom != 0) spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&info->framerate), 0); - if (info->modifier != 0 || info->flags & SPA_VIDEO_FLAG_MODIFIER) - spa_pod_builder_add(builder, - SPA_FORMAT_VIDEO_modifier, SPA_POD_Long(info->modifier), 0); + if (info->modifier != 0 || info->flags & SPA_VIDEO_FLAG_MODIFIER) { + spa_pod_builder_prop(builder, + SPA_FORMAT_VIDEO_modifier, SPA_POD_PROP_FLAG_MANDATORY); + spa_pod_builder_long(builder, info->modifier); + } if (info->max_framerate.denom != 0) spa_pod_builder_add(builder, - SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_Fraction(info->max_framerate), 0); + SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_Fraction(&info->max_framerate), 0); if (info->views != 0) spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_views, SPA_POD_Int(info->views), 0); @@ -79,7 +92,7 @@ spa_format_video_raw_build(struct spa_pod_builder *builder, uint32_t id, SPA_FORMAT_VIDEO_interlaceMode, SPA_POD_Id(info->interlace_mode), 0); if (info->pixel_aspect_ratio.denom != 0) spa_pod_builder_add(builder, - SPA_FORMAT_VIDEO_pixelAspectRatio,SPA_POD_Fraction(info->pixel_aspect_ratio), 0); + SPA_FORMAT_VIDEO_pixelAspectRatio, SPA_POD_Fraction(&info->pixel_aspect_ratio), 0); if (info->multiview_mode != 0) spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_multiviewMode, SPA_POD_Id(info->multiview_mode), 0); diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw.h b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw.h index 5f5a5b64a5192..c2d369569d888 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/param/video/raw.h @@ -134,11 +134,12 @@ enum spa_video_format { * Extra video flags */ enum spa_video_flags { - SPA_VIDEO_FLAG_NONE = 0, /**< no flags */ - SPA_VIDEO_FLAG_VARIABLE_FPS = (1 << 0), /**< a variable fps is selected, fps_n and fps_d - * denote the maximum fps of the video */ - SPA_VIDEO_FLAG_PREMULTIPLIED_ALPHA = (1 << 1), /**< Each color has been scaled by the alpha value. */ - SPA_VIDEO_FLAG_MODIFIER = (1 << 2), /**< use the format modifier */ + SPA_VIDEO_FLAG_NONE = 0, /**< no flags */ + SPA_VIDEO_FLAG_VARIABLE_FPS = (1 << 0), /**< a variable fps is selected, fps_n and fps_d + * denote the maximum fps of the video */ + SPA_VIDEO_FLAG_PREMULTIPLIED_ALPHA = (1 << 1), /**< Each color has been scaled by the alpha value. */ + SPA_VIDEO_FLAG_MODIFIER = (1 << 2), /**< use the format modifier */ + SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED = (1 << 3), /**< format modifier was not fixated yet */ }; /** diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/pod/builder.h b/src/java.desktop/unix/native/libpipewire/include/spa/pod/builder.h index d9283baa036c4..745e0d671a56f 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/pod/builder.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/pod/builder.h @@ -24,6 +24,14 @@ extern "C" { #include #include +#ifndef SPA_API_POD_BUILDER + #ifdef SPA_API_IMPL + #define SPA_API_POD_BUILDER SPA_API_IMPL + #else + #define SPA_API_POD_BUILDER static inline + #endif +#endif + struct spa_pod_builder_state { uint32_t offset; #define SPA_POD_BUILDER_FLAG_BODY (1<<0) @@ -49,22 +57,22 @@ struct spa_pod_builder { struct spa_callbacks callbacks; }; -#define SPA_POD_BUILDER_INIT(buffer,size) ((struct spa_pod_builder){ (buffer), (size), 0, {}, {} }) +#define SPA_POD_BUILDER_INIT(buffer,size) ((struct spa_pod_builder){ (buffer), (size), 0, {0,0,NULL},{NULL,NULL}}) -static inline void +SPA_API_POD_BUILDER void spa_pod_builder_get_state(struct spa_pod_builder *builder, struct spa_pod_builder_state *state) { *state = builder->state; } -static inline void +SPA_API_POD_BUILDER void spa_pod_builder_set_callbacks(struct spa_pod_builder *builder, const struct spa_pod_builder_callbacks *callbacks, void *data) { builder->callbacks = SPA_CALLBACKS_INIT(callbacks, data); } -static inline void +SPA_API_POD_BUILDER void spa_pod_builder_reset(struct spa_pod_builder *builder, struct spa_pod_builder_state *state) { struct spa_pod_frame *f; @@ -74,12 +82,12 @@ spa_pod_builder_reset(struct spa_pod_builder *builder, struct spa_pod_builder_st f->pod.size -= size; } -static inline void spa_pod_builder_init(struct spa_pod_builder *builder, void *data, uint32_t size) +SPA_API_POD_BUILDER void spa_pod_builder_init(struct spa_pod_builder *builder, void *data, uint32_t size) { *builder = SPA_POD_BUILDER_INIT(data, size); } -static inline struct spa_pod * +SPA_API_POD_BUILDER struct spa_pod * spa_pod_builder_deref(struct spa_pod_builder *builder, uint32_t offset) { uint32_t size = builder->size; @@ -91,7 +99,7 @@ spa_pod_builder_deref(struct spa_pod_builder *builder, uint32_t offset) return NULL; } -static inline struct spa_pod * +SPA_API_POD_BUILDER struct spa_pod * spa_pod_builder_frame(struct spa_pod_builder *builder, struct spa_pod_frame *frame) { if (frame->offset + SPA_POD_SIZE(&frame->pod) <= builder->size) @@ -99,7 +107,7 @@ spa_pod_builder_frame(struct spa_pod_builder *builder, struct spa_pod_frame *fra return NULL; } -static inline void +SPA_API_POD_BUILDER void spa_pod_builder_push(struct spa_pod_builder *builder, struct spa_pod_frame *frame, const struct spa_pod *pod, @@ -115,7 +123,7 @@ spa_pod_builder_push(struct spa_pod_builder *builder, builder->state.flags = SPA_POD_BUILDER_FLAG_FIRST | SPA_POD_BUILDER_FLAG_BODY; } -static inline int spa_pod_builder_raw(struct spa_pod_builder *builder, const void *data, uint32_t size) +SPA_API_POD_BUILDER int spa_pod_builder_raw(struct spa_pod_builder *builder, const void *data, uint32_t size) { int res = 0; struct spa_pod_frame *f; @@ -139,14 +147,14 @@ static inline int spa_pod_builder_raw(struct spa_pod_builder *builder, const voi return res; } -static inline int spa_pod_builder_pad(struct spa_pod_builder *builder, uint32_t size) +SPA_API_POD_BUILDER int spa_pod_builder_pad(struct spa_pod_builder *builder, uint32_t size) { uint64_t zeroes = 0; size = SPA_ROUND_UP_N(size, 8) - size; return size ? spa_pod_builder_raw(builder, &zeroes, size) : 0; } -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_raw_padded(struct spa_pod_builder *builder, const void *data, uint32_t size) { int r, res = spa_pod_builder_raw(builder, data, size); @@ -155,7 +163,7 @@ spa_pod_builder_raw_padded(struct spa_pod_builder *builder, const void *data, ui return res; } -static inline void *spa_pod_builder_pop(struct spa_pod_builder *builder, struct spa_pod_frame *frame) +SPA_API_POD_BUILDER void *spa_pod_builder_pop(struct spa_pod_builder *builder, struct spa_pod_frame *frame) { struct spa_pod *pod; @@ -172,7 +180,7 @@ static inline void *spa_pod_builder_pop(struct spa_pod_builder *builder, struct return pod; } -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_primitive(struct spa_pod_builder *builder, const struct spa_pod *p) { const void *data; @@ -198,13 +206,13 @@ spa_pod_builder_primitive(struct spa_pod_builder *builder, const struct spa_pod #define SPA_POD_INIT_None() SPA_POD_INIT(0, SPA_TYPE_None) -static inline int spa_pod_builder_none(struct spa_pod_builder *builder) +SPA_API_POD_BUILDER int spa_pod_builder_none(struct spa_pod_builder *builder) { const struct spa_pod p = SPA_POD_INIT_None(); return spa_pod_builder_primitive(builder, &p); } -static inline int spa_pod_builder_child(struct spa_pod_builder *builder, uint32_t size, uint32_t type) +SPA_API_POD_BUILDER int spa_pod_builder_child(struct spa_pod_builder *builder, uint32_t size, uint32_t type) { const struct spa_pod p = SPA_POD_INIT(size,type); SPA_FLAG_CLEAR(builder->state.flags, SPA_POD_BUILDER_FLAG_FIRST); @@ -213,7 +221,7 @@ static inline int spa_pod_builder_child(struct spa_pod_builder *builder, uint32_ #define SPA_POD_INIT_Bool(val) ((struct spa_pod_bool){ { sizeof(uint32_t), SPA_TYPE_Bool }, (val) ? 1 : 0, 0 }) -static inline int spa_pod_builder_bool(struct spa_pod_builder *builder, bool val) +SPA_API_POD_BUILDER int spa_pod_builder_bool(struct spa_pod_builder *builder, bool val) { const struct spa_pod_bool p = SPA_POD_INIT_Bool(val); return spa_pod_builder_primitive(builder, &p.pod); @@ -221,7 +229,7 @@ static inline int spa_pod_builder_bool(struct spa_pod_builder *builder, bool val #define SPA_POD_INIT_Id(val) ((struct spa_pod_id){ { sizeof(uint32_t), SPA_TYPE_Id }, (val), 0 }) -static inline int spa_pod_builder_id(struct spa_pod_builder *builder, uint32_t val) +SPA_API_POD_BUILDER int spa_pod_builder_id(struct spa_pod_builder *builder, uint32_t val) { const struct spa_pod_id p = SPA_POD_INIT_Id(val); return spa_pod_builder_primitive(builder, &p.pod); @@ -229,7 +237,7 @@ static inline int spa_pod_builder_id(struct spa_pod_builder *builder, uint32_t v #define SPA_POD_INIT_Int(val) ((struct spa_pod_int){ { sizeof(int32_t), SPA_TYPE_Int }, (val), 0 }) -static inline int spa_pod_builder_int(struct spa_pod_builder *builder, int32_t val) +SPA_API_POD_BUILDER int spa_pod_builder_int(struct spa_pod_builder *builder, int32_t val) { const struct spa_pod_int p = SPA_POD_INIT_Int(val); return spa_pod_builder_primitive(builder, &p.pod); @@ -237,7 +245,7 @@ static inline int spa_pod_builder_int(struct spa_pod_builder *builder, int32_t v #define SPA_POD_INIT_Long(val) ((struct spa_pod_long){ { sizeof(int64_t), SPA_TYPE_Long }, (val) }) -static inline int spa_pod_builder_long(struct spa_pod_builder *builder, int64_t val) +SPA_API_POD_BUILDER int spa_pod_builder_long(struct spa_pod_builder *builder, int64_t val) { const struct spa_pod_long p = SPA_POD_INIT_Long(val); return spa_pod_builder_primitive(builder, &p.pod); @@ -245,7 +253,7 @@ static inline int spa_pod_builder_long(struct spa_pod_builder *builder, int64_t #define SPA_POD_INIT_Float(val) ((struct spa_pod_float){ { sizeof(float), SPA_TYPE_Float }, (val), 0 }) -static inline int spa_pod_builder_float(struct spa_pod_builder *builder, float val) +SPA_API_POD_BUILDER int spa_pod_builder_float(struct spa_pod_builder *builder, float val) { const struct spa_pod_float p = SPA_POD_INIT_Float(val); return spa_pod_builder_primitive(builder, &p.pod); @@ -253,7 +261,7 @@ static inline int spa_pod_builder_float(struct spa_pod_builder *builder, float v #define SPA_POD_INIT_Double(val) ((struct spa_pod_double){ { sizeof(double), SPA_TYPE_Double }, (val) }) -static inline int spa_pod_builder_double(struct spa_pod_builder *builder, double val) +SPA_API_POD_BUILDER int spa_pod_builder_double(struct spa_pod_builder *builder, double val) { const struct spa_pod_double p = SPA_POD_INIT_Double(val); return spa_pod_builder_primitive(builder, &p.pod); @@ -261,7 +269,7 @@ static inline int spa_pod_builder_double(struct spa_pod_builder *builder, double #define SPA_POD_INIT_String(len) ((struct spa_pod_string){ { (len), SPA_TYPE_String } }) -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_write_string(struct spa_pod_builder *builder, const char *str, uint32_t len) { int r, res; @@ -273,7 +281,7 @@ spa_pod_builder_write_string(struct spa_pod_builder *builder, const char *str, u return res; } -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_string_len(struct spa_pod_builder *builder, const char *str, uint32_t len) { const struct spa_pod_string p = SPA_POD_INIT_String(len+1); @@ -283,7 +291,7 @@ spa_pod_builder_string_len(struct spa_pod_builder *builder, const char *str, uin return res; } -static inline int spa_pod_builder_string(struct spa_pod_builder *builder, const char *str) +SPA_API_POD_BUILDER int spa_pod_builder_string(struct spa_pod_builder *builder, const char *str) { uint32_t len = str ? strlen(str) : 0; return spa_pod_builder_string_len(builder, str ? str : "", len); @@ -291,7 +299,7 @@ static inline int spa_pod_builder_string(struct spa_pod_builder *builder, const #define SPA_POD_INIT_Bytes(len) ((struct spa_pod_bytes){ { (len), SPA_TYPE_Bytes } }) -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_bytes(struct spa_pod_builder *builder, const void *bytes, uint32_t len) { const struct spa_pod_bytes p = SPA_POD_INIT_Bytes(len); @@ -300,7 +308,7 @@ spa_pod_builder_bytes(struct spa_pod_builder *builder, const void *bytes, uint32 res = r; return res; } -static inline void * +SPA_API_POD_BUILDER void * spa_pod_builder_reserve_bytes(struct spa_pod_builder *builder, uint32_t len) { uint32_t offset = builder->state.offset; @@ -311,7 +319,7 @@ spa_pod_builder_reserve_bytes(struct spa_pod_builder *builder, uint32_t len) #define SPA_POD_INIT_Pointer(type,value) ((struct spa_pod_pointer){ { sizeof(struct spa_pod_pointer_body), SPA_TYPE_Pointer }, { (type), 0, (value) } }) -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_pointer(struct spa_pod_builder *builder, uint32_t type, const void *val) { const struct spa_pod_pointer p = SPA_POD_INIT_Pointer(type, val); @@ -320,7 +328,7 @@ spa_pod_builder_pointer(struct spa_pod_builder *builder, uint32_t type, const vo #define SPA_POD_INIT_Fd(fd) ((struct spa_pod_fd){ { sizeof(int64_t), SPA_TYPE_Fd }, (fd) }) -static inline int spa_pod_builder_fd(struct spa_pod_builder *builder, int64_t fd) +SPA_API_POD_BUILDER int spa_pod_builder_fd(struct spa_pod_builder *builder, int64_t fd) { const struct spa_pod_fd p = SPA_POD_INIT_Fd(fd); return spa_pod_builder_primitive(builder, &p.pod); @@ -328,7 +336,7 @@ static inline int spa_pod_builder_fd(struct spa_pod_builder *builder, int64_t fd #define SPA_POD_INIT_Rectangle(val) ((struct spa_pod_rectangle){ { sizeof(struct spa_rectangle), SPA_TYPE_Rectangle }, (val) }) -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_rectangle(struct spa_pod_builder *builder, uint32_t width, uint32_t height) { const struct spa_pod_rectangle p = SPA_POD_INIT_Rectangle(SPA_RECTANGLE(width, height)); @@ -337,14 +345,14 @@ spa_pod_builder_rectangle(struct spa_pod_builder *builder, uint32_t width, uint3 #define SPA_POD_INIT_Fraction(val) ((struct spa_pod_fraction){ { sizeof(struct spa_fraction), SPA_TYPE_Fraction }, (val) }) -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_fraction(struct spa_pod_builder *builder, uint32_t num, uint32_t denom) { const struct spa_pod_fraction p = SPA_POD_INIT_Fraction(SPA_FRACTION(num, denom)); return spa_pod_builder_primitive(builder, &p.pod); } -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_push_array(struct spa_pod_builder *builder, struct spa_pod_frame *frame) { const struct spa_pod_array p = @@ -356,7 +364,7 @@ spa_pod_builder_push_array(struct spa_pod_builder *builder, struct spa_pod_frame return res; } -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_array(struct spa_pod_builder *builder, uint32_t child_size, uint32_t child_type, uint32_t n_elems, const void *elems) { @@ -378,7 +386,7 @@ spa_pod_builder_array(struct spa_pod_builder *builder, { { { (n_vals) * sizeof(ctype) + sizeof(struct spa_pod_choice_body), SPA_TYPE_Choice }, \ { (type), 0, { sizeof(ctype), (child_type) } } }, { __VA_ARGS__ } }) -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_push_choice(struct spa_pod_builder *builder, struct spa_pod_frame *frame, uint32_t type, uint32_t flags) { @@ -393,7 +401,7 @@ spa_pod_builder_push_choice(struct spa_pod_builder *builder, struct spa_pod_fram #define SPA_POD_INIT_Struct(size) ((struct spa_pod_struct){ { (size), SPA_TYPE_Struct } }) -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_push_struct(struct spa_pod_builder *builder, struct spa_pod_frame *frame) { const struct spa_pod_struct p = SPA_POD_INIT_Struct(0); @@ -405,7 +413,7 @@ spa_pod_builder_push_struct(struct spa_pod_builder *builder, struct spa_pod_fram #define SPA_POD_INIT_Object(size,type,id,...) ((struct spa_pod_object){ { (size), SPA_TYPE_Object }, { (type), (id) }, ##__VA_ARGS__ }) -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_push_object(struct spa_pod_builder *builder, struct spa_pod_frame *frame, uint32_t type, uint32_t id) { @@ -420,7 +428,7 @@ spa_pod_builder_push_object(struct spa_pod_builder *builder, struct spa_pod_fram #define SPA_POD_INIT_Prop(key,flags,size,type) \ ((struct spa_pod_prop){ (key), (flags), { (size), (type) } }) -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_prop(struct spa_pod_builder *builder, uint32_t key, uint32_t flags) { const struct { uint32_t key; uint32_t flags; } p = { key, flags }; @@ -430,7 +438,7 @@ spa_pod_builder_prop(struct spa_pod_builder *builder, uint32_t key, uint32_t fla #define SPA_POD_INIT_Sequence(size,unit) \ ((struct spa_pod_sequence){ { (size), SPA_TYPE_Sequence}, {(unit), 0 } }) -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_push_sequence(struct spa_pod_builder *builder, struct spa_pod_frame *frame, uint32_t unit) { const struct spa_pod_sequence p = @@ -441,14 +449,14 @@ spa_pod_builder_push_sequence(struct spa_pod_builder *builder, struct spa_pod_fr return res; } -static inline uint32_t +SPA_API_POD_BUILDER int spa_pod_builder_control(struct spa_pod_builder *builder, uint32_t offset, uint32_t type) { const struct { uint32_t offset; uint32_t type; } p = { offset, type }; return spa_pod_builder_raw(builder, &p, sizeof(p)); } -static inline uint32_t spa_choice_from_id(char id) +SPA_API_POD_BUILDER uint32_t spa_choice_from_id(char id) { switch (id) { case 'r': @@ -481,7 +489,7 @@ do { \ spa_pod_builder_long(builder, va_arg(args, int64_t)); \ break; \ case 'f': \ - spa_pod_builder_float(builder, va_arg(args, double)); \ + spa_pod_builder_float(builder, (float)va_arg(args, double)); \ break; \ case 'd': \ spa_pod_builder_double(builder, va_arg(args, double)); \ @@ -560,7 +568,7 @@ do { \ } \ } while(false) -static inline int +SPA_API_POD_BUILDER int spa_pod_builder_addv(struct spa_pod_builder *builder, va_list args) { int res = 0; @@ -618,7 +626,7 @@ spa_pod_builder_addv(struct spa_pod_builder *builder, va_list args) return res; } -static inline int spa_pod_builder_add(struct spa_pod_builder *builder, ...) +SPA_API_POD_BUILDER int spa_pod_builder_add(struct spa_pod_builder *builder, ...) { int res; va_list args; @@ -658,7 +666,7 @@ static inline int spa_pod_builder_add(struct spa_pod_builder *builder, ...) }) /** Copy a pod structure */ -static inline struct spa_pod * +SPA_API_POD_BUILDER struct spa_pod * spa_pod_copy(const struct spa_pod *pod) { size_t size; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/pod/event.h b/src/java.desktop/unix/native/libpipewire/include/spa/pod/event.h index 23a75a2fd439d..0fa02f698f57f 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/pod/event.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/pod/event.h @@ -30,7 +30,7 @@ struct spa_event { (ev)->body.body.id : SPA_ID_INVALID) #define SPA_EVENT_INIT_FULL(t,size,type,id,...) ((t) \ - { { (size), SPA_TYPE_OBJECT }, \ + { { (size), SPA_TYPE_Object }, \ { { (type), (id) }, ##__VA_ARGS__ } }) \ #define SPA_EVENT_INIT(type,id) \ diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/pod/iter.h b/src/java.desktop/unix/native/libpipewire/include/spa/pod/iter.h index 3dd24a8eb4425..cb9b7b898848e 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/pod/iter.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/pod/iter.h @@ -14,6 +14,14 @@ extern "C" { #include +#ifndef SPA_API_POD_ITER + #ifdef SPA_API_IMPL + #define SPA_API_POD_ITER SPA_API_IMPL + #else + #define SPA_API_POD_ITER static inline + #endif +#endif + /** * \addtogroup spa_pod * \{ @@ -26,54 +34,60 @@ struct spa_pod_frame { uint32_t flags; }; -static inline bool spa_pod_is_inside(const void *pod, uint32_t size, const void *iter) +SPA_API_POD_ITER bool spa_pod_is_inside(const void *pod, uint32_t size, const void *iter) { - return SPA_POD_BODY(iter) <= SPA_PTROFF(pod, size, void) && - SPA_PTROFF(iter, SPA_POD_SIZE(iter), void) <= SPA_PTROFF(pod, size, void); + size_t remaining; + + return spa_ptr_type_inside(pod, size, iter, struct spa_pod, &remaining) && + remaining >= SPA_POD_BODY_SIZE(iter); } -static inline void *spa_pod_next(const void *iter) +SPA_API_POD_ITER void *spa_pod_next(const void *iter) { return SPA_PTROFF(iter, SPA_ROUND_UP_N(SPA_POD_SIZE(iter), 8), void); } -static inline struct spa_pod_prop *spa_pod_prop_first(const struct spa_pod_object_body *body) +SPA_API_POD_ITER struct spa_pod_prop *spa_pod_prop_first(const struct spa_pod_object_body *body) { return SPA_PTROFF(body, sizeof(struct spa_pod_object_body), struct spa_pod_prop); } -static inline bool spa_pod_prop_is_inside(const struct spa_pod_object_body *body, +SPA_API_POD_ITER bool spa_pod_prop_is_inside(const struct spa_pod_object_body *body, uint32_t size, const struct spa_pod_prop *iter) { - return SPA_POD_CONTENTS(struct spa_pod_prop, iter) <= SPA_PTROFF(body, size, void) && - SPA_PTROFF(iter, SPA_POD_PROP_SIZE(iter), void) <= SPA_PTROFF(body, size, void); + size_t remaining; + + return spa_ptr_type_inside(body, size, iter, struct spa_pod_prop, &remaining) && + remaining >= iter->value.size; } -static inline struct spa_pod_prop *spa_pod_prop_next(const struct spa_pod_prop *iter) +SPA_API_POD_ITER struct spa_pod_prop *spa_pod_prop_next(const struct spa_pod_prop *iter) { return SPA_PTROFF(iter, SPA_ROUND_UP_N(SPA_POD_PROP_SIZE(iter), 8), struct spa_pod_prop); } -static inline struct spa_pod_control *spa_pod_control_first(const struct spa_pod_sequence_body *body) +SPA_API_POD_ITER struct spa_pod_control *spa_pod_control_first(const struct spa_pod_sequence_body *body) { return SPA_PTROFF(body, sizeof(struct spa_pod_sequence_body), struct spa_pod_control); } -static inline bool spa_pod_control_is_inside(const struct spa_pod_sequence_body *body, +SPA_API_POD_ITER bool spa_pod_control_is_inside(const struct spa_pod_sequence_body *body, uint32_t size, const struct spa_pod_control *iter) { - return SPA_POD_CONTENTS(struct spa_pod_control, iter) <= SPA_PTROFF(body, size, void) && - SPA_PTROFF(iter, SPA_POD_CONTROL_SIZE(iter), void) <= SPA_PTROFF(body, size, void); + size_t remaining; + + return spa_ptr_type_inside(body, size, iter, struct spa_pod_control, &remaining) && + remaining >= iter->value.size; } -static inline struct spa_pod_control *spa_pod_control_next(const struct spa_pod_control *iter) +SPA_API_POD_ITER struct spa_pod_control *spa_pod_control_next(const struct spa_pod_control *iter) { return SPA_PTROFF(iter, SPA_ROUND_UP_N(SPA_POD_CONTROL_SIZE(iter), 8), struct spa_pod_control); } #define SPA_POD_ARRAY_BODY_FOREACH(body, _size, iter) \ for ((iter) = (__typeof__(iter))SPA_PTROFF((body), sizeof(struct spa_pod_array_body), void); \ - (iter) < (__typeof__(iter))SPA_PTROFF((body), (_size), void); \ + (body)->child.size > 0 && spa_ptrinside(body, _size, iter, (body)->child.size, NULL); \ (iter) = (__typeof__(iter))SPA_PTROFF((iter), (body)->child.size, void)) #define SPA_POD_ARRAY_FOREACH(obj, iter) \ @@ -81,7 +95,7 @@ static inline struct spa_pod_control *spa_pod_control_next(const struct spa_pod_ #define SPA_POD_CHOICE_BODY_FOREACH(body, _size, iter) \ for ((iter) = (__typeof__(iter))SPA_PTROFF((body), sizeof(struct spa_pod_choice_body), void); \ - (iter) < (__typeof__(iter))SPA_PTROFF((body), (_size), void); \ + (body)->child.size > 0 && spa_ptrinside(body, _size, iter, (body)->child.size, NULL); \ (iter) = (__typeof__(iter))SPA_PTROFF((iter), (body)->child.size, void)) #define SPA_POD_CHOICE_FOREACH(obj, iter) \ @@ -112,7 +126,7 @@ static inline struct spa_pod_control *spa_pod_control_next(const struct spa_pod_ SPA_POD_SEQUENCE_BODY_FOREACH(&(seq)->body, SPA_POD_BODY_SIZE(seq), iter) -static inline void *spa_pod_from_data(void *data, size_t maxsize, off_t offset, size_t size) +SPA_API_POD_ITER void *spa_pod_from_data(void *data, size_t maxsize, off_t offset, size_t size) { void *pod; if (size < sizeof(struct spa_pod) || offset + size > maxsize) @@ -123,17 +137,17 @@ static inline void *spa_pod_from_data(void *data, size_t maxsize, off_t offset, return pod; } -static inline int spa_pod_is_none(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_none(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_None); } -static inline int spa_pod_is_bool(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_bool(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Bool && SPA_POD_BODY_SIZE(pod) >= sizeof(int32_t)); } -static inline int spa_pod_get_bool(const struct spa_pod *pod, bool *value) +SPA_API_POD_ITER int spa_pod_get_bool(const struct spa_pod *pod, bool *value) { if (!spa_pod_is_bool(pod)) return -EINVAL; @@ -141,12 +155,12 @@ static inline int spa_pod_get_bool(const struct spa_pod *pod, bool *value) return 0; } -static inline int spa_pod_is_id(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_id(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Id && SPA_POD_BODY_SIZE(pod) >= sizeof(uint32_t)); } -static inline int spa_pod_get_id(const struct spa_pod *pod, uint32_t *value) +SPA_API_POD_ITER int spa_pod_get_id(const struct spa_pod *pod, uint32_t *value) { if (!spa_pod_is_id(pod)) return -EINVAL; @@ -154,12 +168,12 @@ static inline int spa_pod_get_id(const struct spa_pod *pod, uint32_t *value) return 0; } -static inline int spa_pod_is_int(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_int(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Int && SPA_POD_BODY_SIZE(pod) >= sizeof(int32_t)); } -static inline int spa_pod_get_int(const struct spa_pod *pod, int32_t *value) +SPA_API_POD_ITER int spa_pod_get_int(const struct spa_pod *pod, int32_t *value) { if (!spa_pod_is_int(pod)) return -EINVAL; @@ -167,12 +181,12 @@ static inline int spa_pod_get_int(const struct spa_pod *pod, int32_t *value) return 0; } -static inline int spa_pod_is_long(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_long(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Long && SPA_POD_BODY_SIZE(pod) >= sizeof(int64_t)); } -static inline int spa_pod_get_long(const struct spa_pod *pod, int64_t *value) +SPA_API_POD_ITER int spa_pod_get_long(const struct spa_pod *pod, int64_t *value) { if (!spa_pod_is_long(pod)) return -EINVAL; @@ -180,12 +194,12 @@ static inline int spa_pod_get_long(const struct spa_pod *pod, int64_t *value) return 0; } -static inline int spa_pod_is_float(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_float(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Float && SPA_POD_BODY_SIZE(pod) >= sizeof(float)); } -static inline int spa_pod_get_float(const struct spa_pod *pod, float *value) +SPA_API_POD_ITER int spa_pod_get_float(const struct spa_pod *pod, float *value) { if (!spa_pod_is_float(pod)) return -EINVAL; @@ -193,12 +207,12 @@ static inline int spa_pod_get_float(const struct spa_pod *pod, float *value) return 0; } -static inline int spa_pod_is_double(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_double(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Double && SPA_POD_BODY_SIZE(pod) >= sizeof(double)); } -static inline int spa_pod_get_double(const struct spa_pod *pod, double *value) +SPA_API_POD_ITER int spa_pod_get_double(const struct spa_pod *pod, double *value) { if (!spa_pod_is_double(pod)) return -EINVAL; @@ -206,7 +220,7 @@ static inline int spa_pod_get_double(const struct spa_pod *pod, double *value) return 0; } -static inline int spa_pod_is_string(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_string(const struct spa_pod *pod) { const char *s = (const char *)SPA_POD_CONTENTS(struct spa_pod_string, pod); return (SPA_POD_TYPE(pod) == SPA_TYPE_String && @@ -214,7 +228,7 @@ static inline int spa_pod_is_string(const struct spa_pod *pod) s[SPA_POD_BODY_SIZE(pod)-1] == '\0'); } -static inline int spa_pod_get_string(const struct spa_pod *pod, const char **value) +SPA_API_POD_ITER int spa_pod_get_string(const struct spa_pod *pod, const char **value) { if (!spa_pod_is_string(pod)) return -EINVAL; @@ -222,7 +236,7 @@ static inline int spa_pod_get_string(const struct spa_pod *pod, const char **val return 0; } -static inline int spa_pod_copy_string(const struct spa_pod *pod, size_t maxlen, char *dest) +SPA_API_POD_ITER int spa_pod_copy_string(const struct spa_pod *pod, size_t maxlen, char *dest) { const char *s = (const char *)SPA_POD_CONTENTS(struct spa_pod_string, pod); if (!spa_pod_is_string(pod) || maxlen < 1) @@ -232,12 +246,12 @@ static inline int spa_pod_copy_string(const struct spa_pod *pod, size_t maxlen, return 0; } -static inline int spa_pod_is_bytes(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_bytes(const struct spa_pod *pod) { return SPA_POD_TYPE(pod) == SPA_TYPE_Bytes; } -static inline int spa_pod_get_bytes(const struct spa_pod *pod, const void **value, uint32_t *len) +SPA_API_POD_ITER int spa_pod_get_bytes(const struct spa_pod *pod, const void **value, uint32_t *len) { if (!spa_pod_is_bytes(pod)) return -EINVAL; @@ -246,13 +260,13 @@ static inline int spa_pod_get_bytes(const struct spa_pod *pod, const void **valu return 0; } -static inline int spa_pod_is_pointer(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_pointer(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Pointer && SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_pointer_body)); } -static inline int spa_pod_get_pointer(const struct spa_pod *pod, uint32_t *type, const void **value) +SPA_API_POD_ITER int spa_pod_get_pointer(const struct spa_pod *pod, uint32_t *type, const void **value) { if (!spa_pod_is_pointer(pod)) return -EINVAL; @@ -261,13 +275,13 @@ static inline int spa_pod_get_pointer(const struct spa_pod *pod, uint32_t *type, return 0; } -static inline int spa_pod_is_fd(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_fd(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Fd && SPA_POD_BODY_SIZE(pod) >= sizeof(int64_t)); } -static inline int spa_pod_get_fd(const struct spa_pod *pod, int64_t *value) +SPA_API_POD_ITER int spa_pod_get_fd(const struct spa_pod *pod, int64_t *value) { if (!spa_pod_is_fd(pod)) return -EINVAL; @@ -275,13 +289,13 @@ static inline int spa_pod_get_fd(const struct spa_pod *pod, int64_t *value) return 0; } -static inline int spa_pod_is_rectangle(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_rectangle(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Rectangle && SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_rectangle)); } -static inline int spa_pod_get_rectangle(const struct spa_pod *pod, struct spa_rectangle *value) +SPA_API_POD_ITER int spa_pod_get_rectangle(const struct spa_pod *pod, struct spa_rectangle *value) { if (!spa_pod_is_rectangle(pod)) return -EINVAL; @@ -289,39 +303,39 @@ static inline int spa_pod_get_rectangle(const struct spa_pod *pod, struct spa_re return 0; } -static inline int spa_pod_is_fraction(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_fraction(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Fraction && SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_fraction)); } -static inline int spa_pod_get_fraction(const struct spa_pod *pod, struct spa_fraction *value) +SPA_API_POD_ITER int spa_pod_get_fraction(const struct spa_pod *pod, struct spa_fraction *value) { spa_return_val_if_fail(spa_pod_is_fraction(pod), -EINVAL); *value = SPA_POD_VALUE(struct spa_pod_fraction, pod); return 0; } -static inline int spa_pod_is_bitmap(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_bitmap(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Bitmap && SPA_POD_BODY_SIZE(pod) >= sizeof(uint8_t)); } -static inline int spa_pod_is_array(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_array(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Array && SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_array_body)); } -static inline void *spa_pod_get_array(const struct spa_pod *pod, uint32_t *n_values) +SPA_API_POD_ITER void *spa_pod_get_array(const struct spa_pod *pod, uint32_t *n_values) { spa_return_val_if_fail(spa_pod_is_array(pod), NULL); *n_values = SPA_POD_ARRAY_N_VALUES(pod); return SPA_POD_ARRAY_VALUES(pod); } -static inline uint32_t spa_pod_copy_array(const struct spa_pod *pod, uint32_t type, +SPA_API_POD_ITER uint32_t spa_pod_copy_array(const struct spa_pod *pod, uint32_t type, void *values, uint32_t max_values) { uint32_t n_values; @@ -333,13 +347,13 @@ static inline uint32_t spa_pod_copy_array(const struct spa_pod *pod, uint32_t ty return n_values; } -static inline int spa_pod_is_choice(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_choice(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Choice && SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_choice_body)); } -static inline struct spa_pod *spa_pod_get_values(const struct spa_pod *pod, uint32_t *n_vals, uint32_t *choice) +SPA_API_POD_ITER struct spa_pod *spa_pod_get_values(const struct spa_pod *pod, uint32_t *n_vals, uint32_t *choice) { if (pod->type == SPA_TYPE_Choice) { *n_vals = SPA_POD_CHOICE_N_VALUES(pod); @@ -353,34 +367,34 @@ static inline struct spa_pod *spa_pod_get_values(const struct spa_pod *pod, uint } } -static inline int spa_pod_is_struct(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_struct(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Struct); } -static inline int spa_pod_is_object(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_object(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Object && SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_object_body)); } -static inline bool spa_pod_is_object_type(const struct spa_pod *pod, uint32_t type) +SPA_API_POD_ITER bool spa_pod_is_object_type(const struct spa_pod *pod, uint32_t type) { return (pod && spa_pod_is_object(pod) && SPA_POD_OBJECT_TYPE(pod) == type); } -static inline bool spa_pod_is_object_id(const struct spa_pod *pod, uint32_t id) +SPA_API_POD_ITER bool spa_pod_is_object_id(const struct spa_pod *pod, uint32_t id) { return (pod && spa_pod_is_object(pod) && SPA_POD_OBJECT_ID(pod) == id); } -static inline int spa_pod_is_sequence(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_is_sequence(const struct spa_pod *pod) { return (SPA_POD_TYPE(pod) == SPA_TYPE_Sequence && SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_sequence_body)); } -static inline const struct spa_pod_prop *spa_pod_object_find_prop(const struct spa_pod_object *pod, +SPA_API_POD_ITER const struct spa_pod_prop *spa_pod_object_find_prop(const struct spa_pod_object *pod, const struct spa_pod_prop *start, uint32_t key) { const struct spa_pod_prop *first, *res; @@ -400,7 +414,7 @@ static inline const struct spa_pod_prop *spa_pod_object_find_prop(const struct s return NULL; } -static inline const struct spa_pod_prop *spa_pod_find_prop(const struct spa_pod *pod, +SPA_API_POD_ITER const struct spa_pod_prop *spa_pod_find_prop(const struct spa_pod *pod, const struct spa_pod_prop *start, uint32_t key) { if (!spa_pod_is_object(pod)) @@ -408,7 +422,7 @@ static inline const struct spa_pod_prop *spa_pod_find_prop(const struct spa_pod return spa_pod_object_find_prop((const struct spa_pod_object *)pod, start, key); } -static inline int spa_pod_object_fixate(struct spa_pod_object *pod) +SPA_API_POD_ITER int spa_pod_object_fixate(struct spa_pod_object *pod) { struct spa_pod_prop *res; SPA_POD_OBJECT_FOREACH(pod, res) { @@ -419,14 +433,14 @@ static inline int spa_pod_object_fixate(struct spa_pod_object *pod) return 0; } -static inline int spa_pod_fixate(struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_fixate(struct spa_pod *pod) { if (!spa_pod_is_object(pod)) return -EINVAL; return spa_pod_object_fixate((struct spa_pod_object *)pod); } -static inline int spa_pod_object_is_fixated(const struct spa_pod_object *pod) +SPA_API_POD_ITER int spa_pod_object_is_fixated(const struct spa_pod_object *pod) { struct spa_pod_prop *res; SPA_POD_OBJECT_FOREACH(pod, res) { @@ -437,7 +451,15 @@ static inline int spa_pod_object_is_fixated(const struct spa_pod_object *pod) return 1; } -static inline int spa_pod_is_fixated(const struct spa_pod *pod) +SPA_API_POD_ITER int spa_pod_object_has_props(const struct spa_pod_object *pod) +{ + struct spa_pod_prop *res; + SPA_POD_OBJECT_FOREACH(pod, res) + return 1; + return 0; +} + +SPA_API_POD_ITER int spa_pod_is_fixated(const struct spa_pod *pod) { if (!spa_pod_is_object(pod)) return -EINVAL; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/pod/parser.h b/src/java.desktop/unix/native/libpipewire/include/spa/pod/parser.h index 76c73e2e6cae9..bfec7b88c805c 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/pod/parser.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/pod/parser.h @@ -15,6 +15,14 @@ extern "C" { #include #include +#ifndef SPA_API_POD_PARSER + #ifdef SPA_API_IMPL + #define SPA_API_POD_PARSER SPA_API_IMPL + #else + #define SPA_API_POD_PARSER static inline + #endif +#endif + /** * \addtogroup spa_pod * \{ @@ -33,33 +41,33 @@ struct spa_pod_parser { struct spa_pod_parser_state state; }; -#define SPA_POD_PARSER_INIT(buffer,size) ((struct spa_pod_parser){ (buffer), (size), 0, {} }) +#define SPA_POD_PARSER_INIT(buffer,size) ((struct spa_pod_parser){ (buffer), (size), 0, {0,0,NULL}}) -static inline void spa_pod_parser_init(struct spa_pod_parser *parser, +SPA_API_POD_PARSER void spa_pod_parser_init(struct spa_pod_parser *parser, const void *data, uint32_t size) { *parser = SPA_POD_PARSER_INIT(data, size); } -static inline void spa_pod_parser_pod(struct spa_pod_parser *parser, +SPA_API_POD_PARSER void spa_pod_parser_pod(struct spa_pod_parser *parser, const struct spa_pod *pod) { spa_pod_parser_init(parser, pod, SPA_POD_SIZE(pod)); } -static inline void +SPA_API_POD_PARSER void spa_pod_parser_get_state(struct spa_pod_parser *parser, struct spa_pod_parser_state *state) { *state = parser->state; } -static inline void +SPA_API_POD_PARSER void spa_pod_parser_reset(struct spa_pod_parser *parser, struct spa_pod_parser_state *state) { parser->state = *state; } -static inline struct spa_pod * +SPA_API_POD_PARSER struct spa_pod * spa_pod_parser_deref(struct spa_pod_parser *parser, uint32_t offset, uint32_t size) { /* Cast to uint64_t to avoid wraparound. Add 8 for the pod itself. */ @@ -78,12 +86,12 @@ spa_pod_parser_deref(struct spa_pod_parser *parser, uint32_t offset, uint32_t si return NULL; } -static inline struct spa_pod *spa_pod_parser_frame(struct spa_pod_parser *parser, struct spa_pod_frame *frame) +SPA_API_POD_PARSER struct spa_pod *spa_pod_parser_frame(struct spa_pod_parser *parser, struct spa_pod_frame *frame) { return SPA_PTROFF(parser->data, frame->offset, struct spa_pod); } -static inline void spa_pod_parser_push(struct spa_pod_parser *parser, +SPA_API_POD_PARSER void spa_pod_parser_push(struct spa_pod_parser *parser, struct spa_pod_frame *frame, const struct spa_pod *pod, uint32_t offset) { frame->pod = *pod; @@ -93,19 +101,19 @@ static inline void spa_pod_parser_push(struct spa_pod_parser *parser, parser->state.frame = frame; } -static inline struct spa_pod *spa_pod_parser_current(struct spa_pod_parser *parser) +SPA_API_POD_PARSER struct spa_pod *spa_pod_parser_current(struct spa_pod_parser *parser) { struct spa_pod_frame *f = parser->state.frame; uint32_t size = f ? f->offset + SPA_POD_SIZE(&f->pod) : parser->size; return spa_pod_parser_deref(parser, parser->state.offset, size); } -static inline void spa_pod_parser_advance(struct spa_pod_parser *parser, const struct spa_pod *pod) +SPA_API_POD_PARSER void spa_pod_parser_advance(struct spa_pod_parser *parser, const struct spa_pod *pod) { parser->state.offset += SPA_ROUND_UP_N(SPA_POD_SIZE(pod), 8); } -static inline struct spa_pod *spa_pod_parser_next(struct spa_pod_parser *parser) +SPA_API_POD_PARSER struct spa_pod *spa_pod_parser_next(struct spa_pod_parser *parser) { struct spa_pod *pod = spa_pod_parser_current(parser); if (pod) @@ -113,7 +121,7 @@ static inline struct spa_pod *spa_pod_parser_next(struct spa_pod_parser *parser) return pod; } -static inline int spa_pod_parser_pop(struct spa_pod_parser *parser, +SPA_API_POD_PARSER int spa_pod_parser_pop(struct spa_pod_parser *parser, struct spa_pod_frame *frame) { parser->state.frame = frame->parent; @@ -121,7 +129,7 @@ static inline int spa_pod_parser_pop(struct spa_pod_parser *parser, return 0; } -static inline int spa_pod_parser_get_bool(struct spa_pod_parser *parser, bool *value) +SPA_API_POD_PARSER int spa_pod_parser_get_bool(struct spa_pod_parser *parser, bool *value) { int res = -EPIPE; const struct spa_pod *pod = spa_pod_parser_current(parser); @@ -130,7 +138,7 @@ static inline int spa_pod_parser_get_bool(struct spa_pod_parser *parser, bool *v return res; } -static inline int spa_pod_parser_get_id(struct spa_pod_parser *parser, uint32_t *value) +SPA_API_POD_PARSER int spa_pod_parser_get_id(struct spa_pod_parser *parser, uint32_t *value) { int res = -EPIPE; const struct spa_pod *pod = spa_pod_parser_current(parser); @@ -139,7 +147,7 @@ static inline int spa_pod_parser_get_id(struct spa_pod_parser *parser, uint32_t return res; } -static inline int spa_pod_parser_get_int(struct spa_pod_parser *parser, int32_t *value) +SPA_API_POD_PARSER int spa_pod_parser_get_int(struct spa_pod_parser *parser, int32_t *value) { int res = -EPIPE; const struct spa_pod *pod = spa_pod_parser_current(parser); @@ -148,7 +156,7 @@ static inline int spa_pod_parser_get_int(struct spa_pod_parser *parser, int32_t return res; } -static inline int spa_pod_parser_get_long(struct spa_pod_parser *parser, int64_t *value) +SPA_API_POD_PARSER int spa_pod_parser_get_long(struct spa_pod_parser *parser, int64_t *value) { int res = -EPIPE; const struct spa_pod *pod = spa_pod_parser_current(parser); @@ -157,7 +165,7 @@ static inline int spa_pod_parser_get_long(struct spa_pod_parser *parser, int64_t return res; } -static inline int spa_pod_parser_get_float(struct spa_pod_parser *parser, float *value) +SPA_API_POD_PARSER int spa_pod_parser_get_float(struct spa_pod_parser *parser, float *value) { int res = -EPIPE; const struct spa_pod *pod = spa_pod_parser_current(parser); @@ -166,7 +174,7 @@ static inline int spa_pod_parser_get_float(struct spa_pod_parser *parser, float return res; } -static inline int spa_pod_parser_get_double(struct spa_pod_parser *parser, double *value) +SPA_API_POD_PARSER int spa_pod_parser_get_double(struct spa_pod_parser *parser, double *value) { int res = -EPIPE; const struct spa_pod *pod = spa_pod_parser_current(parser); @@ -175,7 +183,7 @@ static inline int spa_pod_parser_get_double(struct spa_pod_parser *parser, doubl return res; } -static inline int spa_pod_parser_get_string(struct spa_pod_parser *parser, const char **value) +SPA_API_POD_PARSER int spa_pod_parser_get_string(struct spa_pod_parser *parser, const char **value) { int res = -EPIPE; const struct spa_pod *pod = spa_pod_parser_current(parser); @@ -184,7 +192,7 @@ static inline int spa_pod_parser_get_string(struct spa_pod_parser *parser, const return res; } -static inline int spa_pod_parser_get_bytes(struct spa_pod_parser *parser, const void **value, uint32_t *len) +SPA_API_POD_PARSER int spa_pod_parser_get_bytes(struct spa_pod_parser *parser, const void **value, uint32_t *len) { int res = -EPIPE; const struct spa_pod *pod = spa_pod_parser_current(parser); @@ -193,7 +201,7 @@ static inline int spa_pod_parser_get_bytes(struct spa_pod_parser *parser, const return res; } -static inline int spa_pod_parser_get_pointer(struct spa_pod_parser *parser, uint32_t *type, const void **value) +SPA_API_POD_PARSER int spa_pod_parser_get_pointer(struct spa_pod_parser *parser, uint32_t *type, const void **value) { int res = -EPIPE; const struct spa_pod *pod = spa_pod_parser_current(parser); @@ -202,7 +210,7 @@ static inline int spa_pod_parser_get_pointer(struct spa_pod_parser *parser, uint return res; } -static inline int spa_pod_parser_get_fd(struct spa_pod_parser *parser, int64_t *value) +SPA_API_POD_PARSER int spa_pod_parser_get_fd(struct spa_pod_parser *parser, int64_t *value) { int res = -EPIPE; const struct spa_pod *pod = spa_pod_parser_current(parser); @@ -211,7 +219,7 @@ static inline int spa_pod_parser_get_fd(struct spa_pod_parser *parser, int64_t * return res; } -static inline int spa_pod_parser_get_rectangle(struct spa_pod_parser *parser, struct spa_rectangle *value) +SPA_API_POD_PARSER int spa_pod_parser_get_rectangle(struct spa_pod_parser *parser, struct spa_rectangle *value) { int res = -EPIPE; const struct spa_pod *pod = spa_pod_parser_current(parser); @@ -220,7 +228,7 @@ static inline int spa_pod_parser_get_rectangle(struct spa_pod_parser *parser, st return res; } -static inline int spa_pod_parser_get_fraction(struct spa_pod_parser *parser, struct spa_fraction *value) +SPA_API_POD_PARSER int spa_pod_parser_get_fraction(struct spa_pod_parser *parser, struct spa_fraction *value) { int res = -EPIPE; const struct spa_pod *pod = spa_pod_parser_current(parser); @@ -229,7 +237,7 @@ static inline int spa_pod_parser_get_fraction(struct spa_pod_parser *parser, str return res; } -static inline int spa_pod_parser_get_pod(struct spa_pod_parser *parser, struct spa_pod **value) +SPA_API_POD_PARSER int spa_pod_parser_get_pod(struct spa_pod_parser *parser, struct spa_pod **value) { struct spa_pod *pod = spa_pod_parser_current(parser); if (pod == NULL) @@ -238,7 +246,7 @@ static inline int spa_pod_parser_get_pod(struct spa_pod_parser *parser, struct s spa_pod_parser_advance(parser, pod); return 0; } -static inline int spa_pod_parser_push_struct(struct spa_pod_parser *parser, +SPA_API_POD_PARSER int spa_pod_parser_push_struct(struct spa_pod_parser *parser, struct spa_pod_frame *frame) { const struct spa_pod *pod = spa_pod_parser_current(parser); @@ -251,7 +259,7 @@ static inline int spa_pod_parser_push_struct(struct spa_pod_parser *parser, return 0; } -static inline int spa_pod_parser_push_object(struct spa_pod_parser *parser, +SPA_API_POD_PARSER int spa_pod_parser_push_object(struct spa_pod_parser *parser, struct spa_pod_frame *frame, uint32_t type, uint32_t *id) { const struct spa_pod *pod = spa_pod_parser_current(parser); @@ -268,7 +276,7 @@ static inline int spa_pod_parser_push_object(struct spa_pod_parser *parser, return 0; } -static inline bool spa_pod_parser_can_collect(const struct spa_pod *pod, char type) +SPA_API_POD_PARSER bool spa_pod_parser_can_collect(const struct spa_pod *pod, char type) { if (pod == NULL) return false; @@ -443,7 +451,7 @@ do { \ } \ } while(false) -static inline int spa_pod_parser_getv(struct spa_pod_parser *parser, va_list args) +SPA_API_POD_PARSER int spa_pod_parser_getv(struct spa_pod_parser *parser, va_list args) { struct spa_pod_frame *f = parser->state.frame; uint32_t ftype = f ? f->pod.type : (uint32_t)SPA_TYPE_Struct; @@ -455,7 +463,7 @@ static inline int spa_pod_parser_getv(struct spa_pod_parser *parser, va_list arg const struct spa_pod *pod = NULL; const char *format; - if (ftype == SPA_TYPE_Object) { + if (f && ftype == SPA_TYPE_Object) { uint32_t key = va_arg(args, uint32_t); const struct spa_pod_object *object; @@ -496,7 +504,7 @@ static inline int spa_pod_parser_getv(struct spa_pod_parser *parser, va_list arg return count; } -static inline int spa_pod_parser_get(struct spa_pod_parser *parser, ...) +SPA_API_POD_PARSER int spa_pod_parser_get(struct spa_pod_parser *parser, ...) { int res; va_list args; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/support/loop.h b/src/java.desktop/unix/native/libpipewire/include/spa/support/loop.h index 4beac560b250b..376ab559de314 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/support/loop.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/support/loop.h @@ -9,10 +9,20 @@ extern "C" { #endif +#include + #include #include #include +#ifndef SPA_API_LOOP + #ifdef SPA_API_IMPL + #define SPA_API_LOOP SPA_API_IMPL + #else + #define SPA_API_LOOP static inline + #endif +#endif + /** \defgroup spa_loop Loop * Event loop interface */ @@ -66,19 +76,56 @@ struct spa_loop_methods { #define SPA_VERSION_LOOP_METHODS 0 uint32_t version; - /** add a source to the loop */ + /** Add a source to the loop. Must be called from the loop's own thread. + * + * \param[in] object The callbacks data. + * \param[in] source The source. + * \return 0 on success, negative errno-style value on failure. + */ int (*add_source) (void *object, struct spa_source *source); - /** update the source io mask */ + /** Update the source io mask. Must be called from the loop's own thread. + * + * \param[in] object The callbacks data. + * \param[in] source The source. + * \return 0 on success, negative errno-style value on failure. + */ int (*update_source) (void *object, struct spa_source *source); - /** remove a source from the loop */ + /** Remove a source from the loop. Must be called from the loop's own thread. + * + * \param[in] object The callbacks data. + * \param[in] source The source. + * \return 0 on success, negative errno-style value on failure. + */ int (*remove_source) (void *object, struct spa_source *source); - /** invoke a function in the context of this loop */ + /** Invoke a function in the context of this loop. + * May be called from any thread and multiple threads at the same time. + * If called from the loop's thread, all callbacks previously queued with + * invoke() will be run synchronously, which might cause unexpected + * reentrancy problems. + * + * \param[in] object The callbacks data. + * \param func The function to be invoked. + * \param seq An opaque sequence number. This will be made + * available to func. + * \param[in] data Data that will be copied into the internal ring buffer and made + * available to func. Because this data is copied, it is okay to + * pass a pointer to a local variable, but do not pass a pointer to + * an object that has identity. + * \param size The size of data to copy. + * \param block If \true, do not return until func has been called. Otherwise, + * returns immediately. Passing \true does not risk a deadlock because + * the data thread is never allowed to wait on any other thread. + * \param user_data An opaque pointer passed to func. + * \return `-EPIPE` if the internal ring buffer filled up, + * if block is \false, 0 if seq was SPA_ID_INVALID or + * seq with the ASYNC flag set + * or the return value of func otherwise. */ int (*invoke) (void *object, spa_invoke_func_t func, uint32_t seq, @@ -88,21 +135,29 @@ struct spa_loop_methods { void *user_data); }; -#define spa_loop_method(o,method,version,...) \ -({ \ - int _res = -ENOTSUP; \ - struct spa_loop *_o = o; \ - spa_interface_call_res(&_o->iface, \ - struct spa_loop_methods, _res, \ - method, version, ##__VA_ARGS__); \ - _res; \ -}) - -#define spa_loop_add_source(l,...) spa_loop_method(l,add_source,0,##__VA_ARGS__) -#define spa_loop_update_source(l,...) spa_loop_method(l,update_source,0,##__VA_ARGS__) -#define spa_loop_remove_source(l,...) spa_loop_method(l,remove_source,0,##__VA_ARGS__) -#define spa_loop_invoke(l,...) spa_loop_method(l,invoke,0,##__VA_ARGS__) - +SPA_API_LOOP int spa_loop_add_source(struct spa_loop *object, struct spa_source *source) +{ + return spa_api_method_r(int, -ENOTSUP, + spa_loop, &object->iface, add_source, 0, source); +} +SPA_API_LOOP int spa_loop_update_source(struct spa_loop *object, struct spa_source *source) +{ + return spa_api_method_r(int, -ENOTSUP, + spa_loop, &object->iface, update_source, 0, source); +} +SPA_API_LOOP int spa_loop_remove_source(struct spa_loop *object, struct spa_source *source) +{ + return spa_api_method_r(int, -ENOTSUP, + spa_loop, &object->iface, remove_source, 0, source); +} +SPA_API_LOOP int spa_loop_invoke(struct spa_loop *object, + spa_invoke_func_t func, uint32_t seq, const void *data, + size_t size, bool block, void *user_data) +{ + return spa_api_method_r(int, -ENOTSUP, + spa_loop, &object->iface, invoke, 0, func, seq, data, + size, block, user_data); +} /** Control hooks. These hooks can't be removed from their * callbacks and must be removed from a safe place (when the loop @@ -118,24 +173,42 @@ struct spa_loop_control_hooks { void (*after) (void *data); }; -#define spa_loop_control_hook_before(l) \ -({ \ - struct spa_hook_list *_l = l; \ - struct spa_hook *_h; \ - spa_list_for_each_reverse(_h, &_l->list, link) \ - spa_callbacks_call(&_h->cb, struct spa_loop_control_hooks, before, 0); \ -}) - -#define spa_loop_control_hook_after(l) \ -({ \ - struct spa_hook_list *_l = l; \ - struct spa_hook *_h; \ - spa_list_for_each(_h, &_l->list, link) \ - spa_callbacks_call(&_h->cb, struct spa_loop_control_hooks, after, 0); \ -}) +SPA_API_LOOP void spa_loop_control_hook_before(struct spa_hook_list *l) +{ + struct spa_hook *h; + spa_list_for_each_reverse(h, &l->list, link) + spa_callbacks_call_fast(&h->cb, struct spa_loop_control_hooks, before, 0); +} + +SPA_API_LOOP void spa_loop_control_hook_after(struct spa_hook_list *l) +{ + struct spa_hook *h; + spa_list_for_each(h, &l->list, link) + spa_callbacks_call_fast(&h->cb, struct spa_loop_control_hooks, after, 0); +} /** * Control an event loop + * + * The event loop control function provide API to run the event loop. + * + * The below (pseudo)code is a minimal example outlining the use of the loop + * control: + * \code{.c} + * spa_loop_control_enter(loop); + * while (running) { + * spa_loop_control_iterate(loop, -1); + * } + * spa_loop_control_leave(loop); + * \endcode + * + * It is also possible to add the loop to an existing event loop by using the + * spa_loop_control_get_fd() call. This fd will become readable when activity + * has been detected on the sources in the loop. spa_loop_control_iterate() with + * a 0 timeout should be called to process the pending sources. + * + * spa_loop_control_enter() and spa_loop_control_leave() should be called once + * from the thread that will run the iterate() function. */ struct spa_loop_control_methods { /* the version of this structure. This can be used to expand this @@ -143,10 +216,19 @@ struct spa_loop_control_methods { #define SPA_VERSION_LOOP_CONTROL_METHODS 1 uint32_t version; + /** get the loop fd + * \param object the control to query + * + * Get the fd of this loop control. This fd will be readable when a + * source in the loop has activity. The user should call iterate() + * with a 0 timeout to schedule one iteration of the loop and dispatch + * the sources. + * \return the fd of the loop + */ int (*get_fd) (void *object); /** Add a hook - * \param ctrl the control to change + * \param object the control to change * \param hooks the hooks to add * * Adds hooks to the loop controlled by \a ctrl. @@ -157,18 +239,19 @@ struct spa_loop_control_methods { void *data); /** Enter a loop - * \param ctrl the control + * \param object the control * - * Start an iteration of the loop. This function should be called - * before calling iterate and is typically used to capture the thread - * that this loop will run in. + * This function should be called before calling iterate and is + * typically used to capture the thread that this loop will run in. + * It should ideally be called once from the thread that will run + * the loop. */ void (*enter) (void *object); /** Leave a loop - * \param ctrl the control + * \param object the control * - * Ends the iteration of a loop. This should be called after calling - * iterate. + * It should ideally be called once after calling iterate when the loop + * will no longer be iterated from the thread that called enter(). */ void (*leave) (void *object); @@ -194,30 +277,43 @@ struct spa_loop_control_methods { int (*check) (void *object); }; -#define spa_loop_control_method_v(o,method,version,...) \ -({ \ - struct spa_loop_control *_o = o; \ - spa_interface_call(&_o->iface, \ - struct spa_loop_control_methods, \ - method, version, ##__VA_ARGS__); \ -}) - -#define spa_loop_control_method_r(o,method,version,...) \ -({ \ - int _res = -ENOTSUP; \ - struct spa_loop_control *_o = o; \ - spa_interface_call_res(&_o->iface, \ - struct spa_loop_control_methods, _res, \ - method, version, ##__VA_ARGS__); \ - _res; \ -}) - -#define spa_loop_control_get_fd(l) spa_loop_control_method_r(l,get_fd,0) -#define spa_loop_control_add_hook(l,...) spa_loop_control_method_v(l,add_hook,0,__VA_ARGS__) -#define spa_loop_control_enter(l) spa_loop_control_method_v(l,enter,0) -#define spa_loop_control_leave(l) spa_loop_control_method_v(l,leave,0) -#define spa_loop_control_iterate(l,...) spa_loop_control_method_r(l,iterate,0,__VA_ARGS__) -#define spa_loop_control_check(l) spa_loop_control_method_r(l,check,1) +SPA_API_LOOP int spa_loop_control_get_fd(struct spa_loop_control *object) +{ + return spa_api_method_r(int, -ENOTSUP, + spa_loop_control, &object->iface, get_fd, 0); +} +SPA_API_LOOP void spa_loop_control_add_hook(struct spa_loop_control *object, + struct spa_hook *hook, const struct spa_loop_control_hooks *hooks, + void *data) +{ + spa_api_method_v(spa_loop_control, &object->iface, add_hook, 0, + hook, hooks, data); +} +SPA_API_LOOP void spa_loop_control_enter(struct spa_loop_control *object) +{ + spa_api_method_v(spa_loop_control, &object->iface, enter, 0); +} +SPA_API_LOOP void spa_loop_control_leave(struct spa_loop_control *object) +{ + spa_api_method_v(spa_loop_control, &object->iface, leave, 0); +} +SPA_API_LOOP int spa_loop_control_iterate(struct spa_loop_control *object, + int timeout) +{ + return spa_api_method_r(int, -ENOTSUP, + spa_loop_control, &object->iface, iterate, 0, timeout); +} +SPA_API_LOOP int spa_loop_control_iterate_fast(struct spa_loop_control *object, + int timeout) +{ + return spa_api_method_fast_r(int, -ENOTSUP, + spa_loop_control, &object->iface, iterate, 0, timeout); +} +SPA_API_LOOP int spa_loop_control_check(struct spa_loop_control *object) +{ + return spa_api_method_r(int, -ENOTSUP, + spa_loop_control, &object->iface, check, 1); +} typedef void (*spa_source_io_func_t) (void *data, int fd, uint32_t mask); typedef void (*spa_source_idle_func_t) (void *data); @@ -268,44 +364,71 @@ struct spa_loop_utils_methods { void (*destroy_source) (void *object, struct spa_source *source); }; -#define spa_loop_utils_method_v(o,method,version,...) \ -({ \ - struct spa_loop_utils *_o = o; \ - spa_interface_call(&_o->iface, \ - struct spa_loop_utils_methods, \ - method, version, ##__VA_ARGS__); \ -}) - -#define spa_loop_utils_method_r(o,method,version,...) \ -({ \ - int _res = -ENOTSUP; \ - struct spa_loop_utils *_o = o; \ - spa_interface_call_res(&_o->iface, \ - struct spa_loop_utils_methods, _res, \ - method, version, ##__VA_ARGS__); \ - _res; \ -}) -#define spa_loop_utils_method_s(o,method,version,...) \ -({ \ - struct spa_source *_res = NULL; \ - struct spa_loop_utils *_o = o; \ - spa_interface_call_res(&_o->iface, \ - struct spa_loop_utils_methods, _res, \ - method, version, ##__VA_ARGS__); \ - _res; \ -}) - - -#define spa_loop_utils_add_io(l,...) spa_loop_utils_method_s(l,add_io,0,__VA_ARGS__) -#define spa_loop_utils_update_io(l,...) spa_loop_utils_method_r(l,update_io,0,__VA_ARGS__) -#define spa_loop_utils_add_idle(l,...) spa_loop_utils_method_s(l,add_idle,0,__VA_ARGS__) -#define spa_loop_utils_enable_idle(l,...) spa_loop_utils_method_r(l,enable_idle,0,__VA_ARGS__) -#define spa_loop_utils_add_event(l,...) spa_loop_utils_method_s(l,add_event,0,__VA_ARGS__) -#define spa_loop_utils_signal_event(l,...) spa_loop_utils_method_r(l,signal_event,0,__VA_ARGS__) -#define spa_loop_utils_add_timer(l,...) spa_loop_utils_method_s(l,add_timer,0,__VA_ARGS__) -#define spa_loop_utils_update_timer(l,...) spa_loop_utils_method_r(l,update_timer,0,__VA_ARGS__) -#define spa_loop_utils_add_signal(l,...) spa_loop_utils_method_s(l,add_signal,0,__VA_ARGS__) -#define spa_loop_utils_destroy_source(l,...) spa_loop_utils_method_v(l,destroy_source,0,__VA_ARGS__) +SPA_API_LOOP struct spa_source * +spa_loop_utils_add_io(struct spa_loop_utils *object, int fd, uint32_t mask, + bool close, spa_source_io_func_t func, void *data) +{ + return spa_api_method_r(struct spa_source *, NULL, + spa_loop_utils, &object->iface, add_io, 0, fd, mask, close, func, data); +} +SPA_API_LOOP int spa_loop_utils_update_io(struct spa_loop_utils *object, + struct spa_source *source, uint32_t mask) +{ + return spa_api_method_r(int, -ENOTSUP, + spa_loop_utils, &object->iface, update_io, 0, source, mask); +} +SPA_API_LOOP struct spa_source * +spa_loop_utils_add_idle(struct spa_loop_utils *object, bool enabled, + spa_source_idle_func_t func, void *data) +{ + return spa_api_method_r(struct spa_source *, NULL, + spa_loop_utils, &object->iface, add_idle, 0, enabled, func, data); +} +SPA_API_LOOP int spa_loop_utils_enable_idle(struct spa_loop_utils *object, + struct spa_source *source, bool enabled) +{ + return spa_api_method_r(int, -ENOTSUP, + spa_loop_utils, &object->iface, enable_idle, 0, source, enabled); +} +SPA_API_LOOP struct spa_source * +spa_loop_utils_add_event(struct spa_loop_utils *object, spa_source_event_func_t func, void *data) +{ + return spa_api_method_r(struct spa_source *, NULL, + spa_loop_utils, &object->iface, add_event, 0, func, data); +} +SPA_API_LOOP int spa_loop_utils_signal_event(struct spa_loop_utils *object, + struct spa_source *source) +{ + return spa_api_method_r(int, -ENOTSUP, + spa_loop_utils, &object->iface, signal_event, 0, source); +} +SPA_API_LOOP struct spa_source * +spa_loop_utils_add_timer(struct spa_loop_utils *object, spa_source_timer_func_t func, void *data) +{ + return spa_api_method_r(struct spa_source *, NULL, + spa_loop_utils, &object->iface, add_timer, 0, func, data); +} +SPA_API_LOOP int spa_loop_utils_update_timer(struct spa_loop_utils *object, + struct spa_source *source, struct timespec *value, + struct timespec *interval, bool absolute) +{ + return spa_api_method_r(int, -ENOTSUP, + spa_loop_utils, &object->iface, update_timer, 0, source, + value, interval, absolute); +} +SPA_API_LOOP struct spa_source * +spa_loop_utils_add_signal(struct spa_loop_utils *object, int signal_number, + spa_source_signal_func_t func, void *data) +{ + return spa_api_method_r(struct spa_source *, NULL, + spa_loop_utils, &object->iface, add_signal, 0, + signal_number, func, data); +} +SPA_API_LOOP void spa_loop_utils_destroy_source(struct spa_loop_utils *object, + struct spa_source *source) +{ + spa_api_method_v(spa_loop_utils, &object->iface, destroy_source, 0, source); +} /** * \} diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/support/system.h b/src/java.desktop/unix/native/libpipewire/include/spa/support/system.h index 6bd9dcd015985..fb58dc337b636 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/support/system.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/support/system.h @@ -12,11 +12,20 @@ extern "C" { struct itimerspec; #include +#include #include #include #include +#ifndef SPA_API_SYSTEM + #ifdef SPA_API_IMPL + #define SPA_API_SYSTEM SPA_API_IMPL + #else + #define SPA_API_SYSTEM static inline + #endif +#endif + /** \defgroup spa_system System * I/O, clock, polling, timer, and signal interfaces */ @@ -97,42 +106,106 @@ struct spa_system_methods { int (*signalfd_read) (void *object, int fd, int *signal); }; -#define spa_system_method_r(o,method,version,...) \ -({ \ - volatile int _res = -ENOTSUP; \ - struct spa_system *_o = o; \ - spa_interface_call_res(&_o->iface, \ - struct spa_system_methods, _res, \ - method, version, ##__VA_ARGS__); \ - _res; \ -}) - - -#define spa_system_read(s,...) spa_system_method_r(s,read,0,__VA_ARGS__) -#define spa_system_write(s,...) spa_system_method_r(s,write,0,__VA_ARGS__) -#define spa_system_ioctl(s,...) spa_system_method_r(s,ioctl,0,__VA_ARGS__) -#define spa_system_close(s,...) spa_system_method_r(s,close,0,__VA_ARGS__) - -#define spa_system_clock_gettime(s,...) spa_system_method_r(s,clock_gettime,0,__VA_ARGS__) -#define spa_system_clock_getres(s,...) spa_system_method_r(s,clock_getres,0,__VA_ARGS__) - -#define spa_system_pollfd_create(s,...) spa_system_method_r(s,pollfd_create,0,__VA_ARGS__) -#define spa_system_pollfd_add(s,...) spa_system_method_r(s,pollfd_add,0,__VA_ARGS__) -#define spa_system_pollfd_mod(s,...) spa_system_method_r(s,pollfd_mod,0,__VA_ARGS__) -#define spa_system_pollfd_del(s,...) spa_system_method_r(s,pollfd_del,0,__VA_ARGS__) -#define spa_system_pollfd_wait(s,...) spa_system_method_r(s,pollfd_wait,0,__VA_ARGS__) - -#define spa_system_timerfd_create(s,...) spa_system_method_r(s,timerfd_create,0,__VA_ARGS__) -#define spa_system_timerfd_settime(s,...) spa_system_method_r(s,timerfd_settime,0,__VA_ARGS__) -#define spa_system_timerfd_gettime(s,...) spa_system_method_r(s,timerfd_gettime,0,__VA_ARGS__) -#define spa_system_timerfd_read(s,...) spa_system_method_r(s,timerfd_read,0,__VA_ARGS__) - -#define spa_system_eventfd_create(s,...) spa_system_method_r(s,eventfd_create,0,__VA_ARGS__) -#define spa_system_eventfd_write(s,...) spa_system_method_r(s,eventfd_write,0,__VA_ARGS__) -#define spa_system_eventfd_read(s,...) spa_system_method_r(s,eventfd_read,0,__VA_ARGS__) - -#define spa_system_signalfd_create(s,...) spa_system_method_r(s,signalfd_create,0,__VA_ARGS__) -#define spa_system_signalfd_read(s,...) spa_system_method_r(s,signalfd_read,0,__VA_ARGS__) +SPA_API_SYSTEM ssize_t spa_system_read(struct spa_system *object, int fd, void *buf, size_t count) +{ + return spa_api_method_fast_r(ssize_t, -ENOTSUP, spa_system, &object->iface, read, 0, fd, buf, count); +} +SPA_API_SYSTEM ssize_t spa_system_write(struct spa_system *object, int fd, const void *buf, size_t count) +{ + return spa_api_method_fast_r(ssize_t, -ENOTSUP, spa_system, &object->iface, write, 0, fd, buf, count); +} +#define spa_system_ioctl(object,fd,request,...) \ + spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, ioctl, 0, fd, request, ##__VA_ARGS__) + +SPA_API_SYSTEM int spa_system_close(struct spa_system *object, int fd) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, close, 0, fd); +} +SPA_API_SYSTEM int spa_system_clock_gettime(struct spa_system *object, + int clockid, struct timespec *value) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, clock_gettime, 0, clockid, value); +} +SPA_API_SYSTEM int spa_system_clock_getres(struct spa_system *object, + int clockid, struct timespec *res) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, clock_getres, 0, clockid, res); +} + +SPA_API_SYSTEM int spa_system_pollfd_create(struct spa_system *object, int flags) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, pollfd_create, 0, flags); +} +SPA_API_SYSTEM int spa_system_pollfd_add(struct spa_system *object, int pfd, int fd, uint32_t events, void *data) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, pollfd_add, 0, pfd, fd, events, data); +} +SPA_API_SYSTEM int spa_system_pollfd_mod(struct spa_system *object, int pfd, int fd, uint32_t events, void *data) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, pollfd_mod, 0, pfd, fd, events, data); +} +SPA_API_SYSTEM int spa_system_pollfd_del(struct spa_system *object, int pfd, int fd) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, pollfd_del, 0, pfd, fd); +} +SPA_API_SYSTEM int spa_system_pollfd_wait(struct spa_system *object, int pfd, + struct spa_poll_event *ev, int n_ev, int timeout) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, pollfd_wait, 0, pfd, ev, n_ev, timeout); +} + +SPA_API_SYSTEM int spa_system_timerfd_create(struct spa_system *object, int clockid, int flags) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, timerfd_create, 0, clockid, flags); +} + +SPA_API_SYSTEM int spa_system_timerfd_settime(struct spa_system *object, + int fd, int flags, + const struct itimerspec *new_value, + struct itimerspec *old_value) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, timerfd_settime, 0, + fd, flags, new_value, old_value); +} + +SPA_API_SYSTEM int spa_system_timerfd_gettime(struct spa_system *object, + int fd, struct itimerspec *curr_value) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, timerfd_gettime, 0, + fd, curr_value); +} +SPA_API_SYSTEM int spa_system_timerfd_read(struct spa_system *object, int fd, uint64_t *expirations) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, timerfd_read, 0, + fd, expirations); +} + +SPA_API_SYSTEM int spa_system_eventfd_create(struct spa_system *object, int flags) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, eventfd_create, 0, flags); +} +SPA_API_SYSTEM int spa_system_eventfd_write(struct spa_system *object, int fd, uint64_t count) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, eventfd_write, 0, + fd, count); +} +SPA_API_SYSTEM int spa_system_eventfd_read(struct spa_system *object, int fd, uint64_t *count) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, eventfd_read, 0, + fd, count); +} + +SPA_API_SYSTEM int spa_system_signalfd_create(struct spa_system *object, int signal, int flags) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, signalfd_create, 0, + signal, flags); +} + +SPA_API_SYSTEM int spa_system_signalfd_read(struct spa_system *object, int fd, int *signal) +{ + return spa_api_method_fast_r(int, -ENOTSUP, spa_system, &object->iface, signalfd_read, 0, + fd, signal); +} /** * \} diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/utils/cleanup.h b/src/java.desktop/unix/native/libpipewire/include/spa/utils/cleanup.h new file mode 100644 index 0000000000000..944907ccffbd2 --- /dev/null +++ b/src/java.desktop/unix/native/libpipewire/include/spa/utils/cleanup.h @@ -0,0 +1,124 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2023 PipeWire authors */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_UTILS_CLEANUP_H +#define SPA_UTILS_CLEANUP_H + +#define spa_exchange(var, new_value) \ +__extension__ ({ \ + __typeof__(var) *_ptr_ = &(var); \ + __typeof__(var) _old_value_ = *_ptr_; \ + *_ptr_ = (new_value); \ + _old_value_; \ +}) + +/* ========================================================================== */ + +#if __GNUC__ >= 10 || defined(__clang__) +#define spa_steal_ptr(ptr) ((__typeof__(*(ptr)) *) spa_exchange((ptr), NULL)) +#else +#define spa_steal_ptr(ptr) spa_exchange((ptr), NULL) +#endif + +#define spa_clear_ptr(ptr, destructor) \ +__extension__ ({ \ + __typeof__(ptr) _old_value = spa_steal_ptr(ptr); \ + if (_old_value) \ + destructor(_old_value); \ + (void) 0; \ +}) + +/* ========================================================================== */ + +#include +#include + +#define spa_steal_fd(fd) spa_exchange((fd), -1) + +#define spa_clear_fd(fd) \ +__extension__ ({ \ + int _old_value = spa_steal_fd(fd), _res = 0; \ + if (_old_value >= 0) \ + _res = close(_old_value); \ + _res; \ +}) + +/* ========================================================================== */ + +#if defined(__has_attribute) && __has_attribute(__cleanup__) + +#define spa_cleanup(func) __attribute__((__cleanup__(func))) + +#define SPA_DEFINE_AUTO_CLEANUP(name, type, ...) \ +typedef __typeof__(type) _spa_auto_cleanup_type_ ## name; \ +static inline void _spa_auto_cleanup_func_ ## name (__typeof__(type) *thing) \ +{ \ + int _save_errno = errno; \ + __VA_ARGS__ \ + errno = _save_errno; \ +} + +#define spa_auto(name) \ + spa_cleanup(_spa_auto_cleanup_func_ ## name) \ + _spa_auto_cleanup_type_ ## name + +#define SPA_DEFINE_AUTOPTR_CLEANUP(name, type, ...) \ +typedef __typeof__(type) * _spa_autoptr_cleanup_type_ ## name; \ +static inline void _spa_autoptr_cleanup_func_ ## name (__typeof__(type) **thing) \ +{ \ + int _save_errno = errno; \ + __VA_ARGS__ \ + errno = _save_errno; \ +} + +#define spa_autoptr(name) \ + spa_cleanup(_spa_autoptr_cleanup_func_ ## name) \ + _spa_autoptr_cleanup_type_ ## name + +/* ========================================================================== */ + +#include + +static inline void _spa_autofree_cleanup_func(void *p) +{ + int save_errno = errno; + free(*(void **) p); + errno = save_errno; +} +#define spa_autofree spa_cleanup(_spa_autofree_cleanup_func) + +/* ========================================================================== */ + +static inline void _spa_autoclose_cleanup_func(int *fd) +{ + int save_errno = errno; + spa_clear_fd(*fd); + errno = save_errno; +} +#define spa_autoclose spa_cleanup(_spa_autoclose_cleanup_func) + +/* ========================================================================== */ + +#include + +SPA_DEFINE_AUTOPTR_CLEANUP(FILE, FILE, { + spa_clear_ptr(*thing, fclose); +}) + +/* ========================================================================== */ + +#include + +SPA_DEFINE_AUTOPTR_CLEANUP(DIR, DIR, { + spa_clear_ptr(*thing, closedir); +}) + +#else + +#define SPA_DEFINE_AUTO_CLEANUP(name, type, ...) +#define SPA_DEFINE_AUTOPTR_CLEANUP(name, type, ...) + +#endif + +#endif /* SPA_UTILS_CLEANUP_H */ diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/utils/defs.h b/src/java.desktop/unix/native/libpipewire/include/spa/utils/defs.h index 66c238987d0ac..ace677015cad2 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/utils/defs.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/utils/defs.h @@ -9,20 +9,31 @@ extern "C" { # if __cplusplus >= 201103L # define SPA_STATIC_ASSERT_IMPL(expr, msg, ...) static_assert(expr, msg) +# define SPA_ALIGNOF alignof # endif +#elif __STDC_VERSION__ >= 202311L +# define SPA_STATIC_ASSERT_IMPL(expr, msg, ...) static_assert(expr, msg) +# define SPA_ALIGNOF alignof #else # include # if __STDC_VERSION__ >= 201112L # define SPA_STATIC_ASSERT_IMPL(expr, msg, ...) _Static_assert(expr, msg) +# define SPA_ALIGNOF _Alignof # endif #endif #ifndef SPA_STATIC_ASSERT_IMPL #define SPA_STATIC_ASSERT_IMPL(expr, ...) \ ((void)sizeof(struct { int spa_static_assertion_failed : 2 * !!(expr) - 1; })) #endif +#ifndef SPA_ALIGNOF +#define SPA_ALIGNOF __alignof__ +#endif #define SPA_STATIC_ASSERT(expr, ...) SPA_STATIC_ASSERT_IMPL(expr, ## __VA_ARGS__, "`" #expr "` evaluated to false") +#define SPA_CONCAT_NOEXPAND(a, b) a ## b +#define SPA_CONCAT(a, b) SPA_CONCAT_NOEXPAND(a, b) + #include #include #include @@ -122,10 +133,10 @@ struct spa_fraction { * ``` */ #define SPA_FOR_EACH_ELEMENT(arr, ptr) \ - for ((ptr) = arr; (void*)(ptr) < SPA_PTROFF(arr, sizeof(arr), void); (ptr)++) + for ((ptr) = arr; (ptr) < (arr) + SPA_N_ELEMENTS(arr); (ptr)++) #define SPA_FOR_EACH_ELEMENT_VAR(arr, var) \ - for (__typeof__((arr)[0])* var = arr; (void*)(var) < SPA_PTROFF(arr, sizeof(arr), void); (var)++) + for (__typeof__((arr)[0])* var = arr; (var) < (arr) + SPA_N_ELEMENTS(arr); (var)++) #define SPA_ABS(a) \ ({ \ @@ -156,6 +167,10 @@ struct spa_fraction { ({ \ fminf(fmaxf(v, low), high); \ }) +#define SPA_CLAMPD(v,low,high) \ +({ \ + fmin(fmax(v, low), high); \ +}) #define SPA_SWAP(a,b) \ @@ -171,6 +186,16 @@ struct spa_fraction { x; \ }) +/** 3-way comparison. NaN > NaN and NaN > finite numbers */ +#define SPA_CMP(a, b) \ +({ \ + __typeof__(a) _a = (a); \ + __typeof__(b) _b = (b); \ + (_a > _b) ? 1 : (_a == _b) ? 0 : (_a < _b) ? -1 \ + : (_a == _a) ? -1 : (_b == _b) ? 1 \ + : 1; \ +}) + /** * Return the address (buffer + offset) as pointer of \a type */ @@ -178,7 +203,6 @@ struct spa_fraction { #define SPA_PTROFF_ALIGN(ptr_,offset_,alignment_,type_) \ SPA_PTR_ALIGN(SPA_PTROFF(ptr_,offset_,type_),alignment_,type_) - /** * Deprecated, use SPA_PTROFF and SPA_PTROFF_ALIGN instead */ @@ -189,9 +213,6 @@ struct spa_fraction { #define SPA_PTRDIFF(p1,p2) ((intptr_t)(p1) - (intptr_t)(p2)) -#define SPA_PTR_TO_INT(p) ((int) ((intptr_t) (p))) -#define SPA_INT_TO_PTR(u) ((void*) ((intptr_t) (u))) - #define SPA_PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p))) #define SPA_UINT32_TO_PTR(u) ((void*) ((uintptr_t) (u))) @@ -233,6 +254,20 @@ struct spa_fraction { #define SPA_WARN_UNUSED_RESULT #endif +#ifndef SPA_API_IMPL +#define SPA_API_PROTO static inline +#define SPA_API_IMPL static inline +#endif + +#ifndef SPA_API_UTILS_DEFS + #ifdef SPA_API_IMPL + #define SPA_API_UTILS_DEFS SPA_API_IMPL + #else + #define SPA_API_UTILS_DEFS static inline + #endif +#endif + + #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define SPA_RESTRICT restrict #elif defined(__GNUC__) && __GNUC__ >= 4 @@ -265,7 +300,7 @@ struct spa_fraction { }) -#define SPA_PTR_ALIGNMENT(p,align) ((intptr_t)(p) & ((align)-1)) +#define SPA_PTR_ALIGNMENT(p,align) ((uintptr_t)(p) & ((align)-1)) #define SPA_IS_ALIGNED(p,align) (SPA_PTR_ALIGNMENT(p,align) == 0) #define SPA_PTR_ALIGN(p,align,type) ((type*)SPA_ROUND_UP_N((intptr_t)(p), (intptr_t)(align))) @@ -279,9 +314,51 @@ struct spa_fraction { #endif #endif +SPA_API_UTILS_DEFS bool spa_ptrinside(const void *p1, size_t s1, const void *p2, size_t s2, + size_t *remaining) +{ + if (SPA_LIKELY((uintptr_t)p1 <= (uintptr_t)p2 && s2 <= s1 && + (uintptr_t)p2 - (uintptr_t)p1 <= s1 - s2)) { + if (remaining != NULL) + *remaining = ((uintptr_t)p1 + s1) - ((uintptr_t)p2 + s2); + return true; + } else { + if (remaining != NULL) + *remaining = 0; + return false; + } +} + +SPA_API_UTILS_DEFS bool spa_ptr_inside_and_aligned(const void *p1, size_t s1, + const void *p2, size_t s2, size_t align, + size_t *remaining) +{ + if (SPA_IS_ALIGNED(p2, align)) { + return spa_ptrinside(p1, s1, p2, s2, remaining); + } else { + if (remaining != NULL) + *remaining = 0; + return false; + } +} + +#define spa_ptr_type_inside(p1, s1, p2, type, remaining) \ + spa_ptr_inside_and_aligned(p1, s1, p2, sizeof(type), SPA_ALIGNOF(type), remaining) + +#define SPA_PTR_TO_INT(p) ((int) ((intptr_t) (p))) +#define SPA_INT_TO_PTR(u) ((void*) ((intptr_t) (u))) + #define SPA_STRINGIFY_1(...) #__VA_ARGS__ #define SPA_STRINGIFY(...) SPA_STRINGIFY_1(__VA_ARGS__) +struct spa_error_location { + int line; + int col; + size_t len; + const char *location; + const char *reason; +}; + #define spa_return_if_fail(expr) \ do { \ if (SPA_UNLIKELY(!(expr))) { \ diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/utils/dict.h b/src/java.desktop/unix/native/libpipewire/include/spa/utils/dict.h index f34cd21f84078..d9258a5fe1c4d 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/utils/dict.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/utils/dict.h @@ -13,6 +13,14 @@ extern "C" { #include +#ifndef SPA_API_DICT + #ifdef SPA_API_IMPL + #define SPA_API_DICT SPA_API_IMPL + #else + #define SPA_API_DICT static inline + #endif +#endif + /** * \defgroup spa_dict Dictionary * Dictionary data structure @@ -28,7 +36,8 @@ struct spa_dict_item { const char *value; }; -#define SPA_DICT_ITEM_INIT(key,value) ((struct spa_dict_item) { (key), (value) }) +#define SPA_DICT_ITEM(key,value) ((struct spa_dict_item) { (key), (value) }) +#define SPA_DICT_ITEM_INIT(key,value) SPA_DICT_ITEM(key,value) struct spa_dict { #define SPA_DICT_FLAG_SORTED (1<<0) /**< items are sorted */ @@ -37,22 +46,26 @@ struct spa_dict { const struct spa_dict_item *items; }; -#define SPA_DICT_INIT(items,n_items) ((struct spa_dict) { 0, (n_items), (items) }) -#define SPA_DICT_INIT_ARRAY(items) ((struct spa_dict) { 0, SPA_N_ELEMENTS(items), (items) }) +#define SPA_DICT(items,n_items) ((struct spa_dict) { 0, (n_items), (items) }) +#define SPA_DICT_ARRAY(items) SPA_DICT((items),SPA_N_ELEMENTS(items)) +#define SPA_DICT_ITEMS(...) SPA_DICT_ARRAY(((struct spa_dict_item[]) { __VA_ARGS__})) + +#define SPA_DICT_INIT(items,n_items) SPA_DICT(items,n_items) +#define SPA_DICT_INIT_ARRAY(items) SPA_DICT_ARRAY(items) #define spa_dict_for_each(item, dict) \ for ((item) = (dict)->items; \ (item) < &(dict)->items[(dict)->n_items]; \ (item)++) -static inline int spa_dict_item_compare(const void *i1, const void *i2) +SPA_API_DICT int spa_dict_item_compare(const void *i1, const void *i2) { const struct spa_dict_item *it1 = (const struct spa_dict_item *)i1, *it2 = (const struct spa_dict_item *)i2; return strcmp(it1->key, it2->key); } -static inline void spa_dict_qsort(struct spa_dict *dict) +SPA_API_DICT void spa_dict_qsort(struct spa_dict *dict) { if (dict->n_items > 0) qsort((void*)dict->items, dict->n_items, sizeof(struct spa_dict_item), @@ -60,7 +73,7 @@ static inline void spa_dict_qsort(struct spa_dict *dict) SPA_FLAG_SET(dict->flags, SPA_DICT_FLAG_SORTED); } -static inline const struct spa_dict_item *spa_dict_lookup_item(const struct spa_dict *dict, +SPA_API_DICT const struct spa_dict_item *spa_dict_lookup_item(const struct spa_dict *dict, const char *key) { const struct spa_dict_item *item; @@ -83,7 +96,7 @@ static inline const struct spa_dict_item *spa_dict_lookup_item(const struct spa_ return NULL; } -static inline const char *spa_dict_lookup(const struct spa_dict *dict, const char *key) +SPA_API_DICT const char *spa_dict_lookup(const struct spa_dict *dict, const char *key) { const struct spa_dict_item *item = spa_dict_lookup_item(dict, key); return item ? item->value : NULL; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/utils/endian.h b/src/java.desktop/unix/native/libpipewire/include/spa/utils/endian.h new file mode 100644 index 0000000000000..2d002d4538c30 --- /dev/null +++ b/src/java.desktop/unix/native/libpipewire/include/spa/utils/endian.h @@ -0,0 +1,26 @@ +/* Spa */ +/* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_ENDIAN_H +#define SPA_ENDIAN_H + +#if defined(__FreeBSD__) || defined(__MidnightBSD__) +#include +#define bswap_16 bswap16 +#define bswap_32 bswap32 +#define bswap_64 bswap64 +#elif defined(_MSC_VER) && defined(_WIN32) +#include +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#define __BYTE_ORDER __LITTLE_ENDIAN +#define bswap_16 _byteswap_ushort +#define bswap_32 _byteswap_ulong +#define bswap_64 _byteswap_uint64 +#else +#include +#include +#endif + +#endif /* SPA_ENDIAN_H */ diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/utils/enum-types.h b/src/java.desktop/unix/native/libpipewire/include/spa/utils/enum-types.h index b374995b5cf1f..c1313f0390ef5 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/utils/enum-types.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/utils/enum-types.h @@ -10,6 +10,12 @@ extern "C" { #endif #include +#include + +/** + * \addtogroup spa_types + * \{ + */ #define SPA_TYPE_INFO_Direction SPA_TYPE_INFO_ENUM_BASE "Direction" #define SPA_TYPE_INFO_DIRECTION_BASE SPA_TYPE_INFO_Direction ":" @@ -20,8 +26,6 @@ static const struct spa_type_info spa_type_direction[] = { { 0, 0, NULL, NULL } }; -#include - #define SPA_TYPE_INFO_Choice SPA_TYPE_INFO_ENUM_BASE "Choice" #define SPA_TYPE_INFO_CHOICE_BASE SPA_TYPE_INFO_Choice ":" diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/utils/hook.h b/src/java.desktop/unix/native/libpipewire/include/spa/utils/hook.h index 81fc07b8a05d9..566433bf8de29 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/utils/hook.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/utils/hook.h @@ -12,6 +12,14 @@ extern "C" { #include #include +#ifndef SPA_API_HOOK + #ifdef SPA_API_IMPL + #define SPA_API_HOOK SPA_API_IMPL + #else + #define SPA_API_HOOK static inline + #endif +#endif + /** \defgroup spa_interfaces Interfaces * * \brief Generic implementation of implementation-independent interfaces @@ -158,10 +166,18 @@ struct spa_interface { const type *_f = (const type *) (callbacks)->funcs; \ bool _res = SPA_CALLBACK_CHECK(_f,method,vers); \ if (SPA_LIKELY(_res)) \ - _f->method((callbacks)->data, ## __VA_ARGS__); \ + (_f->method)((callbacks)->data, ## __VA_ARGS__); \ _res; \ }) +#define spa_callbacks_call_fast(callbacks,type,method,vers,...) \ +({ \ + const type *_f = (const type *) (callbacks)->funcs; \ + (_f->method)((callbacks)->data, ## __VA_ARGS__); \ + true; \ +}) + + /** * True if the \a callbacks are of version \a vers, false otherwise */ @@ -191,9 +207,14 @@ struct spa_interface { ({ \ const type *_f = (const type *) (callbacks)->funcs; \ if (SPA_LIKELY(SPA_CALLBACK_CHECK(_f,method,vers))) \ - res = _f->method((callbacks)->data, ## __VA_ARGS__); \ + res = (_f->method)((callbacks)->data, ## __VA_ARGS__); \ res; \ }) +#define spa_callbacks_call_fast_res(callbacks,type,res,method,vers,...) \ +({ \ + const type *_f = (const type *) (callbacks)->funcs; \ + res = (_f->method)((callbacks)->data, ## __VA_ARGS__); \ +}) /** * True if the \a iface's callbacks are of version \a vers, false otherwise @@ -216,6 +237,9 @@ struct spa_interface { #define spa_interface_call(iface,method_type,method,vers,...) \ spa_callbacks_call(&(iface)->cb,method_type,method,vers,##__VA_ARGS__) +#define spa_interface_call_fast(iface,method_type,method,vers,...) \ + spa_callbacks_call_fast(&(iface)->cb,method_type,method,vers,##__VA_ARGS__) + /** * Invoke method named \a method in the callbacks on the given interface object. * The \a method_type defines the type of the method struct, not the interface @@ -226,6 +250,76 @@ struct spa_interface { #define spa_interface_call_res(iface,method_type,res,method,vers,...) \ spa_callbacks_call_res(&(iface)->cb,method_type,res,method,vers,##__VA_ARGS__) +#define spa_interface_call_fast_res(iface,method_type,res,method,vers,...) \ + spa_callbacks_call_fast_res(&(iface)->cb,method_type,res,method,vers,##__VA_ARGS__) + + +#define spa_api_func_v(o,method,version,...) \ +({ \ + if (SPA_LIKELY(SPA_CALLBACK_CHECK(o,method,version))) \ + ((o)->method)(o, ##__VA_ARGS__); \ +}) +#define spa_api_func_r(rtype,def,o,method,version,...) \ +({ \ + rtype _res = def; \ + if (SPA_LIKELY(SPA_CALLBACK_CHECK(o,method,version))) \ + _res = ((o)->method)(o, ##__VA_ARGS__); \ + _res; \ +}) +#define spa_api_func_fast(o,method,...) \ +({ \ + ((o)->method)(o, ##__VA_ARGS__); \ +}) + +#define spa_api_method_v(type,o,method,version,...) \ +({ \ + struct spa_interface *_i = o; \ + spa_interface_call(_i, struct type ##_methods, \ + method, version, ##__VA_ARGS__); \ +}) +#define spa_api_method_r(rtype,def,type,o,method,version,...) \ +({ \ + rtype _res = def; \ + struct spa_interface *_i = o; \ + spa_interface_call_res(_i, struct type ##_methods, \ + _res, method, version, ##__VA_ARGS__); \ + _res; \ +}) +#define spa_api_method_null_v(type,co,o,method,version,...) \ +({ \ + struct type *_co = co; \ + if (SPA_LIKELY(_co != NULL)) { \ + struct spa_interface *_i = o; \ + spa_interface_call(_i, struct type ##_methods, \ + method, version, ##__VA_ARGS__); \ + } \ +}) +#define spa_api_method_null_r(rtype,def,type,co,o,method,version,...) \ +({ \ + rtype _res = def; \ + struct type *_co = co; \ + if (SPA_LIKELY(_co != NULL)) { \ + struct spa_interface *_i = o; \ + spa_interface_call_res(_i, struct type ##_methods, \ + _res, method, version, ##__VA_ARGS__); \ + } \ + _res; \ +}) +#define spa_api_method_fast_v(type,o,method,version,...) \ +({ \ + struct spa_interface *_i = o; \ + spa_interface_call_fast(_i, struct type ##_methods, \ + method, version, ##__VA_ARGS__); \ +}) +#define spa_api_method_fast_r(rtype,def,type,o,method,version,...) \ +({ \ + rtype _res = def; \ + struct spa_interface *_i = o; \ + spa_interface_call_fast_res(_i, struct type ##_methods, \ + _res, method, version, ##__VA_ARGS__); \ + _res; \ +}) + /** * \} */ @@ -329,18 +423,18 @@ struct spa_hook { }; /** Initialize a hook list to the empty list*/ -static inline void spa_hook_list_init(struct spa_hook_list *list) +SPA_API_HOOK void spa_hook_list_init(struct spa_hook_list *list) { spa_list_init(&list->list); } -static inline bool spa_hook_list_is_empty(struct spa_hook_list *list) +SPA_API_HOOK bool spa_hook_list_is_empty(struct spa_hook_list *list) { return spa_list_is_empty(&list->list); } /** Append a hook. */ -static inline void spa_hook_list_append(struct spa_hook_list *list, +SPA_API_HOOK void spa_hook_list_append(struct spa_hook_list *list, struct spa_hook *hook, const void *funcs, void *data) { @@ -350,7 +444,7 @@ static inline void spa_hook_list_append(struct spa_hook_list *list, } /** Prepend a hook */ -static inline void spa_hook_list_prepend(struct spa_hook_list *list, +SPA_API_HOOK void spa_hook_list_prepend(struct spa_hook_list *list, struct spa_hook *hook, const void *funcs, void *data) { @@ -360,7 +454,7 @@ static inline void spa_hook_list_prepend(struct spa_hook_list *list, } /** Remove a hook */ -static inline void spa_hook_remove(struct spa_hook *hook) +SPA_API_HOOK void spa_hook_remove(struct spa_hook *hook) { if (spa_list_is_initialized(&hook->link)) spa_list_remove(&hook->link); @@ -369,14 +463,14 @@ static inline void spa_hook_remove(struct spa_hook *hook) } /** Remove all hooks from the list */ -static inline void spa_hook_list_clean(struct spa_hook_list *list) +SPA_API_HOOK void spa_hook_list_clean(struct spa_hook_list *list) { struct spa_hook *h; spa_list_consume(h, &list->list, link) spa_hook_remove(h); } -static inline void +SPA_API_HOOK void spa_hook_list_isolate(struct spa_hook_list *list, struct spa_hook_list *save, struct spa_hook *hook, @@ -390,7 +484,7 @@ spa_hook_list_isolate(struct spa_hook_list *list, spa_hook_list_append(list, hook, funcs, data); } -static inline void +SPA_API_HOOK void spa_hook_list_join(struct spa_hook_list *list, struct spa_hook_list *save) { diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/utils/list.h b/src/java.desktop/unix/native/libpipewire/include/spa/utils/list.h index 5d4169217b52f..6bcc0e2328b53 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/utils/list.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/utils/list.h @@ -9,6 +9,16 @@ extern "C" { #endif +#include + +#ifndef SPA_API_LIST + #ifdef SPA_API_IMPL + #define SPA_API_LIST SPA_API_IMPL + #else + #define SPA_API_LIST static inline + #endif +#endif + /** * \defgroup spa_list List * Doubly linked list data structure @@ -26,19 +36,19 @@ struct spa_list { #define SPA_LIST_INIT(list) ((struct spa_list){ (list), (list) }) -static inline void spa_list_init(struct spa_list *list) +SPA_API_LIST void spa_list_init(struct spa_list *list) { *list = SPA_LIST_INIT(list); } -static inline int spa_list_is_initialized(struct spa_list *list) +SPA_API_LIST int spa_list_is_initialized(struct spa_list *list) { return !!list->prev; } #define spa_list_is_empty(l) ((l)->next == (l)) -static inline void spa_list_insert(struct spa_list *list, struct spa_list *elem) +SPA_API_LIST void spa_list_insert(struct spa_list *list, struct spa_list *elem) { elem->prev = list; elem->next = list->next; @@ -46,7 +56,7 @@ static inline void spa_list_insert(struct spa_list *list, struct spa_list *elem) elem->next->prev = elem; } -static inline void spa_list_insert_list(struct spa_list *list, struct spa_list *other) +SPA_API_LIST void spa_list_insert_list(struct spa_list *list, struct spa_list *other) { if (spa_list_is_empty(other)) return; @@ -56,7 +66,7 @@ static inline void spa_list_insert_list(struct spa_list *list, struct spa_list * list->next = other->next; } -static inline void spa_list_remove(struct spa_list *elem) +SPA_API_LIST void spa_list_remove(struct spa_list *elem) { elem->prev->next = elem->next; elem->next->prev = elem->prev; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/utils/string.h b/src/java.desktop/unix/native/libpipewire/include/spa/utils/string.h index 529b8fa38cdc6..d225a3c87c3d2 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/utils/string.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/utils/string.h @@ -17,6 +17,14 @@ extern "C" { #include +#ifndef SPA_API_STRING + #ifdef SPA_API_IMPL + #define SPA_API_STRING SPA_API_IMPL + #else + #define SPA_API_STRING static inline + #endif +#endif + /** * \defgroup spa_string String handling * String handling utilities @@ -33,7 +41,7 @@ extern "C" { * If both \a a and \a b are NULL, the two are considered equal. * */ -static inline bool spa_streq(const char *s1, const char *s2) +SPA_API_STRING bool spa_streq(const char *s1, const char *s2) { return SPA_LIKELY(s1 && s2) ? strcmp(s1, s2) == 0 : s1 == s2; } @@ -43,7 +51,7 @@ static inline bool spa_streq(const char *s1, const char *s2) * * If both \a a and \a b are NULL, the two are considered equal. */ -static inline bool spa_strneq(const char *s1, const char *s2, size_t len) +SPA_API_STRING bool spa_strneq(const char *s1, const char *s2, size_t len) { return SPA_LIKELY(s1 && s2) ? strncmp(s1, s2, len) == 0 : s1 == s2; } @@ -54,7 +62,7 @@ static inline bool spa_strneq(const char *s1, const char *s2, size_t len) * A \a s is NULL, it never starts with the given \a prefix. A \a prefix of * NULL is a bug in the caller. */ -static inline bool spa_strstartswith(const char *s, const char *prefix) +SPA_API_STRING bool spa_strstartswith(const char *s, const char *prefix) { if (SPA_UNLIKELY(s == NULL)) return false; @@ -70,7 +78,7 @@ static inline bool spa_strstartswith(const char *s, const char *prefix) * A \a s is NULL, it never ends with the given \a suffix. A \a suffix of * NULL is a bug in the caller. */ -static inline bool spa_strendswith(const char *s, const char *suffix) +SPA_API_STRING bool spa_strendswith(const char *s, const char *suffix) { size_t l1, l2; @@ -92,7 +100,7 @@ static inline bool spa_strendswith(const char *s, const char *suffix) * * \return true on success, false otherwise */ -static inline bool spa_atoi32(const char *str, int32_t *val, int base) +SPA_API_STRING bool spa_atoi32(const char *str, int32_t *val, int base) { char *endptr; long v; @@ -120,7 +128,7 @@ static inline bool spa_atoi32(const char *str, int32_t *val, int base) * * \return true on success, false otherwise */ -static inline bool spa_atou32(const char *str, uint32_t *val, int base) +SPA_API_STRING bool spa_atou32(const char *str, uint32_t *val, int base) { char *endptr; unsigned long long v; @@ -148,7 +156,7 @@ static inline bool spa_atou32(const char *str, uint32_t *val, int base) * * \return true on success, false otherwise */ -static inline bool spa_atoi64(const char *str, int64_t *val, int base) +SPA_API_STRING bool spa_atoi64(const char *str, int64_t *val, int base) { char *endptr; long long v; @@ -173,7 +181,7 @@ static inline bool spa_atoi64(const char *str, int64_t *val, int base) * * \return true on success, false otherwise */ -static inline bool spa_atou64(const char *str, uint64_t *val, int base) +SPA_API_STRING bool spa_atou64(const char *str, uint64_t *val, int base) { char *endptr; unsigned long long v; @@ -196,7 +204,7 @@ static inline bool spa_atou64(const char *str, uint64_t *val, int base) * * \return true on success, false otherwise */ -static inline bool spa_atob(const char *str) +SPA_API_STRING bool spa_atob(const char *str) { return spa_streq(str, "true") || spa_streq(str, "1"); } @@ -210,7 +218,7 @@ static inline bool spa_atob(const char *str) * number on error. */ SPA_PRINTF_FUNC(3, 0) -static inline int spa_vscnprintf(char *buffer, size_t size, const char *format, va_list args) +SPA_API_STRING int spa_vscnprintf(char *buffer, size_t size, const char *format, va_list args) { int r; @@ -233,7 +241,7 @@ static inline int spa_vscnprintf(char *buffer, size_t size, const char *format, * number on error. */ SPA_PRINTF_FUNC(3, 4) -static inline int spa_scnprintf(char *buffer, size_t size, const char *format, ...) +SPA_API_STRING int spa_scnprintf(char *buffer, size_t size, const char *format, ...) { int r; va_list args; @@ -253,7 +261,7 @@ static inline int spa_scnprintf(char *buffer, size_t size, const char *format, . * * \return the result float. */ -static inline float spa_strtof(const char *str, char **endptr) +SPA_API_STRING float spa_strtof(const char *str, char **endptr) { #ifndef __LOCALE_C_ONLY static locale_t locale = NULL; @@ -279,7 +287,7 @@ static inline float spa_strtof(const char *str, char **endptr) * * \return true on success, false otherwise */ -static inline bool spa_atof(const char *str, float *val) +SPA_API_STRING bool spa_atof(const char *str, float *val) { char *endptr; float v; @@ -303,7 +311,7 @@ static inline bool spa_atof(const char *str, float *val) * * \return the result float. */ -static inline double spa_strtod(const char *str, char **endptr) +SPA_API_STRING double spa_strtod(const char *str, char **endptr) { #ifndef __LOCALE_C_ONLY static locale_t locale = NULL; @@ -329,7 +337,7 @@ static inline double spa_strtod(const char *str, char **endptr) * * \return true on success, false otherwise */ -static inline bool spa_atod(const char *str, double *val) +SPA_API_STRING bool spa_atod(const char *str, double *val) { char *endptr; double v; @@ -346,7 +354,7 @@ static inline bool spa_atod(const char *str, double *val) return true; } -static inline char *spa_dtoa(char *str, size_t size, double val) +SPA_API_STRING char *spa_dtoa(char *str, size_t size, double val) { int i, l; l = spa_scnprintf(str, size, "%f", val); @@ -362,15 +370,17 @@ struct spa_strbuf { size_t pos; }; -static inline void spa_strbuf_init(struct spa_strbuf *buf, char *buffer, size_t maxsize) +SPA_API_STRING void spa_strbuf_init(struct spa_strbuf *buf, char *buffer, size_t maxsize) { buf->buffer = buffer; buf->maxsize = maxsize; buf->pos = 0; + if (maxsize > 0) + buf->buffer[0] = '\0'; } SPA_PRINTF_FUNC(2, 3) -static inline int spa_strbuf_append(struct spa_strbuf *buf, const char *fmt, ...) +SPA_API_STRING int spa_strbuf_append(struct spa_strbuf *buf, const char *fmt, ...) { size_t remain = buf->maxsize - buf->pos; ssize_t written; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/utils/type-info.h b/src/java.desktop/unix/native/libpipewire/include/spa/utils/type-info.h index 86a6b87bc49c8..85f831daede10 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/utils/type-info.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/utils/type-info.h @@ -20,10 +20,6 @@ extern "C" { #define SPA_TYPE_ROOT spa_types #endif -static inline bool spa_type_is_a(const char *type, const char *parent) -{ - return type != NULL && parent != NULL && strncmp(type, parent, strlen(parent)) == 0; -} #include #include @@ -83,6 +79,7 @@ static const struct spa_type_info spa_types[] = { { SPA_TYPE_OBJECT_Profiler, SPA_TYPE_Object, SPA_TYPE_INFO_Profiler, spa_type_profiler }, { SPA_TYPE_OBJECT_ParamLatency, SPA_TYPE_Object, SPA_TYPE_INFO_PARAM_Latency, spa_type_param_latency }, { SPA_TYPE_OBJECT_ParamProcessLatency, SPA_TYPE_Object, SPA_TYPE_INFO_PARAM_ProcessLatency, spa_type_param_process_latency }, + { SPA_TYPE_OBJECT_ParamTag, SPA_TYPE_Object, SPA_TYPE_INFO_PARAM_Tag, spa_type_param_tag }, { 0, 0, NULL, NULL } }; diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/utils/type.h b/src/java.desktop/unix/native/libpipewire/include/spa/utils/type.h index fcadda93101a3..79802d2f07eb8 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/utils/type.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/utils/type.h @@ -10,6 +10,15 @@ extern "C" { #endif #include +#include + +#ifndef SPA_API_TYPE + #ifdef SPA_API_IMPL + #define SPA_API_TYPE SPA_API_IMPL + #else + #define SPA_API_TYPE static inline + #endif +#endif /** \defgroup spa_types Types * Data type information enumerations @@ -78,6 +87,7 @@ enum { SPA_TYPE_OBJECT_Profiler, SPA_TYPE_OBJECT_ParamLatency, SPA_TYPE_OBJECT_ParamProcessLatency, + SPA_TYPE_OBJECT_ParamTag, _SPA_TYPE_OBJECT_LAST, /**< not part of ABI */ /* vendor extensions */ @@ -122,6 +132,47 @@ struct spa_type_info { const struct spa_type_info *values; }; +SPA_API_TYPE bool spa_type_is_a(const char *type, const char *parent) +{ + return type != NULL && parent != NULL && strncmp(type, parent, strlen(parent)) == 0; +} + +SPA_API_TYPE const char *spa_type_short_name(const char *name) +{ + const char *h; + if ((h = strrchr(name, ':')) != NULL) + name = h + 1; + return name; +} + +SPA_API_TYPE uint32_t spa_type_from_short_name(const char *name, + const struct spa_type_info *info, uint32_t unknown) +{ + int i; + for (i = 0; info[i].name; i++) { + if (spa_streq(name, spa_type_short_name(info[i].name))) + return info[i].type; + } + return unknown; +} +SPA_API_TYPE const char * spa_type_to_name(uint32_t type, + const struct spa_type_info *info, const char *unknown) +{ + int i; + for (i = 0; info[i].name; i++) { + if (info[i].type == type) + return info[i].name; + } + return unknown; +} + +SPA_API_TYPE const char * spa_type_to_short_name(uint32_t type, + const struct spa_type_info *info, const char *unknown) +{ + const char *n = spa_type_to_name(type, info, unknown); + return n ? spa_type_short_name(n) : NULL; +} + /** * \} */ From a682f8d1dcaeb223c402613d8b87626589cfe65c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:48:23 +0000 Subject: [PATCH 027/846] 8349751: AIX build failure after upgrade pipewire to 1.3.81 Backport-of: 19c0ce43e258d00d77314d76a361feb2069a5af1 --- .../unix/native/libpipewire/include/spa/utils/endian.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/java.desktop/unix/native/libpipewire/include/spa/utils/endian.h b/src/java.desktop/unix/native/libpipewire/include/spa/utils/endian.h index 2d002d4538c30..0a8f62c73ce7a 100644 --- a/src/java.desktop/unix/native/libpipewire/include/spa/utils/endian.h +++ b/src/java.desktop/unix/native/libpipewire/include/spa/utils/endian.h @@ -18,6 +18,10 @@ #define bswap_16 _byteswap_ushort #define bswap_32 _byteswap_ulong #define bswap_64 _byteswap_uint64 +#elif defined(AIX) +#include +#define __BIG_ENDIAN BIG_ENDIAN +#define __BYTE_ORDER BIG_ENDIAN #else #include #include From d215a1f47ce869179e1fddbb724fba5902816676 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 10 Mar 2025 14:49:49 +0000 Subject: [PATCH 028/846] 8348936: [Accessibility,macOS,VoiceOver] VoiceOver doesn't announce untick on toggling the checkbox with "space" key on macOS 8345728: [Accessibility,macOS,Screen Magnifier]: JCheckbox unchecked state does not magnify but works for checked state Backport-of: 1e87ff01994df16df7de331040fc5d7a4a85f630 --- .../classes/sun/lwawt/macosx/CAccessible.java | 7 +- .../TestJCheckBoxToggleAccessibility.java | 129 ++++++++++++++++++ 2 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 test/jdk/javax/accessibility/TestJCheckBoxToggleAccessibility.java diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java index 779423bc28fc0..8f67a06a13d88 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, 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 @@ -28,6 +28,7 @@ import java.awt.Component; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.Objects; import javax.accessibility.Accessible; import javax.accessibility.AccessibleContext; @@ -182,7 +183,7 @@ public void propertyChange(PropertyChangeEvent e) { // Do send check box state changes to native side if (thisRole == AccessibleRole.CHECK_BOX) { - if (newValue != null && !newValue.equals(oldValue)) { + if (!Objects.equals(newValue, oldValue)) { valueChanged(ptr); } @@ -208,7 +209,7 @@ public void propertyChange(PropertyChangeEvent e) { // Do send toggle button state changes to native side if (thisRole == AccessibleRole.TOGGLE_BUTTON) { - if (newValue != null && !newValue.equals(oldValue)) { + if (!Objects.equals(newValue, oldValue)) { valueChanged(ptr); } } diff --git a/test/jdk/javax/accessibility/TestJCheckBoxToggleAccessibility.java b/test/jdk/javax/accessibility/TestJCheckBoxToggleAccessibility.java new file mode 100644 index 0000000000000..2a1d03117b738 --- /dev/null +++ b/test/jdk/javax/accessibility/TestJCheckBoxToggleAccessibility.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.GridLayout; + +import javax.swing.JCheckBox; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JToggleButton; + +/* + * @test + * @bug 8348936 8345728 + * @summary Verifies that VoiceOver announces the untick state of CheckBox and + * ToggleButton when space key is pressed. Also verifies that CheckBox + * and ToggleButton untick state is magnified with Screen Magnifier. + * @requires os.family == "mac" + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual TestJCheckBoxToggleAccessibility + */ + +public class TestJCheckBoxToggleAccessibility { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + +

Testing with VoiceOver

+ +
    +
  1. Start the VoiceOver application + (Press Command + F5) +
  2. Click on the Frame with CheckBox and ToggleButton + window to move focus +
  3. Press Spacebar +
  4. VO should announce the checked state +
  5. Press Spacebar again +
  6. VO should announce the unchecked state +
  7. Press Tab to move focus to ToggleButton +
  8. Repeat steps 3 to 6 and listen the announcement +
  9. If announcements are incorrect, press Fail +
  10. Stop the VoiceOver application + (Press Command + F5 again) +
+ +

Testing with Screen Magnifier

+
    +
  1. Enable Screen magnifier on the Mac: + System Settings -> Accessibility -> + Hover Text -> Enable Hover Text
    + Default Hover Text Activation Modifier is Command key +
  2. Move focus back to the test application and perform the following tests + +
      +
    • Test CheckBox states with Screen Magnifier +
        +
      1. Click on CheckBox to select it +
      2. Press the Command key and + hover mouse over CheckBox +
      3. CheckBox ticked state along with its label should be magnified +
      4. Keep the Command key pressed and + click CheckBox to deselect it +
      5. CheckBox unticked state along with its label should be magnified +
      6. Release the Command key +
      7. If Screen Magnifier behaviour is incorrect, press Fail +
      +
    • Test ToggleButton states with Screen Magnifier +
        +
      1. Click on ToggleButton to select it +
      2. Press the Command key and + hover mouse over ToggleButton +
      3. Ticked state along with label should be magnified +
      4. Keep the Command button pressed and + click ToggleButton to deselect it +
      5. Unticked state along with its label should be magnified +
      6. Release the Command key +
      7. If Screen Magnifier behaviour is incorrect, press Fail +
      +
    +
  3. Disable Hover Text (optionally) in the Settings +
+ +

Press Pass if you are able to hear correct VoiceOver announcements and + able to see the correct screen magnifier behaviour.

"""; + + PassFailJFrame.builder() + .title("TestJCheckBoxToggleAccessibility Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .rows(25) + .testUI(TestJCheckBoxToggleAccessibility::createUI) + .testTimeOut(8) + .build() + .awaitAndCheck(); + } + + private static JFrame createUI() { + JFrame frame = new JFrame("A Frame with CheckBox and ToggleButton"); + JCheckBox cb = new JCheckBox("CheckBox", false); + JToggleButton tb = new JToggleButton("ToggleButton"); + + JPanel p = new JPanel(new GridLayout(2, 1)); + p.add(cb); + p.add(tb); + frame.getContentPane().add(p, BorderLayout.CENTER); + frame.setSize(400, 400); + return frame; + } +} From cf54b0d7dbbddf8cd590409e9aac5e0423eb9c3c Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Mon, 10 Mar 2025 17:24:35 +0000 Subject: [PATCH 029/846] 8347126: gc/stress/TestStressG1Uncommit.java gets OOM-killed Backport-of: dff5719e6f95f9ce50a5d49adf13541e22f7b5b1 --- test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java b/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java index 2f61c166cb8f0..9fe729333f975 100644 --- a/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java +++ b/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java @@ -57,6 +57,7 @@ public static void main(String[] args) throws Exception { Collections.addAll(options, "-Xlog:gc,gc+heap+region=debug", "-XX:+UseG1GC", + "-Xmx1g", StressUncommit.class.getName() ); ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(options); @@ -80,9 +81,9 @@ public static void main(String args[]) throws InterruptedException { // Leave 20% head room to try to avoid Full GCs. long allocationSize = (long) (Runtime.getRuntime().maxMemory() * 0.8); - // Figure out suitable number of workers (~1 per gig). - int gigsOfAllocation = (int) Math.ceil((double) allocationSize / G); - int numWorkers = Math.min(gigsOfAllocation, Runtime.getRuntime().availableProcessors()); + // Figure out suitable number of workers (~1 per 100M). + int allocationChunks = (int) Math.ceil((double) allocationSize / (100 * M)); + int numWorkers = Math.min(allocationChunks, Runtime.getRuntime().availableProcessors()); long workerAllocation = allocationSize / numWorkers; log("Using " + numWorkers + " workers, each allocating: ~" + (workerAllocation / M) + "M"); From 682c9390339a79b89f82e580f90587deafbeef45 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 11 Mar 2025 14:22:24 +0000 Subject: [PATCH 030/846] 8348596: Update FreeType to 2.13.3 Backport-of: 6b719eeebc346fd4655fc718d7d033b3ebf54d9e --- src/java.desktop/share/legal/freetype.md | 46 +- .../include/freetype/config/ftconfig.h | 2 +- .../include/freetype/config/ftheader.h | 2 +- .../include/freetype/config/ftoption.h | 18 +- .../include/freetype/config/ftstdlib.h | 2 +- .../include/freetype/config/integer-types.h | 2 +- .../include/freetype/config/mac-support.h | 2 +- .../include/freetype/config/public-macros.h | 2 +- .../libfreetype/include/freetype/freetype.h | 118 +- .../libfreetype/include/freetype/ftadvanc.h | 2 +- .../libfreetype/include/freetype/ftbbox.h | 2 +- .../libfreetype/include/freetype/ftbdf.h | 2 +- .../libfreetype/include/freetype/ftbitmap.h | 2 +- .../libfreetype/include/freetype/ftcid.h | 2 +- .../libfreetype/include/freetype/ftcolor.h | 2 +- .../libfreetype/include/freetype/ftdriver.h | 76 +- .../libfreetype/include/freetype/fterrdef.h | 2 +- .../libfreetype/include/freetype/fterrors.h | 2 +- .../libfreetype/include/freetype/ftfntfmt.h | 2 +- .../libfreetype/include/freetype/ftgasp.h | 2 +- .../libfreetype/include/freetype/ftglyph.h | 2 +- .../libfreetype/include/freetype/ftgzip.h | 2 +- .../libfreetype/include/freetype/ftimage.h | 29 +- .../libfreetype/include/freetype/ftincrem.h | 2 +- .../libfreetype/include/freetype/ftlcdfil.h | 2 +- .../libfreetype/include/freetype/ftlist.h | 2 +- .../libfreetype/include/freetype/ftlogging.h | 2 +- .../libfreetype/include/freetype/ftmac.h | 2 +- .../libfreetype/include/freetype/ftmm.h | 33 +- .../libfreetype/include/freetype/ftmodapi.h | 2 +- .../libfreetype/include/freetype/ftmoderr.h | 2 +- .../libfreetype/include/freetype/ftoutln.h | 4 +- .../libfreetype/include/freetype/ftparams.h | 2 +- .../libfreetype/include/freetype/ftrender.h | 2 +- .../libfreetype/include/freetype/ftsizes.h | 2 +- .../libfreetype/include/freetype/ftsnames.h | 2 +- .../libfreetype/include/freetype/ftstroke.h | 2 +- .../libfreetype/include/freetype/ftsynth.h | 2 +- .../libfreetype/include/freetype/ftsystem.h | 2 +- .../libfreetype/include/freetype/fttrigon.h | 2 +- .../libfreetype/include/freetype/fttypes.h | 2 +- .../include/freetype/internal/autohint.h | 2 +- .../include/freetype/internal/cffotypes.h | 2 +- .../include/freetype/internal/cfftypes.h | 10 +- .../freetype/internal/compiler-macros.h | 2 +- .../include/freetype/internal/ftcalc.h | 21 +- .../include/freetype/internal/ftdebug.h | 2 +- .../include/freetype/internal/ftdrv.h | 2 +- .../include/freetype/internal/ftgloadr.h | 2 +- .../include/freetype/internal/ftmemory.h | 9 +- .../include/freetype/internal/ftmmtypes.h | 2 +- .../include/freetype/internal/ftobjs.h | 8 +- .../include/freetype/internal/ftpsprop.h | 2 +- .../include/freetype/internal/ftrfork.h | 2 +- .../include/freetype/internal/ftserv.h | 2 +- .../include/freetype/internal/ftstream.h | 2 +- .../include/freetype/internal/fttrace.h | 3 +- .../include/freetype/internal/ftvalid.h | 2 +- .../include/freetype/internal/psaux.h | 21 +- .../include/freetype/internal/pshints.h | 2 +- .../freetype/internal/services/svbdf.h | 2 +- .../freetype/internal/services/svcfftl.h | 2 +- .../freetype/internal/services/svcid.h | 2 +- .../freetype/internal/services/svfntfmt.h | 2 +- .../freetype/internal/services/svgldict.h | 2 +- .../freetype/internal/services/svgxval.h | 2 +- .../freetype/internal/services/svkern.h | 2 +- .../freetype/internal/services/svmetric.h | 2 +- .../include/freetype/internal/services/svmm.h | 2 +- .../freetype/internal/services/svotval.h | 2 +- .../freetype/internal/services/svpfr.h | 2 +- .../freetype/internal/services/svpostnm.h | 2 +- .../freetype/internal/services/svprop.h | 2 +- .../freetype/internal/services/svpscmap.h | 2 +- .../freetype/internal/services/svpsinfo.h | 2 +- .../freetype/internal/services/svsfnt.h | 2 +- .../freetype/internal/services/svttcmap.h | 2 +- .../freetype/internal/services/svtteng.h | 2 +- .../freetype/internal/services/svttglyf.h | 2 +- .../freetype/internal/services/svwinfnt.h | 2 +- .../include/freetype/internal/sfnt.h | 9 +- .../include/freetype/internal/svginterface.h | 2 +- .../include/freetype/internal/t1types.h | 52 +- .../include/freetype/internal/tttypes.h | 12 +- .../include/freetype/internal/wofftypes.h | 2 +- .../libfreetype/include/freetype/otsvg.h | 2 +- .../libfreetype/include/freetype/t1tables.h | 60 +- .../libfreetype/include/freetype/ttnameid.h | 2 +- .../libfreetype/include/freetype/tttables.h | 7 +- .../libfreetype/include/freetype/tttags.h | 2 +- .../native/libfreetype/include/ft2build.h | 2 +- .../native/libfreetype/src/autofit/afblue.c | 2 +- .../native/libfreetype/src/autofit/afblue.cin | 2 +- .../native/libfreetype/src/autofit/afblue.dat | 2 +- .../native/libfreetype/src/autofit/afblue.h | 2 +- .../native/libfreetype/src/autofit/afblue.hin | 2 +- .../native/libfreetype/src/autofit/afcjk.c | 2 +- .../native/libfreetype/src/autofit/afcjk.h | 4 +- .../native/libfreetype/src/autofit/afcover.h | 2 +- .../native/libfreetype/src/autofit/afdummy.c | 2 +- .../native/libfreetype/src/autofit/afdummy.h | 2 +- .../native/libfreetype/src/autofit/aferrors.h | 2 +- .../native/libfreetype/src/autofit/afglobal.c | 2 +- .../native/libfreetype/src/autofit/afglobal.h | 2 +- .../native/libfreetype/src/autofit/afhints.c | 18 +- .../native/libfreetype/src/autofit/afhints.h | 2 +- .../native/libfreetype/src/autofit/afindic.c | 2 +- .../native/libfreetype/src/autofit/afindic.h | 2 +- .../native/libfreetype/src/autofit/aflatin.c | 9 +- .../native/libfreetype/src/autofit/aflatin.h | 4 +- .../native/libfreetype/src/autofit/afloader.c | 2 +- .../native/libfreetype/src/autofit/afloader.h | 2 +- .../native/libfreetype/src/autofit/afmodule.c | 4 +- .../native/libfreetype/src/autofit/afmodule.h | 2 +- .../native/libfreetype/src/autofit/afranges.c | 2 +- .../native/libfreetype/src/autofit/afranges.h | 2 +- .../native/libfreetype/src/autofit/afscript.h | 2 +- .../native/libfreetype/src/autofit/afshaper.c | 2 +- .../native/libfreetype/src/autofit/afshaper.h | 2 +- .../native/libfreetype/src/autofit/afstyles.h | 2 +- .../native/libfreetype/src/autofit/aftypes.h | 2 +- .../libfreetype/src/autofit/afws-decl.h | 2 +- .../libfreetype/src/autofit/afws-iter.h | 2 +- .../native/libfreetype/src/base/ftadvanc.c | 2 +- .../native/libfreetype/src/base/ftbase.h | 2 +- .../native/libfreetype/src/base/ftbbox.c | 4 +- .../native/libfreetype/src/base/ftbitmap.c | 2 +- .../native/libfreetype/src/base/ftcalc.c | 169 +- .../share/native/libfreetype/src/base/ftcid.c | 2 +- .../native/libfreetype/src/base/ftcolor.c | 2 +- .../native/libfreetype/src/base/ftdbgmem.c | 2 +- .../native/libfreetype/src/base/ftdebug.c | 2 +- .../native/libfreetype/src/base/ftfntfmt.c | 2 +- .../native/libfreetype/src/base/ftfstype.c | 2 +- .../native/libfreetype/src/base/ftgasp.c | 2 +- .../native/libfreetype/src/base/ftgloadr.c | 33 +- .../native/libfreetype/src/base/ftglyph.c | 2 +- .../native/libfreetype/src/base/ftinit.c | 2 +- .../native/libfreetype/src/base/ftlcdfil.c | 2 +- .../share/native/libfreetype/src/base/ftmac.c | 21 +- .../share/native/libfreetype/src/base/ftmm.c | 2 +- .../native/libfreetype/src/base/ftobjs.c | 9 +- .../native/libfreetype/src/base/ftoutln.c | 18 +- .../native/libfreetype/src/base/ftpatent.c | 2 +- .../native/libfreetype/src/base/ftpsprop.c | 2 +- .../native/libfreetype/src/base/ftrfork.c | 2 +- .../native/libfreetype/src/base/ftsnames.c | 2 +- .../native/libfreetype/src/base/ftstream.c | 8 +- .../native/libfreetype/src/base/ftstroke.c | 16 +- .../native/libfreetype/src/base/ftsynth.c | 2 +- .../native/libfreetype/src/base/ftsystem.c | 2 +- .../native/libfreetype/src/base/fttrigon.c | 2 +- .../native/libfreetype/src/base/fttype1.c | 2 +- .../native/libfreetype/src/base/ftutil.c | 2 +- .../native/libfreetype/src/cff/cffcmap.c | 2 +- .../native/libfreetype/src/cff/cffcmap.h | 2 +- .../native/libfreetype/src/cff/cffdrivr.c | 2 +- .../native/libfreetype/src/cff/cffdrivr.h | 2 +- .../native/libfreetype/src/cff/cfferrs.h | 2 +- .../native/libfreetype/src/cff/cffgload.c | 2 +- .../native/libfreetype/src/cff/cffgload.h | 2 +- .../native/libfreetype/src/cff/cffload.c | 77 +- .../native/libfreetype/src/cff/cffload.h | 2 +- .../native/libfreetype/src/cff/cffobjs.c | 95 +- .../native/libfreetype/src/cff/cffobjs.h | 2 +- .../native/libfreetype/src/cff/cffparse.c | 97 +- .../native/libfreetype/src/cff/cffparse.h | 3 +- .../native/libfreetype/src/cff/cfftoken.h | 74 +- .../native/libfreetype/src/cid/ciderrs.h | 2 +- .../native/libfreetype/src/cid/cidgload.c | 2 +- .../native/libfreetype/src/cid/cidgload.h | 2 +- .../native/libfreetype/src/cid/cidload.c | 41 +- .../native/libfreetype/src/cid/cidload.h | 2 +- .../native/libfreetype/src/cid/cidobjs.c | 2 +- .../native/libfreetype/src/cid/cidobjs.h | 2 +- .../native/libfreetype/src/cid/cidparse.c | 69 +- .../native/libfreetype/src/cid/cidparse.h | 2 +- .../native/libfreetype/src/cid/cidriver.c | 2 +- .../native/libfreetype/src/cid/cidriver.h | 2 +- .../native/libfreetype/src/cid/cidtoken.h | 2 +- .../native/libfreetype/src/psaux/afmparse.c | 2 +- .../native/libfreetype/src/psaux/afmparse.h | 2 +- .../native/libfreetype/src/psaux/cffdecode.c | 20 +- .../native/libfreetype/src/psaux/cffdecode.h | 2 +- .../native/libfreetype/src/psaux/psauxerr.h | 2 +- .../native/libfreetype/src/psaux/psauxmod.c | 2 +- .../native/libfreetype/src/psaux/psauxmod.h | 2 +- .../native/libfreetype/src/psaux/psblues.c | 48 +- .../native/libfreetype/src/psaux/psconv.c | 2 +- .../native/libfreetype/src/psaux/psconv.h | 2 +- .../share/native/libfreetype/src/psaux/psft.c | 16 +- .../share/native/libfreetype/src/psaux/psft.h | 8 +- .../native/libfreetype/src/psaux/psintrp.c | 27 +- .../native/libfreetype/src/psaux/psobjs.c | 46 +- .../native/libfreetype/src/psaux/psobjs.h | 2 +- .../native/libfreetype/src/psaux/t1cmap.c | 2 +- .../native/libfreetype/src/psaux/t1cmap.h | 2 +- .../native/libfreetype/src/psaux/t1decode.c | 2 +- .../native/libfreetype/src/psaux/t1decode.h | 2 +- .../native/libfreetype/src/pshinter/pshalgo.c | 10 +- .../native/libfreetype/src/pshinter/pshalgo.h | 2 +- .../native/libfreetype/src/pshinter/pshglob.c | 2 +- .../native/libfreetype/src/pshinter/pshglob.h | 2 +- .../native/libfreetype/src/pshinter/pshmod.c | 2 +- .../native/libfreetype/src/pshinter/pshmod.h | 2 +- .../libfreetype/src/pshinter/pshnterr.h | 2 +- .../native/libfreetype/src/pshinter/pshrec.c | 4 +- .../native/libfreetype/src/pshinter/pshrec.h | 2 +- .../native/libfreetype/src/psnames/psmodule.c | 2 +- .../native/libfreetype/src/psnames/psmodule.h | 2 +- .../native/libfreetype/src/psnames/psnamerr.h | 2 +- .../native/libfreetype/src/psnames/pstables.h | 2 +- .../native/libfreetype/src/raster/ftmisc.h | 23 +- .../native/libfreetype/src/raster/ftraster.c | 1750 ++++++----------- .../native/libfreetype/src/raster/ftraster.h | 2 +- .../native/libfreetype/src/raster/ftrend1.c | 2 +- .../native/libfreetype/src/raster/ftrend1.h | 2 +- .../native/libfreetype/src/raster/rasterrs.h | 2 +- .../native/libfreetype/src/sfnt/pngshim.c | 2 +- .../native/libfreetype/src/sfnt/pngshim.h | 2 +- .../native/libfreetype/src/sfnt/sfdriver.c | 17 +- .../native/libfreetype/src/sfnt/sfdriver.h | 2 +- .../native/libfreetype/src/sfnt/sferrors.h | 2 +- .../native/libfreetype/src/sfnt/sfobjs.c | 21 +- .../native/libfreetype/src/sfnt/sfobjs.h | 2 +- .../native/libfreetype/src/sfnt/sfwoff.c | 20 +- .../native/libfreetype/src/sfnt/sfwoff.h | 2 +- .../native/libfreetype/src/sfnt/sfwoff2.c | 52 +- .../native/libfreetype/src/sfnt/sfwoff2.h | 2 +- .../native/libfreetype/src/sfnt/ttcmap.c | 2 +- .../native/libfreetype/src/sfnt/ttcmap.h | 2 +- .../native/libfreetype/src/sfnt/ttcmapc.h | 2 +- .../native/libfreetype/src/sfnt/ttcolr.c | 38 +- .../native/libfreetype/src/sfnt/ttcolr.h | 2 +- .../native/libfreetype/src/sfnt/ttcpal.c | 2 +- .../native/libfreetype/src/sfnt/ttcpal.h | 2 +- .../native/libfreetype/src/sfnt/ttkern.c | 2 +- .../native/libfreetype/src/sfnt/ttkern.h | 2 +- .../native/libfreetype/src/sfnt/ttload.c | 4 +- .../native/libfreetype/src/sfnt/ttload.h | 2 +- .../share/native/libfreetype/src/sfnt/ttmtx.c | 2 +- .../share/native/libfreetype/src/sfnt/ttmtx.h | 2 +- .../native/libfreetype/src/sfnt/ttpost.c | 50 +- .../native/libfreetype/src/sfnt/ttpost.h | 2 +- .../native/libfreetype/src/sfnt/ttsbit.c | 2 +- .../native/libfreetype/src/sfnt/ttsbit.h | 2 +- .../native/libfreetype/src/sfnt/woff2tags.c | 2 +- .../native/libfreetype/src/sfnt/woff2tags.h | 2 +- .../native/libfreetype/src/smooth/ftgrays.c | 461 ++--- .../native/libfreetype/src/smooth/ftgrays.h | 2 +- .../native/libfreetype/src/smooth/ftsmerrs.h | 2 +- .../native/libfreetype/src/smooth/ftsmooth.c | 2 +- .../native/libfreetype/src/smooth/ftsmooth.h | 2 +- .../libfreetype/src/truetype/ttdriver.c | 17 +- .../libfreetype/src/truetype/ttdriver.h | 2 +- .../libfreetype/src/truetype/tterrors.h | 2 +- .../native/libfreetype/src/truetype/ttgload.c | 51 +- .../native/libfreetype/src/truetype/ttgload.h | 2 +- .../native/libfreetype/src/truetype/ttgxvar.c | 417 ++-- .../native/libfreetype/src/truetype/ttgxvar.h | 2 +- .../libfreetype/src/truetype/ttinterp.c | 16 +- .../libfreetype/src/truetype/ttinterp.h | 2 +- .../native/libfreetype/src/truetype/ttobjs.c | 50 +- .../native/libfreetype/src/truetype/ttobjs.h | 4 +- .../native/libfreetype/src/truetype/ttpload.c | 2 +- .../native/libfreetype/src/truetype/ttpload.h | 2 +- .../native/libfreetype/src/type1/t1afm.c | 2 +- .../native/libfreetype/src/type1/t1afm.h | 2 +- .../native/libfreetype/src/type1/t1driver.c | 10 +- .../native/libfreetype/src/type1/t1driver.h | 2 +- .../native/libfreetype/src/type1/t1errors.h | 2 +- .../native/libfreetype/src/type1/t1gload.c | 2 +- .../native/libfreetype/src/type1/t1gload.h | 2 +- .../native/libfreetype/src/type1/t1load.c | 28 +- .../native/libfreetype/src/type1/t1load.h | 2 +- .../native/libfreetype/src/type1/t1objs.c | 2 +- .../native/libfreetype/src/type1/t1objs.h | 2 +- .../native/libfreetype/src/type1/t1parse.c | 2 +- .../native/libfreetype/src/type1/t1parse.h | 2 +- .../native/libfreetype/src/type1/t1tokens.h | 2 +- 280 files changed, 2149 insertions(+), 2800 deletions(-) diff --git a/src/java.desktop/share/legal/freetype.md b/src/java.desktop/share/legal/freetype.md index 6bcb4976fd201..2c654e154ba4f 100644 --- a/src/java.desktop/share/legal/freetype.md +++ b/src/java.desktop/share/legal/freetype.md @@ -1,4 +1,4 @@ -## The FreeType Project: Freetype v2.13.2 +## The FreeType Project: Freetype v2.13.3 ### FreeType Notice @@ -21,23 +21,23 @@ which fits your needs best. ### FreeType License ``` -Copyright (C) 1996-2023 by David Turner, Robert Wilhelm, and Werner Lemberg. -Copyright (C) 2007-2023 by Dereg Clegg and Michael Toftdal. -Copyright (C) 1996-2023 by Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. -Copyright (C) 2022-2023 by David Turner, Robert Wilhelm, Werner Lemberg, George Williams, and -Copyright (C) 2004-2023 by Masatake YAMATO and Redhat K.K. -Copyright (C) 2007-2023 by Derek Clegg and Michael Toftdal. -Copyright (C) 2003-2023 by Masatake YAMATO, Red Hat K.K., -Copyright (C) 1996-2023 by David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches. -Copyright (C) 2007-2023 by David Turner. -Copyright (C) 2022-2023 by David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti. -Copyright (C) 2007-2023 by Rahul Bhalerao , . -Copyright (C) 2008-2023 by David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. -Copyright (C) 2013-2023 by Google, Inc. -Copyright (C) 2019-2023 by Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. -Copyright (C) 2009-2023 by Oran Agra and Mickey Gabel. -Copyright (C) 2018-2023 by David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg. -Copyright (C) 2004-2023 by David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. +Copyright (C) 1996-2024 by David Turner, Robert Wilhelm, and Werner Lemberg. +Copyright (C) 2007-2024 by Dereg Clegg and Michael Toftdal. +Copyright (C) 1996-2024 by Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. +Copyright (C) 2022-2024 by David Turner, Robert Wilhelm, Werner Lemberg, George Williams, and +Copyright (C) 2004-2024 by Masatake YAMATO and Redhat K.K. +Copyright (C) 2007-2024 by Derek Clegg and Michael Toftdal. +Copyright (C) 2003-2024 by Masatake YAMATO, Red Hat K.K., +Copyright (C) 1996-2024 by David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches. +Copyright (C) 2007-2024 by David Turner. +Copyright (C) 2022-2024 by David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti. +Copyright (C) 2007-2024 by Rahul Bhalerao , . +Copyright (C) 2008-2024 by David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. +Copyright (C) 2013-2024 by Google, Inc. +Copyright (C) 2019-2024 by Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. +Copyright (C) 2009-2024 by Oran Agra and Mickey Gabel. +Copyright (C) 2018-2024 by David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg. +Copyright (C) 2004-2024 by David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. The FreeType Project LICENSE @@ -559,7 +559,7 @@ Public License instead of this License. ``` --------------------------------- -The below license applies to the following files: +The below applies to the following file(s): libfreetype/src/psaux/psarrst.c libfreetype/src/psaux/psarrst.h libfreetype/src/psaux/psblues.c @@ -582,7 +582,7 @@ libfreetype/src/psaux/psstack.c libfreetype/src/psaux/psstack.h libfreetype/src/psaux/pstypes.h -Copyright 2006-2014 Adobe Systems Incorporated. +Copyright (C) 2006-2014 Adobe Systems Incorporated. This software, and all works of authorship, whether in source or object code form as indicated by the copyright notice(s) included @@ -618,12 +618,12 @@ and you accept them fully. ``` --------------------------------- -The below license applies to the following files: +The below applies to the following file(s): libfreetype/include/freetype/internal/fthash.h libfreetype/src/base/fthash.c -Copyright 2000 Computing Research Labs, New Mexico State University -Copyright 2001-2015 +Copyright (C) 2000 Computing Research Labs, New Mexico State University +Copyright (C) 2001-2015 Francesco Zappa Nardelli diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/config/ftconfig.h b/src/java.desktop/share/native/libfreetype/include/freetype/config/ftconfig.h index a85151699d0e0..0667493fec64c 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/config/ftconfig.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/config/ftconfig.h @@ -4,7 +4,7 @@ * * ANSI-specific configuration file (specification only). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/config/ftheader.h b/src/java.desktop/share/native/libfreetype/include/freetype/config/ftheader.h index e607bce15c576..f6ef2618dedeb 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/config/ftheader.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/config/ftheader.h @@ -4,7 +4,7 @@ * * Build macros of the FreeType 2 library. * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h b/src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h index 4375c7a6ff34f..d29a0a7cefbd0 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h @@ -4,7 +4,7 @@ * * User-selectable configuration macros (specification only). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -757,6 +757,22 @@ FT_BEGIN_HEADER #endif + /************************************************************************** + * + * Option `TT_CONFIG_OPTION_GPOS_KERNING` enables a basic GPOS kerning + * implementation (for TrueType fonts only). With this defined, FreeType + * is able to get kerning pair data from the GPOS 'kern' feature as well as + * legacy 'kern' tables; without this defined, FreeType will only be able + * to use legacy 'kern' tables. + * + * Note that FreeType does not support more advanced GPOS layout features; + * even the 'kern' feature implemented here doesn't handle more + * sophisticated kerning variants. Use a higher-level library like + * HarfBuzz instead for that. + */ +/* #define TT_CONFIG_OPTION_GPOS_KERNING */ + + /*************************************************************************/ /*************************************************************************/ /**** ****/ diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/config/ftstdlib.h b/src/java.desktop/share/native/libfreetype/include/freetype/config/ftstdlib.h index f65148a902eac..e17aa7b89d572 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/config/ftstdlib.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/config/ftstdlib.h @@ -5,7 +5,7 @@ * ANSI-specific library and header configuration file (specification * only). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/config/integer-types.h b/src/java.desktop/share/native/libfreetype/include/freetype/config/integer-types.h index 7258b50854150..c27505ffc4b6d 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/config/integer-types.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/config/integer-types.h @@ -4,7 +4,7 @@ * * FreeType integer types definitions. * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/config/mac-support.h b/src/java.desktop/share/native/libfreetype/include/freetype/config/mac-support.h index b77b96d5db835..07b6f915bd83b 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/config/mac-support.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/config/mac-support.h @@ -4,7 +4,7 @@ * * Mac/OS X support configuration header. * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/config/public-macros.h b/src/java.desktop/share/native/libfreetype/include/freetype/config/public-macros.h index 23d0fa6a329c6..f56581a6ee796 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/config/public-macros.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/config/public-macros.h @@ -4,7 +4,7 @@ * * Define a set of compiler macros used in public FreeType headers. * - * Copyright (C) 2020-2023 by + * Copyright (C) 2020-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/freetype.h b/src/java.desktop/share/native/libfreetype/include/freetype/freetype.h index 92acf3794a7e8..58fc33dfe60ab 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/freetype.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/freetype.h @@ -4,7 +4,7 @@ * * FreeType high-level API and common types (specification only). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -1322,9 +1322,13 @@ FT_BEGIN_HEADER * FT_FACE_FLAG_KERNING :: * The face contains kerning information. If set, the kerning distance * can be retrieved using the function @FT_Get_Kerning. Otherwise the - * function always returns the vector (0,0). Note that FreeType - * doesn't handle kerning data from the SFNT 'GPOS' table (as present - * in many OpenType fonts). + * function always returns the vector (0,0). + * + * Note that for TrueType fonts only, FreeType supports both the 'kern' + * table and the basic, pair-wise kerning feature from the 'GPOS' table + * (with `TT_CONFIG_OPTION_GPOS_KERNING` enabled), though FreeType does + * not support the more advanced GPOS layout features; use a library + * like HarfBuzz for those instead. * * FT_FACE_FLAG_FAST_GLYPHS :: * THIS FLAG IS DEPRECATED. DO NOT USE OR TEST IT. @@ -3767,87 +3771,18 @@ FT_BEGIN_HEADER * pixels and use the @FT_PIXEL_MODE_LCD_V mode. * * FT_RENDER_MODE_SDF :: - * This mode corresponds to 8-bit, single-channel signed distance field - * (SDF) bitmaps. Each pixel in the SDF grid is the value from the - * pixel's position to the nearest glyph's outline. The distances are - * calculated from the center of the pixel and are positive if they are - * filled by the outline (i.e., inside the outline) and negative - * otherwise. Check the note below on how to convert the output values - * to usable data. + * The positive (unsigned) 8-bit bitmap values can be converted to the + * single-channel signed distance field (SDF) by subtracting 128, with + * the positive and negative results corresponding to the inside and + * the outside of a glyph contour, respectively. The distance units are + * arbitrarily determined by an adjustable @spread property. * * @note: - * The selected render mode only affects vector glyphs of a font. + * The selected render mode only affects scalable vector glyphs of a font. * Embedded bitmaps often have a different pixel mode like * @FT_PIXEL_MODE_MONO. You can use @FT_Bitmap_Convert to transform them * into 8-bit pixmaps. * - * For @FT_RENDER_MODE_SDF the output bitmap buffer contains normalized - * distances that are packed into unsigned 8-bit values. To get pixel - * values in floating point representation use the following pseudo-C - * code for the conversion. - * - * ``` - * // Load glyph and render using FT_RENDER_MODE_SDF, - * // then use the output buffer as follows. - * - * ... - * FT_Byte buffer = glyph->bitmap->buffer; - * - * - * for pixel in buffer - * { - * // `sd` is the signed distance and `spread` is the current spread; - * // the default spread is 2 and can be changed. - * - * float sd = (float)pixel - 128.0f; - * - * - * // Convert to pixel values. - * sd = ( sd / 128.0f ) * spread; - * - * // Store `sd` in a buffer or use as required. - * } - * - * ``` - * - * FreeType has two rasterizers for generating SDF, namely: - * - * 1. `sdf` for generating SDF directly from glyph's outline, and - * - * 2. `bsdf` for generating SDF from rasterized bitmaps. - * - * Depending on the glyph type (i.e., outline or bitmap), one of the two - * rasterizers is chosen at runtime and used for generating SDFs. To - * force the use of `bsdf` you should render the glyph with any of the - * FreeType's other rendering modes (e.g., `FT_RENDER_MODE_NORMAL`) and - * then re-render with `FT_RENDER_MODE_SDF`. - * - * There are some issues with stability and possible failures of the SDF - * renderers (specifically `sdf`). - * - * 1. The `sdf` rasterizer is sensitive to really small features (e.g., - * sharp turns that are less than 1~pixel) and imperfections in the - * glyph's outline, causing artifacts in the final output. - * - * 2. The `sdf` rasterizer has limited support for handling intersecting - * contours and *cannot* handle self-intersecting contours whatsoever. - * Self-intersection happens when a single connected contour - * intersects itself at some point; having these in your font - * definitely poses a problem to the rasterizer and cause artifacts, - * too. - * - * 3. Generating SDF for really small glyphs may result in undesirable - * output; the pixel grid (which stores distance information) becomes - * too coarse. - * - * 4. Since the output buffer is normalized, precision at smaller spreads - * is greater than precision at larger spread values because the - * output range of [0..255] gets mapped to a smaller SDF range. A - * spread of~2 should be sufficient in most cases. - * - * Points (1) and (2) can be avoided by using the `bsdf` rasterizer, - * which is more stable than the `sdf` rasterizer in general. - * */ typedef enum FT_Render_Mode_ { @@ -4058,9 +3993,26 @@ FT_BEGIN_HEADER * out of the scope of this API function -- they can be implemented * through format-specific interfaces. * - * Kerning for OpenType fonts implemented in a 'GPOS' table is not - * supported; use @FT_HAS_KERNING to find out whether a font has data - * that can be extracted with `FT_Get_Kerning`. + * Note that, for TrueType fonts only, this can extract data from both + * the 'kern' table and the basic, pair-wise kerning feature from the + * GPOS table (with `TT_CONFIG_OPTION_GPOS_KERNING` enabled), though + * FreeType does not support the more advanced GPOS layout features; use + * a library like HarfBuzz for those instead. If a font has both a + * 'kern' table and kern features of a GPOS table, the 'kern' table will + * be used. + * + * Also note for right-to-left scripts, the functionality may differ for + * fonts with GPOS tables vs. 'kern' tables. For GPOS, right-to-left + * fonts typically use both a placement offset and an advance for pair + * positioning, which this API does not support, so it would output + * kerning values of zero; though if the right-to-left font used only + * advances in GPOS pair positioning, then this API could output kerning + * values for it, but it would use `left_glyph` to mean the first glyph + * for that case. Whereas 'kern' tables are always advance-only and + * always store the left glyph first. + * + * Use @FT_HAS_KERNING to find out whether a font has data that can be + * extracted with `FT_Get_Kerning`. */ FT_EXPORT( FT_Error ) FT_Get_Kerning( FT_Face face, @@ -5222,7 +5174,7 @@ FT_BEGIN_HEADER */ #define FREETYPE_MAJOR 2 #define FREETYPE_MINOR 13 -#define FREETYPE_PATCH 2 +#define FREETYPE_PATCH 3 /************************************************************************** diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftadvanc.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftadvanc.h index 4560ded6dcbd3..85b8ba2554be7 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftadvanc.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftadvanc.h @@ -4,7 +4,7 @@ * * Quick computation of advance widths (specification only). * - * Copyright (C) 2008-2023 by + * Copyright (C) 2008-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftbbox.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftbbox.h index fc21740fc2bf8..12bbfa63a6284 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftbbox.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftbbox.h @@ -4,7 +4,7 @@ * * FreeType exact bbox computation (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftbdf.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftbdf.h index e8ce6431285d2..6f63b0b1e7812 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftbdf.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftbdf.h @@ -4,7 +4,7 @@ * * FreeType API for accessing BDF-specific strings (specification). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftbitmap.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftbitmap.h index eb6b4b1eebedf..df9d462652e75 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftbitmap.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftbitmap.h @@ -4,7 +4,7 @@ * * FreeType utility functions for bitmaps (specification). * - * Copyright (C) 2004-2023 by + * Copyright (C) 2004-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftcid.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftcid.h index ef22939022453..96b2a90fc59f3 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftcid.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftcid.h @@ -4,7 +4,7 @@ * * FreeType API for accessing CID font information (specification). * - * Copyright (C) 2007-2023 by + * Copyright (C) 2007-2024 by * Dereg Clegg and Michael Toftdal. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftcolor.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftcolor.h index eae200fdf1485..420720ddf225d 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftcolor.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftcolor.h @@ -4,7 +4,7 @@ * * FreeType's glyph color management (specification). * - * Copyright (C) 2018-2023 by + * Copyright (C) 2018-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftdriver.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftdriver.h index 7af7465bc768e..1b7f539f5e22d 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftdriver.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftdriver.h @@ -4,7 +4,7 @@ * * FreeType API for controlling driver modules (specification only). * - * Copyright (C) 2017-2023 by + * Copyright (C) 2017-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -817,6 +817,80 @@ FT_BEGIN_HEADER * 2.5 */ + + /************************************************************************** + * + * @property: + * spread + * + * @description: + * This property of the 'sdf' and 'bsdf' renderers defines how the signed + * distance field (SDF) is represented in the output bitmap. The output + * values are calculated as follows, '128 * ( SDF / spread + 1 )', with + * the result clamped to the 8-bit range [0..255]. Therefore, 'spread' + * is also the maximum euclidean distance from the edge after which the + * values are clamped. The spread is specified in pixels with the + * default value of 8. For accurate SDF texture mapping (interpolation), + * the spread should be large enough to accommodate the target grid unit. + * + * @example: + * The following example code demonstrates how to set the SDF spread + * (omitting the error handling). + * + * ``` + * FT_Library library; + * FT_Int spread = 2; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "sdf", "spread", &spread ); + * ``` + * + * @note: + * FreeType has two rasterizers for generating SDF, namely: + * + * 1. `sdf` for generating SDF directly from glyph's outline, and + * + * 2. `bsdf` for generating SDF from rasterized bitmaps. + * + * Depending on the glyph type (i.e., outline or bitmap), one of the two + * rasterizers is chosen at runtime and used for generating SDFs. To + * force the use of `bsdf` you should render the glyph with any of the + * FreeType's other rendering modes (e.g., `FT_RENDER_MODE_NORMAL`) and + * then re-render with `FT_RENDER_MODE_SDF`. + * + * There are some issues with stability and possible failures of the SDF + * renderers (specifically `sdf`). + * + * 1. The `sdf` rasterizer is sensitive to really small features (e.g., + * sharp turns that are less than 1~pixel) and imperfections in the + * glyph's outline, causing artifacts in the final output. + * + * 2. The `sdf` rasterizer has limited support for handling intersecting + * contours and *cannot* handle self-intersecting contours whatsoever. + * Self-intersection happens when a single connected contour + * intersects itself at some point; having these in your font + * definitely poses a problem to the rasterizer and cause artifacts, + * too. + * + * 3. Generating SDF for really small glyphs may result in undesirable + * output; the pixel grid (which stores distance information) becomes + * too coarse. + * + * 4. Since the output buffer is normalized, precision at smaller spreads + * is greater than precision at larger spread values because the + * output range of [0..255] gets mapped to a smaller SDF range. A + * spread of~2 should be sufficient in most cases. + * + * Points (1) and (2) can be avoided by using the `bsdf` rasterizer, + * which is more stable than the `sdf` rasterizer in general. + * + * @since: + * 2.11 + */ + + /************************************************************************** * * @property: diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/fterrdef.h b/src/java.desktop/share/native/libfreetype/include/freetype/fterrdef.h index d59b3cc2da277..710ca91bbddb8 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/fterrdef.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/fterrdef.h @@ -4,7 +4,7 @@ * * FreeType error codes (specification). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/fterrors.h b/src/java.desktop/share/native/libfreetype/include/freetype/fterrors.h index 15ef3f76b59fc..27c0ece5c1ca6 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/fterrors.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/fterrors.h @@ -4,7 +4,7 @@ * * FreeType error code handling (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftfntfmt.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftfntfmt.h index c0018fc830c25..7c8b0874a8183 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftfntfmt.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftfntfmt.h @@ -4,7 +4,7 @@ * * Support functions for font formats. * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftgasp.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftgasp.h index d5f19add8f209..30e5a9bf82b00 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftgasp.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftgasp.h @@ -4,7 +4,7 @@ * * Access of TrueType's 'gasp' table (specification). * - * Copyright (C) 2007-2023 by + * Copyright (C) 2007-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftglyph.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftglyph.h index 4658895f7a962..dc1eb8873ae8c 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftglyph.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftglyph.h @@ -4,7 +4,7 @@ * * FreeType convenience functions to handle glyphs (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftgzip.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftgzip.h index 443ec29db1bd3..9516dc030ac51 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftgzip.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftgzip.h @@ -4,7 +4,7 @@ * * Gzip-compressed stream support. * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftimage.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftimage.h index 6baa812560ead..2b4b4ac60ae2f 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftimage.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftimage.h @@ -5,7 +5,7 @@ * FreeType glyph image formats and default raster interface * (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -21,6 +21,11 @@ * Note: A 'raster' is simply a scan-line converter, used to render * `FT_Outline`s into `FT_Bitmap`s. * + * Note: This file can be used for `STANDALONE_` compilation of raster + * (B/W) and smooth (anti-aliased) renderers. Therefore, it must + * rely on standard variable types only instead of aliases in + * `fttypes.h`. + * */ @@ -318,7 +323,7 @@ FT_BEGIN_HEADER * * If bit~2 is set, bits 5-7 contain the drop-out mode (as defined in * the OpenType specification; the value is the same as the argument to - * the 'SCANMODE' instruction). + * the 'SCANTYPE' instruction). * * Bits 3 and~4 are reserved for internal purposes. * @@ -341,14 +346,14 @@ FT_BEGIN_HEADER */ typedef struct FT_Outline_ { - short n_contours; /* number of contours in glyph */ - short n_points; /* number of points in the glyph */ + unsigned short n_contours; /* number of contours in glyph */ + unsigned short n_points; /* number of points in the glyph */ - FT_Vector* points; /* the outline's points */ - char* tags; /* the points flags */ - short* contours; /* the contour end points */ + FT_Vector* points; /* the outline's points */ + unsigned char* tags; /* the points flags */ + unsigned short* contours; /* the contour end points */ - int flags; /* outline masks */ + int flags; /* outline masks */ } FT_Outline; @@ -356,8 +361,8 @@ FT_BEGIN_HEADER /* Following limits must be consistent with */ /* FT_Outline.{n_contours,n_points} */ -#define FT_OUTLINE_CONTOURS_MAX SHRT_MAX -#define FT_OUTLINE_POINTS_MAX SHRT_MAX +#define FT_OUTLINE_CONTOURS_MAX USHRT_MAX +#define FT_OUTLINE_POINTS_MAX USHRT_MAX /************************************************************************** @@ -434,8 +439,8 @@ FT_BEGIN_HEADER * rasterizer; see the `tags` field in @FT_Outline. * * Please refer to the description of the 'SCANTYPE' instruction in the - * OpenType specification (in file `ttinst1.doc`) how simple drop-outs, - * smart drop-outs, and stubs are defined. + * [OpenType specification](https://learn.microsoft.com/en-us/typography/opentype/spec/tt_instructions#scantype) + * how simple drop-outs, smart drop-outs, and stubs are defined. */ #define FT_OUTLINE_NONE 0x0 #define FT_OUTLINE_OWNER 0x1 diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftincrem.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftincrem.h index 2d4f5def241b0..816581b78ebd5 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftincrem.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftincrem.h @@ -4,7 +4,7 @@ * * FreeType incremental loading (specification). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftlcdfil.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftlcdfil.h index d3723e16f67dc..25274dc4ac223 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftlcdfil.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftlcdfil.h @@ -5,7 +5,7 @@ * FreeType API for color filtering of subpixel bitmap glyphs * (specification). * - * Copyright (C) 2006-2023 by + * Copyright (C) 2006-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftlist.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftlist.h index b55313133593f..972fbfa2fe4e3 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftlist.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftlist.h @@ -4,7 +4,7 @@ * * Generic list support for FreeType (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftlogging.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftlogging.h index 53b8b89642711..1813cfc2c27a2 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftlogging.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftlogging.h @@ -4,7 +4,7 @@ * * Additional debugging APIs. * - * Copyright (C) 2020-2023 by + * Copyright (C) 2020-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftmac.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftmac.h index a91e38f9ea752..e4efde33dd839 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftmac.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftmac.h @@ -4,7 +4,7 @@ * * Additional Mac-specific API. * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftmm.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftmm.h index d145128a9bcdb..35ed039c89b8d 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftmm.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftmm.h @@ -4,7 +4,7 @@ * * FreeType Multiple Master font interface (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -19,8 +19,13 @@ #ifndef FTMM_H_ #define FTMM_H_ +#include -#include +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif FT_BEGIN_HEADER @@ -53,6 +58,30 @@ FT_BEGIN_HEADER */ + /************************************************************************** + * + * @enum: + * T1_MAX_MM_XXX + * + * @description: + * Multiple Masters limits as defined in their specifications. + * + * @values: + * T1_MAX_MM_AXIS :: + * The maximum number of Multiple Masters axes. + * + * T1_MAX_MM_DESIGNS :: + * The maximum number of Multiple Masters designs. + * + * T1_MAX_MM_MAP_POINTS :: + * The maximum number of elements in a design map. + * + */ +#define T1_MAX_MM_AXIS 4 +#define T1_MAX_MM_DESIGNS 16 +#define T1_MAX_MM_MAP_POINTS 20 + + /************************************************************************** * * @struct: diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftmodapi.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftmodapi.h index c8f0c2c2a45ec..0ee715898f7b7 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftmodapi.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftmodapi.h @@ -4,7 +4,7 @@ * * FreeType modules public interface (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftmoderr.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftmoderr.h index c8c892dcce8b2..6722fbf8b709c 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftmoderr.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftmoderr.h @@ -4,7 +4,7 @@ * * FreeType module error offsets (specification). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftoutln.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftoutln.h index f9329ca40c98a..44e94b4f5bbbb 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftoutln.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftoutln.h @@ -5,7 +5,7 @@ * Support for the FT_Outline type used to store glyph shapes of * most scalable font formats (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -112,7 +112,7 @@ FT_BEGIN_HEADER * Degenerate contours, segments, and Bezier arcs may be reported. In * most cases, it is best to filter these out before using the outline * for stroking or other path modification purposes (which may cause - * degenerate segments to become non-degenrate and visible, like when + * degenerate segments to become non-degenerate and visible, like when * stroke caps are used or the path is otherwise outset). Some glyph * outlines may contain deliberate degenerate single points for mark * attachement. diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftparams.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftparams.h index 6a9f243bc904c..43bf69c202f76 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftparams.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftparams.h @@ -4,7 +4,7 @@ * * FreeType API for possible FT_Parameter tags (specification only). * - * Copyright (C) 2017-2023 by + * Copyright (C) 2017-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftrender.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftrender.h index 0b6fad32e8497..dc5018a1b54b6 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftrender.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftrender.h @@ -4,7 +4,7 @@ * * FreeType renderer modules public interface (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftsizes.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftsizes.h index 7bfb1aed4c255..4ef5c7955dfde 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftsizes.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftsizes.h @@ -4,7 +4,7 @@ * * FreeType size objects management (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftsnames.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftsnames.h index 9d5d22bb25543..d5d5cd9310329 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftsnames.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftsnames.h @@ -7,7 +7,7 @@ * * This is _not_ used to retrieve glyph names! * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftstroke.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftstroke.h index b3d90802a56a1..41626dc9d7b38 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftstroke.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftstroke.h @@ -4,7 +4,7 @@ * * FreeType path stroker (specification). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftsynth.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftsynth.h index af90967dda0de..43081b6c33074 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftsynth.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftsynth.h @@ -5,7 +5,7 @@ * FreeType synthesizing code for emboldening and slanting * (specification). * - * Copyright (C) 2000-2023 by + * Copyright (C) 2000-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftsystem.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftsystem.h index 3a08f4912c982..1eacb3af398f3 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ftsystem.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftsystem.h @@ -4,7 +4,7 @@ * * FreeType low-level system interface definition (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/fttrigon.h b/src/java.desktop/share/native/libfreetype/include/freetype/fttrigon.h index 294981a6f3127..a5299e938d450 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/fttrigon.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/fttrigon.h @@ -4,7 +4,7 @@ * * FreeType trigonometric functions (specification). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/fttypes.h b/src/java.desktop/share/native/libfreetype/include/freetype/fttypes.h index 5b109f0c73c2f..27815143a6453 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/fttypes.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/fttypes.h @@ -4,7 +4,7 @@ * * FreeType simple types definitions (specification only). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/autohint.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/autohint.h index bf9c8b7cf2a50..8865d53b38945 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/autohint.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/autohint.h @@ -4,7 +4,7 @@ * * High-level 'autohint' module-specific interface (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/cffotypes.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/cffotypes.h index 50d535384989d..36b0390a5a565 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/cffotypes.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/cffotypes.h @@ -4,7 +4,7 @@ * * Basic OpenType/CFF object type definitions (specification). * - * Copyright (C) 2017-2023 by + * Copyright (C) 2017-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/cfftypes.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/cfftypes.h index c2521764caa07..ef2e8e7569c34 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/cfftypes.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/cfftypes.h @@ -5,7 +5,7 @@ * Basic OpenType/CFF type definitions and interface (specification * only). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -248,10 +248,10 @@ FT_BEGIN_HEADER FT_Byte num_family_blues; FT_Byte num_family_other_blues; - FT_Pos blue_values[14]; - FT_Pos other_blues[10]; - FT_Pos family_blues[14]; - FT_Pos family_other_blues[10]; + FT_Fixed blue_values[14]; + FT_Fixed other_blues[10]; + FT_Fixed family_blues[14]; + FT_Fixed family_other_blues[10]; FT_Fixed blue_scale; FT_Pos blue_shift; diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/compiler-macros.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/compiler-macros.h index 6f67650979e9e..876f66e256171 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/compiler-macros.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/compiler-macros.h @@ -4,7 +4,7 @@ * * Compiler-specific macro definitions used internally by FreeType. * - * Copyright (C) 2020-2023 by + * Copyright (C) 2020-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftcalc.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftcalc.h index d9aea236024fb..71128a2df9090 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftcalc.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftcalc.h @@ -4,7 +4,7 @@ * * Arithmetic computations (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -415,7 +415,7 @@ FT_BEGIN_HEADER #define FT_MSB( x ) ( 31 - _CountLeadingZeros( x ) ) -#elif defined( _M_ARM64 ) || defined( _M_ARM ) +#elif defined( _M_ARM64 ) || defined( _M_ARM ) || defined( _M_ARM64EC ) #include #pragma intrinsic( _CountLeadingZeros ) @@ -455,6 +455,12 @@ FT_BEGIN_HEADER #define FT_MSB( x ) FT_MSB_i386( x ) +#elif defined( __SunOS_5_11 ) + +#include + +#define FT_MSB( x ) ( fls( x ) - 1 ) + #elif defined( __DECC ) || defined( __DECCXX ) #include @@ -489,8 +495,6 @@ FT_BEGIN_HEADER FT_Fixed y ); -#if 0 - /************************************************************************** * * @function: @@ -507,12 +511,11 @@ FT_BEGIN_HEADER * The result of 'sqrt(x)'. * * @note: - * This function is not very fast. + * This function is slow and should be avoided. Consider @FT_Hypot or + * @FT_Vector_NormLen instead. */ - FT_BASE( FT_Int32 ) - FT_SqrtFixed( FT_Int32 x ); - -#endif /* 0 */ + FT_BASE( FT_UInt32 ) + FT_SqrtFixed( FT_UInt32 x ); #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) * 64 ) /* << 6 */ diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdebug.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdebug.h index 4e013ba1e2673..d7fa8dc93cf7b 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdebug.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdebug.h @@ -4,7 +4,7 @@ * * Debugging and logging component (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdrv.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdrv.h index 9001c07ad0b4a..5609b3ef12bd2 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdrv.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdrv.h @@ -4,7 +4,7 @@ * * FreeType internal font driver interface (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftgloadr.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftgloadr.h index 36e5509f9eab6..f1c155b162caa 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftgloadr.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftgloadr.h @@ -4,7 +4,7 @@ * * The FreeType glyph loader (specification). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmemory.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmemory.h index 5eb1d21ff67c1..4e05a29f13a14 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmemory.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmemory.h @@ -4,7 +4,7 @@ * * The FreeType memory management macros (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg * * This file is part of the FreeType project, and may only be used, @@ -371,8 +371,11 @@ extern "C++" #define FT_STRDUP( dst, str ) \ FT_MEM_SET_ERROR( FT_MEM_STRDUP( dst, str ) ) -#define FT_MEM_DUP( dst, address, size ) \ - (dst) = ft_mem_dup( memory, (address), (FT_ULong)(size), &error ) +#define FT_MEM_DUP( dst, address, size ) \ + FT_ASSIGNP_INNER( dst, ft_mem_dup( memory, \ + (address), \ + (FT_ULong)(size), \ + &error ) ) #define FT_DUP( dst, address, size ) \ FT_MEM_SET_ERROR( FT_MEM_DUP( dst, address, size ) ) diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmmtypes.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmmtypes.h index c4b21d6144ea0..8449e7a010d09 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmmtypes.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmmtypes.h @@ -5,7 +5,7 @@ * OpenType Variations type definitions for internal use * with the multi-masters service (specification). * - * Copyright (C) 2022-2023 by + * Copyright (C) 2022-2024 by * David Turner, Robert Wilhelm, Werner Lemberg, George Williams, and * Dominik Röttsches. * diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftobjs.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftobjs.h index 28bc9b65f0584..a1e93298fdbc4 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftobjs.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftobjs.h @@ -4,7 +4,7 @@ * * The FreeType private base classes (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -604,12 +604,6 @@ FT_BEGIN_HEADER #define FT_FACE_MEMORY( x ) FT_FACE( x )->memory #define FT_FACE_STREAM( x ) FT_FACE( x )->stream -#define FT_SIZE_FACE( x ) FT_SIZE( x )->face -#define FT_SLOT_FACE( x ) FT_SLOT( x )->face - -#define FT_FACE_SLOT( x ) FT_FACE( x )->glyph -#define FT_FACE_SIZE( x ) FT_FACE( x )->size - /************************************************************************** * diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftpsprop.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftpsprop.h index 1d5b287ad2081..4f11aa16ba111 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftpsprop.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftpsprop.h @@ -4,7 +4,7 @@ * * Get and set properties of PostScript drivers (specification). * - * Copyright (C) 2017-2023 by + * Copyright (C) 2017-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftrfork.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftrfork.h index e96459921ef90..05c1d6c48b53e 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftrfork.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftrfork.h @@ -4,7 +4,7 @@ * * Embedded resource forks accessor (specification). * - * Copyright (C) 2004-2023 by + * Copyright (C) 2004-2024 by * Masatake YAMATO and Redhat K.K. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftserv.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftserv.h index 1e85d6d3856a9..8c35dbd713950 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftserv.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftserv.h @@ -4,7 +4,7 @@ * * The FreeType services (specification only). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftstream.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftstream.h index 88e19287c8099..fd52f767ef774 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftstream.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftstream.h @@ -4,7 +4,7 @@ * * Stream handling (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/fttrace.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/fttrace.h index 319fe56fd2d37..42595a29ff33b 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/fttrace.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/fttrace.h @@ -4,7 +4,7 @@ * * Tracing handling (specification only). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -64,6 +64,7 @@ FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */ FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ FT_TRACE_DEF( ttcolr ) /* glyph layer table (ttcolr.c) */ FT_TRACE_DEF( ttcpal ) /* color palette table (ttcpal.c) */ +FT_TRACE_DEF( ttgpos ) /* GPOS handler (ttgpos.c) */ FT_TRACE_DEF( ttsvg ) /* OpenType SVG table (ttsvg.c) */ FT_TRACE_DEF( ttkern ) /* kerning handler (ttkern.c) */ FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftvalid.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftvalid.h index e98ee4e473738..a1312f2aba6c1 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftvalid.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftvalid.h @@ -4,7 +4,7 @@ * * FreeType validation support (specification). * - * Copyright (C) 2004-2023 by + * Copyright (C) 2004-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/psaux.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/psaux.h index dfb1987f86897..745d2cb56b77c 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/psaux.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/psaux.h @@ -5,7 +5,7 @@ * Auxiliary functions and data structures related to PostScript fonts * (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -225,6 +225,7 @@ FT_BEGIN_HEADER typedef enum T1_FieldLocation_ { + T1_FIELD_LOCATION_NONE = 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_LOCATION_FONT_DICT, T1_FIELD_LOCATION_FONT_EXTRA, @@ -249,6 +250,7 @@ FT_BEGIN_HEADER /* structure type used to model object fields */ typedef struct T1_FieldRec_ { + FT_UInt len; /* field identifier length */ const char* ident; /* field identifier */ T1_FieldLocation location; T1_FieldType type; /* type of field */ @@ -273,8 +275,9 @@ FT_BEGIN_HEADER #define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname, _dict ) \ { \ + sizeof ( _ident ) - 1, \ _ident, T1CODE, _type, \ - 0, \ + NULL, \ FT_FIELD_OFFSET( _fname ), \ FT_FIELD_SIZE( _fname ), \ 0, 0, \ @@ -283,6 +286,7 @@ FT_BEGIN_HEADER #define T1_NEW_CALLBACK_FIELD( _ident, _reader, _dict ) \ { \ + sizeof ( _ident ) - 1, \ _ident, T1CODE, T1_FIELD_TYPE_CALLBACK, \ (T1_Field_ParseFunc)_reader, \ 0, 0, \ @@ -292,8 +296,9 @@ FT_BEGIN_HEADER #define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max, _dict ) \ { \ + sizeof ( _ident ) - 1, \ _ident, T1CODE, _type, \ - 0, \ + NULL, \ FT_FIELD_OFFSET( _fname ), \ FT_FIELD_SIZE_DELTA( _fname ), \ _max, \ @@ -303,8 +308,9 @@ FT_BEGIN_HEADER #define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max, _dict ) \ { \ + sizeof ( _ident ) - 1, \ _ident, T1CODE, _type, \ - 0, \ + NULL, \ FT_FIELD_OFFSET( _fname ), \ FT_FIELD_SIZE_DELTA( _fname ), \ _max, 0, \ @@ -354,6 +360,13 @@ FT_BEGIN_HEADER #define T1_FIELD_CALLBACK( _ident, _name, _dict ) \ T1_NEW_CALLBACK_FIELD( _ident, _name, _dict ) +#define T1_FIELD_ZERO \ + { \ + 0, \ + NULL, T1_FIELD_LOCATION_NONE, T1_FIELD_TYPE_NONE, \ + NULL, 0, 0, 0, 0, 0 \ + } + /*************************************************************************/ /*************************************************************************/ diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/pshints.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/pshints.h index ededc4c72e7a1..dba6c7303fdcf 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/pshints.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/pshints.h @@ -6,7 +6,7 @@ * recorders (specification only). These are used to support native * T1/T2 hints in the 'type1', 'cid', and 'cff' font drivers. * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svbdf.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svbdf.h index bf0c1dcc71457..89e9c2e5de80a 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svbdf.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svbdf.h @@ -4,7 +4,7 @@ * * The FreeType BDF services (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcfftl.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcfftl.h index 4a20498ee0cfe..3cb483c344f87 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcfftl.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcfftl.h @@ -4,7 +4,7 @@ * * The FreeType CFF tables loader service (specification). * - * Copyright (C) 2017-2023 by + * Copyright (C) 2017-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcid.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcid.h index 06d0cb8fd62ea..8362cb8724d86 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcid.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcid.h @@ -4,7 +4,7 @@ * * The FreeType CID font services (specification). * - * Copyright (C) 2007-2023 by + * Copyright (C) 2007-2024 by * Derek Clegg and Michael Toftdal. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svfntfmt.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svfntfmt.h index bc45e80568fc7..6b837e79fcd43 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svfntfmt.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svfntfmt.h @@ -4,7 +4,7 @@ * * The FreeType font format service (specification only). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgldict.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgldict.h index 6437abfbf2e8b..6126ec9ada4ab 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgldict.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgldict.h @@ -4,7 +4,7 @@ * * The FreeType glyph dictionary services (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgxval.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgxval.h index 31016afe0d040..29cf552818936 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgxval.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgxval.h @@ -4,7 +4,7 @@ * * FreeType API for validating TrueTypeGX/AAT tables (specification). * - * Copyright (C) 2004-2023 by + * Copyright (C) 2004-2024 by * Masatake YAMATO, Red Hat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svkern.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svkern.h index bcabbc3e68fde..ac1bc30c412f0 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svkern.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svkern.h @@ -4,7 +4,7 @@ * * The FreeType Kerning service (specification). * - * Copyright (C) 2006-2023 by + * Copyright (C) 2006-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmetric.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmetric.h index 167617ebb3d0e..8b3563b25ca4b 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmetric.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmetric.h @@ -4,7 +4,7 @@ * * The FreeType services for metrics variations (specification). * - * Copyright (C) 2016-2023 by + * Copyright (C) 2016-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmm.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmm.h index 7e76ab8324e43..5288fadf3755f 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmm.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmm.h @@ -4,7 +4,7 @@ * * The FreeType Multiple Masters and GX var services (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svotval.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svotval.h index a4683cd5fb648..7aea7ec11f02a 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svotval.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svotval.h @@ -4,7 +4,7 @@ * * The FreeType OpenType validation service (specification). * - * Copyright (C) 2004-2023 by + * Copyright (C) 2004-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpfr.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpfr.h index fd189c7de773b..b2fac6d086b26 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpfr.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpfr.h @@ -4,7 +4,7 @@ * * Internal PFR service functions (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpostnm.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpostnm.h index 2b8f6dfecfb02..d19f3adc6d5a4 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpostnm.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpostnm.h @@ -4,7 +4,7 @@ * * The FreeType PostScript name services (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svprop.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svprop.h index 932ce32e03d78..ba39c0dd4da9e 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svprop.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svprop.h @@ -4,7 +4,7 @@ * * The FreeType property service (specification). * - * Copyright (C) 2012-2023 by + * Copyright (C) 2012-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpscmap.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpscmap.h index 6e599f3aabe40..d4908ee41aa22 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpscmap.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpscmap.h @@ -4,7 +4,7 @@ * * The FreeType PostScript charmap service (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpsinfo.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpsinfo.h index 09c4cdccc5342..2aadcdd02a1bc 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpsinfo.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpsinfo.h @@ -4,7 +4,7 @@ * * The FreeType PostScript info service (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svsfnt.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svsfnt.h index f98df2ef5fe70..9e0f4ff202e99 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svsfnt.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svsfnt.h @@ -4,7 +4,7 @@ * * The FreeType SFNT table loading service (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttcmap.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttcmap.h index 5f9eb02d66558..250886bcc5dba 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttcmap.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttcmap.h @@ -4,7 +4,7 @@ * * The FreeType TrueType/sfnt cmap extra information service. * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * Masatake YAMATO, Redhat K.K., * David Turner, Robert Wilhelm, and Werner Lemberg. * diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svtteng.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svtteng.h index ad577cb2904d5..14967529a9ac7 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svtteng.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svtteng.h @@ -4,7 +4,7 @@ * * The FreeType TrueType engine query service (specification). * - * Copyright (C) 2006-2023 by + * Copyright (C) 2006-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttglyf.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttglyf.h index ca6fff74444b3..f190b3985d021 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttglyf.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttglyf.h @@ -4,7 +4,7 @@ * * The FreeType TrueType glyph service. * - * Copyright (C) 2007-2023 by + * Copyright (C) 2007-2024 by * David Turner. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svwinfnt.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svwinfnt.h index 002923f8c914a..49f3fb7f775be 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svwinfnt.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svwinfnt.h @@ -4,7 +4,7 @@ * * The FreeType Windows FNT/FONT service (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/sfnt.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/sfnt.h index a2d4e15baafde..35e4e73af02f8 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/sfnt.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/sfnt.h @@ -4,7 +4,7 @@ * * High-level 'sfnt' driver interface (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -924,6 +924,7 @@ FT_BEGIN_HEADER /* this field was called `load_kerning' up to version 2.1.10 */ TT_Load_Table_Func load_kern; + TT_Load_Table_Func load_gpos; TT_Load_Table_Func load_gasp; TT_Load_Table_Func load_pclt; @@ -944,6 +945,8 @@ FT_BEGIN_HEADER /* new elements introduced after version 2.1.10 */ + TT_Face_GetKerningFunc get_gpos_kerning; + /* load the font directory, i.e., the offset table and */ /* the table directory */ TT_Load_Table_Func load_font_dir; @@ -1002,6 +1005,7 @@ FT_BEGIN_HEADER load_name_, \ free_name_, \ load_kern_, \ + load_gpos_, \ load_gasp_, \ load_pclt_, \ load_bhed_, \ @@ -1009,6 +1013,7 @@ FT_BEGIN_HEADER get_psname_, \ free_psnames_, \ get_kerning_, \ + get_gpos_kerning_, \ load_font_dir_, \ load_hmtx_, \ load_eblc_, \ @@ -1050,6 +1055,7 @@ FT_BEGIN_HEADER load_name_, \ free_name_, \ load_kern_, \ + load_gpos_, \ load_gasp_, \ load_pclt_, \ load_bhed_, \ @@ -1057,6 +1063,7 @@ FT_BEGIN_HEADER get_psname_, \ free_psnames_, \ get_kerning_, \ + get_gpos_kerning_, \ load_font_dir_, \ load_hmtx_, \ load_eblc_, \ diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/svginterface.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/svginterface.h index f464b2c0583a8..68c99efb10ab8 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/svginterface.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/svginterface.h @@ -4,7 +4,7 @@ * * Interface of ot-svg module (specification only). * - * Copyright (C) 2022-2023 by + * Copyright (C) 2022-2024 by * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/t1types.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/t1types.h index b9c94398fd155..1821ae5cc8390 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/t1types.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/t1types.h @@ -5,7 +5,7 @@ * Basic Type1/Type2 type definitions and interface (specification * only). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -21,7 +21,7 @@ #define T1TYPES_H_ -#include +#include #include #include #include @@ -137,6 +137,54 @@ FT_BEGIN_HEADER } CID_SubrsRec, *CID_Subrs; + /* this structure is used to store the BlendDesignMap entry for an axis */ + typedef struct PS_DesignMap_ + { + FT_Byte num_points; + FT_Long* design_points; + FT_Fixed* blend_points; + + } PS_DesignMapRec, *PS_DesignMap; + + /* backward compatible definition */ + typedef PS_DesignMapRec T1_DesignMap; + + + typedef struct PS_BlendRec_ + { + FT_UInt num_designs; + FT_UInt num_axis; + + FT_String* axis_names[T1_MAX_MM_AXIS]; + FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; + PS_DesignMapRec design_map[T1_MAX_MM_AXIS]; + + FT_Fixed* weight_vector; + FT_Fixed* default_weight_vector; + + PS_FontInfo font_infos[T1_MAX_MM_DESIGNS + 1]; + PS_Private privates [T1_MAX_MM_DESIGNS + 1]; + + FT_ULong blend_bitflags; + + FT_BBox* bboxes [T1_MAX_MM_DESIGNS + 1]; + + /* since 2.3.0 */ + + /* undocumented, optional: the default design instance; */ + /* corresponds to default_weight_vector -- */ + /* num_default_design_vector == 0 means it is not present */ + /* in the font and associated metrics files */ + FT_UInt default_design_vector[T1_MAX_MM_DESIGNS]; + FT_UInt num_default_design_vector; + + } PS_BlendRec, *PS_Blend; + + + /* backward compatible definition */ + typedef PS_BlendRec T1_Blend; + + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/tttypes.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/tttypes.h index b9788c7831ec5..7053e656a7e5d 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/tttypes.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/tttypes.h @@ -5,7 +5,7 @@ * Basic SFNT/TrueType type definitions and interface (specification * only). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -24,6 +24,7 @@ #include #include #include +#include "freetype/fttypes.h" #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include @@ -1581,6 +1582,11 @@ FT_BEGIN_HEADER FT_UInt32 kern_avail_bits; FT_UInt32 kern_order_bits; +#ifdef TT_CONFIG_OPTION_GPOS_KERNING + FT_Byte* gpos_table; + FT_Bool gpos_kerning_available; +#endif + #ifdef TT_CONFIG_OPTION_BDF TT_BDFRec bdf; #endif /* TT_CONFIG_OPTION_BDF */ @@ -1649,9 +1655,9 @@ FT_BEGIN_HEADER { FT_Memory memory; FT_UShort max_points; - FT_Short max_contours; + FT_UShort max_contours; FT_UShort n_points; /* number of points in zone */ - FT_Short n_contours; /* number of contours */ + FT_UShort n_contours; /* number of contours */ FT_Vector* org; /* original point coordinates */ FT_Vector* cur; /* current point coordinates */ diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/wofftypes.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/wofftypes.h index 0c1d8eeaf8c8b..4a169d12f57e5 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/wofftypes.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/wofftypes.h @@ -5,7 +5,7 @@ * Basic WOFF/WOFF2 type definitions and interface (specification * only). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/otsvg.h b/src/java.desktop/share/native/libfreetype/include/freetype/otsvg.h index bfe9a6ab74e47..9d356938cc70e 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/otsvg.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/otsvg.h @@ -4,7 +4,7 @@ * * Interface for OT-SVG support related things (specification). * - * Copyright (C) 2022-2023 by + * Copyright (C) 2022-2024 by * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/t1tables.h b/src/java.desktop/share/native/libfreetype/include/freetype/t1tables.h index 1aecfbbd902f2..fbd558aa34d05 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/t1tables.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/t1tables.h @@ -5,7 +5,7 @@ * Basic Type 1/Type 2 tables definitions and interface (specification * only). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -269,64 +269,6 @@ FT_BEGIN_HEADER /* */ - /* maximum number of Multiple Masters designs, as defined in the spec */ -#define T1_MAX_MM_DESIGNS 16 - - /* maximum number of Multiple Masters axes, as defined in the spec */ -#define T1_MAX_MM_AXIS 4 - - /* maximum number of elements in a design map */ -#define T1_MAX_MM_MAP_POINTS 20 - - - /* this structure is used to store the BlendDesignMap entry for an axis */ - typedef struct PS_DesignMap_ - { - FT_Byte num_points; - FT_Long* design_points; - FT_Fixed* blend_points; - - } PS_DesignMapRec, *PS_DesignMap; - - /* backward compatible definition */ - typedef PS_DesignMapRec T1_DesignMap; - - - typedef struct PS_BlendRec_ - { - FT_UInt num_designs; - FT_UInt num_axis; - - FT_String* axis_names[T1_MAX_MM_AXIS]; - FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; - PS_DesignMapRec design_map[T1_MAX_MM_AXIS]; - - FT_Fixed* weight_vector; - FT_Fixed* default_weight_vector; - - PS_FontInfo font_infos[T1_MAX_MM_DESIGNS + 1]; - PS_Private privates [T1_MAX_MM_DESIGNS + 1]; - - FT_ULong blend_bitflags; - - FT_BBox* bboxes [T1_MAX_MM_DESIGNS + 1]; - - /* since 2.3.0 */ - - /* undocumented, optional: the default design instance; */ - /* corresponds to default_weight_vector -- */ - /* num_default_design_vector == 0 means it is not present */ - /* in the font and associated metrics files */ - FT_UInt default_design_vector[T1_MAX_MM_DESIGNS]; - FT_UInt num_default_design_vector; - - } PS_BlendRec, *PS_Blend; - - - /* backward compatible definition */ - typedef PS_BlendRec T1_Blend; - - /************************************************************************** * * @struct: diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ttnameid.h b/src/java.desktop/share/native/libfreetype/include/freetype/ttnameid.h index e31c68b9baf34..d5d470e380f44 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/ttnameid.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/ttnameid.h @@ -4,7 +4,7 @@ * * TrueType name ID definitions (specification only). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/tttables.h b/src/java.desktop/share/native/libfreetype/include/freetype/tttables.h index a9f60e76201b1..2cf0ff1bc61e4 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/tttables.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/tttables.h @@ -5,7 +5,7 @@ * Basic SFNT/TrueType tables definitions and interface * (specification only). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -838,8 +838,9 @@ FT_BEGIN_HEADER * The target charmap. * * @return: - * The format of `charmap`. If `charmap` doesn't belong to an SFNT face, - * return -1. + * The format of `charmap`. If `charmap` doesn't belong to an SFNT face + * (including the synthetic Unicode charmap sometimes created by + * FreeType), return -1. */ FT_EXPORT( FT_Long ) FT_Get_CMap_Format( FT_CharMap charmap ); diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/tttags.h b/src/java.desktop/share/native/libfreetype/include/freetype/tttags.h index 9bf4fca23fb3a..da0af5d3f2353 100644 --- a/src/java.desktop/share/native/libfreetype/include/freetype/tttags.h +++ b/src/java.desktop/share/native/libfreetype/include/freetype/tttags.h @@ -4,7 +4,7 @@ * * Tags for TrueType and OpenType tables (specification only). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/include/ft2build.h b/src/java.desktop/share/native/libfreetype/include/ft2build.h index 58491ceea1fb8..d3d7685039c4e 100644 --- a/src/java.desktop/share/native/libfreetype/include/ft2build.h +++ b/src/java.desktop/share/native/libfreetype/include/ft2build.h @@ -4,7 +4,7 @@ * * FreeType 2 build and setup macros. * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.c b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.c index d7655b9b99e16..ea83969cdc973 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.c +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.c @@ -7,7 +7,7 @@ * * Auto-fitter data for blue strings (body). * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.cin b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.cin index d561c5093b78b..d2270fac74438 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.cin +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.cin @@ -4,7 +4,7 @@ * * Auto-fitter data for blue strings (body). * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.dat b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.dat index 8299baa2591d3..88bab2632abef 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.dat +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.dat @@ -2,7 +2,7 @@ // // Auto-fitter data for blue strings. // -// Copyright (C) 2013-2023 by +// Copyright (C) 2013-2024 by // David Turner, Robert Wilhelm, and Werner Lemberg. // // This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.h b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.h index 76f2f47cb0083..2aa9d0984ef75 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.h @@ -7,7 +7,7 @@ * * Auto-fitter data for blue strings (specification). * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.hin b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.hin index 6a31298e65fde..38031505a85bf 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.hin +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.hin @@ -4,7 +4,7 @@ * * Auto-fitter data for blue strings (specification). * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.c b/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.c index f414289adcd25..869b60487c21c 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.c +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.c @@ -4,7 +4,7 @@ * * Auto-fitter hinting routines for CJK writing system (body). * - * Copyright (C) 2006-2023 by + * Copyright (C) 2006-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.h b/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.h index f380ef6e03211..bc5aaf12e6ee8 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.h @@ -4,7 +4,7 @@ * * Auto-fitter hinting routines for CJK writing system (specification). * - * Copyright (C) 2006-2023 by + * Copyright (C) 2006-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -84,7 +84,7 @@ FT_BEGIN_HEADER /* used for horizontal metrics too for CJK */ FT_Bool control_overshoot; FT_UInt blue_count; - AF_CJKBlueRec blues[AF_BLUE_STRINGSET_MAX]; + AF_CJKBlueRec blues[AF_BLUE_STRINGSET_MAX_LEN]; FT_Fixed org_scale; FT_Pos org_delta; diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afcover.h b/src/java.desktop/share/native/libfreetype/src/autofit/afcover.h index 102ed42782872..7980cf2e97969 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afcover.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afcover.h @@ -4,7 +4,7 @@ * * Auto-fitter coverages (specification only). * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.c b/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.c index a4629b528dc63..ad667d2edc796 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.c +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.c @@ -5,7 +5,7 @@ * Auto-fitter dummy routines to be used if no hinting should be * performed (body). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.h b/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.h index a7af3f62c9eca..613c2f88a3898 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.h @@ -5,7 +5,7 @@ * Auto-fitter dummy routines to be used if no hinting should be * performed (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/aferrors.h b/src/java.desktop/share/native/libfreetype/src/autofit/aferrors.h index 88faf05c95005..ae584ff06db62 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/aferrors.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/aferrors.h @@ -4,7 +4,7 @@ * * Autofitter error codes (specification only). * - * Copyright (C) 2005-2023 by + * Copyright (C) 2005-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.c b/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.c index b1957570f03bf..b7403fa65e1b5 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.c +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.c @@ -4,7 +4,7 @@ * * Auto-fitter routines to compute global hinting values (body). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.h b/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.h index 66170e419ddc9..ddb54c89b2769 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.h @@ -5,7 +5,7 @@ * Auto-fitter routines to compute global hinting values * (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afhints.c b/src/java.desktop/share/native/libfreetype/src/autofit/afhints.c index e4a378fbf74ca..96ffe343aa441 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afhints.c +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afhints.c @@ -4,7 +4,7 @@ * * Auto-fitter hinting routines (body). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -979,8 +979,8 @@ /* compute coordinates & Bezier flags, next and prev */ { FT_Vector* vec = outline->points; - char* tag = outline->tags; - FT_Short endpoint = outline->contours[0]; + FT_Byte* tag = outline->tags; + FT_UShort endpoint = outline->contours[0]; AF_Point end = points + endpoint; AF_Point prev = end; FT_Int contour_index = 0; @@ -1046,16 +1046,16 @@ /* set up the contours array */ { - AF_Point* contour = hints->contours; - AF_Point* contour_limit = contour + hints->num_contours; - short* end = outline->contours; - short idx = 0; + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + FT_UShort* end = outline->contours; + FT_Int idx = 0; for ( ; contour < contour_limit; contour++, end++ ) { contour[0] = points + idx; - idx = (short)( end[0] + 1 ); + idx = *end + 1; } } @@ -1292,7 +1292,7 @@ AF_Point point = hints->points; AF_Point limit = point + hints->num_points; FT_Vector* vec = outline->points; - char* tag = outline->tags; + FT_Byte* tag = outline->tags; for ( ; point < limit; point++, vec++, tag++ ) diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afhints.h b/src/java.desktop/share/native/libfreetype/src/autofit/afhints.h index d1cf9529bf12d..76fe83006a52a 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afhints.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afhints.h @@ -4,7 +4,7 @@ * * Auto-fitter hinting routines (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afindic.c b/src/java.desktop/share/native/libfreetype/src/autofit/afindic.c index 7fb12c63d5a35..c6d23efd86f58 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afindic.c +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afindic.c @@ -4,7 +4,7 @@ * * Auto-fitter hinting routines for Indic writing system (body). * - * Copyright (C) 2007-2023 by + * Copyright (C) 2007-2024 by * Rahul Bhalerao , . * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afindic.h b/src/java.desktop/share/native/libfreetype/src/autofit/afindic.h index 3eb67f63b0013..a7f73f25153a1 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afindic.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afindic.h @@ -5,7 +5,7 @@ * Auto-fitter hinting routines for Indic writing system * (specification). * - * Copyright (C) 2007-2023 by + * Copyright (C) 2007-2024 by * Rahul Bhalerao , . * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.c b/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.c index b86367aa94dc6..89287f7ea5a65 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.c +++ b/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.c @@ -4,7 +4,7 @@ * * Auto-fitter hinting routines for latin writing system (body). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -981,7 +981,7 @@ /* `ref' and `shoot' values of two blue zones must not overlap */ FT_UInt i; - AF_LatinBlue blue_sorted[AF_BLUE_STRINGSET_MAX_LEN + 2]; + AF_LatinBlue blue_sorted[AF_BLUE_STRINGSET_MAX_LEN]; for ( i = 0; i < axis->blue_count; i++ ) @@ -1263,10 +1263,9 @@ max_height = FT_MAX( max_height, -Axis->blues[nn].descender ); } - dist = FT_ABS( FT_MulFix( max_height, new_scale - scale ) ); - dist &= ~127; + dist = FT_MulFix( max_height, new_scale - scale ); - if ( dist == 0 ) + if ( -128 < dist && dist < 128 ) { FT_TRACE5(( "af_latin_metrics_scale_dim:" " x height alignment (style `%s'):\n", diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.h b/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.h index 31aa91d3bdb05..54e5061502147 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.h @@ -5,7 +5,7 @@ * Auto-fitter hinting routines for latin writing system * (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -98,7 +98,7 @@ FT_BEGIN_HEADER /* ignored for horizontal metrics */ FT_UInt blue_count; - AF_LatinBlueRec blues[AF_BLUE_STRINGSET_MAX]; + AF_LatinBlueRec blues[AF_BLUE_STRINGSET_MAX_LEN]; FT_Fixed org_scale; FT_Pos org_delta; diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afloader.c b/src/java.desktop/share/native/libfreetype/src/autofit/afloader.c index 7c47d562af66f..af1d59a689696 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afloader.c +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afloader.c @@ -4,7 +4,7 @@ * * Auto-fitter glyph loading routines (body). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afloader.h b/src/java.desktop/share/native/libfreetype/src/autofit/afloader.h index e4e197e374fd3..99f0e15f92b64 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afloader.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afloader.h @@ -4,7 +4,7 @@ * * Auto-fitter glyph loading routines (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.c b/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.c index 20a6b96bc4ff4..726f6ca2b78b4 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.c +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.c @@ -4,7 +4,7 @@ * * Auto-fitter module implementation (body). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -438,7 +438,7 @@ AF_Module module = (AF_Module)module_; FT_Error error = FT_Err_Ok; - FT_Memory memory = module->root.library->memory; + FT_Memory memory = module->root.memory; #ifdef FT_DEBUG_AUTOFIT diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.h b/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.h index 4b8b4562c67c7..91a1abfef1fd7 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.h @@ -4,7 +4,7 @@ * * Auto-fitter module implementation (specification). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afranges.c b/src/java.desktop/share/native/libfreetype/src/autofit/afranges.c index cfcaf340a79e6..007b43281898a 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afranges.c +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afranges.c @@ -4,7 +4,7 @@ * * Auto-fitter Unicode script ranges (body). * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afranges.h b/src/java.desktop/share/native/libfreetype/src/autofit/afranges.h index 5775738bc0bb0..813b3ee78ef66 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afranges.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afranges.h @@ -4,7 +4,7 @@ * * Auto-fitter Unicode script ranges (specification). * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afscript.h b/src/java.desktop/share/native/libfreetype/src/autofit/afscript.h index 3a101937d7032..0a83d771501f5 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afscript.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afscript.h @@ -4,7 +4,7 @@ * * Auto-fitter scripts (specification only). * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.c b/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.c index abc6f1d292d42..df0f46ada898a 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.c +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.c @@ -4,7 +4,7 @@ * * HarfBuzz interface for accessing OpenType features (body). * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.h b/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.h index 054a18ffbc2d3..2eb03bb5d9883 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.h @@ -4,7 +4,7 @@ * * HarfBuzz interface for accessing OpenType features (specification). * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afstyles.h b/src/java.desktop/share/native/libfreetype/src/autofit/afstyles.h index 73ebef01716c3..7a33f37a85684 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afstyles.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afstyles.h @@ -4,7 +4,7 @@ * * Auto-fitter styles (specification only). * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/aftypes.h b/src/java.desktop/share/native/libfreetype/src/autofit/aftypes.h index 661519449653d..27e4185e9f857 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/aftypes.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/aftypes.h @@ -4,7 +4,7 @@ * * Auto-fitter types (specification only). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afws-decl.h b/src/java.desktop/share/native/libfreetype/src/autofit/afws-decl.h index 48c888afed88e..b78745af74e9e 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afws-decl.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afws-decl.h @@ -4,7 +4,7 @@ * * Auto-fitter writing system declarations (specification only). * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afws-iter.h b/src/java.desktop/share/native/libfreetype/src/autofit/afws-iter.h index a0a686f8cee7f..c86d609a35231 100644 --- a/src/java.desktop/share/native/libfreetype/src/autofit/afws-iter.h +++ b/src/java.desktop/share/native/libfreetype/src/autofit/afws-iter.h @@ -4,7 +4,7 @@ * * Auto-fitter writing systems iterator (specification only). * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftadvanc.c b/src/java.desktop/share/native/libfreetype/src/base/ftadvanc.c index de25476fe9287..717f7d08b3549 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftadvanc.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftadvanc.c @@ -4,7 +4,7 @@ * * Quick computation of advance widths (body). * - * Copyright (C) 2008-2023 by + * Copyright (C) 2008-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftbase.h b/src/java.desktop/share/native/libfreetype/src/base/ftbase.h index 00790d3b226f6..1d98b26dd5109 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftbase.h +++ b/src/java.desktop/share/native/libfreetype/src/base/ftbase.h @@ -4,7 +4,7 @@ * * Private functions used in the `base' module (specification). * - * Copyright (C) 2008-2023 by + * Copyright (C) 2008-2024 by * David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftbbox.c b/src/java.desktop/share/native/libfreetype/src/base/ftbbox.c index 385fea4040103..d6aa5d56df878 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftbbox.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftbbox.c @@ -4,7 +4,7 @@ * * FreeType bbox computation (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used @@ -489,7 +489,7 @@ return FT_THROW( Invalid_Outline ); /* if outline is empty, return (0,0,0,0) */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) + if ( outline->n_points == 0 || outline->n_contours == 0 ) { abbox->xMin = abbox->xMax = 0; abbox->yMin = abbox->yMax = 0; diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftbitmap.c b/src/java.desktop/share/native/libfreetype/src/base/ftbitmap.c index 1c93648dcbc88..4be145679fd50 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftbitmap.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftbitmap.c @@ -4,7 +4,7 @@ * * FreeType utility functions for bitmaps (body). * - * Copyright (C) 2004-2023 by + * Copyright (C) 2004-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftcalc.c b/src/java.desktop/share/native/libfreetype/src/base/ftcalc.c index c5bc7e3b14eed..92de09ed8770c 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftcalc.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftcalc.c @@ -4,7 +4,7 @@ * * Arithmetic computations (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -69,13 +69,15 @@ /* transfer sign, leaving a positive number; */ /* we need an unsigned value to safely negate INT_MIN (or LONG_MIN) */ -#define FT_MOVE_SIGN( x, x_unsigned, s ) \ - FT_BEGIN_STMNT \ - if ( x < 0 ) \ - { \ - x_unsigned = 0U - (x_unsigned); \ - s = -s; \ - } \ +#define FT_MOVE_SIGN( utype, x, x_unsigned, s ) \ + FT_BEGIN_STMNT \ + if ( x < 0 ) \ + { \ + x_unsigned = 0U - (utype)x; \ + s = -s; \ + } \ + else \ + x_unsigned = (utype)x; \ FT_END_STMNT /* The following three functions are available regardless of whether */ @@ -179,13 +181,9 @@ FT_Long d_; - a = (FT_UInt64)a_; - b = (FT_UInt64)b_; - c = (FT_UInt64)c_; - - FT_MOVE_SIGN( a_, a, s ); - FT_MOVE_SIGN( b_, b, s ); - FT_MOVE_SIGN( c_, c, s ); + FT_MOVE_SIGN( FT_UInt64, a_, a, s ); + FT_MOVE_SIGN( FT_UInt64, b_, b, s ); + FT_MOVE_SIGN( FT_UInt64, c_, c, s ); d = c > 0 ? ( a * b + ( c >> 1 ) ) / c : 0x7FFFFFFFUL; @@ -208,13 +206,9 @@ FT_Long d_; - a = (FT_UInt64)a_; - b = (FT_UInt64)b_; - c = (FT_UInt64)c_; - - FT_MOVE_SIGN( a_, a, s ); - FT_MOVE_SIGN( b_, b, s ); - FT_MOVE_SIGN( c_, c, s ); + FT_MOVE_SIGN( FT_UInt64, a_, a, s ); + FT_MOVE_SIGN( FT_UInt64, b_, b, s ); + FT_MOVE_SIGN( FT_UInt64, c_, c, s ); d = c > 0 ? a * b / c : 0x7FFFFFFFUL; @@ -257,11 +251,8 @@ FT_Long q_; - a = (FT_UInt64)a_; - b = (FT_UInt64)b_; - - FT_MOVE_SIGN( a_, a, s ); - FT_MOVE_SIGN( b_, b, s ); + FT_MOVE_SIGN( FT_UInt64, a_, a, s ); + FT_MOVE_SIGN( FT_UInt64, b_, b, s ); q = b > 0 ? ( ( a << 16 ) + ( b >> 1 ) ) / b : 0x7FFFFFFFUL; @@ -422,13 +413,9 @@ /* XXX: this function does not allow 64-bit arguments */ - a = (FT_UInt32)a_; - b = (FT_UInt32)b_; - c = (FT_UInt32)c_; - - FT_MOVE_SIGN( a_, a, s ); - FT_MOVE_SIGN( b_, b, s ); - FT_MOVE_SIGN( c_, c, s ); + FT_MOVE_SIGN( FT_UInt32, a_, a, s ); + FT_MOVE_SIGN( FT_UInt32, b_, b, s ); + FT_MOVE_SIGN( FT_UInt32, c_, c, s ); if ( c == 0 ) a = 0x7FFFFFFFUL; @@ -470,13 +457,9 @@ /* XXX: this function does not allow 64-bit arguments */ - a = (FT_UInt32)a_; - b = (FT_UInt32)b_; - c = (FT_UInt32)c_; - - FT_MOVE_SIGN( a_, a, s ); - FT_MOVE_SIGN( b_, b, s ); - FT_MOVE_SIGN( c_, c, s ); + FT_MOVE_SIGN( FT_UInt32, a_, a, s ); + FT_MOVE_SIGN( FT_UInt32, b_, b, s ); + FT_MOVE_SIGN( FT_UInt32, c_, c, s ); if ( c == 0 ) a = 0x7FFFFFFFUL; @@ -575,11 +558,8 @@ /* XXX: this function does not allow 64-bit arguments */ - a = (FT_UInt32)a_; - b = (FT_UInt32)b_; - - FT_MOVE_SIGN( a_, a, s ); - FT_MOVE_SIGN( b_, b, s ); + FT_MOVE_SIGN( FT_UInt32, a_, a, s ); + FT_MOVE_SIGN( FT_UInt32, b_, b, s ); if ( a + ( b >> 8 ) <= 8190UL ) a = ( a * b + 0x8000UL ) >> 16; @@ -614,11 +594,8 @@ /* XXX: this function does not allow 64-bit arguments */ - a = (FT_UInt32)a_; - b = (FT_UInt32)b_; - - FT_MOVE_SIGN( a_, a, s ); - FT_MOVE_SIGN( b_, b, s ); + FT_MOVE_SIGN( FT_UInt32, a_, a, s ); + FT_MOVE_SIGN( FT_UInt32, b_, b, s ); if ( b == 0 ) { @@ -829,11 +806,8 @@ FT_Int sx = 1, sy = 1, shift; - x = (FT_UInt32)x_; - y = (FT_UInt32)y_; - - FT_MOVE_SIGN( x_, x, sx ); - FT_MOVE_SIGN( y_, y, sy ); + FT_MOVE_SIGN( FT_UInt32, x_, x, sx ); + FT_MOVE_SIGN( FT_UInt32, y_, y, sy ); /* trivial cases */ if ( x == 0 ) @@ -913,43 +887,71 @@ } -#if 0 - /* documentation is in ftcalc.h */ - FT_BASE_DEF( FT_Int32 ) - FT_SqrtFixed( FT_Int32 x ) + FT_BASE_DEF( FT_UInt32 ) + FT_SqrtFixed( FT_UInt32 v ) { - FT_UInt32 root, rem_hi, rem_lo, test_div; - FT_Int count; - + if ( v == 0 ) + return 0; - root = 0; +#ifndef FT_INT64 - if ( x > 0 ) + /* Algorithm by Christophe Meessen (1993) with overflow fixed and */ + /* rounding added. Any unsigned fixed 16.16 argument is acceptable. */ + /* However, this algorithm is slower than the Babylonian method with */ + /* a good initial guess. We only use it for large 32-bit values when */ + /* 64-bit computations are not desirable. */ + else if ( v > 0x10000U ) { - rem_hi = 0; - rem_lo = (FT_UInt32)x; - count = 24; + FT_UInt32 r = v >> 1; + FT_UInt32 q = ( v & 1 ) << 15; + FT_UInt32 b = 0x20000000; + FT_UInt32 t; + + do { - rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 ); - rem_lo <<= 2; - root <<= 1; - test_div = ( root << 1 ) + 1; - - if ( rem_hi >= test_div ) + t = q + b; + if ( r >= t ) { - rem_hi -= test_div; - root += 1; + r -= t; + q = t + b; /* equivalent to q += 2*b */ } - } while ( --count ); + r <<= 1; + b >>= 1; + + } while ( b > 0x10 ); /* exactly 25 cycles */ + + return ( q + 0x40 ) >> 7; } + else + { + FT_UInt32 r = ( v << 16 ) - 1; - return (FT_Int32)root; - } +#else /* FT_INT64 */ -#endif /* 0 */ + else + { + FT_UInt64 r = ( (FT_UInt64)v << 16 ) - 1; + +#endif /* FT_INT64 */ + + FT_UInt32 q = 1 << ( ( 17 + FT_MSB( v ) ) >> 1 ); + FT_UInt32 t; + + + /* Babylonian method with rounded-up division */ + do + { + t = q; + q = ( t + (FT_UInt32)( r / t ) + 1 ) >> 1; + + } while ( q != t ); /* less than 6 cycles */ + + return q; + } + } /* documentation is in ftcalc.h */ @@ -1094,11 +1096,8 @@ FT_UInt32 factor; - scalar = (FT_UInt32)s[i]; - factor = (FT_UInt32)f[i]; - - FT_MOVE_SIGN( s[i], scalar, sign ); - FT_MOVE_SIGN( f[i], factor, sign ); + FT_MOVE_SIGN( FT_UInt32, s[i], scalar, sign ); + FT_MOVE_SIGN( FT_UInt32, f[i], factor, sign ); ft_multo64( scalar, factor, &multResult ); diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftcid.c b/src/java.desktop/share/native/libfreetype/src/base/ftcid.c index 866cd23e91b59..4f2deb19a053f 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftcid.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftcid.c @@ -4,7 +4,7 @@ * * FreeType API for accessing CID font information. * - * Copyright (C) 2007-2023 by + * Copyright (C) 2007-2024 by * Derek Clegg and Michael Toftdal. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftcolor.c b/src/java.desktop/share/native/libfreetype/src/base/ftcolor.c index bcd6e893d4a57..c6bf2a3cd1a44 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftcolor.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftcolor.c @@ -4,7 +4,7 @@ * * FreeType's glyph color management (body). * - * Copyright (C) 2018-2023 by + * Copyright (C) 2018-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftdbgmem.c b/src/java.desktop/share/native/libfreetype/src/base/ftdbgmem.c index 8fab50dd017e6..902a5dc8bbce4 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftdbgmem.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftdbgmem.c @@ -4,7 +4,7 @@ * * Memory debugger (body). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftdebug.c b/src/java.desktop/share/native/libfreetype/src/base/ftdebug.c index 61c4563b0c433..11307eaace4e1 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftdebug.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftdebug.c @@ -4,7 +4,7 @@ * * Debugging and logging component (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftfntfmt.c b/src/java.desktop/share/native/libfreetype/src/base/ftfntfmt.c index 0b41f7cc83d00..77b4089e7e270 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftfntfmt.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftfntfmt.c @@ -4,7 +4,7 @@ * * FreeType utility file for font formats (body). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftfstype.c b/src/java.desktop/share/native/libfreetype/src/base/ftfstype.c index ea24e64c6ea92..1565c3b7e25ad 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftfstype.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftfstype.c @@ -4,7 +4,7 @@ * * FreeType utility file to access FSType data (body). * - * Copyright (C) 2008-2023 by + * Copyright (C) 2008-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftgasp.c b/src/java.desktop/share/native/libfreetype/src/base/ftgasp.c index 29b7b08b787c3..c63d30e978c61 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftgasp.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftgasp.c @@ -4,7 +4,7 @@ * * Access of TrueType's `gasp' table (body). * - * Copyright (C) 2007-2023 by + * Copyright (C) 2007-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftgloadr.c b/src/java.desktop/share/native/libfreetype/src/base/ftgloadr.c index 9823d09e41afa..484d98f1722a9 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftgloadr.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftgloadr.c @@ -4,7 +4,7 @@ * * The FreeType glyph loader (body). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg * * This file is part of the FreeType project, and may only be used, @@ -355,34 +355,25 @@ FT_BASE_DEF( void ) FT_GlyphLoader_Add( FT_GlyphLoader loader ) { - FT_GlyphLoad base; - FT_GlyphLoad current; - - FT_Int n_curr_contours; - FT_Int n_base_points; - FT_Int n; + FT_Outline* base; + FT_Outline* current; + FT_Int n; if ( !loader ) return; - base = &loader->base; - current = &loader->current; - - n_curr_contours = current->outline.n_contours; - n_base_points = base->outline.n_points; + base = &loader->base.outline; + current = &loader->current.outline; - base->outline.n_points = - (short)( base->outline.n_points + current->outline.n_points ); - base->outline.n_contours = - (short)( base->outline.n_contours + current->outline.n_contours ); + /* adjust contours count in newest outline */ + for ( n = 0; n < current->n_contours; n++ ) + current->contours[n] += base->n_points; - base->num_subglyphs += current->num_subglyphs; + base->n_points += current->n_points; + base->n_contours += current->n_contours; - /* adjust contours count in newest outline */ - for ( n = 0; n < n_curr_contours; n++ ) - current->outline.contours[n] = - (short)( current->outline.contours[n] + n_base_points ); + loader->base.num_subglyphs += loader->current.num_subglyphs; /* prepare for another new glyph image */ FT_GlyphLoader_Prepare( loader ); diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftglyph.c b/src/java.desktop/share/native/libfreetype/src/base/ftglyph.c index 393d4949f849d..1b5849f99afa1 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftglyph.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftglyph.c @@ -4,7 +4,7 @@ * * FreeType convenience functions to handle glyphs (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftinit.c b/src/java.desktop/share/native/libfreetype/src/base/ftinit.c index c9c71d24bf961..9a6c00e13efaf 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftinit.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftinit.c @@ -4,7 +4,7 @@ * * FreeType initialization layer (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftlcdfil.c b/src/java.desktop/share/native/libfreetype/src/base/ftlcdfil.c index 6c3fd66e0bb15..1e69d4da70f51 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftlcdfil.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftlcdfil.c @@ -4,7 +4,7 @@ * * FreeType API for color filtering of subpixel bitmap glyphs (body). * - * Copyright (C) 2006-2023 by + * Copyright (C) 2006-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftmac.c b/src/java.desktop/share/native/libfreetype/src/base/ftmac.c index 492d0553845dc..e8e35627b50c5 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftmac.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftmac.c @@ -8,7 +8,7 @@ * This file is for Mac OS X only; see builds/mac/ftoldmac.c for * classic platforms built by MPW. * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -812,6 +812,7 @@ ResourceIndex res_index; Handle fond; short num_faces_in_res; + FT_Long count; if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) ) @@ -821,8 +822,10 @@ if ( ResError() ) return FT_THROW( Cannot_Open_Resource ); + res_index = 1; num_faces_in_res = 0; - for ( res_index = 1; ; res_index++ ) + count = face_index; + while ( count >= 0 ) { short num_faces_in_fond; @@ -834,15 +837,21 @@ num_faces_in_fond = count_faces( fond, pathname ); num_faces_in_res += num_faces_in_fond; - if ( 0 <= face_index && face_index < num_faces_in_fond && error ) - error = FT_New_Face_From_FOND( library, fond, face_index, aface ); + if ( count < num_faces_in_fond ) + error = FT_New_Face_From_FOND( library, fond, count, aface ); - face_index -= num_faces_in_fond; + res_index++; + count -= num_faces_in_fond; } CloseResFile( res_ref ); + if ( !error && aface && *aface ) - (*aface)->num_faces = num_faces_in_res; + { + (*aface)->num_faces = num_faces_in_res; + (*aface)->face_index = face_index; + } + return error; } diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftmm.c b/src/java.desktop/share/native/libfreetype/src/base/ftmm.c index 9e2dd7ee79ddc..cc4ca22fba3ba 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftmm.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftmm.c @@ -4,7 +4,7 @@ * * Multiple Master font support (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftobjs.c b/src/java.desktop/share/native/libfreetype/src/base/ftobjs.c index 89a25bc732d6f..9b97820c379ec 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftobjs.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftobjs.c @@ -4,7 +4,7 @@ * * The FreeType private base classes (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -2302,7 +2302,10 @@ face_index_internal, aface ); FT_FREE( data_offsets ); if ( !error ) - (*aface)->num_faces = count; + { + (*aface)->num_faces = count; + (*aface)->face_index = face_index_internal; + } } return error; @@ -5791,7 +5794,7 @@ ttface = (TT_Face)face; sfnt = (SFNT_Service)ttface->sfnt; - if ( sfnt->get_colr_layer ) + if ( sfnt->get_colr_glyph_paint ) return sfnt->get_colr_glyph_paint( ttface, base_glyph, root_transform, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftoutln.c b/src/java.desktop/share/native/libfreetype/src/base/ftoutln.c index 134f39d2b1fa0..ef699b3c7cd39 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftoutln.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftoutln.c @@ -4,7 +4,7 @@ * * FreeType outline management (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -53,7 +53,7 @@ FT_Vector* point; FT_Vector* limit; - char* tags; + FT_Byte* tags; FT_Error error; @@ -332,8 +332,8 @@ FT_NEW_ARRAY( anoutline->contours, numContours ) ) goto Fail; - anoutline->n_points = (FT_Short)numPoints; - anoutline->n_contours = (FT_Short)numContours; + anoutline->n_points = (FT_UShort)numPoints; + anoutline->n_contours = (FT_UShort)numContours; anoutline->flags |= FT_OUTLINE_OWNER; return FT_Err_Ok; @@ -359,12 +359,14 @@ FT_Int n; + FT_TRACE5(( "FT_Outline_Check: contours = %d, points = %d\n", + n_contours, n_points )); /* empty glyph? */ if ( n_points == 0 && n_contours == 0 ) return FT_Err_Ok; /* check point and contour counts */ - if ( n_points <= 0 || n_contours <= 0 ) + if ( n_points == 0 || n_contours == 0 ) goto Bad; end0 = -1; @@ -576,13 +578,13 @@ /* reverse tags table */ { - char* p = outline->tags + first; - char* q = outline->tags + last; + FT_Byte* p = outline->tags + first; + FT_Byte* q = outline->tags + last; while ( p < q ) { - char swap; + FT_Byte swap; swap = *p; diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftpatent.c b/src/java.desktop/share/native/libfreetype/src/base/ftpatent.c index cb5efadffb1df..2055757e023cd 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftpatent.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftpatent.c @@ -5,7 +5,7 @@ * FreeType API for checking patented TrueType bytecode instructions * (body). Obsolete, retained for backward compatibility. * - * Copyright (C) 2007-2023 by + * Copyright (C) 2007-2024 by * David Turner. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftpsprop.c b/src/java.desktop/share/native/libfreetype/src/base/ftpsprop.c index cefdf489d7f68..37a6cee6cc9ab 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftpsprop.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftpsprop.c @@ -5,7 +5,7 @@ * Get and set properties of PostScript drivers (body). * See `ftdriver.h' for available properties. * - * Copyright (C) 2017-2023 by + * Copyright (C) 2017-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftrfork.c b/src/java.desktop/share/native/libfreetype/src/base/ftrfork.c index 2ab430195f20b..dc9b043d8bb5b 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftrfork.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftrfork.c @@ -4,7 +4,7 @@ * * Embedded resource forks accessor (body). * - * Copyright (C) 2004-2023 by + * Copyright (C) 2004-2024 by * Masatake YAMATO and Redhat K.K. * * FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftsnames.c b/src/java.desktop/share/native/libfreetype/src/base/ftsnames.c index 1917a3f1dffbd..f7231fd61ccde 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftsnames.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftsnames.c @@ -7,7 +7,7 @@ * * This is _not_ used to retrieve glyph names! * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftstream.c b/src/java.desktop/share/native/libfreetype/src/base/ftstream.c index 64826acebe52a..6672224612820 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftstream.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftstream.c @@ -4,7 +4,7 @@ * * I/O stream support (body). * - * Copyright (C) 2000-2023 by + * Copyright (C) 2000-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -763,10 +763,10 @@ case ft_frame_bytes: /* read a byte sequence */ case ft_frame_skip: /* skip some bytes */ { - FT_UInt len = fields->size; + FT_Offset len = fields->size; - if ( cursor + len > stream->limit ) + if ( len > (FT_Offset)( stream->limit - cursor ) ) { error = FT_THROW( Invalid_Stream_Operation ); goto Exit; @@ -830,7 +830,7 @@ goto Exit; } - /* now, compute the signed value is necessary */ + /* now, compute the signed value if necessary */ if ( fields->value & FT_FRAME_OP_SIGNED ) value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift ); diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftstroke.c b/src/java.desktop/share/native/libfreetype/src/base/ftstroke.c index 92f1e43080fdc..64f46ce43e76c 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftstroke.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftstroke.c @@ -4,7 +4,7 @@ * * FreeType path stroker (body). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -711,7 +711,7 @@ { FT_UInt count = border->num_points; FT_Byte* read = border->tags; - FT_Byte* write = (FT_Byte*)outline->tags + outline->n_points; + FT_Byte* write = outline->tags + outline->n_points; for ( ; count > 0; count--, read++, write++ ) @@ -727,10 +727,10 @@ /* copy contours */ { - FT_UInt count = border->num_points; - FT_Byte* tags = border->tags; - FT_Short* write = outline->contours + outline->n_contours; - FT_Short idx = (FT_Short)outline->n_points; + FT_UInt count = border->num_points; + FT_Byte* tags = border->tags; + FT_UShort* write = outline->contours + outline->n_contours; + FT_UShort idx = outline->n_points; for ( ; count > 0; count--, tags++, idx++ ) @@ -743,7 +743,7 @@ } } - outline->n_points += (short)border->num_points; + outline->n_points += (FT_UShort)border->num_points; FT_ASSERT( FT_Outline_Check( outline ) == 0 ); } @@ -2050,7 +2050,7 @@ FT_Vector* point; FT_Vector* limit; - char* tags; + FT_Byte* tags; FT_Error error; diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftsynth.c b/src/java.desktop/share/native/libfreetype/src/base/ftsynth.c index f32edd3388b0b..ec05bce33a9a6 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftsynth.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftsynth.c @@ -4,7 +4,7 @@ * * FreeType synthesizing code for emboldening and slanting (body). * - * Copyright (C) 2000-2023 by + * Copyright (C) 2000-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftsystem.c b/src/java.desktop/share/native/libfreetype/src/base/ftsystem.c index 61c99e3635714..eee3642334f6e 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftsystem.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftsystem.c @@ -4,7 +4,7 @@ * * ANSI-specific FreeType low-level system interface (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/fttrigon.c b/src/java.desktop/share/native/libfreetype/src/base/fttrigon.c index 2dd2c3459e5fd..4b1aced1cbab0 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/fttrigon.c +++ b/src/java.desktop/share/native/libfreetype/src/base/fttrigon.c @@ -4,7 +4,7 @@ * * FreeType trigonometric functions (body). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/fttype1.c b/src/java.desktop/share/native/libfreetype/src/base/fttype1.c index 637c5cf775e6c..cedf7c405054d 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/fttype1.c +++ b/src/java.desktop/share/native/libfreetype/src/base/fttype1.c @@ -4,7 +4,7 @@ * * FreeType utility file for PS names support (body). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftutil.c b/src/java.desktop/share/native/libfreetype/src/base/ftutil.c index 6120846d2ca0c..b13512f870429 100644 --- a/src/java.desktop/share/native/libfreetype/src/base/ftutil.c +++ b/src/java.desktop/share/native/libfreetype/src/base/ftutil.c @@ -4,7 +4,7 @@ * * FreeType utility file for memory and list management (body). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.c b/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.c index 10d287bc81fbb..ea5f8ed288514 100644 --- a/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.c +++ b/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.c @@ -4,7 +4,7 @@ * * CFF character mapping table (cmap) support (body). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.h b/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.h index b2afc2fab622c..1dd8700cd8baa 100644 --- a/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.h +++ b/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.h @@ -4,7 +4,7 @@ * * CFF character mapping table (cmap) support (specification). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.c b/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.c index 9898d625ca4ed..f6ebdb3810a24 100644 --- a/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.c +++ b/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.c @@ -4,7 +4,7 @@ * * OpenType font driver implementation (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.h b/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.h index ab1f147bb2a6a..fd5bc37ecd42a 100644 --- a/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.h +++ b/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.h @@ -4,7 +4,7 @@ * * High-level OpenType driver interface (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cfferrs.h b/src/java.desktop/share/native/libfreetype/src/cff/cfferrs.h index bc9a3043fcff7..128adc3b716b8 100644 --- a/src/java.desktop/share/native/libfreetype/src/cff/cfferrs.h +++ b/src/java.desktop/share/native/libfreetype/src/cff/cfferrs.h @@ -4,7 +4,7 @@ * * CFF error codes (specification only). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffgload.c b/src/java.desktop/share/native/libfreetype/src/cff/cffgload.c index c483d1d1a5912..cbb071abdfeb4 100644 --- a/src/java.desktop/share/native/libfreetype/src/cff/cffgload.c +++ b/src/java.desktop/share/native/libfreetype/src/cff/cffgload.c @@ -4,7 +4,7 @@ * * OpenType Glyph Loader (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffgload.h b/src/java.desktop/share/native/libfreetype/src/cff/cffgload.h index 3b8cf236ddc21..346d4b11c31ac 100644 --- a/src/java.desktop/share/native/libfreetype/src/cff/cffgload.h +++ b/src/java.desktop/share/native/libfreetype/src/cff/cffgload.h @@ -4,7 +4,7 @@ * * OpenType Glyph Loader (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffload.c b/src/java.desktop/share/native/libfreetype/src/cff/cffload.c index af79082e98cb5..979fd45f6ca8d 100644 --- a/src/java.desktop/share/native/libfreetype/src/cff/cffload.c +++ b/src/java.desktop/share/native/libfreetype/src/cff/cffload.c @@ -4,7 +4,7 @@ * * OpenType and CFF data/program tables loader (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -1202,17 +1202,21 @@ { CFF_AxisCoords* axis = ®ion->axisList[j]; - FT_Int16 start14, peak14, end14; + FT_Int start, peak, end; - if ( FT_READ_SHORT( start14 ) || - FT_READ_SHORT( peak14 ) || - FT_READ_SHORT( end14 ) ) + if ( FT_READ_SHORT( start ) || + FT_READ_SHORT( peak ) || + FT_READ_SHORT( end ) ) goto Exit; - axis->startCoord = FT_fdot14ToFixed( start14 ); - axis->peakCoord = FT_fdot14ToFixed( peak14 ); - axis->endCoord = FT_fdot14ToFixed( end14 ); + /* immediately tag invalid ranges with special peak = 0 */ + if ( ( start < 0 && end > 0 ) || start > peak || peak > end ) + peak = 0; + + axis->startCoord = FT_fdot14ToFixed( start ); + axis->peakCoord = FT_fdot14ToFixed( peak ); + axis->endCoord = FT_fdot14ToFixed( end ); } } @@ -1379,10 +1383,10 @@ /* opcode in both CFF and CFF2 DICTs. See `cff_parse_num' for */ /* decode of this, which rounds to an integer. */ *subFont->blend_top++ = 255; - *subFont->blend_top++ = (FT_Byte)( sum >> 24 ); - *subFont->blend_top++ = (FT_Byte)( sum >> 16 ); - *subFont->blend_top++ = (FT_Byte)( sum >> 8 ); - *subFont->blend_top++ = (FT_Byte)sum; + *subFont->blend_top++ = (FT_Byte)( (FT_UInt32)sum >> 24 ); + *subFont->blend_top++ = (FT_Byte)( (FT_UInt32)sum >> 16 ); + *subFont->blend_top++ = (FT_Byte)( (FT_UInt32)sum >> 8 ); + *subFont->blend_top++ = (FT_Byte)( (FT_UInt32)sum ); } /* leave only numBlends results on parser stack */ @@ -1495,44 +1499,31 @@ for ( j = 0; j < lenNDV; j++ ) { CFF_AxisCoords* axis = &varRegion->axisList[j]; - FT_Fixed axisScalar; - - - /* compute the scalar contribution of this axis; */ - /* ignore invalid ranges */ - if ( axis->startCoord > axis->peakCoord || - axis->peakCoord > axis->endCoord ) - axisScalar = FT_FIXED_ONE; - else if ( axis->startCoord < 0 && - axis->endCoord > 0 && - axis->peakCoord != 0 ) - axisScalar = FT_FIXED_ONE; - /* peak of 0 means ignore this axis */ - else if ( axis->peakCoord == 0 ) - axisScalar = FT_FIXED_ONE; + /* compute the scalar contribution of this axis */ + /* with peak of 0 used for invalid axes */ + if ( axis->peakCoord == NDV[j] || + axis->peakCoord == 0 ) + continue; /* ignore this region if coords are out of range */ - else if ( NDV[j] < axis->startCoord || - NDV[j] > axis->endCoord ) - axisScalar = 0; - - /* calculate a proportional factor */ - else + else if ( NDV[j] <= axis->startCoord || + NDV[j] >= axis->endCoord ) { - if ( NDV[j] == axis->peakCoord ) - axisScalar = FT_FIXED_ONE; - else if ( NDV[j] < axis->peakCoord ) - axisScalar = FT_DivFix( NDV[j] - axis->startCoord, - axis->peakCoord - axis->startCoord ); - else - axisScalar = FT_DivFix( axis->endCoord - NDV[j], - axis->endCoord - axis->peakCoord ); + blend->BV[master] = 0; + break; } - /* take product of all the axis scalars */ - blend->BV[master] = FT_MulFix( blend->BV[master], axisScalar ); + /* adjust proportionally */ + else if ( NDV[j] < axis->peakCoord ) + blend->BV[master] = FT_MulDiv( blend->BV[master], + NDV[j] - axis->startCoord, + axis->peakCoord - axis->startCoord ); + else /* NDV[j] > axis->peakCoord ) */ + blend->BV[master] = FT_MulDiv( blend->BV[master], + axis->endCoord - NDV[j], + axis->endCoord - axis->peakCoord ); } FT_TRACE4(( ", %f ", diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffload.h b/src/java.desktop/share/native/libfreetype/src/cff/cffload.h index b5286b0c8cb05..0220924542188 100644 --- a/src/java.desktop/share/native/libfreetype/src/cff/cffload.h +++ b/src/java.desktop/share/native/libfreetype/src/cff/cffload.h @@ -4,7 +4,7 @@ * * OpenType & CFF data/program tables loader (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.c b/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.c index 6d08620c487c0..7c6713739a126 100644 --- a/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.c +++ b/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.c @@ -4,7 +4,7 @@ * * OpenType objects manager (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -42,6 +42,8 @@ #include #include +#define CFF_fixedToInt( x ) \ + ( (FT_Short)( ( (x) + 0x8000U ) >> 16 ) ) /************************************************************************** * @@ -124,19 +126,20 @@ count = priv->num_blue_values = cpriv->num_blue_values; for ( n = 0; n < count; n++ ) - priv->blue_values[n] = (FT_Short)cpriv->blue_values[n]; + priv->blue_values[n] = CFF_fixedToInt( cpriv->blue_values[n] ); count = priv->num_other_blues = cpriv->num_other_blues; for ( n = 0; n < count; n++ ) - priv->other_blues[n] = (FT_Short)cpriv->other_blues[n]; + priv->other_blues[n] = CFF_fixedToInt( cpriv->other_blues[n] ); count = priv->num_family_blues = cpriv->num_family_blues; for ( n = 0; n < count; n++ ) - priv->family_blues[n] = (FT_Short)cpriv->family_blues[n]; + priv->family_blues[n] = CFF_fixedToInt( cpriv->family_blues[n] ); count = priv->num_family_other_blues = cpriv->num_family_other_blues; for ( n = 0; n < count; n++ ) - priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; + priv->family_other_blues[n] = + CFF_fixedToInt( cpriv->family_other_blues[n] ); priv->blue_scale = cpriv->blue_scale; priv->blue_shift = (FT_Int)cpriv->blue_shift; @@ -421,32 +424,23 @@ static void remove_subset_prefix( FT_String* name ) { - FT_Int32 idx = 0; - FT_Int32 length = (FT_Int32)ft_strlen( name ) + 1; - FT_Bool continue_search = 1; + FT_UInt32 i = 0, idx = 0; - while ( continue_search ) + /* six ASCII uppercase letters followed by a plus sign */ + while ( 'A' <= name[i] && name[i++] <= 'Z' && + 'A' <= name[i] && name[i++] <= 'Z' && + 'A' <= name[i] && name[i++] <= 'Z' && + 'A' <= name[i] && name[i++] <= 'Z' && + 'A' <= name[i] && name[i++] <= 'Z' && + 'A' <= name[i] && name[i++] <= 'Z' && + name[i++] == '+' ) { - if ( length >= 7 && name[6] == '+' ) - { - for ( idx = 0; idx < 6; idx++ ) - { - /* ASCII uppercase letters */ - if ( !( 'A' <= name[idx] && name[idx] <= 'Z' ) ) - continue_search = 0; - } - - if ( continue_search ) - { - for ( idx = 7; idx < length; idx++ ) - name[idx - 7] = name[idx]; - length -= 7; - } - } - else - continue_search = 0; + idx = i; } + + if ( idx ) + FT_MEM_MOVE( name, name + idx, ft_strlen( name + idx ) + 1 ); } @@ -456,42 +450,20 @@ remove_style( FT_String* family_name, const FT_String* style_name ) { - FT_Int32 family_name_length, style_name_length; + FT_String* f = family_name + ft_strlen( family_name ); + const FT_String* s = style_name + ft_strlen( style_name ); - family_name_length = (FT_Int32)ft_strlen( family_name ); - style_name_length = (FT_Int32)ft_strlen( style_name ); + /* compare strings moving backwards */ + while ( s > style_name ) + if ( f == family_name || *--s != *--f ) + return; - if ( family_name_length > style_name_length ) - { - FT_Int idx; - - - for ( idx = 1; idx <= style_name_length; idx++ ) - { - if ( family_name[family_name_length - idx] != - style_name[style_name_length - idx] ) - break; - } - - if ( idx > style_name_length ) - { - /* family_name ends with style_name; remove it */ - idx = family_name_length - style_name_length - 1; - - /* also remove special characters */ - /* between real family name and style */ - while ( idx > 0 && - ( family_name[idx] == '-' || - family_name[idx] == ' ' || - family_name[idx] == '_' || - family_name[idx] == '+' ) ) - idx--; - - if ( idx > 0 ) - family_name[idx + 1] = '\0'; - } - } + /* terminate and remove special characters */ + do + *f = '\0'; + while ( f-- > family_name && + ( *f == '-' || *f == ' ' || *f == '_' || *f == '+' ) ); } @@ -722,8 +694,7 @@ FT_UInt instance_index = (FT_UInt)face_index >> 16; - if ( FT_HAS_MULTIPLE_MASTERS( cffface ) && - instance_index > 0 ) + if ( FT_HAS_MULTIPLE_MASTERS( cffface ) ) { error = FT_Set_Named_Instance( cffface, instance_index ); if ( error ) diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.h b/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.h index 8f05f6132bc01..91ad83b1cd0c7 100644 --- a/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.h +++ b/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.h @@ -4,7 +4,7 @@ * * OpenType objects manager (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffparse.c b/src/java.desktop/share/native/libfreetype/src/cff/cffparse.c index 3b076704cf732..92a69c3b51659 100644 --- a/src/java.desktop/share/native/libfreetype/src/cff/cffparse.c +++ b/src/java.desktop/share/native/libfreetype/src/cff/cffparse.c @@ -4,7 +4,7 @@ * * CFF token stream parser (body) * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -501,10 +501,10 @@ return cff_parse_real( *d, parser->limit, scaling, NULL ); else if ( **d == 255 ) { - FT_Fixed val = ( ( ( (FT_UInt32)*( d[0] + 1 ) << 24 ) | - ( (FT_UInt32)*( d[0] + 2 ) << 16 ) | - ( (FT_UInt32)*( d[0] + 3 ) << 8 ) | - (FT_UInt32)*( d[0] + 4 ) ) ); + FT_Fixed val = (FT_Int32)( ( ( (FT_UInt32)*( d[0] + 1 ) << 24 ) | + ( (FT_UInt32)*( d[0] + 2 ) << 16 ) | + ( (FT_UInt32)*( d[0] + 3 ) << 8 ) | + (FT_UInt32)*( d[0] + 4 ) ) ); if ( scaling ) { @@ -1031,10 +1031,14 @@ CFF_FIELD( code, name, id, cff_kind_string ) #define CFF_FIELD_BOOL( code, name, id ) \ CFF_FIELD( code, name, id, cff_kind_bool ) +#define CFF_FIELD_DELTA( code, name, max, id ) \ + CFF_FIELD_DELTA_KIND( code, name, max, id, cff_kind_delta ) +#define CFF_FIELD_DELTA_FIXED( code, name, max, id ) \ + CFF_FIELD_DELTA_KIND( code, name, max, id, cff_kind_delta_fixed ) #undef CFF_FIELD -#undef CFF_FIELD_DELTA +#undef CFF_FIELD_DELTA_KIND #ifndef FT_DEBUG_LEVEL_TRACE @@ -1064,18 +1068,18 @@ code | CFFCODE, \ FT_FIELD_OFFSET( name ), \ FT_FIELD_SIZE( name ), \ - 0, 0, 0 \ + NULL, 0, 0 \ }, -#define CFF_FIELD_DELTA( code, name, max, id ) \ - { \ - cff_kind_delta, \ - code | CFFCODE, \ - FT_FIELD_OFFSET( name ), \ - FT_FIELD_SIZE_DELTA( name ), \ - 0, \ - max, \ - FT_FIELD_OFFSET( num_ ## name ) \ +#define CFF_FIELD_DELTA_KIND( code, name, max, id, kind ) \ + { \ + kind, \ + code | CFFCODE, \ + FT_FIELD_OFFSET( name ), \ + FT_FIELD_SIZE_DELTA( name ), \ + NULL, \ + max, \ + FT_FIELD_OFFSET( num_ ## name ) \ }, static const CFF_Field_Handler cff_field_handlers[] = @@ -1083,7 +1087,7 @@ #include "cfftoken.h" - { 0, 0, 0, 0, 0, 0, 0 } + { 0, 0, 0, 0, NULL, 0, 0 } }; @@ -1117,20 +1121,20 @@ code | CFFCODE, \ FT_FIELD_OFFSET( name ), \ FT_FIELD_SIZE( name ), \ - 0, 0, 0, \ + NULL, 0, 0, \ id \ }, -#define CFF_FIELD_DELTA( code, name, max, id ) \ - { \ - cff_kind_delta, \ - code | CFFCODE, \ - FT_FIELD_OFFSET( name ), \ - FT_FIELD_SIZE_DELTA( name ), \ - 0, \ - max, \ - FT_FIELD_OFFSET( num_ ## name ), \ - id \ +#define CFF_FIELD_DELTA_KIND( code, name, max, id, kind ) \ + { \ + kind, \ + code | CFFCODE, \ + FT_FIELD_OFFSET( name ), \ + FT_FIELD_SIZE_DELTA( name ), \ + NULL, \ + max, \ + FT_FIELD_OFFSET( num_ ## name ), \ + id \ }, static const CFF_Field_Handler cff_field_handlers[] = @@ -1138,7 +1142,7 @@ #include "cfftoken.h" - { 0, 0, 0, 0, 0, 0, 0, 0 } + { 0, 0, 0, 0, NULL, 0, 0, NULL } }; @@ -1356,7 +1360,8 @@ /* check that we have enough arguments -- except for */ /* delta encoded arrays, which can be empty */ - if ( field->kind != cff_kind_delta && num_args < 1 ) + if ( field->kind != cff_kind_delta && + field->kind != cff_kind_delta_fixed && num_args < 1 ) goto Stack_Underflow; switch ( field->kind ) @@ -1471,6 +1476,38 @@ } break; + case cff_kind_delta_fixed: + { + FT_Byte* qcount = (FT_Byte*)parser->object + + field->count_offset; + + FT_Byte** data = parser->stack; + + + if ( num_args > field->array_max ) + num_args = field->array_max; + + FT_TRACE4(( " [" )); + + /* store count */ + *qcount = (FT_Byte)num_args; + + val = 0; + while ( num_args > 0 ) + { + val = ADD_LONG( val, cff_parse_fixed( parser, data++ ) ); + *(FT_Long*)q = val; + + FT_TRACE4(( " %f\n", (double)val / 65536 )); + + q += field->size; + num_args--; + } + + FT_TRACE4(( "]\n" )); + } + break; + default: /* callback or blend */ error = field->reader( parser ); if ( error ) diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffparse.h b/src/java.desktop/share/native/libfreetype/src/cff/cffparse.h index 418caacc68c94..ca6b18af6aa32 100644 --- a/src/java.desktop/share/native/libfreetype/src/cff/cffparse.h +++ b/src/java.desktop/share/native/libfreetype/src/cff/cffparse.h @@ -4,7 +4,7 @@ * * CFF token stream parser (specification) * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -107,6 +107,7 @@ FT_BEGIN_HEADER cff_kind_string, cff_kind_bool, cff_kind_delta, + cff_kind_delta_fixed, cff_kind_callback, cff_kind_blend, diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cfftoken.h b/src/java.desktop/share/native/libfreetype/src/cff/cfftoken.h index b61cb0e66e8d5..da45faa7f4ee3 100644 --- a/src/java.desktop/share/native/libfreetype/src/cff/cfftoken.h +++ b/src/java.desktop/share/native/libfreetype/src/cff/cfftoken.h @@ -4,7 +4,7 @@ * * CFF token definitions (specification only). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -80,26 +80,26 @@ #undef CFFCODE #define CFFCODE CFF_CODE_PRIVATE - CFF_FIELD_DELTA ( 6, blue_values, 14, "BlueValues" ) - CFF_FIELD_DELTA ( 7, other_blues, 10, "OtherBlues" ) - CFF_FIELD_DELTA ( 8, family_blues, 14, "FamilyBlues" ) - CFF_FIELD_DELTA ( 9, family_other_blues, 10, "FamilyOtherBlues" ) - CFF_FIELD_FIXED_1000( 0x109, blue_scale, "BlueScale" ) - CFF_FIELD_NUM ( 0x10A, blue_shift, "BlueShift" ) - CFF_FIELD_NUM ( 0x10B, blue_fuzz, "BlueFuzz" ) - CFF_FIELD_NUM ( 10, standard_width, "StdHW" ) - CFF_FIELD_NUM ( 11, standard_height, "StdVW" ) - CFF_FIELD_DELTA ( 0x10C, snap_widths, 13, "StemSnapH" ) - CFF_FIELD_DELTA ( 0x10D, snap_heights, 13, "StemSnapV" ) - CFF_FIELD_BOOL ( 0x10E, force_bold, "ForceBold" ) - CFF_FIELD_FIXED ( 0x10F, force_bold_threshold, "ForceBoldThreshold" ) - CFF_FIELD_NUM ( 0x110, lenIV, "lenIV" ) - CFF_FIELD_NUM ( 0x111, language_group, "LanguageGroup" ) - CFF_FIELD_FIXED ( 0x112, expansion_factor, "ExpansionFactor" ) - CFF_FIELD_NUM ( 0x113, initial_random_seed, "initialRandomSeed" ) - CFF_FIELD_NUM ( 19, local_subrs_offset, "Subrs" ) - CFF_FIELD_NUM ( 20, default_width, "defaultWidthX" ) - CFF_FIELD_NUM ( 21, nominal_width, "nominalWidthX" ) + CFF_FIELD_DELTA_FIXED( 6, blue_values, 14, "BlueValues" ) + CFF_FIELD_DELTA_FIXED( 7, other_blues, 10, "OtherBlues" ) + CFF_FIELD_DELTA_FIXED( 8, family_blues, 14, "FamilyBlues" ) + CFF_FIELD_DELTA_FIXED( 9, family_other_blues, 10, "FamilyOtherBlues" ) + CFF_FIELD_FIXED_1000 ( 0x109, blue_scale, "BlueScale" ) + CFF_FIELD_NUM ( 0x10A, blue_shift, "BlueShift" ) + CFF_FIELD_NUM ( 0x10B, blue_fuzz, "BlueFuzz" ) + CFF_FIELD_NUM ( 10, standard_width, "StdHW" ) + CFF_FIELD_NUM ( 11, standard_height, "StdVW" ) + CFF_FIELD_DELTA ( 0x10C, snap_widths, 13, "StemSnapH" ) + CFF_FIELD_DELTA ( 0x10D, snap_heights, 13, "StemSnapV" ) + CFF_FIELD_BOOL ( 0x10E, force_bold, "ForceBold" ) + CFF_FIELD_FIXED ( 0x10F, force_bold_threshold, "ForceBoldThreshold" ) + CFF_FIELD_NUM ( 0x110, lenIV, "lenIV" ) + CFF_FIELD_NUM ( 0x111, language_group, "LanguageGroup" ) + CFF_FIELD_FIXED ( 0x112, expansion_factor, "ExpansionFactor" ) + CFF_FIELD_NUM ( 0x113, initial_random_seed, "initialRandomSeed" ) + CFF_FIELD_NUM ( 19, local_subrs_offset, "Subrs" ) + CFF_FIELD_NUM ( 20, default_width, "defaultWidthX" ) + CFF_FIELD_NUM ( 21, nominal_width, "nominalWidthX" ) #undef FT_STRUCTURE @@ -129,22 +129,22 @@ #undef CFFCODE #define CFFCODE CFF2_CODE_PRIVATE - CFF_FIELD_DELTA ( 6, blue_values, 14, "BlueValues" ) - CFF_FIELD_DELTA ( 7, other_blues, 10, "OtherBlues" ) - CFF_FIELD_DELTA ( 8, family_blues, 14, "FamilyBlues" ) - CFF_FIELD_DELTA ( 9, family_other_blues, 10, "FamilyOtherBlues" ) - CFF_FIELD_FIXED_1000( 0x109, blue_scale, "BlueScale" ) - CFF_FIELD_NUM ( 0x10A, blue_shift, "BlueShift" ) - CFF_FIELD_NUM ( 0x10B, blue_fuzz, "BlueFuzz" ) - CFF_FIELD_NUM ( 10, standard_width, "StdHW" ) - CFF_FIELD_NUM ( 11, standard_height, "StdVW" ) - CFF_FIELD_DELTA ( 0x10C, snap_widths, 13, "StemSnapH" ) - CFF_FIELD_DELTA ( 0x10D, snap_heights, 13, "StemSnapV" ) - CFF_FIELD_NUM ( 0x111, language_group, "LanguageGroup" ) - CFF_FIELD_FIXED ( 0x112, expansion_factor, "ExpansionFactor" ) - CFF_FIELD_CALLBACK ( 22, vsindex, "vsindex" ) - CFF_FIELD_BLEND ( 23, "blend" ) - CFF_FIELD_NUM ( 19, local_subrs_offset, "Subrs" ) + CFF_FIELD_DELTA_FIXED( 6, blue_values, 14, "BlueValues" ) + CFF_FIELD_DELTA_FIXED( 7, other_blues, 10, "OtherBlues" ) + CFF_FIELD_DELTA_FIXED( 8, family_blues, 14, "FamilyBlues" ) + CFF_FIELD_DELTA_FIXED( 9, family_other_blues, 10, "FamilyOtherBlues" ) + CFF_FIELD_FIXED_1000 ( 0x109, blue_scale, "BlueScale" ) + CFF_FIELD_NUM ( 0x10A, blue_shift, "BlueShift" ) + CFF_FIELD_NUM ( 0x10B, blue_fuzz, "BlueFuzz" ) + CFF_FIELD_NUM ( 10, standard_width, "StdHW" ) + CFF_FIELD_NUM ( 11, standard_height, "StdVW" ) + CFF_FIELD_DELTA ( 0x10C, snap_widths, 13, "StemSnapH" ) + CFF_FIELD_DELTA ( 0x10D, snap_heights, 13, "StemSnapV" ) + CFF_FIELD_NUM ( 0x111, language_group, "LanguageGroup" ) + CFF_FIELD_FIXED ( 0x112, expansion_factor, "ExpansionFactor" ) + CFF_FIELD_CALLBACK ( 22, vsindex, "vsindex" ) + CFF_FIELD_BLEND ( 23, "blend" ) + CFF_FIELD_NUM ( 19, local_subrs_offset, "Subrs" ) /* END */ diff --git a/src/java.desktop/share/native/libfreetype/src/cid/ciderrs.h b/src/java.desktop/share/native/libfreetype/src/cid/ciderrs.h index 40a1097d0ac7a..c439a8c4a0b30 100644 --- a/src/java.desktop/share/native/libfreetype/src/cid/ciderrs.h +++ b/src/java.desktop/share/native/libfreetype/src/cid/ciderrs.h @@ -4,7 +4,7 @@ * * CID error codes (specification only). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidgload.c b/src/java.desktop/share/native/libfreetype/src/cid/cidgload.c index eaca765ad06c8..7b571322d456b 100644 --- a/src/java.desktop/share/native/libfreetype/src/cid/cidgload.c +++ b/src/java.desktop/share/native/libfreetype/src/cid/cidgload.c @@ -4,7 +4,7 @@ * * CID-keyed Type1 Glyph Loader (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidgload.h b/src/java.desktop/share/native/libfreetype/src/cid/cidgload.h index edd6229234c41..9fdc9db589231 100644 --- a/src/java.desktop/share/native/libfreetype/src/cid/cidgload.h +++ b/src/java.desktop/share/native/libfreetype/src/cid/cidgload.h @@ -4,7 +4,7 @@ * * OpenType Glyph Loader (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidload.c b/src/java.desktop/share/native/libfreetype/src/cid/cidload.c index a7da8ea39d5d2..722f5a34ddf95 100644 --- a/src/java.desktop/share/native/libfreetype/src/cid/cidload.c +++ b/src/java.desktop/share/native/libfreetype/src/cid/cidload.c @@ -4,7 +4,7 @@ * * CID-keyed Type1 font loader (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -388,7 +388,7 @@ T1_FIELD_CALLBACK( "ExpansionFactor", parse_expansion_factor, 0 ) T1_FIELD_CALLBACK( "FontName", parse_font_name, 0 ) - { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } + T1_FIELD_ZERO }; @@ -469,36 +469,23 @@ T1_Field keyword = (T1_Field)cid_field_records; - for (;;) + while ( keyword->len ) { - FT_Byte* name; + FT_Byte* name = (FT_Byte*)keyword->ident; - name = (FT_Byte*)keyword->ident; - if ( !name ) - break; - - if ( cur[0] == name[0] && - len == ft_strlen( (const char*)name ) ) + if ( keyword->len == len && + ft_memcmp( cur, name, len ) == 0 ) { - FT_UInt n; - - - for ( n = 1; n < len; n++ ) - if ( cur[n] != name[n] ) - break; - - if ( n >= len ) - { - /* we found it - run the parsing callback */ - parser->root.error = cid_load_keyword( face, - loader, - keyword ); - if ( parser->root.error ) - return parser->root.error; - break; - } + /* we found it - run the parsing callback */ + parser->root.error = cid_load_keyword( face, + loader, + keyword ); + if ( parser->root.error ) + return parser->root.error; + break; } + keyword++; } } diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidload.h b/src/java.desktop/share/native/libfreetype/src/cid/cidload.h index d12d2962a6866..7f030b32df731 100644 --- a/src/java.desktop/share/native/libfreetype/src/cid/cidload.h +++ b/src/java.desktop/share/native/libfreetype/src/cid/cidload.h @@ -4,7 +4,7 @@ * * CID-keyed Type1 font loader (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.c b/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.c index f698a419289e0..8d337c4112839 100644 --- a/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.c +++ b/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.c @@ -4,7 +4,7 @@ * * CID objects manager (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.h b/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.h index 83c0c61c3ca63..d371cbe995423 100644 --- a/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.h +++ b/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.h @@ -4,7 +4,7 @@ * * CID objects manager (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidparse.c b/src/java.desktop/share/native/libfreetype/src/cid/cidparse.c index 171a886215ad2..73a3ade893be3 100644 --- a/src/java.desktop/share/native/libfreetype/src/cid/cidparse.c +++ b/src/java.desktop/share/native/libfreetype/src/cid/cidparse.c @@ -4,7 +4,7 @@ * * CID-keyed Type1 parser (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -90,10 +90,15 @@ if ( error ) goto Exit; - Again: - /* now, read the rest of the file until we find */ - /* `StartData' or `/sfnts' */ + if ( !stream->read ) { + /* just parse memory-based streams */ + offset = stream->size; + } + else { + /* Find the last `StartData` or `/sfnts`. The parser requires */ + /* contiguous memory; attempt to pin as little as necessary. */ + /* * The algorithm is as follows (omitting the case with less than 256 * bytes to fill for simplicity). @@ -119,7 +124,8 @@ FT_Byte* p = buffer; - for ( offset = FT_STREAM_POS(); ; offset += 256 ) + offset = 0; + while ( 1 ) { FT_ULong stream_len; @@ -127,7 +133,7 @@ stream_len = stream->size - FT_STREAM_POS(); read_len = FT_MIN( read_len, stream_len ); - if ( FT_STREAM_READ( p, read_len ) ) + if ( read_len && FT_STREAM_READ( p, read_len ) ) goto Exit; /* ensure that we do not compare with data beyond the buffer */ @@ -141,20 +147,23 @@ ft_strncmp( (char*)p, STARTDATA, STARTDATA_LEN ) == 0 ) { /* save offset of binary data after `StartData' */ - offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN + 1; - goto Found; + offset = FT_STREAM_POS() - read_len - read_offset + + (FT_ULong)( p - buffer ) + STARTDATA_LEN + 1; } else if ( p[1] == 's' && ft_strncmp( (char*)p, SFNTS, SFNTS_LEN ) == 0 ) { - offset += (FT_ULong)( p - buffer ) + SFNTS_LEN + 1; - goto Found; + offset = FT_STREAM_POS() - read_len - read_offset + + (FT_ULong)( p - buffer ) + SFNTS_LEN + 1; } } - if ( read_offset + read_len < STARTDATA_LEN ) + if ( read_offset + read_len <= STARTDATA_LEN ) { - FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); + if ( offset ) + goto Found; + + FT_TRACE2(( "cid_parser_new: no `StartData` keyword found\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } @@ -171,9 +180,9 @@ } Found: - /* We have found the start of the binary data or the `/sfnts' token. */ - /* Now rewind and extract the frame corresponding to this PostScript */ - /* section. */ + /* We have found an efficient range to look for the binary data or */ + /* `/sfnts' token. Now rewind and extract the frame corresponding to */ + /* this PostScript section. */ ps_len = offset - base_offset; if ( FT_STREAM_SEEK( base_offset ) || @@ -187,8 +196,8 @@ parser->root.limit = parser->root.cursor + ps_len; parser->num_dict = FT_UINT_MAX; - /* Finally, we check whether `StartData' or `/sfnts' was real -- */ - /* it could be in a comment or string. We also get the arguments */ + /* Find the first real `StartData' or `/sfnts' -- the last one */ + /* could be in a comment or string. We also get the arguments */ /* of `StartData' to find out whether the data is represented in */ /* binary or hex format. */ @@ -216,6 +225,7 @@ { T1_TokenRec type_token; FT_Long binary_length; + FT_ULong found_offset; parser->root.cursor = arg1; @@ -234,6 +244,24 @@ parser->binary_length = (FT_ULong)binary_length; } + /* set the real values for the parser, if different */ + found_offset = (FT_ULong)( cur - parser->postscript ) + + STARTDATA_LEN + 1; + if ( found_offset != offset ) + { + FT_FRAME_RELEASE( parser->postscript ); + + ps_len = found_offset - base_offset; + if ( FT_STREAM_SEEK( base_offset ) || + FT_FRAME_EXTRACT( ps_len, parser->postscript ) ) + goto Exit; + + parser->data_offset = found_offset; + parser->postscript_len = ps_len; + parser->root.base = parser->postscript; + parser->root.cursor = parser->postscript; + parser->root.limit = parser->root.cursor + ps_len; + } goto Exit; } else if ( cur[1] == 's' && @@ -251,11 +279,8 @@ cur = parser->root.cursor; } - /* we haven't found the correct `StartData'; go back and continue */ - /* searching */ - FT_FRAME_RELEASE( parser->postscript ); - if ( !FT_STREAM_SEEK( offset ) ) - goto Again; + FT_TRACE2(( "cid_parser_new: no `StartData` token found\n" )); + error = FT_THROW( Invalid_File_Format ); Exit: return error; diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidparse.h b/src/java.desktop/share/native/libfreetype/src/cid/cidparse.h index 2fd4e7a9310b1..0f5baddcb926e 100644 --- a/src/java.desktop/share/native/libfreetype/src/cid/cidparse.h +++ b/src/java.desktop/share/native/libfreetype/src/cid/cidparse.h @@ -4,7 +4,7 @@ * * CID-keyed Type1 parser (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidriver.c b/src/java.desktop/share/native/libfreetype/src/cid/cidriver.c index 99e7b11839511..4be8a5c00d51a 100644 --- a/src/java.desktop/share/native/libfreetype/src/cid/cidriver.c +++ b/src/java.desktop/share/native/libfreetype/src/cid/cidriver.c @@ -4,7 +4,7 @@ * * CID driver interface (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidriver.h b/src/java.desktop/share/native/libfreetype/src/cid/cidriver.h index a6249385c8116..7ddce431c5b1c 100644 --- a/src/java.desktop/share/native/libfreetype/src/cid/cidriver.h +++ b/src/java.desktop/share/native/libfreetype/src/cid/cidriver.h @@ -4,7 +4,7 @@ * * High-level CID driver interface (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidtoken.h b/src/java.desktop/share/native/libfreetype/src/cid/cidtoken.h index 925951acdbd28..160897d144727 100644 --- a/src/java.desktop/share/native/libfreetype/src/cid/cidtoken.h +++ b/src/java.desktop/share/native/libfreetype/src/cid/cidtoken.h @@ -4,7 +4,7 @@ * * CID token definitions (specification only). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.c b/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.c index db08941def744..e2f6a8e5adb9c 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.c +++ b/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.c @@ -4,7 +4,7 @@ * * AFM parser (body). * - * Copyright (C) 2006-2023 by + * Copyright (C) 2006-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.h b/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.h index 2d3b6e6e1695f..b7766372821a9 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.h +++ b/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.h @@ -4,7 +4,7 @@ * * AFM parser (specification). * - * Copyright (C) 2006-2023 by + * Copyright (C) 2006-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.c b/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.c index 562d17d221649..9556e11a5861b 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.c +++ b/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.c @@ -4,7 +4,7 @@ * * PostScript CFF (Type 2) decoding routines (body). * - * Copyright (C) 2017-2023 by + * Copyright (C) 2017-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -17,6 +17,7 @@ #include +#include #include #include #include @@ -1752,22 +1753,9 @@ /* without upper limit the loop below might not finish */ if ( args[0] > 0x7FFFFFFFL ) - args[0] = 46341; + args[0] = 0xB504F4L; /* sqrt( 32768.0044 ) */ else if ( args[0] > 0 ) - { - FT_Fixed root = args[0]; - FT_Fixed new_root; - - - for (;;) - { - new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1; - if ( new_root == root ) - break; - root = new_root; - } - args[0] = new_root; - } + args[0] = (FT_Fixed)FT_SqrtFixed( args[0] ); else args[0] = 0; args++; diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.h b/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.h index e8bb4001cba23..038f7235c3d64 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.h +++ b/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.h @@ -4,7 +4,7 @@ * * PostScript CFF (Type 2) decoding routines (specification). * - * Copyright (C) 2017-2023 by + * Copyright (C) 2017-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/psauxerr.h b/src/java.desktop/share/native/libfreetype/src/psaux/psauxerr.h index 895ffa48c2c31..18428c40d5a45 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/psauxerr.h +++ b/src/java.desktop/share/native/libfreetype/src/psaux/psauxerr.h @@ -4,7 +4,7 @@ * * PS auxiliary module error codes (specification only). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.c b/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.c index 45e35aa53c4cb..6826f9d8d3ede 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.c +++ b/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.c @@ -4,7 +4,7 @@ * * FreeType auxiliary PostScript module implementation (body). * - * Copyright (C) 2000-2023 by + * Copyright (C) 2000-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.h b/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.h index 94dbf48813c16..82d7e348af813 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.h +++ b/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.h @@ -4,7 +4,7 @@ * * FreeType auxiliary PostScript module implementation (specification). * - * Copyright (C) 2000-2023 by + * Copyright (C) 2000-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/psblues.c b/src/java.desktop/share/native/libfreetype/src/psaux/psblues.c index f9c864fea9aeb..213b943b46576 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/psblues.c +++ b/src/java.desktop/share/native/libfreetype/src/psaux/psblues.c @@ -54,14 +54,6 @@ #define FT_COMPONENT cf2blues - /* - * For blue values, the FreeType parser produces an array of integers, - * while the Adobe CFF engine produces an array of fixed. - * Define a macro to convert FreeType to fixed. - */ -#define cf2_blueToFixed( x ) cf2_intToFixed( x ) - - FT_LOCAL_DEF( void ) cf2_blues_init( CF2_Blues blues, CF2_Font font ) @@ -78,10 +70,10 @@ size_t numFamilyBlues; size_t numFamilyOtherBlues; - FT_Pos* blueValues; - FT_Pos* otherBlues; - FT_Pos* familyBlues; - FT_Pos* familyOtherBlues; + FT_Fixed* blueValues; + FT_Fixed* otherBlues; + FT_Fixed* familyBlues; + FT_Fixed* familyOtherBlues; size_t i; CF2_Fixed emBoxBottom, emBoxTop; @@ -138,13 +130,13 @@ emBoxTop = CF2_ICF_Top; } - if ( cf2_getLanguageGroup( decoder ) == 1 && - ( numBlueValues == 0 || - ( numBlueValues == 4 && - cf2_blueToFixed( blueValues[0] ) < emBoxBottom && - cf2_blueToFixed( blueValues[1] ) < emBoxBottom && - cf2_blueToFixed( blueValues[2] ) > emBoxTop && - cf2_blueToFixed( blueValues[3] ) > emBoxTop ) ) ) + if ( cf2_getLanguageGroup( decoder ) == 1 && + ( numBlueValues == 0 || + ( numBlueValues == 4 && + blueValues[0] < emBoxBottom && + blueValues[1] < emBoxBottom && + blueValues[2] > emBoxTop && + blueValues[3] > emBoxTop ) ) ) { /* * Construct hint edges suitable for synthetic ghost hints at top @@ -189,10 +181,8 @@ /* bottom zones */ for ( i = 0; i < numBlueValues; i += 2 ) { - blues->zone[blues->count].csBottomEdge = - cf2_blueToFixed( blueValues[i] ); - blues->zone[blues->count].csTopEdge = - cf2_blueToFixed( blueValues[i + 1] ); + blues->zone[blues->count].csBottomEdge = blueValues[i]; + blues->zone[blues->count].csTopEdge = blueValues[i + 1]; zoneHeight = SUB_INT32( blues->zone[blues->count].csTopEdge, blues->zone[blues->count].csBottomEdge ); @@ -238,10 +228,8 @@ for ( i = 0; i < numOtherBlues; i += 2 ) { - blues->zone[blues->count].csBottomEdge = - cf2_blueToFixed( otherBlues[i] ); - blues->zone[blues->count].csTopEdge = - cf2_blueToFixed( otherBlues[i + 1] ); + blues->zone[blues->count].csBottomEdge = otherBlues[i]; + blues->zone[blues->count].csTopEdge = otherBlues[i + 1]; zoneHeight = SUB_INT32( blues->zone[blues->count].csTopEdge, blues->zone[blues->count].csBottomEdge ); @@ -299,7 +287,7 @@ for ( j = 0; j < numFamilyOtherBlues; j += 2 ) { /* top edge */ - flatFamilyEdge = cf2_blueToFixed( familyOtherBlues[j + 1] ); + flatFamilyEdge = familyOtherBlues[j + 1]; diff = cf2_fixedAbs( SUB_INT32( flatEdge, flatFamilyEdge ) ); @@ -317,7 +305,7 @@ if ( numFamilyBlues >= 2 ) { /* top edge */ - flatFamilyEdge = cf2_blueToFixed( familyBlues[1] ); + flatFamilyEdge = familyBlues[1]; diff = cf2_fixedAbs( SUB_INT32( flatEdge, flatFamilyEdge ) ); @@ -337,7 +325,7 @@ for ( j = 2; j < numFamilyBlues; j += 2 ) { /* bottom edge */ - flatFamilyEdge = cf2_blueToFixed( familyBlues[j] ); + flatFamilyEdge = familyBlues[j]; /* adjust edges of top zone upward by twice darkening amount */ flatFamilyEdge += 2 * font->darkenY; /* bottom edge */ diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/psconv.c b/src/java.desktop/share/native/libfreetype/src/psaux/psconv.c index b9c7138d84637..56c0ecd1d7f21 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/psconv.c +++ b/src/java.desktop/share/native/libfreetype/src/psaux/psconv.c @@ -4,7 +4,7 @@ * * Some convenience conversions (body). * - * Copyright (C) 2006-2023 by + * Copyright (C) 2006-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/psconv.h b/src/java.desktop/share/native/libfreetype/src/psaux/psconv.h index b7c3ee00be872..91fcd15a1c96b 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/psconv.h +++ b/src/java.desktop/share/native/libfreetype/src/psaux/psconv.h @@ -4,7 +4,7 @@ * * Some convenience conversions (specification). * - * Copyright (C) 2006-2023 by + * Copyright (C) 2006-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/psft.c b/src/java.desktop/share/native/libfreetype/src/psaux/psft.c index 618864e6e0728..fd0abe17154c7 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/psft.c +++ b/src/java.desktop/share/native/libfreetype/src/psaux/psft.c @@ -566,12 +566,12 @@ FT_LOCAL_DEF( void ) cf2_getBlueValues( PS_Decoder* decoder, size_t* count, - FT_Pos* *data ) + FT_Fixed* *data ) { FT_ASSERT( decoder && decoder->current_subfont ); *count = decoder->current_subfont->private_dict.num_blue_values; - *data = (FT_Pos*) + *data = (FT_Fixed*) &decoder->current_subfont->private_dict.blue_values; } @@ -579,12 +579,12 @@ FT_LOCAL_DEF( void ) cf2_getOtherBlues( PS_Decoder* decoder, size_t* count, - FT_Pos* *data ) + FT_Fixed* *data ) { FT_ASSERT( decoder && decoder->current_subfont ); *count = decoder->current_subfont->private_dict.num_other_blues; - *data = (FT_Pos*) + *data = (FT_Fixed*) &decoder->current_subfont->private_dict.other_blues; } @@ -592,12 +592,12 @@ FT_LOCAL_DEF( void ) cf2_getFamilyBlues( PS_Decoder* decoder, size_t* count, - FT_Pos* *data ) + FT_Fixed* *data ) { FT_ASSERT( decoder && decoder->current_subfont ); *count = decoder->current_subfont->private_dict.num_family_blues; - *data = (FT_Pos*) + *data = (FT_Fixed*) &decoder->current_subfont->private_dict.family_blues; } @@ -605,12 +605,12 @@ FT_LOCAL_DEF( void ) cf2_getFamilyOtherBlues( PS_Decoder* decoder, size_t* count, - FT_Pos* *data ) + FT_Fixed* *data ) { FT_ASSERT( decoder && decoder->current_subfont ); *count = decoder->current_subfont->private_dict.num_family_other_blues; - *data = (FT_Pos*) + *data = (FT_Fixed*) &decoder->current_subfont->private_dict.family_other_blues; } diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/psft.h b/src/java.desktop/share/native/libfreetype/src/psaux/psft.h index 3da454e6012a5..d9082f3a2be12 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/psft.h +++ b/src/java.desktop/share/native/libfreetype/src/psaux/psft.h @@ -92,19 +92,19 @@ FT_BEGIN_HEADER FT_LOCAL( void ) cf2_getBlueValues( PS_Decoder* decoder, size_t* count, - FT_Pos* *data ); + FT_Fixed* *data ); FT_LOCAL( void ) cf2_getOtherBlues( PS_Decoder* decoder, size_t* count, - FT_Pos* *data ); + FT_Fixed* *data ); FT_LOCAL( void ) cf2_getFamilyBlues( PS_Decoder* decoder, size_t* count, - FT_Pos* *data ); + FT_Fixed* *data ); FT_LOCAL( void ) cf2_getFamilyOtherBlues( PS_Decoder* decoder, size_t* count, - FT_Pos* *data ); + FT_Fixed* *data ); FT_LOCAL( CF2_Int ) cf2_getLanguageGroup( PS_Decoder* decoder ); diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/psintrp.c b/src/java.desktop/share/native/libfreetype/src/psaux/psintrp.c index 6c640eebd5a50..7572e225e3777 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/psintrp.c +++ b/src/java.desktop/share/native/libfreetype/src/psaux/psintrp.c @@ -37,6 +37,7 @@ #include "psft.h" +#include #include #include @@ -428,6 +429,8 @@ base = cf2_stack_count( opStack ) - numOperands; delta = base + numBlends; + FT_TRACE6(( " (" )); + for ( i = 0; i < numBlends; i++ ) { const CF2_Fixed* weight = &blend->BV[1]; @@ -442,10 +445,14 @@ cf2_stack_getReal( opStack, delta++ ) ) ); + FT_TRACE6(( "%f ", (double)sum / 65536 )); + /* store blended result */ cf2_stack_setReal( opStack, i + base, sum ); } + FT_TRACE6(( "blended)\n" )); + /* leave only `numBlends' results on stack */ cf2_stack_pop( opStack, numOperands - numBlends ); } @@ -734,7 +741,7 @@ FT_UInt numBlends; - FT_TRACE4(( " blend\n" )); + FT_TRACE4(( " blend" )); if ( !font->isCFF2 ) break; /* clear stack & ignore */ @@ -2275,23 +2282,7 @@ arg = cf2_stack_popFixed( opStack ); if ( arg > 0 ) - { - /* use a start value that doesn't make */ - /* the algorithm's addition overflow */ - FT_Fixed root = arg < 10 ? arg : arg >> 1; - FT_Fixed new_root; - - - /* Babylonian method */ - for (;;) - { - new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1; - if ( new_root == root ) - break; - root = new_root; - } - arg = new_root; - } + arg = (CF2_F16Dot16)FT_SqrtFixed( (FT_UInt32)arg ); else arg = 0; diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.c b/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.c index 8da755d0e5769..eca465f009e96 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.c +++ b/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.c @@ -4,7 +4,7 @@ * * Auxiliary functions for PostScript fonts (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -23,6 +23,7 @@ #include "psobjs.h" #include "psconv.h" +#include "psft.h" #include "psauxerr.h" #include "psauxmod.h" @@ -200,7 +201,9 @@ /* add the object to the base block and adjust offset */ table->elements[idx] = FT_OFFSET( table->block, table->cursor ); table->lengths [idx] = length; - FT_MEM_COPY( table->block + table->cursor, object, length ); + /* length == 0 also implies a NULL destination, so skip the copy call */ + if ( length > 0 ) + FT_MEM_COPY( table->block + table->cursor, object, length ); table->cursor += length; return FT_Err_Ok; @@ -1624,7 +1627,7 @@ if ( builder->load_points ) { FT_Vector* point = outline->points + outline->n_points; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; + FT_Byte* control = outline->tags + outline->n_points; point->x = FIXED_TO_INT( x ); @@ -1677,8 +1680,7 @@ if ( !error ) { if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + outline->contours[outline->n_contours - 1] = outline->n_points - 1; outline->n_contours++; } @@ -1740,7 +1742,7 @@ { FT_Vector* p1 = outline->points + first; FT_Vector* p2 = outline->points + outline->n_points - 1; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; + FT_Byte* control = outline->tags + outline->n_points - 1; /* `delete' last point only if it coincides with the first */ @@ -1760,8 +1762,7 @@ outline->n_points--; } else - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + outline->contours[outline->n_contours - 1] = outline->n_points - 1; } } @@ -1899,7 +1900,7 @@ if ( builder->load_points ) { FT_Vector* point = outline->points + outline->n_points; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; + FT_Byte* control = outline->tags + outline->n_points; #ifdef CFF_CONFIG_OPTION_OLD_ENGINE PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( builder->face ); @@ -1959,8 +1960,7 @@ if ( !error ) { if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + outline->contours[outline->n_contours - 1] = outline->n_points - 1; outline->n_contours++; } @@ -2019,7 +2019,7 @@ { FT_Vector* p1 = outline->points + first; FT_Vector* p2 = outline->points + outline->n_points - 1; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; + FT_Byte* control = outline->tags + outline->n_points - 1; /* `delete' last point only if it coincides with the first */ @@ -2039,8 +2039,7 @@ outline->n_points--; } else - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + outline->contours[outline->n_contours - 1] = outline->n_points - 1; } } @@ -2188,7 +2187,7 @@ if ( builder->load_points ) { FT_Vector* point = outline->points + outline->n_points; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; + FT_Byte* control = outline->tags + outline->n_points; #ifdef CFF_CONFIG_OPTION_OLD_ENGINE PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( builder->face ); @@ -2267,8 +2266,7 @@ if ( !error ) { if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + outline->contours[outline->n_contours - 1] = outline->n_points - 1; outline->n_contours++; } @@ -2327,7 +2325,7 @@ { FT_Vector* p1 = outline->points + first; FT_Vector* p2 = outline->points + outline->n_points - 1; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; + FT_Byte* control = outline->tags + outline->n_points - 1; /* `delete' last point only if it coincides with the first */ @@ -2347,8 +2345,7 @@ outline->n_points--; } else - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + outline->contours[outline->n_contours - 1] = outline->n_points - 1; } } @@ -2463,19 +2460,20 @@ count = cpriv->num_blue_values = priv->num_blue_values; for ( n = 0; n < count; n++ ) - cpriv->blue_values[n] = (FT_Pos)priv->blue_values[n]; + cpriv->blue_values[n] = cf2_intToFixed( priv->blue_values[n] ); count = cpriv->num_other_blues = priv->num_other_blues; for ( n = 0; n < count; n++ ) - cpriv->other_blues[n] = (FT_Pos)priv->other_blues[n]; + cpriv->other_blues[n] = cf2_intToFixed( priv->other_blues[n] ); count = cpriv->num_family_blues = priv->num_family_blues; for ( n = 0; n < count; n++ ) - cpriv->family_blues[n] = (FT_Pos)priv->family_blues[n]; + cpriv->family_blues[n] = cf2_intToFixed( priv->family_blues[n] ); count = cpriv->num_family_other_blues = priv->num_family_other_blues; for ( n = 0; n < count; n++ ) - cpriv->family_other_blues[n] = (FT_Pos)priv->family_other_blues[n]; + cpriv->family_other_blues[n] = + cf2_intToFixed( priv->family_other_blues[n] ); cpriv->blue_scale = priv->blue_scale; cpriv->blue_shift = (FT_Pos)priv->blue_shift; diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.h b/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.h index d5bce541082fd..345fc8a733561 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.h +++ b/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.h @@ -4,7 +4,7 @@ * * Auxiliary functions for PostScript fonts (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.c b/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.c index c4bcf599ea3ad..5681c3bd0fdbb 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.c +++ b/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.c @@ -4,7 +4,7 @@ * * Type 1 character map support (body). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.h b/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.h index b3702498a5537..445e6a2784f52 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.h +++ b/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.h @@ -4,7 +4,7 @@ * * Type 1 character map support (specification). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.c b/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.c index 4b6b969bcb99e..c74baa8038f3f 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.c +++ b/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.c @@ -4,7 +4,7 @@ * * PostScript Type 1 decoding routines (body). * - * Copyright (C) 2000-2023 by + * Copyright (C) 2000-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.h b/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.h index 0970def960b22..16203b8f734f8 100644 --- a/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.h +++ b/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.h @@ -4,7 +4,7 @@ * * PostScript Type 1 decoding routines (specification). * - * Copyright (C) 2000-2023 by + * Copyright (C) 2000-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.c b/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.c index 4f622e1e440f0..967767b348573 100644 --- a/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.c +++ b/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.c @@ -4,7 +4,7 @@ * * PostScript hinting algorithm (body). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used @@ -1118,7 +1118,7 @@ FT_UInt n; PSH_Point point = glyph->points; FT_Vector* vec = glyph->outline->points; - char* tags = glyph->outline->tags; + FT_Byte* tags = glyph->outline->tags; for ( n = 0; n < glyph->num_points; n++ ) @@ -1171,8 +1171,8 @@ FT_QNEW_ARRAY( glyph->contours, outline->n_contours ) ) goto Exit; - glyph->num_points = (FT_UInt)outline->n_points; - glyph->num_contours = (FT_UInt)outline->n_contours; + glyph->num_points = outline->n_points; + glyph->num_contours = outline->n_contours; { FT_UInt first = 0, next, n; @@ -1186,7 +1186,7 @@ PSH_Point point; - next = (FT_UInt)outline->contours[n] + 1; + next = outline->contours[n] + 1; count = next - first; contour->start = points + first; diff --git a/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.h b/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.h index 3f0ba28a6930b..fb362f061b6e3 100644 --- a/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.h +++ b/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.h @@ -4,7 +4,7 @@ * * PostScript hinting algorithm (specification). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.c b/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.c index d4c5eb32b1c57..435f45838ffd7 100644 --- a/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.c +++ b/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.c @@ -5,7 +5,7 @@ * PostScript hinter global hinting management (body). * Inspired by the new auto-hinter module. * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used diff --git a/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.h b/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.h index 579eb2148a572..c5a5c91316806 100644 --- a/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.h +++ b/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.h @@ -4,7 +4,7 @@ * * PostScript hinter global hinting management. * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.c b/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.c index 974a99e0186d3..9965d5b16bf16 100644 --- a/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.c +++ b/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.c @@ -4,7 +4,7 @@ * * FreeType PostScript hinter module implementation (body). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.h b/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.h index 4bd781a35d76b..62ac0a60fdce5 100644 --- a/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.h +++ b/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.h @@ -4,7 +4,7 @@ * * PostScript hinter module interface (specification). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/pshinter/pshnterr.h b/src/java.desktop/share/native/libfreetype/src/pshinter/pshnterr.h index 97624952d8caf..e9641340e5301 100644 --- a/src/java.desktop/share/native/libfreetype/src/pshinter/pshnterr.h +++ b/src/java.desktop/share/native/libfreetype/src/pshinter/pshnterr.h @@ -4,7 +4,7 @@ * * PS Hinter error codes (specification only). * - * Copyright (C) 2003-2023 by + * Copyright (C) 2003-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.c b/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.c index 680e6d013588f..0b2b549fc2969 100644 --- a/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.c +++ b/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.c @@ -4,7 +4,7 @@ * * FreeType PostScript hints recorder (body). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -806,7 +806,7 @@ ps_hints_stem( PS_Hints hints, FT_UInt dimension, FT_Int count, - FT_Long* stems ) + FT_Pos* stems ) { PS_Dimension dim; diff --git a/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.h b/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.h index 0b2484af12100..7e375af7ba874 100644 --- a/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.h +++ b/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.h @@ -4,7 +4,7 @@ * * Postscript (Type1/Type2) hints recorder (specification). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.c b/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.c index 8203a0465d25e..35d054d1cfb66 100644 --- a/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.c +++ b/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.c @@ -4,7 +4,7 @@ * * psnames module implementation (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.h b/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.h index 0904700bfb8d1..770458316b1e0 100644 --- a/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.h +++ b/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.h @@ -4,7 +4,7 @@ * * High-level psnames module interface (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psnames/psnamerr.h b/src/java.desktop/share/native/libfreetype/src/psnames/psnamerr.h index 0073f8228486b..e123eb65e3930 100644 --- a/src/java.desktop/share/native/libfreetype/src/psnames/psnamerr.h +++ b/src/java.desktop/share/native/libfreetype/src/psnames/psnamerr.h @@ -4,7 +4,7 @@ * * PS names module error codes (specification only). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/psnames/pstables.h b/src/java.desktop/share/native/libfreetype/src/psnames/pstables.h index 7f92cce603960..2a941b0460969 100644 --- a/src/java.desktop/share/native/libfreetype/src/psnames/pstables.h +++ b/src/java.desktop/share/native/libfreetype/src/psnames/pstables.h @@ -4,7 +4,7 @@ * * PostScript glyph names. * - * Copyright (C) 2005-2023 by + * Copyright (C) 2005-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/raster/ftmisc.h b/src/java.desktop/share/native/libfreetype/src/raster/ftmisc.h index 33dbfd631e92e..943f2aa0a50a0 100644 --- a/src/java.desktop/share/native/libfreetype/src/raster/ftmisc.h +++ b/src/java.desktop/share/native/libfreetype/src/raster/ftmisc.h @@ -5,7 +5,7 @@ * Miscellaneous macros for stand-alone rasterizer (specification * only). * - * Copyright (C) 2005-2023 by + * Copyright (C) 2005-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used @@ -92,27 +92,6 @@ #endif - static FT_Long - FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ) - { - FT_Int s; - FT_Long d; - - - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } - - d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c - : 0x7FFFFFFFL ); - - return ( s > 0 ) ? d : -d; - } - - static FT_Long FT_MulDiv_No_Round( FT_Long a, FT_Long b, diff --git a/src/java.desktop/share/native/libfreetype/src/raster/ftraster.c b/src/java.desktop/share/native/libfreetype/src/raster/ftraster.c index 192ca0701a242..e4b7b937d5a8d 100644 --- a/src/java.desktop/share/native/libfreetype/src/raster/ftraster.c +++ b/src/java.desktop/share/native/libfreetype/src/raster/ftraster.c @@ -4,7 +4,7 @@ * * The FreeType glyph rasterizer (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -63,8 +63,7 @@ #else /* !STANDALONE_ */ #include "ftraster.h" -#include /* for FT_MulDiv and FT_MulDiv_No_Round */ -#include /* for FT_Outline_Get_CBox */ +#include /* for FT_MulDiv_No_Round */ #endif /* !STANDALONE_ */ @@ -115,12 +114,12 @@ * a change of direction is detected in the outline, a new profile is * generated until the end of the outline. * - * Note that when all profiles have been generated, the function - * Finalize_Profile_Table() is used to record, for each profile, its - * bottom-most scanline as well as the scanline above its upmost - * boundary. These positions are called `y-turns' because they (sort - * of) correspond to local extrema. They are stored in a sorted list - * built from the top of the render pool as a downwards stack: + * Note that, for all generated profiles, the function End_Profile() + * is used to record all their bottom-most scanlines as well as the + * scanline above their upmost boundary. These positions are called + * `y-turns' because they (sort of) correspond to local extrema. + * They are stored in a sorted list built from the top of the render + * pool as a downwards stack: * * _ _ _______________________________________ * | | @@ -136,7 +135,7 @@ * optimize performance (see technical note on the sweep below). * * Of course, the raster detects whether the two stacks collide and - * handles the situation properly. + * handles the situation by bisecting the job and restarting. * */ @@ -252,7 +251,6 @@ /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */ /* for clipping computations. It simply uses the FT_MulDiv() function */ /* defined in `ftcalc.h'. */ -#define SMulDiv FT_MulDiv #define SMulDiv_No_Round FT_MulDiv_No_Round /* The rasterizer is a very general purpose component; please leave */ @@ -305,16 +303,6 @@ typedef unsigned char Byte, *PByte; typedef char Bool; - - typedef union Alignment_ - { - Long l; - void* p; - void (*f)(void); - - } Alignment, *PAlignment; - - typedef struct TPoint_ { Long x; @@ -327,6 +315,7 @@ #define Flow_Up 0x08U #define Overshoot_Top 0x10U #define Overshoot_Bottom 0x20U +#define Dropout 0x40U /* States of each line, arc, and profile */ @@ -345,31 +334,28 @@ struct TProfile_ { - FT_F26Dot6 X; /* current coordinate during sweep */ PProfile link; /* link to next profile (various purposes) */ - PLong offset; /* start of profile's data in render pool */ + PProfile next; /* next profile in same contour, used */ + /* during drop-out control */ + Int offset; /* bottom or currently scanned array index */ + Int height; /* profile's height in scanlines */ + Int start; /* profile's starting scanline, also use */ + /* as activation counter */ UShort flags; /* Bit 0-2: drop-out mode */ /* Bit 3: profile orientation (up/down) */ /* Bit 4: is top profile? */ /* Bit 5: is bottom profile? */ - Long height; /* profile's height in scanlines */ - Long start; /* profile's starting scanline */ + /* Bit 6: dropout detected */ - Int countL; /* number of lines to step before this */ - /* profile becomes drawable */ - - PProfile next; /* next profile in same contour, used */ - /* during drop-out control */ + FT_F26Dot6 X; /* current coordinate during sweep */ + Long x[1]; /* actually variable array of scanline */ + /* intersections with `height` elements */ }; typedef PProfile TProfileList; typedef PProfile* PProfileList; -#define AlignProfileSize \ - ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( Long ) ) - - #undef RAS_ARG #undef RAS_ARGS #undef RAS_VAR @@ -407,15 +393,13 @@ /* prototypes used for sweep function dispatch */ typedef void - Function_Sweep_Init( RAS_ARGS Short min, - Short max ); + Function_Sweep_Init( RAS_ARGS Int min, + Int max ); typedef void - Function_Sweep_Span( RAS_ARGS Short y, + Function_Sweep_Span( RAS_ARGS Int y, FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ); + FT_F26Dot6 x2 ); typedef void Function_Sweep_Step( RAS_ARG ); @@ -441,8 +425,7 @@ (Bool)( x - FLOOR( x ) >= ras.precision_half ) /* Smart dropout rounding to find which pixel is closer to span ends. */ - /* To mimick Windows, symmetric cases break down indepenently of the */ - /* precision. */ + /* To mimic Windows, symmetric cases do not depend on the precision. */ #define SMART( p, q ) FLOOR( ( (p) + (q) + ras.precision * 63 / 64 ) >> 1 ) #if FT_RENDER_POOL_SIZE > 2048 @@ -462,7 +445,6 @@ Int precision_half; Int precision_scale; Int precision_step; - Int precision_jitter; PLong buff; /* The profiles buffer */ PLong sizeBuff; /* Render pool size */ @@ -471,24 +453,14 @@ FT_Error error; - Int numTurns; /* number of Y-turns in outline */ - Byte dropOutControl; /* current drop_out control method */ - UShort bWidth; /* target bitmap width */ - PByte bOrigin; /* target bitmap bottom-left origin */ - PByte bLine; /* target bitmap current line */ - Long lastX, lastY; Long minY, maxY; UShort num_Profs; /* current number of profiles */ + Int numTurns; /* number of Y-turns in outline */ - Bool fresh; /* signals a fresh new profile which */ - /* `start' field must be completed */ - Bool joint; /* signals that the last arc ended */ - /* exactly on a scanline. Allows */ - /* removal of doublets */ PProfile cProfile; /* current profile */ PProfile fProfile; /* head of linked list of profiles */ PProfile gProfile; /* contour's first profile in case */ @@ -496,9 +468,14 @@ TStates state; /* rendering state */ - FT_Bitmap target; /* description of target bit/pixmap */ FT_Outline outline; + Int bTop; /* target bitmap max line index */ + Int bRight; /* target bitmap rightmost index */ + Int bPitch; /* target bitmap pitch */ + PByte bOrigin; /* target bitmap bottom-left origin */ + PByte bLine; /* target bitmap current line */ + /* dispatch variables */ Function_Sweep_Init* Proc_Sweep_Init; @@ -563,37 +540,82 @@ * * 256 / (1 << 12) = 0.0625 pixels. * - * `precision_jitter' is an epsilon threshold used in - * `Vertical_Sweep_Span' to deal with small imperfections in the Bezier - * decomposition (after all, we are working with approximations only); - * it avoids switching on additional pixels which would cause artifacts - * otherwise. - * - * The value of `precision_jitter' has been determined heuristically. - * */ if ( High ) { ras.precision_bits = 12; ras.precision_step = 256; - ras.precision_jitter = 30; } else { ras.precision_bits = 6; ras.precision_step = 32; - ras.precision_jitter = 2; } - FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); - ras.precision = 1 << ras.precision_bits; ras.precision_half = ras.precision >> 1; ras.precision_scale = ras.precision >> Pixel_Bits; } + /************************************************************************** + * + * @Function: + * Insert_Y_Turn + * + * @Description: + * Insert a salient into the sorted list placed on top of the render + * pool. + * + * @Input: + * New y scanline position. + * + * @Return: + * SUCCESS on success. FAILURE in case of overflow. + */ + static Bool + Insert_Y_Turns( RAS_ARGS Int y, + Int top ) + { + Int n = ras.numTurns; + PLong y_turns = ras.maxBuff; + + + /* update top value */ + if ( n == 0 || top > y_turns[n] ) + y_turns[n] = top; + + /* look for first y value that is <= */ + while ( n-- && y < y_turns[n] ) + ; + + /* if it is <, simply insert it, ignore if == */ + if ( n < 0 || y > y_turns[n] ) + { + ras.maxBuff--; + if ( ras.maxBuff <= ras.top ) + { + ras.error = FT_THROW( Raster_Overflow ); + return FAILURE; + } + + do + { + Int y2 = (Int)y_turns[n]; + + + y_turns[n] = y; + y = y2; + } while ( n-- >= 0 ); + + ras.numTurns++; + } + + return SUCCESS; + } + + /************************************************************************** * * @Function: @@ -606,52 +628,48 @@ * aState :: * The state/orientation of the new profile. * - * overshoot :: - * Whether the profile's unrounded start position - * differs by at least a half pixel. - * * @Return: * SUCCESS on success. FAILURE in case of overflow or of incoherent * profile. */ static Bool - New_Profile( RAS_ARGS TStates aState, - Bool overshoot ) + New_Profile( RAS_ARGS TStates aState ) { - if ( !ras.fProfile ) + Long e; + + + if ( !ras.cProfile || ras.cProfile->height ) { ras.cProfile = (PProfile)ras.top; - ras.fProfile = ras.cProfile; - ras.top += AlignProfileSize; - } + ras.top = ras.cProfile->x; - if ( ras.top >= ras.maxBuff ) - { - ras.error = FT_THROW( Raster_Overflow ); - return FAILURE; + if ( ras.top >= ras.maxBuff ) + { + FT_TRACE1(( "overflow in New_Profile\n" )); + ras.error = FT_THROW( Raster_Overflow ); + return FAILURE; + } + + ras.cProfile->height = 0; } - ras.cProfile->start = 0; - ras.cProfile->height = 0; - ras.cProfile->offset = ras.top; - ras.cProfile->link = (PProfile)0; - ras.cProfile->next = (PProfile)0; ras.cProfile->flags = ras.dropOutControl; switch ( aState ) { case Ascending_State: ras.cProfile->flags |= Flow_Up; - if ( overshoot ) + if ( IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ras.cProfile->flags |= Overshoot_Bottom; - FT_TRACE6(( " new ascending profile = %p\n", (void *)ras.cProfile )); + e = CEILING( ras.lastY ); break; case Descending_State: - if ( overshoot ) + if ( IS_TOP_OVERSHOOT( ras.lastY ) ) ras.cProfile->flags |= Overshoot_Top; - FT_TRACE6(( " new descending profile = %p\n", (void *)ras.cProfile )); + + e = FLOOR( ras.lastY ); break; default: @@ -660,12 +678,20 @@ return FAILURE; } - if ( !ras.gProfile ) - ras.gProfile = ras.cProfile; + if ( e > ras.maxY ) + e = ras.maxY; + if ( e < ras.minY ) + e = ras.minY; + ras.cProfile->start = (Int)TRUNC( e ); + + FT_TRACE7(( " new %s profile = %p, start = %d\n", + aState == Ascending_State ? "ascending" : "descending", + (void *)ras.cProfile, ras.cProfile->start )); + + if ( ras.lastY == e ) + *ras.top++ = ras.lastX; ras.state = aState; - ras.fresh = TRUE; - ras.joint = FALSE; return SUCCESS; } @@ -677,24 +703,19 @@ * End_Profile * * @Description: - * Finalize the current profile. - * - * @Input: - * overshoot :: - * Whether the profile's unrounded end position differs - * by at least a half pixel. + * Finalize the current profile and record y-turns. * * @Return: * SUCCESS on success. FAILURE in case of overflow or incoherency. */ static Bool - End_Profile( RAS_ARGS Bool overshoot ) + End_Profile( RAS_ARG ) { - Long h; + PProfile p = ras.cProfile; + Int h = (Int)( ras.top - p->x ); + Int bottom, top; - h = (Long)( ras.top - ras.cProfile->offset ); - if ( h < 0 ) { FT_ERROR(( "End_Profile: negative height encountered\n" )); @@ -704,98 +725,46 @@ if ( h > 0 ) { - PProfile oldProfile; + FT_TRACE7(( " ending profile %p, start = %2d, height = %+3d\n", + (void *)p, p->start, p->flags & Flow_Up ? h : -h )); + p->height = h; - FT_TRACE6(( " ending profile %p, start = %ld, height = %ld\n", - (void *)ras.cProfile, ras.cProfile->start, h )); + if ( p->flags & Flow_Up ) + { + if ( IS_TOP_OVERSHOOT( ras.lastY ) ) + p->flags |= Overshoot_Top; - ras.cProfile->height = h; - if ( overshoot ) + bottom = p->start; + top = bottom + h; + p->offset = 0; + p->X = p->x[0]; + } + else { - if ( ras.cProfile->flags & Flow_Up ) - ras.cProfile->flags |= Overshoot_Top; - else - ras.cProfile->flags |= Overshoot_Bottom; + if ( IS_BOTTOM_OVERSHOOT( ras.lastY ) ) + p->flags |= Overshoot_Bottom; + + top = p->start + 1; + bottom = top - h; + p->start = bottom; + p->offset = h - 1; + p->X = p->x[h - 1]; } - oldProfile = ras.cProfile; - ras.cProfile = (PProfile)ras.top; + if ( Insert_Y_Turns( RAS_VARS bottom, top ) ) + return FAILURE; - ras.top += AlignProfileSize; + if ( !ras.gProfile ) + ras.gProfile = p; - ras.cProfile->height = 0; - ras.cProfile->offset = ras.top; + /* preliminary values to be finalized */ + p->next = ras.gProfile; + p->link = (PProfile)ras.top; - oldProfile->next = ras.cProfile; ras.num_Profs++; } - if ( ras.top >= ras.maxBuff ) - { - FT_TRACE1(( "overflow in End_Profile\n" )); - ras.error = FT_THROW( Raster_Overflow ); - return FAILURE; - } - - ras.joint = FALSE; - - return SUCCESS; - } - - - /************************************************************************** - * - * @Function: - * Insert_Y_Turn - * - * @Description: - * Insert a salient into the sorted list placed on top of the render - * pool. - * - * @Input: - * New y scanline position. - * - * @Return: - * SUCCESS on success. FAILURE in case of overflow. - */ - static Bool - Insert_Y_Turn( RAS_ARGS Int y ) - { - PLong y_turns; - Int n; - - - n = ras.numTurns - 1; - y_turns = ras.sizeBuff - ras.numTurns; - - /* look for first y value that is <= */ - while ( n >= 0 && y < y_turns[n] ) - n--; - - /* if it is <, simply insert it, ignore if == */ - if ( n >= 0 && y > y_turns[n] ) - do - { - Int y2 = (Int)y_turns[n]; - - - y_turns[n] = y; - y = y2; - } while ( --n >= 0 ); - - if ( n < 0 ) - { - ras.maxBuff--; - if ( ras.maxBuff <= ras.top ) - { - ras.error = FT_THROW( Raster_Overflow ); - return FAILURE; - } - ras.numTurns++; - ras.sizeBuff[-ras.numTurns] = y; - } - return SUCCESS; } @@ -807,56 +776,29 @@ * * @Description: * Adjust all links in the profiles list. - * - * @Return: - * SUCCESS on success. FAILURE in case of overflow. */ - static Bool + static void Finalize_Profile_Table( RAS_ARG ) { - UShort n; - PProfile p; - + UShort n = ras.num_Profs; + PProfile p = ras.fProfile; + PProfile q; - n = ras.num_Profs; - p = ras.fProfile; - if ( n > 1 && p ) + /* there should be at least two profiles, up and down */ + while ( --n ) { - do - { - Int bottom, top; + q = p->link; + /* fix the contour loop */ + if ( q->next == p->next ) + p->next = q; - if ( n > 1 ) - p->link = (PProfile)( p->offset + p->height ); - else - p->link = NULL; - - if ( p->flags & Flow_Up ) - { - bottom = (Int)p->start; - top = (Int)( p->start + p->height - 1 ); - } - else - { - bottom = (Int)( p->start - p->height + 1 ); - top = (Int)p->start; - p->start = bottom; - p->offset += p->height - 1; - } - - if ( Insert_Y_Turn( RAS_VARS bottom ) || - Insert_Y_Turn( RAS_VARS top + 1 ) ) - return FAILURE; - - p = p->link; - } while ( --n ); + p = q; } - else - ras.fProfile = NULL; - return SUCCESS; + /* null-terminate */ + p->link = NULL; } @@ -986,107 +928,78 @@ Long miny, Long maxy ) { - Long Dx, Dy; - Int e1, e2, f1, f2, size; /* XXX: is `Short' sufficient? */ - Long Ix, Rx, Ax; + Long e, e2, Dx, Dy; + Long Ix, Rx, Ax; + Int size; PLong top; - Dx = x2 - x1; - Dy = y2 - y1; - - if ( Dy <= 0 || y2 < miny || y1 > maxy ) + if ( y2 < miny || y1 > maxy ) return SUCCESS; - if ( y1 < miny ) - { - /* Take care: miny-y1 can be a very large value; we use */ - /* a slow MulDiv function to avoid clipping bugs */ - x1 += SMulDiv( Dx, miny - y1, Dy ); - e1 = (Int)TRUNC( miny ); - f1 = 0; - } - else - { - e1 = (Int)TRUNC( y1 ); - f1 = (Int)FRAC( y1 ); - } + e2 = y2 > maxy ? maxy : FLOOR( y2 ); + e = y1 < miny ? miny : CEILING( y1 ); - if ( y2 > maxy ) - { - /* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */ - e2 = (Int)TRUNC( maxy ); - f2 = 0; - } - else - { - e2 = (Int)TRUNC( y2 ); - f2 = (Int)FRAC( y2 ); - } + if ( y1 == e ) + e += ras.precision; - if ( f1 > 0 ) - { - if ( e1 == e2 ) - return SUCCESS; - else - { - x1 += SMulDiv( Dx, ras.precision - f1, Dy ); - e1 += 1; - } - } - else - if ( ras.joint ) - { - ras.top--; - ras.joint = FALSE; - } - - ras.joint = (char)( f2 == 0 ); + if ( e2 < e ) /* nothing to do */ + return SUCCESS; - if ( ras.fresh ) - { - ras.cProfile->start = e1; - ras.fresh = FALSE; - } + size = (Int)TRUNC( e2 - e ) + 1; + top = ras.top; - size = e2 - e1 + 1; - if ( ras.top + size >= ras.maxBuff ) + if ( top + size >= ras.maxBuff ) { ras.error = FT_THROW( Raster_Overflow ); return FAILURE; } - if ( Dx > 0 ) - { - Ix = SMulDiv_No_Round( ras.precision, Dx, Dy ); - Rx = ( ras.precision * Dx ) % Dy; - Dx = 1; - } - else + Dx = x2 - x1; + Dy = y2 - y1; + + if ( Dx == 0 ) /* very easy */ { - Ix = -SMulDiv_No_Round( ras.precision, -Dx, Dy ); - Rx = ( ras.precision * -Dx ) % Dy; - Dx = -1; + do + *top++ = x1; + while ( --size ); + goto Fin; } - Ax = -Dy; - top = ras.top; + Ix = SMulDiv_No_Round( e - y1, Dx, Dy ); + x1 += Ix; + *top++ = x1; - while ( size > 0 ) + if ( --size ) { - *top++ = x1; + Ax = Dx * ( e - y1 ) - Dy * Ix; /* remainder */ + Ix = FMulDiv( ras.precision, Dx, Dy ); + Rx = Dx * ras.precision - Dy * Ix; /* remainder */ + Dx = 1; - x1 += Ix; - Ax += Rx; - if ( Ax >= 0 ) + if ( x2 < x1 ) + { + Ax = -Ax; + Rx = -Rx; + Dx = -Dx; + } + + do { - Ax -= Dy; - x1 += Dx; + x1 += Ix; + Ax += Rx; + if ( Ax >= Dy ) + { + Ax -= Dy; + x1 += Dx; + } + *top++ = x1; } - size--; + while ( --size ); } + Fin: ras.top = top; return SUCCESS; } @@ -1131,17 +1044,7 @@ Long miny, Long maxy ) { - Bool result, fresh; - - - fresh = ras.fresh; - - result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny ); - - if ( fresh && !ras.fresh ) - ras.cProfile->start = -ras.cProfile->start; - - return result; + return Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny ); } @@ -1181,105 +1084,73 @@ Long miny, Long maxy ) { - Long y1, y2, e, e2, e0; - Short f1; + Long y1, y2, e, e2, dy; + Long dx, x2; - TPoint* start_arc; - - PLong top; + PLong top; y1 = arc[degree].y; y2 = arc[0].y; - top = ras.top; if ( y2 < miny || y1 > maxy ) - goto Fin; - - e2 = FLOOR( y2 ); - - if ( e2 > maxy ) - e2 = maxy; - - e0 = miny; - - if ( y1 < miny ) - e = miny; - else - { - e = CEILING( y1 ); - f1 = (Short)( FRAC( y1 ) ); - e0 = e; - - if ( f1 == 0 ) - { - if ( ras.joint ) - { - top--; - ras.joint = FALSE; - } + return SUCCESS; - *top++ = arc[degree].x; + e2 = y2 > maxy ? maxy : FLOOR( y2 ); + e = y1 < miny ? miny : CEILING( y1 ); - e += ras.precision; - } - } + if ( y1 == e ) + e += ras.precision; - if ( ras.fresh ) - { - ras.cProfile->start = TRUNC( e0 ); - ras.fresh = FALSE; - } + if ( e2 < e ) /* nothing to do */ + return SUCCESS; - if ( e2 < e ) - goto Fin; + top = ras.top; if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) { - ras.top = top; ras.error = FT_THROW( Raster_Overflow ); return FAILURE; } - start_arc = arc; - do { - ras.joint = FALSE; - y2 = arc[0].y; + x2 = arc[0].x; if ( y2 > e ) { - y1 = arc[degree].y; - if ( y2 - y1 >= ras.precision_step ) + dy = y2 - arc[degree].y; + dx = x2 - arc[degree].x; + + /* split condition should be invariant of direction */ + if ( dy > ras.precision_step || + dx > ras.precision_step || + -dx > ras.precision_step ) { splitter( arc ); arc += degree; } else { - *top++ = arc[degree].x + FMulDiv( arc[0].x - arc[degree].x, - e - y1, y2 - y1 ); + *top++ = x2 - FMulDiv( y2 - e, dx, dy ); + e += ras.precision; arc -= degree; - e += ras.precision; } } else { if ( y2 == e ) { - ras.joint = TRUE; - *top++ = arc[0].x; - - e += ras.precision; + *top++ = x2; + e += ras.precision; } - arc -= degree; + arc -= degree; } - } while ( arc >= start_arc && e <= e2 ); + } + while ( e <= e2 ); - Fin: - ras.top = top; + ras.top = top; return SUCCESS; } @@ -1316,7 +1187,7 @@ Long miny, Long maxy ) { - Bool result, fresh; + Bool result; arc[0].y = -arc[0].y; @@ -1325,13 +1196,8 @@ if ( degree > 2 ) arc[3].y = -arc[3].y; - fresh = ras.fresh; - result = Bezier_Up( RAS_VARS degree, arc, splitter, -maxy, -miny ); - if ( fresh && !ras.fresh ) - ras.cProfile->start = -ras.cProfile->start; - arc[0].y = -arc[0].y; return result; } @@ -1362,74 +1228,50 @@ Line_To( RAS_ARGS Long x, Long y ) { - /* First, detect a change of direction */ + TStates state; - switch ( ras.state ) - { - case Unknown_State: - if ( y > ras.lastY ) - { - if ( New_Profile( RAS_VARS Ascending_State, - IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) - return FAILURE; - } - else - { - if ( y < ras.lastY ) - if ( New_Profile( RAS_VARS Descending_State, - IS_TOP_OVERSHOOT( ras.lastY ) ) ) - return FAILURE; - } - break; - case Ascending_State: - if ( y < ras.lastY ) - { - if ( End_Profile( RAS_VARS IS_TOP_OVERSHOOT( ras.lastY ) ) || - New_Profile( RAS_VARS Descending_State, - IS_TOP_OVERSHOOT( ras.lastY ) ) ) - return FAILURE; - } - break; + if ( y == ras.lastY ) + goto Fin; - case Descending_State: - if ( y > ras.lastY ) - { - if ( End_Profile( RAS_VARS IS_BOTTOM_OVERSHOOT( ras.lastY ) ) || - New_Profile( RAS_VARS Ascending_State, - IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) - return FAILURE; - } - break; + /* First, detect a change of direction */ - default: - ; + state = ras.lastY < y ? Ascending_State : Descending_State; + + if ( ras.state != state ) + { + /* finalize current profile if any */ + if ( ras.state != Unknown_State && + End_Profile( RAS_VAR ) ) + goto Fail; + + /* create a new profile */ + if ( New_Profile( RAS_VARS state ) ) + goto Fail; } /* Then compute the lines */ - switch ( ras.state ) + if ( state == Ascending_State ) { - case Ascending_State: if ( Line_Up( RAS_VARS ras.lastX, ras.lastY, x, y, ras.minY, ras.maxY ) ) - return FAILURE; - break; - - case Descending_State: + goto Fail; + } + else + { if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, x, y, ras.minY, ras.maxY ) ) - return FAILURE; - break; - - default: - ; + goto Fail; } + Fin: ras.lastX = x; ras.lastY = y; - return SUCCESS; + + Fail: + return FAILURE; } @@ -1500,7 +1342,7 @@ ymax = y1; } - if ( y2 < ymin || y2 > ymax ) + if ( y2 < FLOOR( ymin ) || y2 > CEILING( ymax ) ) { /* this arc has no given direction, split it! */ Split_Conic( arc ); @@ -1508,8 +1350,12 @@ } else if ( y1 == y3 ) { - /* this arc is flat, ignore it and pop it from the Bezier stack */ + /* this arc is flat, advance position */ + /* and pop it from the Bezier stack */ arc -= 2; + + ras.lastX = x3; + ras.lastY = y3; } else { @@ -1518,18 +1364,13 @@ state_bez = y1 < y3 ? Ascending_State : Descending_State; if ( ras.state != state_bez ) { - Bool o = ( state_bez == Ascending_State ) - ? IS_BOTTOM_OVERSHOOT( y1 ) - : IS_TOP_OVERSHOOT( y1 ); - - /* finalize current profile if any */ if ( ras.state != Unknown_State && - End_Profile( RAS_VARS o ) ) + End_Profile( RAS_VAR ) ) goto Fail; /* create a new profile */ - if ( New_Profile( RAS_VARS state_bez, o ) ) + if ( New_Profile( RAS_VARS state_bez ) ) goto Fail; } @@ -1545,13 +1386,13 @@ ras.minY, ras.maxY ) ) goto Fail; arc -= 2; + + ras.lastX = x3; + ras.lastY = y3; } } while ( arc >= arcs ); - ras.lastX = x3; - ras.lastY = y3; - return SUCCESS; Fail: @@ -1648,7 +1489,7 @@ ymax2 = y2; } - if ( ymin2 < ymin1 || ymax2 > ymax1 ) + if ( ymin2 < FLOOR( ymin1 ) || ymax2 > CEILING( ymax1 ) ) { /* this arc has no given direction, split it! */ Split_Cubic( arc ); @@ -1656,27 +1497,26 @@ } else if ( y1 == y4 ) { - /* this arc is flat, ignore it and pop it from the Bezier stack */ + /* this arc is flat, advance position */ + /* and pop it from the Bezier stack */ arc -= 3; + + ras.lastX = x4; + ras.lastY = y4; } else { - state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State; + state_bez = y1 < y4 ? Ascending_State : Descending_State; /* detect a change of direction */ if ( ras.state != state_bez ) { - Bool o = ( state_bez == Ascending_State ) - ? IS_BOTTOM_OVERSHOOT( y1 ) - : IS_TOP_OVERSHOOT( y1 ); - - /* finalize current profile if any */ if ( ras.state != Unknown_State && - End_Profile( RAS_VARS o ) ) + End_Profile( RAS_VAR ) ) goto Fail; - if ( New_Profile( RAS_VARS state_bez, o ) ) + if ( New_Profile( RAS_VARS state_bez ) ) goto Fail; } @@ -1692,13 +1532,13 @@ ras.minY, ras.maxY ) ) goto Fail; arc -= 3; + + ras.lastX = x4; + ras.lastY = y4; } } while ( arc >= arcs ); - ras.lastX = x4; - ras.lastY = y4; - return SUCCESS; Fail: @@ -1740,6 +1580,11 @@ * * @Return: * SUCCESS on success, FAILURE on error. + * + * @Note: + * Unlike FT_Outline_Decompose(), this function handles the scanmode + * dropout tags in the individual contours. Therefore, it cannot be + * replaced. */ static Bool Decompose_Curve( RAS_ARGS Int first, @@ -1753,7 +1598,7 @@ FT_Vector* points; FT_Vector* point; FT_Vector* limit; - char* tags; + FT_Byte* tags; UInt tag; /* current point's state */ @@ -1974,24 +1819,17 @@ ras.fProfile = NULL; - ras.joint = FALSE; - ras.fresh = FALSE; - - ras.maxBuff = ras.sizeBuff - AlignProfileSize; + ras.cProfile = NULL; - ras.numTurns = 0; + ras.top = ras.buff; + ras.maxBuff = ras.sizeBuff - 1; /* top reserve */ - ras.cProfile = (PProfile)ras.top; - ras.cProfile->offset = ras.top; - ras.num_Profs = 0; + ras.numTurns = 0; + ras.num_Profs = 0; last = -1; for ( i = 0; i < ras.outline.n_contours; i++ ) { - PProfile lastProfile; - Bool o; - - ras.state = Unknown_State; ras.gProfile = NULL; @@ -2001,35 +1839,30 @@ if ( Decompose_Curve( RAS_VARS first, last, flipped ) ) return FAILURE; + /* Note that ras.gProfile can stay nil if the contour was */ + /* too small to be drawn or degenerate. */ + if ( !ras.gProfile ) + continue; + /* we must now check whether the extreme arcs join or not */ if ( FRAC( ras.lastY ) == 0 && ras.lastY >= ras.minY && ras.lastY <= ras.maxY ) - if ( ras.gProfile && - ( ras.gProfile->flags & Flow_Up ) == + if ( ( ras.gProfile->flags & Flow_Up ) == ( ras.cProfile->flags & Flow_Up ) ) ras.top--; - /* Note that ras.gProfile can be nil if the contour was too small */ - /* to be drawn. */ - lastProfile = ras.cProfile; - if ( ras.top != ras.cProfile->offset && - ( ras.cProfile->flags & Flow_Up ) ) - o = IS_TOP_OVERSHOOT( ras.lastY ); - else - o = IS_BOTTOM_OVERSHOOT( ras.lastY ); - if ( End_Profile( RAS_VARS o ) ) + if ( End_Profile( RAS_VAR ) ) return FAILURE; - /* close the `next profile in contour' linked list */ - if ( ras.gProfile ) - lastProfile->next = ras.gProfile; + if ( !ras.fProfile ) + ras.fProfile = ras.gProfile; } - if ( Finalize_Profile_Table( RAS_VAR ) ) - return FAILURE; + if ( ras.fProfile ) + Finalize_Profile_Table( RAS_VAR ); - return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE ); + return SUCCESS; } @@ -2042,24 +1875,11 @@ /*************************************************************************/ - /************************************************************************** - * - * Init_Linked - * - * Initializes an empty linked list. - */ - static void - Init_Linked( TProfileList* l ) - { - *l = NULL; - } - - /************************************************************************** * * InsNew * - * Inserts a new profile in a linked list. + * Inserts a new profile in a linked list, sorted by coordinate. */ static void InsNew( PProfileList list, @@ -2073,10 +1893,8 @@ current = *old; x = profile->X; - while ( current ) + while ( current && current->X < x ) { - if ( x < current->X ) - break; old = ¤t->link; current = *old; } @@ -2088,79 +1906,51 @@ /************************************************************************** * - * DelOld + * Increment * - * Removes an old profile from a linked list. + * Advances all profile in the list to the next scanline. It also + * sorts the trace list in the unlikely case of profile crossing. + * The profiles are inserted in sorted order. We might need a single + * swap to fix it when profiles (contours) cross. + * Bubble sort with immediate restart is good enough and simple. */ static void - DelOld( PProfileList list, - const PProfile profile ) + Increment( PProfileList list, + Int flow ) { - PProfile *old, current; - + PProfile *old, current, next; - old = list; - current = *old; - while ( current ) + /* First, set the new X coordinates and remove exhausted profiles */ + old = list; + while ( *old ) { - if ( current == profile ) + current = *old; + if ( --current->height ) { - *old = current->link; - return; + current->offset += flow; + current->X = current->x[current->offset]; + old = ¤t->link; } - - old = ¤t->link; - current = *old; - } - - /* we should never get there, unless the profile was not part of */ - /* the list. */ - } - - - /************************************************************************** - * - * Sort - * - * Sorts a trace list. In 95%, the list is already sorted. We need - * an algorithm which is fast in this case. Bubble sort is enough - * and simple. - */ - static void - Sort( PProfileList list ) - { - PProfile *old, current, next; - - - /* First, set the new X coordinate of each profile */ - current = *list; - while ( current ) - { - current->X = *current->offset; - current->offset += ( current->flags & Flow_Up ) ? 1 : -1; - current->height--; - current = current->link; + else + *old = current->link; /* remove */ } - /* Then sort them */ + /* Then make sure the list remains sorted */ old = list; current = *old; if ( !current ) return; - next = current->link; - - while ( next ) + while ( current->link ) { + next = current->link; + if ( current->X <= next->X ) { old = ¤t->link; - current = *old; - - if ( !current ) - return; + current = next; } else { @@ -2168,11 +1958,10 @@ current->link = next->link; next->link = current; + /* this is likely the only necessary swap -- restart */ old = list; current = *old; } - - next = current->link; } } @@ -2187,74 +1976,51 @@ */ static void - Vertical_Sweep_Init( RAS_ARGS Short min, - Short max ) + Vertical_Sweep_Init( RAS_ARGS Int min, + Int max ) { FT_UNUSED( max ); - ras.bLine = ras.bOrigin - min * ras.target.pitch; + ras.bLine = ras.bOrigin - min * ras.bPitch; } static void - Vertical_Sweep_Span( RAS_ARGS Short y, + Vertical_Sweep_Span( RAS_ARGS Int y, FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) + FT_F26Dot6 x2 ) { - Long e1, e2; - - Int dropOutControl = left->flags & 7; + Int e1 = (Int)TRUNC( CEILING( x1 ) ); + Int e2 = (Int)TRUNC( FLOOR( x2 ) ); FT_UNUSED( y ); - FT_UNUSED( left ); - FT_UNUSED( right ); - /* in high-precision mode, we need 12 digits after the comma to */ - /* represent multiples of 1/(1<<12) = 1/4096 */ - FT_TRACE7(( " y=%d x=[% .12f;% .12f]", + FT_TRACE7(( " y=%d x=[% .*f;% .*f]", y, - (double)x1 / (double)ras.precision, - (double)x2 / (double)ras.precision )); - - /* Drop-out control */ - - e1 = CEILING( x1 ); - e2 = FLOOR( x2 ); - - /* take care of the special case where both the left */ - /* and right contour lie exactly on pixel centers */ - if ( dropOutControl != 2 && - x2 - x1 - ras.precision <= ras.precision_jitter && - e1 != x1 && e2 != x2 ) - e2 = e1; + ras.precision_bits, (double)x1 / (double)ras.precision, + ras.precision_bits, (double)x2 / (double)ras.precision )); - e1 = TRUNC( e1 ); - e2 = TRUNC( e2 ); - - if ( e2 >= 0 && e1 < ras.bWidth ) + if ( e2 >= 0 && e1 <= ras.bRight ) { - Byte* target; + PByte target; - Int c1, c2; - Byte f1, f2; + Int c1, f1, c2, f2; if ( e1 < 0 ) e1 = 0; - if ( e2 >= ras.bWidth ) - e2 = ras.bWidth - 1; + if ( e2 > ras.bRight ) + e2 = ras.bRight; - FT_TRACE7(( " -> x=[%ld;%ld]", e1, e2 )); + FT_TRACE7(( " -> x=[%d;%d]", e1, e2 )); - c1 = (Short)( e1 >> 3 ); - c2 = (Short)( e2 >> 3 ); + c1 = e1 >> 3; + c2 = e2 >> 3; - f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); - f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); + f1 = 0xFF >> ( e1 & 7 ); + f2 = ~0x7F >> ( e2 & 7 ); target = ras.bLine + c1; c2 -= c1; @@ -2280,163 +2046,50 @@ static void - Vertical_Sweep_Drop( RAS_ARGS Short y, + Vertical_Sweep_Drop( RAS_ARGS Int y, FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) + FT_F26Dot6 x2 ) { - Long e1, e2, pxl; - Short c1, f1; - - - FT_TRACE7(( " y=%d x=[% .12f;% .12f]", - y, - (double)x1 / (double)ras.precision, - (double)x2 / (double)ras.precision )); - - /* Drop-out control */ - - /* e2 x2 x1 e1 */ - /* */ - /* ^ | */ - /* | | */ - /* +-------------+---------------------+------------+ */ - /* | | */ - /* | v */ - /* */ - /* pixel contour contour pixel */ - /* center center */ - - /* drop-out mode scan conversion rules (as defined in OpenType) */ - /* --------------------------------------------------------------- */ - /* 0 1, 2, 3 */ - /* 1 1, 2, 4 */ - /* 2 1, 2 */ - /* 3 same as mode 2 */ - /* 4 1, 2, 5 */ - /* 5 1, 2, 6 */ - /* 6, 7 same as mode 2 */ - - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); - pxl = e1; - - if ( e1 > e2 ) - { - Int dropOutControl = left->flags & 7; - - - if ( e1 == e2 + ras.precision ) - { - switch ( dropOutControl ) - { - case 0: /* simple drop-outs including stubs */ - pxl = e2; - break; - - case 4: /* smart drop-outs including stubs */ - pxl = SMART( x1, x2 ); - break; - - case 1: /* simple drop-outs excluding stubs */ - case 5: /* smart drop-outs excluding stubs */ - - /* Drop-out Control Rules #4 and #6 */ - - /* The specification neither provides an exact definition */ - /* of a `stub' nor gives exact rules to exclude them. */ - /* */ - /* Here the constraints we use to recognize a stub. */ - /* */ - /* upper stub: */ - /* */ - /* - P_Left and P_Right are in the same contour */ - /* - P_Right is the successor of P_Left in that contour */ - /* - y is the top of P_Left and P_Right */ - /* */ - /* lower stub: */ - /* */ - /* - P_Left and P_Right are in the same contour */ - /* - P_Left is the successor of P_Right in that contour */ - /* - y is the bottom of P_Left */ - /* */ - /* We draw a stub if the following constraints are met. */ - /* */ - /* - for an upper or lower stub, there is top or bottom */ - /* overshoot, respectively */ - /* - the covered interval is greater or equal to a half */ - /* pixel */ - - /* upper stub test */ - if ( left->next == right && - left->height <= 0 && - !( left->flags & Overshoot_Top && - x2 - x1 >= ras.precision_half ) ) - goto Exit; - - /* lower stub test */ - if ( right->next == left && - left->start == y && - !( left->flags & Overshoot_Bottom && - x2 - x1 >= ras.precision_half ) ) - goto Exit; - - if ( dropOutControl == 1 ) - pxl = e2; - else - pxl = SMART( x1, x2 ); - break; - - default: /* modes 2, 3, 6, 7 */ - goto Exit; /* no drop-out control */ - } + Int e1 = (Int)TRUNC( x1 ); + Int e2 = (Int)TRUNC( x2 ); + Int c1, f1; - /* undocumented but confirmed: If the drop-out would result in a */ - /* pixel outside of the bounding box, use the pixel inside of the */ - /* bounding box instead */ - if ( pxl < 0 ) - pxl = e1; - else if ( TRUNC( pxl ) >= ras.bWidth ) - pxl = e2; + FT_UNUSED( y ); - /* check that the other pixel isn't set */ - e1 = ( pxl == e1 ) ? e2 : e1; - e1 = TRUNC( e1 ); + /* undocumented but confirmed: If the drop-out would result in a */ + /* pixel outside of the bounding box, use the pixel inside of the */ + /* bounding box instead */ + if ( e1 < 0 || e1 > ras.bRight ) + e1 = e2; - c1 = (Short)( e1 >> 3 ); - f1 = (Short)( e1 & 7 ); + /* otherwise check that the other pixel isn't set */ + else if ( e2 >=0 && e2 <= ras.bRight ) + { + c1 = e2 >> 3; + f1 = 0x80 >> ( e2 & 7 ); - if ( e1 >= 0 && e1 < ras.bWidth && - ras.bLine[c1] & ( 0x80 >> f1 ) ) - goto Exit; - } - else - goto Exit; + if ( ras.bLine[c1] & f1 ) + return; } - e1 = TRUNC( pxl ); - - if ( e1 >= 0 && e1 < ras.bWidth ) + if ( e1 >= 0 && e1 <= ras.bRight ) { - FT_TRACE7(( " -> x=%ld", e1 )); + c1 = e1 >> 3; + f1 = 0x80 >> ( e1 & 7 ); - c1 = (Short)( e1 >> 3 ); - f1 = (Short)( e1 & 7 ); + FT_TRACE7(( " y=%d x=%d%s\n", y, e1, + ras.bLine[c1] & f1 ? " redundant" : "" )); - ras.bLine[c1] |= (char)( 0x80 >> f1 ); + ras.bLine[c1] |= f1; } - - Exit: - FT_TRACE7(( " dropout=%d\n", left->flags & 7 )); } static void Vertical_Sweep_Step( RAS_ARG ) { - ras.bLine -= ras.target.pitch; + ras.bLine -= ras.bPitch; } @@ -2450,8 +2103,8 @@ */ static void - Horizontal_Sweep_Init( RAS_ARGS Short min, - Short max ) + Horizontal_Sweep_Init( RAS_ARGS Int min, + Int max ) { /* nothing, really */ FT_UNUSED_RASTER; @@ -2461,22 +2114,18 @@ static void - Horizontal_Sweep_Span( RAS_ARGS Short y, + Horizontal_Sweep_Span( RAS_ARGS Int y, FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) + FT_F26Dot6 x2 ) { - Long e1, e2; + Long e1 = CEILING( x1 ); + Long e2 = FLOOR( x2 ); - FT_UNUSED( left ); - FT_UNUSED( right ); - - FT_TRACE7(( " x=%d y=[% .12f;% .12f]", + FT_TRACE7(( " x=%d y=[% .*f;% .*f]", y, - (double)x1 / (double)ras.precision, - (double)x2 / (double)ras.precision )); + ras.precision_bits, (double)x1 / (double)ras.precision, + ras.precision_bits, (double)x2 / (double)ras.precision )); /* We should not need this procedure but the vertical sweep */ /* mishandles horizontal lines through pixel centers. So we */ @@ -2484,20 +2133,18 @@ /* */ /* XXX: Can we handle horizontal lines better and drop this? */ - e1 = CEILING( x1 ); - if ( x1 == e1 ) { e1 = TRUNC( e1 ); - if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) + if ( e1 >= 0 && e1 <= ras.bTop ) { - Byte f1; + Int f1; PByte bits; - bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.target.pitch; - f1 = (Byte)( 0x80 >> ( y & 7 ) ); + bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.bPitch; + f1 = 0x80 >> ( y & 7 ); FT_TRACE7(( bits[0] & f1 ? " redundant" : " -> y=%ld edge", e1 )); @@ -2506,20 +2153,18 @@ } } - e2 = FLOOR ( x2 ); - if ( x2 == e2 ) { e2 = TRUNC( e2 ); - if ( e2 >= 0 && (ULong)e2 < ras.target.rows ) + if ( e2 >= 0 && e2 <= ras.bTop ) { - Byte f1; + Int f1; PByte bits; - bits = ras.bOrigin + ( y >> 3 ) - e2 * ras.target.pitch; - f1 = (Byte)( 0x80 >> ( y & 7 ) ); + bits = ras.bOrigin + ( y >> 3 ) - e2 * ras.bPitch; + f1 = 0x80 >> ( y & 7 ); FT_TRACE7(( bits[0] & f1 ? " redundant" : " -> y=%ld edge", e2 )); @@ -2533,122 +2178,42 @@ static void - Horizontal_Sweep_Drop( RAS_ARGS Short y, + Horizontal_Sweep_Drop( RAS_ARGS Int y, FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) + FT_F26Dot6 x2 ) { - Long e1, e2, pxl; + Int e1 = (Int)TRUNC( x1 ); + Int e2 = (Int)TRUNC( x2 ); PByte bits; - Byte f1; - - - FT_TRACE7(( " x=%d y=[% .12f;% .12f]", - y, - (double)x1 / (double)ras.precision, - (double)x2 / (double)ras.precision )); - - /* During the horizontal sweep, we only take care of drop-outs */ - - /* e1 + <-- pixel center */ - /* | */ - /* x1 ---+--> <-- contour */ - /* | */ - /* | */ - /* x2 <--+--- <-- contour */ - /* | */ - /* | */ - /* e2 + <-- pixel center */ - - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); - pxl = e1; - - if ( e1 > e2 ) - { - Int dropOutControl = left->flags & 7; - + Int f1; - if ( e1 == e2 + ras.precision ) - { - switch ( dropOutControl ) - { - case 0: /* simple drop-outs including stubs */ - pxl = e2; - break; - - case 4: /* smart drop-outs including stubs */ - pxl = SMART( x1, x2 ); - break; - - case 1: /* simple drop-outs excluding stubs */ - case 5: /* smart drop-outs excluding stubs */ - /* see Vertical_Sweep_Drop for details */ - - /* rightmost stub test */ - if ( left->next == right && - left->height <= 0 && - !( left->flags & Overshoot_Top && - x2 - x1 >= ras.precision_half ) ) - goto Exit; - - /* leftmost stub test */ - if ( right->next == left && - left->start == y && - !( left->flags & Overshoot_Bottom && - x2 - x1 >= ras.precision_half ) ) - goto Exit; - - if ( dropOutControl == 1 ) - pxl = e2; - else - pxl = SMART( x1, x2 ); - break; - default: /* modes 2, 3, 6, 7 */ - goto Exit; /* no drop-out control */ - } - - /* undocumented but confirmed: If the drop-out would result in a */ - /* pixel outside of the bounding box, use the pixel inside of the */ - /* bounding box instead */ - if ( pxl < 0 ) - pxl = e1; - else if ( (ULong)( TRUNC( pxl ) ) >= ras.target.rows ) - pxl = e2; - - /* check that the other pixel isn't set */ - e1 = ( pxl == e1 ) ? e2 : e1; - - e1 = TRUNC( e1 ); + /* undocumented but confirmed: If the drop-out would result in a */ + /* pixel outside of the bounding box, use the pixel inside of the */ + /* bounding box instead */ + if ( e1 < 0 || e1 > ras.bTop ) + e1 = e2; - bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.target.pitch; - f1 = (Byte)( 0x80 >> ( y & 7 ) ); + /* otherwise check that the other pixel isn't set */ + else if ( e2 >=0 && e2 <= ras.bTop ) + { + bits = ras.bOrigin + ( y >> 3 ) - e2 * ras.bPitch; + f1 = 0x80 >> ( y & 7 ); - if ( e1 >= 0 && - (ULong)e1 < ras.target.rows && - *bits & f1 ) - goto Exit; - } - else - goto Exit; + if ( *bits & f1 ) + return; } - e1 = TRUNC( pxl ); - - if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) + if ( e1 >= 0 && e1 <= ras.bTop ) { - FT_TRACE7(( " -> y=%ld", e1 )); + bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.bPitch; + f1 = 0x80 >> ( y & 7 ); - bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.target.pitch; - f1 = (Byte)( 0x80 >> ( y & 7 ) ); + FT_TRACE7(( " x=%d y=%d%s\n", y, e1, + *bits & f1 ? " redundant" : "" )); - bits[0] |= f1; + *bits |= f1; } - - Exit: - FT_TRACE7(( " dropout=%d\n", left->flags & 7 )); } @@ -2664,116 +2229,61 @@ * * Generic Sweep Drawing routine * + * Note that this routine is executed with the pool containing at least + * two valid profiles (up and down) and two y-turns (top and bottom). + * */ - static Bool + static void Draw_Sweep( RAS_ARG ) { - Short y, y_change, y_height; - - PProfile P, Q, P_Left, P_Right; - - Short min_Y, max_Y, top, bottom, dropouts; - - Long x1, x2, xs, e1, e2; - - TProfileList waiting; - TProfileList draw_left, draw_right; - - - /* initialize empty linked lists */ - - Init_Linked( &waiting ); - - Init_Linked( &draw_left ); - Init_Linked( &draw_right ); - - /* first, compute min and max Y */ - - P = ras.fProfile; - max_Y = (Short)TRUNC( ras.minY ); - min_Y = (Short)TRUNC( ras.maxY ); - - while ( P ) - { - Q = P->link; + Int min_Y, max_Y, dropouts; + Int y, y_turn; - bottom = (Short)P->start; - top = (Short)( P->start + P->height - 1 ); + PProfile *Q, P, P_Left, P_Right; - if ( min_Y > bottom ) - min_Y = bottom; - if ( max_Y < top ) - max_Y = top; + TProfileList waiting = ras.fProfile; + TProfileList draw_left = NULL; + TProfileList draw_right = NULL; - P->X = 0; - InsNew( &waiting, P ); - P = Q; - } + /* use y_turns to set the drawing range */ - /* check the Y-turns */ - if ( ras.numTurns == 0 ) - { - ras.error = FT_THROW( Invalid_Outline ); - return FAILURE; - } + min_Y = (Int)ras.maxBuff[0]; + max_Y = (Int)ras.maxBuff[ras.numTurns] - 1; /* now initialize the sweep */ ras.Proc_Sweep_Init( RAS_VARS min_Y, max_Y ); - /* then compute the distance of each profile from min_Y */ - - P = waiting; - - while ( P ) - { - P->countL = P->start - min_Y; - P = P->link; - } - /* let's go */ - y = min_Y; - y_height = 0; - - if ( ras.numTurns > 0 && - ras.sizeBuff[-ras.numTurns] == min_Y ) - ras.numTurns--; - - while ( ras.numTurns > 0 ) + for ( y = min_Y; y <= max_Y; ) { - /* check waiting list for new activations */ - - P = waiting; + /* check waiting list for new profile activations */ - while ( P ) + Q = &waiting; + while ( *Q ) { - Q = P->link; - P->countL -= y_height; - if ( P->countL == 0 ) + P = *Q; + if ( P->start == y ) { - DelOld( &waiting, P ); + *Q = P->link; /* remove */ + /* each active list contains profiles with the same flow */ + /* left and right are arbitrary, correspond to TrueType */ if ( P->flags & Flow_Up ) InsNew( &draw_left, P ); else InsNew( &draw_right, P ); } - - P = Q; + else + Q = &P->link; } - /* sort the drawing lists */ + y_turn = (Int)*++ras.maxBuff; - Sort( &draw_left ); - Sort( &draw_right ); - - y_change = (Short)ras.sizeBuff[-ras.numTurns--]; - y_height = (Short)( y_change - y ); - - while ( y < y_change ) + do { /* let's trace */ @@ -2784,9 +2294,13 @@ while ( P_Left && P_Right ) { - x1 = P_Left ->X; - x2 = P_Right->X; + Long x1 = P_Left ->X; + Long x2 = P_Right->X; + Long xs; + + /* TrueType should have x2 > x1, but can be opposite */ + /* by mistake or in CFF/Type1, fix it then */ if ( x1 > x2 ) { xs = x1; @@ -2794,205 +2308,130 @@ x2 = xs; } - e1 = FLOOR( x1 ); - e2 = CEILING( x2 ); + if ( CEILING( x1 ) <= FLOOR( x2 ) ) + ras.Proc_Sweep_Span( RAS_VARS y, x1, x2 ); - if ( x2 - x1 <= ras.precision && - e1 != x1 && e2 != x2 ) + /* otherwise, bottom ceiling > top floor, it is a drop-out */ + else { - if ( e1 > e2 || e2 == e1 + ras.precision ) + Int dropOutControl = P_Left->flags & 7; + + + /* Drop-out control */ + + /* e2 x2 x1 e1 */ + /* */ + /* ^ | */ + /* | | */ + /* +-------------+---------------------+------------+ */ + /* | | */ + /* | v */ + /* */ + /* pixel contour contour pixel */ + /* center center */ + + /* drop-out mode scan conversion rules (OpenType specs) */ + /* ------------------------------------------------------- */ + /* bit 0 exclude stubs if set */ + /* bit 1 ignore drop-outs if set */ + /* bit 2 smart rounding if set */ + + if ( dropOutControl & 2 ) + goto Next_Pair; + + /* The specification neither provides an exact definition */ + /* of a `stub' nor gives exact rules to exclude them. */ + /* */ + /* Here the constraints we use to recognize a stub. */ + /* */ + /* upper stub: */ + /* */ + /* - P_Left and P_Right are in the same contour */ + /* - P_Right is the successor of P_Left in that contour */ + /* - y is the top of P_Left and P_Right */ + /* */ + /* lower stub: */ + /* */ + /* - P_Left and P_Right are in the same contour */ + /* - P_Left is the successor of P_Right in that contour */ + /* - y is the bottom of P_Left */ + /* */ + /* We draw a stub if the following constraints are met. */ + /* */ + /* - for an upper or lower stub, there is top or bottom */ + /* overshoot, respectively */ + /* - the covered interval is greater or equal to a half */ + /* pixel */ + + if ( dropOutControl & 1 ) { - Int dropOutControl = P_Left->flags & 7; - - - if ( dropOutControl != 2 ) - { - /* a drop-out was detected */ - - P_Left ->X = x1; - P_Right->X = x2; - - /* mark profile for drop-out processing */ - P_Left->countL = 1; - dropouts++; - } + /* upper stub test */ + if ( P_Left->height == 1 && + P_Left->next == P_Right && + !( P_Left->flags & Overshoot_Top && + x2 - x1 >= ras.precision_half ) ) + goto Next_Pair; + + /* lower stub test */ + if ( P_Left->offset == 0 && + P_Right->next == P_Left && + !( P_Left->flags & Overshoot_Bottom && + x2 - x1 >= ras.precision_half ) ) + goto Next_Pair; + } - goto Skip_To_Next; + /* select the pixel to set and the other pixel */ + if ( dropOutControl & 4 ) + { + x2 = SMART( x1, x2 ); + x1 = x1 > x2 ? x2 + ras.precision : x2 - ras.precision; + } + else + { + x2 = FLOOR ( x2 ); + x1 = CEILING( x1 ); } - } - ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right ); + P_Left ->X = x2; + P_Right->X = x1; - Skip_To_Next: + /* mark profile for drop-out processing */ + P_Left->flags |= Dropout; + dropouts++; + } + Next_Pair: P_Left = P_Left->link; P_Right = P_Right->link; } - /* handle drop-outs _after_ the span drawing -- */ - /* drop-out processing has been moved out of the loop */ - /* for performance tuning */ - if ( dropouts > 0 ) - goto Scan_DropOuts; - - Next_Line: - - ras.Proc_Sweep_Step( RAS_VAR ); - - y++; + /* handle drop-outs _after_ the span drawing */ + P_Left = draw_left; + P_Right = draw_right; - if ( y < y_change ) + while ( dropouts ) { - Sort( &draw_left ); - Sort( &draw_right ); - } - } - - /* now finalize the profiles that need it */ - - P = draw_left; - while ( P ) - { - Q = P->link; - if ( P->height == 0 ) - DelOld( &draw_left, P ); - P = Q; - } - - P = draw_right; - while ( P ) - { - Q = P->link; - if ( P->height == 0 ) - DelOld( &draw_right, P ); - P = Q; - } - } - - /* for gray-scaling, flush the bitmap scanline cache */ - while ( y <= max_Y ) - { - ras.Proc_Sweep_Step( RAS_VAR ); - y++; - } - - return SUCCESS; - - Scan_DropOuts: - - P_Left = draw_left; - P_Right = draw_right; - - while ( P_Left && P_Right ) - { - if ( P_Left->countL ) - { - P_Left->countL = 0; -#if 0 - dropouts--; /* -- this is useful when debugging only */ -#endif - ras.Proc_Sweep_Drop( RAS_VARS y, - P_Left->X, - P_Right->X, - P_Left, - P_Right ); - } - - P_Left = P_Left->link; - P_Right = P_Right->link; - } - - goto Next_Line; - } - - -#ifdef STANDALONE_ - - /************************************************************************** - * - * The following functions should only compile in stand-alone mode, - * i.e., when building this component without the rest of FreeType. - * - */ - - /************************************************************************** - * - * @Function: - * FT_Outline_Get_CBox - * - * @Description: - * Return an outline's `control box'. The control box encloses all - * the outline's points, including Bézier control points. Though it - * coincides with the exact bounding box for most glyphs, it can be - * slightly larger in some situations (like when rotating an outline - * that contains Bézier outside arcs). - * - * Computing the control box is very fast, while getting the bounding - * box can take much more time as it needs to walk over all segments - * and arcs in the outline. To get the latter, you can use the - * `ftbbox' component, which is dedicated to this single task. - * - * @Input: - * outline :: - * A pointer to the source outline descriptor. - * - * @Output: - * acbox :: - * The outline's control box. - * - * @Note: - * See @FT_Glyph_Get_CBox for a discussion of tricky fonts. - */ - - static void - FT_Outline_Get_CBox( const FT_Outline* outline, - FT_BBox *acbox ) - { - if ( outline && acbox ) - { - Long xMin, yMin, xMax, yMax; - - - if ( outline->n_points == 0 ) - { - xMin = 0; - yMin = 0; - xMax = 0; - yMax = 0; - } - else - { - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; - - - xMin = xMax = vec->x; - yMin = yMax = vec->y; - vec++; + if ( P_Left->flags & Dropout ) + { + ras.Proc_Sweep_Drop( RAS_VARS y, P_Left->X, P_Right->X ); - for ( ; vec < limit; vec++ ) - { - Long x, y; + P_Left->flags &= ~Dropout; + dropouts--; + } + P_Left = P_Left->link; + P_Right = P_Right->link; + } - x = vec->x; - if ( x < xMin ) xMin = x; - if ( x > xMax ) xMax = x; + ras.Proc_Sweep_Step( RAS_VAR ); - y = vec->y; - if ( y < yMin ) yMin = y; - if ( y > yMax ) yMax = y; - } + Increment( &draw_left, 1 ); + Increment( &draw_right, -1 ); } - acbox->xMin = xMin; - acbox->xMax = xMax; - acbox->yMin = yMin; - acbox->yMax = yMax; + while ( ++y < y_turn ); } } -#endif /* STANDALONE_ */ - /************************************************************************** * @@ -3019,13 +2458,15 @@ Int band_stack[32]; /* enough to bisect 32-bit int bands */ + FT_TRACE6(( "%s pass [%d..%d]\n", + flipped ? "Horizontal" : "Vertical", + y_min, y_max )); + while ( 1 ) { ras.minY = (Long)y_min * ras.precision; ras.maxY = (Long)y_max * ras.precision; - ras.top = ras.buff; - ras.error = Raster_Err_Ok; if ( Convert_Glyph( RAS_VARS flipped ) ) @@ -3038,6 +2479,9 @@ if ( y_min == y_max ) return ras.error; /* still Raster_Overflow */ + FT_TRACE6(( "band [%d..%d]: to be bisected\n", + y_min, y_max )); + y_mid = ( y_min + y_max ) >> 1; band_stack[band_top++] = y_min; @@ -3045,9 +2489,12 @@ } else { + FT_TRACE6(( "band [%d..%d]: %hd profiles; %td bytes remaining\n", + y_min, y_max, ras.num_Profs, + (char*)ras.maxBuff - (char*)ras.top )); + if ( ras.fProfile ) - if ( Draw_Sweep( RAS_VAR ) ) - return ras.error; + Draw_Sweep( RAS_VAR ); if ( --band_top < 0 ) break; @@ -3076,53 +2523,48 @@ Render_Glyph( RAS_ARG ) { FT_Error error; + Long buffer[FT_MAX_BLACK_POOL]; + ras.buff = buffer; + ras.sizeBuff = (&buffer)[1]; /* Points to right after buffer. */ + Set_High_Precision( RAS_VARS ras.outline.flags & FT_OUTLINE_HIGH_PRECISION ); + ras.dropOutControl = 0; + if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) - ras.dropOutControl = 2; - else - { - if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) - ras.dropOutControl = 4; - else - ras.dropOutControl = 0; + ras.dropOutControl |= 2; - if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) - ras.dropOutControl += 1; - } + if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) + ras.dropOutControl |= 4; - /* Vertical Sweep */ - FT_TRACE7(( "Vertical pass (ftraster)\n" )); + if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) + ras.dropOutControl |= 1; + + FT_TRACE6(( "BW Raster: precision 1/%d, dropout mode %d\n", + ras.precision, ras.dropOutControl )); + /* Vertical Sweep */ ras.Proc_Sweep_Init = Vertical_Sweep_Init; ras.Proc_Sweep_Span = Vertical_Sweep_Span; ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; ras.Proc_Sweep_Step = Vertical_Sweep_Step; - ras.bWidth = (UShort)ras.target.width; - ras.bOrigin = (Byte*)ras.target.buffer; - - if ( ras.target.pitch > 0 ) - ras.bOrigin += (Long)( ras.target.rows - 1 ) * ras.target.pitch; - - error = Render_Single_Pass( RAS_VARS 0, 0, (Int)ras.target.rows - 1 ); + error = Render_Single_Pass( RAS_VARS 0, 0, ras.bTop ); if ( error ) return error; /* Horizontal Sweep */ if ( !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ) ) { - FT_TRACE7(( "Horizontal pass (ftraster)\n" )); - ras.Proc_Sweep_Init = Horizontal_Sweep_Init; ras.Proc_Sweep_Span = Horizontal_Sweep_Span; ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; ras.Proc_Sweep_Step = Horizontal_Sweep_Step; - error = Render_Single_Pass( RAS_VARS 1, 0, (Int)ras.target.width - 1 ); + error = Render_Single_Pass( RAS_VARS 1, 0, ras.bRight ); if ( error ) return error; } @@ -3233,8 +2675,6 @@ black_TWorker worker[1]; #endif - Long buffer[FT_MAX_BLACK_POOL]; - if ( !raster ) return FT_THROW( Raster_Uninitialized ); @@ -3243,7 +2683,7 @@ return FT_THROW( Invalid_Outline ); /* return immediately if the outline is empty */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) + if ( outline->n_points == 0 || outline->n_contours == 0 ) return Raster_Err_Ok; if ( !outline->contours || !outline->points ) @@ -3269,10 +2709,14 @@ return FT_THROW( Invalid_Argument ); ras.outline = *outline; - ras.target = *target_map; - ras.buff = buffer; - ras.sizeBuff = (&buffer)[1]; /* Points to right after buffer. */ + ras.bTop = (Int)target_map->rows - 1; + ras.bRight = (Int)target_map->width - 1; + ras.bPitch = (Int)target_map->pitch; + ras.bOrigin = (PByte)target_map->buffer; + + if ( ras.bPitch > 0 ) + ras.bOrigin += ras.bTop * ras.bPitch; return Render_Glyph( RAS_VAR ); } diff --git a/src/java.desktop/share/native/libfreetype/src/raster/ftraster.h b/src/java.desktop/share/native/libfreetype/src/raster/ftraster.h index b511b3a99e9c5..ad9cb1b9fe0dd 100644 --- a/src/java.desktop/share/native/libfreetype/src/raster/ftraster.h +++ b/src/java.desktop/share/native/libfreetype/src/raster/ftraster.h @@ -4,7 +4,7 @@ * * The FreeType glyph rasterizer (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used diff --git a/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.c b/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.c index 6d442b1ff8c52..fd9f174f2e1fa 100644 --- a/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.c +++ b/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.c @@ -4,7 +4,7 @@ * * The FreeType glyph rasterizer interface (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.h b/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.h index cec35c8528ac3..cf3e73c0a248b 100644 --- a/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.h +++ b/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.h @@ -4,7 +4,7 @@ * * The FreeType glyph rasterizer interface (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/raster/rasterrs.h b/src/java.desktop/share/native/libfreetype/src/raster/rasterrs.h index 989d8b44be157..326d42e0438e2 100644 --- a/src/java.desktop/share/native/libfreetype/src/raster/rasterrs.h +++ b/src/java.desktop/share/native/libfreetype/src/raster/rasterrs.h @@ -4,7 +4,7 @@ * * monochrome renderer error codes (specification only). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.c b/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.c index 33712162e00db..76181568af9f3 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.c +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.c @@ -4,7 +4,7 @@ * * PNG Bitmap glyph support. * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * Google, Inc. * Written by Stuart Gill and Behdad Esfahbod. * diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.h b/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.h index 903bd2bc3482d..6e7a5c08e712a 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.h @@ -4,7 +4,7 @@ * * PNG Bitmap glyph support. * - * Copyright (C) 2013-2023 by + * Copyright (C) 2013-2024 by * Google, Inc. * Written by Stuart Gill and Behdad Esfahbod. * diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.c b/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.c index 0925940b03f22..81072207b4908 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.c +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.c @@ -4,7 +4,7 @@ * * High-level SFNT driver interface (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -49,6 +49,10 @@ #include #endif +#ifdef TT_CONFIG_OPTION_GPOS_KERNING +#include "ttgpos.h" +#endif + #include "ttcmap.h" #include "ttkern.h" #include "ttmtx.h" @@ -1249,6 +1253,12 @@ #define PUT_PS_NAMES( a ) a #else #define PUT_PS_NAMES( a ) NULL +#endif + +#ifdef TT_CONFIG_OPTION_GPOS_KERNING +#define PUT_GPOS_KERNING( a ) a +#else +#define PUT_GPOS_KERNING( a ) NULL #endif FT_DEFINE_SFNT_INTERFACE( @@ -1274,6 +1284,8 @@ tt_face_free_name, /* TT_Free_Table_Func free_name */ tt_face_load_kern, /* TT_Load_Table_Func load_kern */ + PUT_GPOS_KERNING( tt_face_load_gpos ), + /* TT_Load_Table_Func load_gpos */ tt_face_load_gasp, /* TT_Load_Table_Func load_gasp */ tt_face_load_pclt, /* TT_Load_Table_Func load_init */ @@ -1292,6 +1304,9 @@ /* since version 2.1.8 */ tt_face_get_kerning, /* TT_Face_GetKerningFunc get_kerning */ + PUT_GPOS_KERNING( tt_face_get_gpos_kerning ), + /* TT_Face_GetKerningFunc get_gpos_kerning */ + /* since version 2.2 */ tt_face_load_font_dir, /* TT_Load_Table_Func load_font_dir */ tt_face_load_hmtx, /* TT_Load_Metrics_Func load_hmtx */ diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.h b/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.h index 2445958b69f42..6f71489fdc17f 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.h @@ -4,7 +4,7 @@ * * High-level SFNT driver interface (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/sferrors.h b/src/java.desktop/share/native/libfreetype/src/sfnt/sferrors.h index e7a8eb04bb883..d3ca1d9aa8b3b 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/sferrors.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/sferrors.h @@ -4,7 +4,7 @@ * * SFNT error codes (specification only). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.c b/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.c index f5d66ef8403a1..6ee4e5e939b47 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.c +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.c @@ -4,7 +4,7 @@ * * SFNT object management (base). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -40,6 +40,10 @@ #include "ttbdf.h" #endif +#ifdef TT_CONFIG_OPTION_GPOS_KERNING +#include "ttgpos.h" +#endif + /************************************************************************** * @@ -1026,6 +1030,10 @@ LOAD_( gasp ); LOAD_( kern ); +#ifdef TT_CONFIG_OPTION_GPOS_KERNING + LOAD_( gpos ); +#endif + face->root.num_glyphs = face->max_profile.numGlyphs; /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes */ @@ -1119,7 +1127,11 @@ flags |= FT_FACE_FLAG_VERTICAL; /* kerning available ? */ - if ( TT_FACE_HAS_KERNING( face ) ) + if ( TT_FACE_HAS_KERNING( face ) +#ifdef TT_CONFIG_OPTION_GPOS_KERNING + || face->gpos_kerning_available +#endif + ) flags |= FT_FACE_FLAG_KERNING; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT @@ -1470,6 +1482,11 @@ /* freeing the kerning table */ tt_face_done_kern( face ); +#ifdef TT_CONFIG_OPTION_GPOS_KERNING + /* freeing the GPOS table */ + tt_face_done_gpos( face ); +#endif + /* freeing the collection table */ FT_FREE( face->ttc_header.offsets ); face->ttc_header.count = 0; diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.h b/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.h index 906aebbf904fe..90847d9573227 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.h @@ -4,7 +4,7 @@ * * SFNT object management (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.c b/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.c index 7c0ce2205e67b..14514bf9574cd 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.c +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.c @@ -4,7 +4,7 @@ * * WOFF format management (base). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -18,6 +18,7 @@ #include "sfwoff.h" #include +#include #include #include #include @@ -149,6 +150,7 @@ /* Miscellaneous checks. */ if ( woff.length != stream->size || woff.num_tables == 0 || + woff.num_tables > 0xFFFU || 44 + woff.num_tables * 20UL >= woff.length || 12 + woff.num_tables * 16UL >= woff.totalSfntSize || ( woff.totalSfntSize & 3 ) != 0 || @@ -169,21 +171,11 @@ /* Write sfnt header. */ { - FT_UInt searchRange, entrySelector, rangeShift, x; + FT_Int entrySelector = FT_MSB( woff.num_tables ); + FT_Int searchRange = ( 1 << entrySelector ) * 16; + FT_Int rangeShift = woff.num_tables * 16 - searchRange; - x = woff.num_tables; - entrySelector = 0; - while ( x ) - { - x >>= 1; - entrySelector += 1; - } - entrySelector--; - - searchRange = ( 1 << entrySelector ) * 16; - rangeShift = woff.num_tables * 16 - searchRange; - WRITE_ULONG ( sfnt_header, woff.flavor ); WRITE_USHORT( sfnt_header, woff.num_tables ); WRITE_USHORT( sfnt_header, searchRange ); diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.h b/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.h index d4384227376b5..a04735ffe280f 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.h @@ -4,7 +4,7 @@ * * WOFFF format management (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.c b/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.c index 2be44a347ad95..589b3e0c6b77d 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.c +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.c @@ -4,7 +4,7 @@ * * WOFF2 format management (base). * - * Copyright (C) 2019-2023 by + * Copyright (C) 2019-2024 by * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -18,6 +18,7 @@ #include "sfwoff2.h" #include "woff2tags.h" #include +#include #include #include @@ -289,23 +290,15 @@ FT_ULong checksum = 0; FT_ULong aligned_size = size & ~3UL; FT_ULong i; - FT_ULong v; + FT_Int shift; for ( i = 0; i < aligned_size; i += 4 ) - checksum += ( (FT_ULong)buf[i ] << 24 ) | - ( (FT_ULong)buf[i + 1] << 16 ) | - ( (FT_ULong)buf[i + 2] << 8 ) | - ( (FT_ULong)buf[i + 3] << 0 ); + checksum += FT_NEXT_ULONG( buf ); - /* If size is not aligned to 4, treat as if it is padded with 0s. */ - if ( size != aligned_size ) - { - v = 0; - for ( i = aligned_size ; i < size; ++i ) - v |= (FT_ULong)buf[i] << ( 24 - 8 * ( i & 3 ) ); - checksum += v; - } + /* remaining bytes can be shifted and added one at a time */ + for ( shift = 24; i < size; i++, shift -= 8 ) + checksum += (FT_UInt32)FT_NEXT_BYTE( buf ) << shift; return checksum; } @@ -1799,7 +1792,6 @@ FT_Byte* sfnt = NULL; FT_Stream sfnt_stream = NULL; - FT_Byte* sfnt_header; FT_ULong sfnt_size; FT_Byte* uncompressed_buf = NULL; @@ -1853,6 +1845,7 @@ /* Miscellaneous checks. */ if ( woff2.length != stream->size || woff2.num_tables == 0 || + woff2.num_tables > 0xFFFU || 48 + woff2.num_tables * 20UL >= woff2.length || ( woff2.metaOffset == 0 && ( woff2.metaLength != 0 || woff2.metaOrigLength != 0 ) ) || @@ -2143,6 +2136,13 @@ WOFF2_TtcFont ttc_font = woff2.ttc_fonts + face_index; + if ( ttc_font->num_tables == 0 || ttc_font->num_tables > 0xFFFU ) + { + FT_ERROR(( "woff2_open_font: invalid WOFF2 CollectionFontEntry\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + /* Create a temporary array. */ if ( FT_QNEW_ARRAY( temp_indices, ttc_font->num_tables ) ) @@ -2198,27 +2198,15 @@ FT_NEW( sfnt_stream ) ) goto Exit; - sfnt_header = sfnt; - - WRITE_ULONG( sfnt_header, woff2.flavor ); - - if ( woff2.num_tables ) { - FT_UInt searchRange, entrySelector, rangeShift, x; + FT_Byte* sfnt_header = sfnt; + FT_Int entrySelector = FT_MSB( woff2.num_tables ); + FT_Int searchRange = ( 1 << entrySelector ) * 16; + FT_Int rangeShift = woff2.num_tables * 16 - searchRange; - x = woff2.num_tables; - entrySelector = 0; - while ( x ) - { - x >>= 1; - entrySelector += 1; - } - entrySelector--; - - searchRange = ( 1 << entrySelector ) * 16; - rangeShift = ( woff2.num_tables * 16 ) - searchRange; + WRITE_ULONG ( sfnt_header, woff2.flavor ); WRITE_USHORT( sfnt_header, woff2.num_tables ); WRITE_USHORT( sfnt_header, searchRange ); WRITE_USHORT( sfnt_header, entrySelector ); diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.h b/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.h index 4901286ee085b..f41140648dc4e 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.h @@ -4,7 +4,7 @@ * * WOFFF2 format management (specification). * - * Copyright (C) 2019-2023 by + * Copyright (C) 2019-2024 by * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.c index 9ba25dcbc1385..28f4d1173c06f 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.c +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.c @@ -4,7 +4,7 @@ * * TrueType character mapping table (cmap) support (body). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.h b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.h index ff52917ed5bc0..e2c5e72bf0292 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.h @@ -4,7 +4,7 @@ * * TrueType character mapping table (cmap) support (specification). * - * Copyright (C) 2002-2023 by + * Copyright (C) 2002-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmapc.h b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmapc.h index 0af48c2478af0..370898363f34c 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmapc.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmapc.h @@ -4,7 +4,7 @@ * * TT CMAP classes definitions (specification only). * - * Copyright (C) 2009-2023 by + * Copyright (C) 2009-2024 by * Oran Agra and Mickey Gabel. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.c index 281e7135eea82..b37658dde9ec0 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.c +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.c @@ -4,7 +4,7 @@ * * TrueType and OpenType colored glyph layer support (body). * - * Copyright (C) 2018-2023 by + * Copyright (C) 2018-2024 by * David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg. * * Originally written by Shao Yu Zhang . @@ -208,18 +208,19 @@ colr->num_base_glyphs = FT_NEXT_USHORT( p ); base_glyph_offset = FT_NEXT_ULONG( p ); - if ( base_glyph_offset >= table_size ) + if ( table_size <= base_glyph_offset ) goto InvalidTable; - if ( colr->num_base_glyphs * BASE_GLYPH_SIZE > - table_size - base_glyph_offset ) + if ( ( table_size - base_glyph_offset ) / BASE_GLYPH_SIZE + < colr->num_base_glyphs ) goto InvalidTable; layer_offset = FT_NEXT_ULONG( p ); colr->num_layers = FT_NEXT_USHORT( p ); - if ( layer_offset >= table_size ) + if ( table_size <= layer_offset ) goto InvalidTable; - if ( colr->num_layers * LAYER_SIZE > table_size - layer_offset ) + if ( ( table_size - layer_offset ) / LAYER_SIZE + < colr->num_layers ) goto InvalidTable; if ( colr->version == 1 ) @@ -229,14 +230,14 @@ base_glyphs_offset_v1 = FT_NEXT_ULONG( p ); - if ( base_glyphs_offset_v1 >= table_size - 4 ) + if ( table_size - 4 <= base_glyphs_offset_v1 ) goto InvalidTable; p1 = (FT_Byte*)( table + base_glyphs_offset_v1 ); num_base_glyphs_v1 = FT_PEEK_ULONG( p1 ); - if ( num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE > - table_size - base_glyphs_offset_v1 ) + if ( ( table_size - base_glyphs_offset_v1 ) / BASE_GLYPH_PAINT_RECORD_SIZE + < num_base_glyphs_v1 ) goto InvalidTable; colr->num_base_glyphs_v1 = num_base_glyphs_v1; @@ -244,19 +245,19 @@ layer_offset_v1 = FT_NEXT_ULONG( p ); - if ( layer_offset_v1 >= table_size ) + if ( table_size <= layer_offset_v1 ) goto InvalidTable; if ( layer_offset_v1 ) { - if ( layer_offset_v1 >= table_size - 4 ) + if ( table_size - 4 <= layer_offset_v1 ) goto InvalidTable; p1 = (FT_Byte*)( table + layer_offset_v1 ); num_layers_v1 = FT_PEEK_ULONG( p1 ); - if ( num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE > - table_size - layer_offset_v1 ) + if ( ( table_size - layer_offset_v1 ) / LAYER_V1_LIST_PAINT_OFFSET_SIZE + < num_layers_v1 ) goto InvalidTable; colr->num_layers_v1 = num_layers_v1; @@ -279,7 +280,7 @@ clip_list_offset = FT_NEXT_ULONG( p ); - if ( clip_list_offset >= table_size ) + if ( table_size <= clip_list_offset ) goto InvalidTable; if ( clip_list_offset ) @@ -311,7 +312,7 @@ goto InvalidTable; var_store_offset = FT_NEXT_ULONG( p ); - if ( var_store_offset >= table_size ) + if ( table_size <= var_store_offset ) goto InvalidTable; if ( var_store_offset ) @@ -661,6 +662,7 @@ FT_UInt32 first_layer_index; + ENSURE_READ_BYTES( 5 ); num_layers = FT_NEXT_BYTE( p ); if ( num_layers > colr->num_layers_v1 ) return 0; @@ -1278,7 +1280,8 @@ while ( min < max ) { - FT_UInt mid = min + ( max - min ) / 2; + FT_UInt mid = min + ( max - min ) / 2; + FT_UShort gid; /* * `base_glyph_begin` is the beginning of `BaseGlyphV1List`; @@ -1287,8 +1290,7 @@ */ FT_Byte *p = base_glyph_begin + 4 + mid * BASE_GLYPH_PAINT_RECORD_SIZE; - FT_UShort gid = FT_NEXT_USHORT( p ); - + gid = FT_NEXT_USHORT( p ); if ( gid < glyph_id ) min = mid + 1; diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.h b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.h index 20c85f0359fe7..30031464c7371 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.h @@ -4,7 +4,7 @@ * * TrueType and OpenType colored glyph layer support (specification). * - * Copyright (C) 2018-2023 by + * Copyright (C) 2018-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * Originally written by Shao Yu Zhang . diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.c index 46ae08596f39b..997eb869ffcaf 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.c +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.c @@ -4,7 +4,7 @@ * * TrueType and OpenType color palette support (body). * - * Copyright (C) 2018-2023 by + * Copyright (C) 2018-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * Originally written by Shao Yu Zhang . diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.h b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.h index 8e9913f0ccd4a..bb301ae88b6a0 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.h @@ -4,7 +4,7 @@ * * TrueType and OpenType color palette support (specification). * - * Copyright (C) 2018-2023 by + * Copyright (C) 2018-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * Originally written by Shao Yu Zhang . diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.c index a47d08bd6de66..f0411366af49d 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.c +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.c @@ -5,7 +5,7 @@ * Load the basic TrueType kerning table. This doesn't handle * kerning data within the GPOS table at the moment. * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.h b/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.h index 960c7da4946d7..a54e51df12d96 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.h @@ -5,7 +5,7 @@ * Load the basic TrueType kerning table. This doesn't handle * kerning data within the GPOS table at the moment. * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.c index 7b44e9cd2e71c..c3a5fae2cb9b3 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.c +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.c @@ -5,7 +5,7 @@ * Load the basic TrueType tables, i.e., tables that can be either in * TTF or OTF fonts (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -1046,7 +1046,7 @@ FT_LOCAL_DEF( void ) tt_face_free_name( TT_Face face ) { - FT_Memory memory = face->root.driver->root.memory; + FT_Memory memory = face->root.memory; TT_NameTable table = &face->name_table; diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.h b/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.h index 1499dd5735f58..2b1d62d9bd9d5 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.h @@ -5,7 +5,7 @@ * Load the basic TrueType tables, i.e., tables that can be either in * TTF or OTF fonts (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.c index 38ee9ae728a1d..2788411856360 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.c +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.c @@ -4,7 +4,7 @@ * * Load the metrics tables common to TTF and OTF fonts (body). * - * Copyright (C) 2006-2023 by + * Copyright (C) 2006-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.h b/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.h index 56d2b62766164..34b3c0e18f2d3 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.h @@ -4,7 +4,7 @@ * * Load the metrics tables common to TTF and OTF fonts (specification). * - * Copyright (C) 2006-2023 by + * Copyright (C) 2006-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.c index 1dfad4298bd67..5698a62c8d1fb 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.c +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.c @@ -5,7 +5,7 @@ * PostScript name table processing for TrueType and OpenType fonts * (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -204,8 +204,8 @@ /* now load the name strings */ if ( num_names ) { - FT_ULong p; - FT_Byte* strings; + FT_Byte* p; + FT_Byte* p_end; post_len -= (FT_ULong)num_glyphs * 2; @@ -214,36 +214,36 @@ post_len + 1 ) ) goto Fail; - strings = (FT_Byte*)( name_strings + num_names ); - if ( FT_STREAM_READ( strings, post_len ) ) + p = (FT_Byte*)( name_strings + num_names ); + if ( FT_STREAM_READ( p, post_len ) ) goto Fail; + p_end = p + post_len; + /* convert from Pascal- to C-strings and set pointers */ - for ( p = 0, n = 0; p < post_len && n < num_names; n++ ) + for ( n = 0; p < p_end && n < num_names; n++ ) { - FT_UInt len = strings[p]; + FT_UInt len = *p; - if ( len > 63U ) - { - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } + /* names in the Adobe Glyph List are shorter than 40 characters */ + if ( len >= 40U ) + FT_TRACE4(( "load_format_20: unusual %u-char name found\n", len )); - strings[p] = 0; - name_strings[n] = strings + p + 1; - p += len + 1; + *p++ = 0; + name_strings[n] = p; + p += len; } - strings[post_len] = 0; + *p_end = 0; /* deal with missing or insufficient string data */ if ( n < num_names ) { FT_TRACE4(( "load_format_20: %hu PostScript names are truncated\n", - num_names - n )); + (FT_UShort)( num_names - n ) )); for ( ; n < num_names; n++ ) - name_strings[n] = strings + post_len; + name_strings[n] = p_end; } } @@ -436,13 +436,8 @@ format = face->postscript.FormatType; - if ( format == 0x00010000L ) - { - if ( idx < 258 ) /* paranoid checking */ - *PSname = MAC_NAME( idx ); - } - else if ( format == 0x00020000L || - format == 0x00025000L ) + if ( format == 0x00020000L || + format == 0x00025000L ) { TT_Post_Names names = &face->postscript_names; @@ -466,6 +461,11 @@ } } + /* version 1.0 is only valid with 258 glyphs */ + else if ( format == 0x00010000L && + face->max_profile.numGlyphs == 258 ) + *PSname = MAC_NAME( idx ); + /* nothing to do for format == 0x00030000L */ End: diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.h b/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.h index 528f1c5f2f207..150db6c3981eb 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.h @@ -5,7 +5,7 @@ * PostScript name table processing for TrueType and OpenType fonts * (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.c index 03f90a628d6e6..cb3a8abf18214 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.c +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.c @@ -4,7 +4,7 @@ * * TrueType and OpenType embedded bitmap support (body). * - * Copyright (C) 2005-2023 by + * Copyright (C) 2005-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * Copyright 2013 by Google, Inc. diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.h b/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.h index 07e2db461a5c9..96f80a5842484 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.h @@ -4,7 +4,7 @@ * * TrueType and OpenType embedded bitmap support (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.c b/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.c index eeedd9906be5a..532ccfa1737e8 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.c +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.c @@ -4,7 +4,7 @@ * * WOFF2 Font table tags (base). * - * Copyright (C) 2019-2023 by + * Copyright (C) 2019-2024 by * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.h b/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.h index 1201848e5ecd9..d03b4b41bc9d8 100644 --- a/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.h +++ b/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.h @@ -4,7 +4,7 @@ * * WOFF2 Font table tags (specification). * - * Copyright (C) 2019-2023 by + * Copyright (C) 2019-2024 by * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c b/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c index 0918272f87046..b7c0632a6fa9e 100644 --- a/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c +++ b/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c @@ -4,7 +4,7 @@ * * A new `perfect' anti-aliasing renderer (body). * - * Copyright (C) 2000-2023 by + * Copyright (C) 2000-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -489,7 +489,7 @@ typedef ptrdiff_t FT_PtrDist; typedef struct gray_TWorker_ { - ft_jmp_buf jump_buffer; + FT_BBox cbox; TCoord min_ex, max_ex; /* min and max integer pixel coordinates */ TCoord min_ey, max_ey; @@ -510,6 +510,8 @@ typedef ptrdiff_t FT_PtrDist; FT_Raster_Span_Func render_span; void* render_span_data; + ft_jmp_buf jump_buffer; + } gray_TWorker, *gray_PWorker; #if defined( _MSC_VER ) @@ -997,49 +999,12 @@ typedef ptrdiff_t FT_PtrDist; #endif /* - * Benchmarking shows that using DDA to flatten the quadratic Bézier arcs - * is slightly faster in the following cases: - * - * - When the host CPU is 64-bit. - * - When SSE2 SIMD registers and instructions are available (even on - * x86). - * - * For other cases, using binary splits is actually slightly faster. - */ -#if ( defined( __SSE2__ ) || \ - defined( __x86_64__ ) || \ - defined( _M_AMD64 ) || \ - ( defined( _M_IX86_FP ) && _M_IX86_FP >= 2 ) ) && \ - !defined( __VMS ) -# define FT_SSE2 1 -#else -# define FT_SSE2 0 -#endif - -#if FT_SSE2 || \ - defined( __aarch64__ ) || \ - defined( _M_ARM64 ) -# define BEZIER_USE_DDA 1 -#else -# define BEZIER_USE_DDA 0 -#endif - - /* - * For now, the code that depends on `BEZIER_USE_DDA` requires `FT_Int64` - * to be defined. If `FT_INT64` is not defined, meaning there is no - * 64-bit type available, disable it to avoid compilation errors. See for - * example https://gitlab.freedesktop.org/freetype/freetype/-/issues/1071. + * For now, the code that uses DDA to render conic curves requires + * `FT_Int64` to be defined. See for example + * https://gitlab.freedesktop.org/freetype/freetype/-/issues/1071. */ -#if !defined( FT_INT64 ) -# undef BEZIER_USE_DDA -# define BEZIER_USE_DDA 0 -#endif - -#if BEZIER_USE_DDA -#if FT_SSE2 -# include -#endif +#ifdef FT_INT64 #define LEFT_SHIFT( a, b ) (FT_Int64)( (FT_UInt64)(a) << (b) ) @@ -1095,16 +1060,17 @@ typedef ptrdiff_t FT_PtrDist; return; } - /* We can calculate the number of necessary bisections because */ + /* We can calculate the number of necessary segments because */ /* each bisection predictably reduces deviation exactly 4-fold. */ /* Even 32-bit deviation would vanish after 16 bisections. */ - shift = 0; + shift = 16; do { - dx >>= 2; - shift += 1; + dx >>= 2; + shift--; } while ( dx > ONE_PIXEL / 4 ); + count = 0x10000U >> shift; /* * The (P0,P1,P2) arc equation, for t in [0,1] range: @@ -1150,75 +1116,19 @@ typedef ptrdiff_t FT_PtrDist; * = (B << (33 - N)) + (A << (32 - 2*N)) */ -#if FT_SSE2 - /* Experience shows that for small shift values, */ - /* SSE2 is actually slower. */ - if ( shift > 2 ) - { - union - { - struct { FT_Int64 ax, ay, bx, by; } i; - struct { __m128i a, b; } vec; - - } u; - - union - { - struct { FT_Int32 px_lo, px_hi, py_lo, py_hi; } i; - __m128i vec; - - } v; - - __m128i a, b; - __m128i r, q, q2; - __m128i p; - - - u.i.ax = ax; - u.i.ay = ay; - u.i.bx = bx; - u.i.by = by; - - a = _mm_load_si128( &u.vec.a ); - b = _mm_load_si128( &u.vec.b ); - - r = _mm_slli_epi64( a, 33 - 2 * shift ); - q = _mm_slli_epi64( b, 33 - shift ); - q2 = _mm_slli_epi64( a, 32 - 2 * shift ); - - q = _mm_add_epi64( q2, q ); - - v.i.px_lo = 0; - v.i.px_hi = p0.x; - v.i.py_lo = 0; - v.i.py_hi = p0.y; - - p = _mm_load_si128( &v.vec ); - - for ( count = 1U << shift; count > 0; count-- ) - { - p = _mm_add_epi64( p, q ); - q = _mm_add_epi64( q, r ); - - _mm_store_si128( &v.vec, p ); - - gray_render_line( RAS_VAR_ v.i.px_hi, v.i.py_hi ); - } - - return; - } -#endif /* FT_SSE2 */ + rx = LEFT_SHIFT( ax, shift + shift ); + ry = LEFT_SHIFT( ay, shift + shift ); - rx = LEFT_SHIFT( ax, 33 - 2 * shift ); - ry = LEFT_SHIFT( ay, 33 - 2 * shift ); + qx = LEFT_SHIFT( bx, shift + 17 ) + rx; + qy = LEFT_SHIFT( by, shift + 17 ) + ry; - qx = LEFT_SHIFT( bx, 33 - shift ) + LEFT_SHIFT( ax, 32 - 2 * shift ); - qy = LEFT_SHIFT( by, 33 - shift ) + LEFT_SHIFT( ay, 32 - 2 * shift ); + rx *= 2; + ry *= 2; px = LEFT_SHIFT( p0.x, 32 ); py = LEFT_SHIFT( p0.y, 32 ); - for ( count = 1U << shift; count > 0; count-- ) + do { px += qx; py += qy; @@ -1227,10 +1137,10 @@ typedef ptrdiff_t FT_PtrDist; gray_render_line( RAS_VAR_ (FT_Pos)( px >> 32 ), (FT_Pos)( py >> 32 ) ); - } + } while ( --count ); } -#else /* !BEZIER_USE_DDA */ +#else /* !FT_INT64 */ /* * Note that multiple attempts to speed up the function below @@ -1324,7 +1234,7 @@ typedef ptrdiff_t FT_PtrDist; } while ( --draw ); } -#endif /* !BEZIER_USE_DDA */ +#endif /* !FT_INT64 */ /* @@ -1486,139 +1396,6 @@ typedef ptrdiff_t FT_PtrDist; } - static void - gray_sweep( RAS_ARG ) - { - int fill = ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) ? 0x100 - : INT_MIN; - int coverage; - int y; - - - for ( y = ras.min_ey; y < ras.max_ey; y++ ) - { - PCell cell = ras.ycells[y - ras.min_ey]; - TCoord x = ras.min_ex; - TArea cover = 0; - - unsigned char* line = ras.target.origin - ras.target.pitch * y; - - - for ( ; cell != ras.cell_null; cell = cell->next ) - { - TArea area; - - - if ( cover != 0 && cell->x > x ) - { - FT_FILL_RULE( coverage, cover, fill ); - FT_GRAY_SET( line + x, coverage, cell->x - x ); - } - - cover += (TArea)cell->cover * ( ONE_PIXEL * 2 ); - area = cover - cell->area; - - if ( area != 0 && cell->x >= ras.min_ex ) - { - FT_FILL_RULE( coverage, area, fill ); - line[cell->x] = (unsigned char)coverage; - } - - x = cell->x + 1; - } - - if ( cover != 0 ) /* only if cropped */ - { - FT_FILL_RULE( coverage, cover, fill ); - FT_GRAY_SET( line + x, coverage, ras.max_ex - x ); - } - } - } - - - static void - gray_sweep_direct( RAS_ARG ) - { - int fill = ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) ? 0x100 - : INT_MIN; - int coverage; - int y; - - FT_Span span[FT_MAX_GRAY_SPANS]; - int n = 0; - - - for ( y = ras.min_ey; y < ras.max_ey; y++ ) - { - PCell cell = ras.ycells[y - ras.min_ey]; - TCoord x = ras.min_ex; - TArea cover = 0; - - - for ( ; cell != ras.cell_null; cell = cell->next ) - { - TArea area; - - - if ( cover != 0 && cell->x > x ) - { - FT_FILL_RULE( coverage, cover, fill ); - - span[n].coverage = (unsigned char)coverage; - span[n].x = (short)x; - span[n].len = (unsigned short)( cell->x - x ); - - if ( ++n == FT_MAX_GRAY_SPANS ) - { - /* flush the span buffer and reset the count */ - ras.render_span( y, n, span, ras.render_span_data ); - n = 0; - } - } - - cover += (TArea)cell->cover * ( ONE_PIXEL * 2 ); - area = cover - cell->area; - - if ( area != 0 && cell->x >= ras.min_ex ) - { - FT_FILL_RULE( coverage, area, fill ); - - span[n].coverage = (unsigned char)coverage; - span[n].x = (short)cell->x; - span[n].len = 1; - - if ( ++n == FT_MAX_GRAY_SPANS ) - { - /* flush the span buffer and reset the count */ - ras.render_span( y, n, span, ras.render_span_data ); - n = 0; - } - } - - x = cell->x + 1; - } - - if ( cover != 0 ) /* only if cropped */ - { - FT_FILL_RULE( coverage, cover, fill ); - - span[n].coverage = (unsigned char)coverage; - span[n].x = (short)x; - span[n].len = (unsigned short)( ras.max_ex - x ); - - ++n; - } - - if ( n ) - { - /* flush the span buffer and reset the count */ - ras.render_span( y, n, span, ras.render_span_data ); - n = 0; - } - } - } - - #ifdef STANDALONE_ /************************************************************************** @@ -1934,7 +1711,7 @@ typedef ptrdiff_t FT_PtrDist; if ( continued ) FT_Trace_Enable(); - FT_TRACE7(( "band [%d..%d]: %td cell%s remaining/\n", + FT_TRACE7(( "band [%d..%d]: %td cell%s remaining\n", ras.min_ey, ras.max_ey, ras.cell_null - ras.cell_free, @@ -1952,14 +1729,144 @@ typedef ptrdiff_t FT_PtrDist; } + static void + gray_sweep( RAS_ARG ) + { + int fill = ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) ? 0x100 + : INT_MIN; + int coverage; + int y; + + + for ( y = ras.min_ey; y < ras.max_ey; y++ ) + { + PCell cell = ras.ycells[y - ras.min_ey]; + TCoord x = ras.min_ex; + TArea cover = 0; + + unsigned char* line = ras.target.origin - ras.target.pitch * y; + + + for ( ; cell != ras.cell_null; cell = cell->next ) + { + TArea area; + + + if ( cover != 0 && cell->x > x ) + { + FT_FILL_RULE( coverage, cover, fill ); + FT_GRAY_SET( line + x, coverage, cell->x - x ); + } + + cover += (TArea)cell->cover * ( ONE_PIXEL * 2 ); + area = cover - cell->area; + + if ( area != 0 && cell->x >= ras.min_ex ) + { + FT_FILL_RULE( coverage, area, fill ); + line[cell->x] = (unsigned char)coverage; + } + + x = cell->x + 1; + } + + if ( cover != 0 ) /* only if cropped */ + { + FT_FILL_RULE( coverage, cover, fill ); + FT_GRAY_SET( line + x, coverage, ras.max_ex - x ); + } + } + } + + + static void + gray_sweep_direct( RAS_ARG ) + { + int fill = ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) ? 0x100 + : INT_MIN; + int coverage; + int y; + + FT_Span span[FT_MAX_GRAY_SPANS]; + int n = 0; + + + for ( y = ras.min_ey; y < ras.max_ey; y++ ) + { + PCell cell = ras.ycells[y - ras.min_ey]; + TCoord x = ras.min_ex; + TArea cover = 0; + + + for ( ; cell != ras.cell_null; cell = cell->next ) + { + TArea area; + + + if ( cover != 0 && cell->x > x ) + { + FT_FILL_RULE( coverage, cover, fill ); + + span[n].coverage = (unsigned char)coverage; + span[n].x = (short)x; + span[n].len = (unsigned short)( cell->x - x ); + + if ( ++n == FT_MAX_GRAY_SPANS ) + { + /* flush the span buffer and reset the count */ + ras.render_span( y, n, span, ras.render_span_data ); + n = 0; + } + } + + cover += (TArea)cell->cover * ( ONE_PIXEL * 2 ); + area = cover - cell->area; + + if ( area != 0 && cell->x >= ras.min_ex ) + { + FT_FILL_RULE( coverage, area, fill ); + + span[n].coverage = (unsigned char)coverage; + span[n].x = (short)cell->x; + span[n].len = 1; + + if ( ++n == FT_MAX_GRAY_SPANS ) + { + /* flush the span buffer and reset the count */ + ras.render_span( y, n, span, ras.render_span_data ); + n = 0; + } + } + + x = cell->x + 1; + } + + if ( cover != 0 ) /* only if cropped */ + { + FT_FILL_RULE( coverage, cover, fill ); + + span[n].coverage = (unsigned char)coverage; + span[n].x = (short)x; + span[n].len = (unsigned short)( ras.max_ex - x ); + + ++n; + } + + if ( n ) + { + /* flush the span buffer and reset the count */ + ras.render_span( y, n, span, ras.render_span_data ); + n = 0; + } + } + } + + static int gray_convert_glyph( RAS_ARG ) { - const TCoord yMin = ras.min_ey; - const TCoord yMax = ras.max_ey; - TCell buffer[FT_MAX_GRAY_POOL]; - size_t height = (size_t)( yMax - yMin ); + size_t height = (size_t)( ras.cbox.yMax - ras.cbox.yMin ); size_t n = FT_MAX_GRAY_POOL / 8; TCoord y; TCoord bands[32]; /* enough to accommodate bisections */ @@ -1985,35 +1892,36 @@ typedef ptrdiff_t FT_PtrDist; height = ( height + n - 1 ) / n; } - for ( y = yMin; y < yMax; ) + for ( y = ras.cbox.yMin; y < ras.cbox.yMax; ) { ras.min_ey = y; y += height; - ras.max_ey = FT_MIN( y, yMax ); + ras.max_ey = FT_MIN( y, ras.cbox.yMax ); + + ras.count_ey = ras.max_ey - ras.min_ey; band = bands; - band[1] = ras.min_ey; - band[0] = ras.max_ey; + band[1] = ras.cbox.xMin; + band[0] = ras.cbox.xMax; do { - TCoord width = band[0] - band[1]; - TCoord w; + TCoord i; int error; - for ( w = 0; w < width; ++w ) - ras.ycells[w] = ras.cell_null; + ras.min_ex = band[1]; + ras.max_ex = band[0]; + + /* memory management: zero out and skip ycells */ + for ( i = 0; i < ras.count_ey; ++i ) + ras.ycells[i] = ras.cell_null; - /* memory management: skip ycells */ - n = ( (size_t)width * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) / - sizeof ( TCell ); + n = ( (size_t)ras.count_ey * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) + / sizeof ( TCell ); ras.cell_free = buffer + n; ras.cell = ras.cell_null; - ras.min_ey = band[1]; - ras.max_ey = band[0]; - ras.count_ey = width; error = gray_convert_glyph_inner( RAS_VAR_ continued ); continued = 1; @@ -2031,10 +1939,10 @@ typedef ptrdiff_t FT_PtrDist; return error; /* render pool overflow; we will reduce the render band by half */ - width >>= 1; + i = ( band[0] - band[1] ) >> 1; /* this should never happen even with tiny rendering pool */ - if ( width == 0 ) + if ( i == 0 ) { FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" )); return FT_THROW( Raster_Overflow ); @@ -2042,7 +1950,7 @@ typedef ptrdiff_t FT_PtrDist; band++; band[1] = band[0]; - band[0] += width; + band[0] += i; } while ( band >= bands ); } @@ -2073,7 +1981,7 @@ typedef ptrdiff_t FT_PtrDist; return FT_THROW( Invalid_Outline ); /* return immediately if the outline is empty */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) + if ( outline->n_points == 0 || outline->n_contours == 0 ) return Smooth_Err_Ok; if ( !outline->contours || !outline->points ) @@ -2093,10 +2001,7 @@ typedef ptrdiff_t FT_PtrDist; ras.render_span = (FT_Raster_Span_Func)params->gray_spans; ras.render_span_data = params->user; - ras.min_ex = params->clip_box.xMin; - ras.min_ey = params->clip_box.yMin; - ras.max_ex = params->clip_box.xMax; - ras.max_ey = params->clip_box.yMax; + ras.cbox = params->clip_box; } else { @@ -2122,14 +2027,14 @@ typedef ptrdiff_t FT_PtrDist; ras.render_span = (FT_Raster_Span_Func)NULL; ras.render_span_data = NULL; - ras.min_ex = 0; - ras.min_ey = 0; - ras.max_ex = (FT_Pos)target_map->width; - ras.max_ey = (FT_Pos)target_map->rows; + ras.cbox.xMin = 0; + ras.cbox.yMin = 0; + ras.cbox.xMax = (FT_Pos)target_map->width; + ras.cbox.yMax = (FT_Pos)target_map->rows; } /* exit if nothing to do */ - if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey ) + if ( ras.cbox.xMin >= ras.cbox.xMax || ras.cbox.yMin >= ras.cbox.yMax ) return Smooth_Err_Ok; return gray_convert_glyph( RAS_VAR ); diff --git a/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.h b/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.h index a5001bf40d325..940fbe8c79bdd 100644 --- a/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.h +++ b/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.h @@ -4,7 +4,7 @@ * * FreeType smooth renderer declaration * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/smooth/ftsmerrs.h b/src/java.desktop/share/native/libfreetype/src/smooth/ftsmerrs.h index f4ac93dc410f3..6d41fb8e0fd96 100644 --- a/src/java.desktop/share/native/libfreetype/src/smooth/ftsmerrs.h +++ b/src/java.desktop/share/native/libfreetype/src/smooth/ftsmerrs.h @@ -4,7 +4,7 @@ * * smooth renderer error codes (specification only). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.c b/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.c index 9b0e8886cb332..f0acc1ea4a6e2 100644 --- a/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.c +++ b/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.c @@ -4,7 +4,7 @@ * * Anti-aliasing renderer interface (body). * - * Copyright (C) 2000-2023 by + * Copyright (C) 2000-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.h b/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.h index f8bdc9938b32c..d7b61a9e60ec3 100644 --- a/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.h +++ b/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.h @@ -4,7 +4,7 @@ * * Anti-aliasing renderer interface (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.c b/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.c index d1496fec7fad7..4ab68eb9a12d5 100644 --- a/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.c +++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.c @@ -4,7 +4,7 @@ * * TrueType font driver implementation (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -217,7 +217,20 @@ kerning->y = 0; if ( sfnt ) - kerning->x = sfnt->get_kerning( ttface, left_glyph, right_glyph ); + { + /* Use 'kern' table if available since that can be faster; otherwise */ + /* use GPOS kerning pairs if available. */ + if ( ttface->kern_avail_bits != 0 ) + kerning->x = sfnt->get_kerning( ttface, + left_glyph, + right_glyph ); +#ifdef TT_CONFIG_OPTION_GPOS_KERNING + else if ( ttface->gpos_kerning_available ) + kerning->x = sfnt->get_gpos_kerning( ttface, + left_glyph, + right_glyph ); +#endif + } return 0; } diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.h b/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.h index 757a66f425d5b..3e1cf234fcfd4 100644 --- a/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.h +++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.h @@ -4,7 +4,7 @@ * * High-level TrueType driver interface (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/tterrors.h b/src/java.desktop/share/native/libfreetype/src/truetype/tterrors.h index 008ee99853cbb..7ad937bd04d35 100644 --- a/src/java.desktop/share/native/libfreetype/src/truetype/tterrors.h +++ b/src/java.desktop/share/native/libfreetype/src/truetype/tterrors.h @@ -4,7 +4,7 @@ * * TrueType error codes (specification only). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.c b/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.c index dc427e8a1160a..b656ccf04e3c1 100644 --- a/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.c +++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.c @@ -4,7 +4,7 @@ * * TrueType Glyph Loader (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -353,7 +353,8 @@ FT_Byte c, count; FT_Vector *vec, *vec_limit; FT_Pos x, y; - FT_Short *cont, *cont_limit, last; + FT_UShort *cont, *cont_limit; + FT_Int last; /* check that we can add the contours to the glyph */ @@ -372,7 +373,7 @@ last = -1; for ( ; cont < cont_limit; cont++ ) { - *cont = FT_NEXT_SHORT( p ); + *cont = FT_NEXT_USHORT( p ); if ( *cont <= last ) goto Invalid_Outline; @@ -418,11 +419,9 @@ /* and thus allocate the bytecode array size by ourselves */ if ( n_ins ) { - if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) ) + if ( FT_DUP( exec->glyphIns, p, n_ins ) ) return error; - FT_MEM_COPY( exec->glyphIns, p, (FT_Long)n_ins ); - exec->glyphSize = n_ins; } } @@ -432,7 +431,7 @@ p += n_ins; /* reading the point tags */ - flag = (FT_Byte*)outline->tags; + flag = outline->tags; flag_limit = flag + n_points; FT_ASSERT( flag ); @@ -465,7 +464,7 @@ vec = outline->points; vec_limit = vec + n_points; - flag = (FT_Byte*)outline->tags; + flag = outline->tags; x = 0; for ( ; vec < vec_limit; vec++, flag++ ) @@ -499,7 +498,7 @@ vec = outline->points; vec_limit = vec + n_points; - flag = (FT_Byte*)outline->tags; + flag = outline->tags; y = 0; for ( ; vec < vec_limit; vec++, flag++ ) @@ -532,8 +531,8 @@ *flag = (FT_Byte)( f & ON_CURVE_POINT ); } - outline->n_points = (FT_Short)n_points; - outline->n_contours = (FT_Short)n_contours; + outline->n_points = (FT_UShort)n_points; + outline->n_contours = (FT_UShort)n_contours; load->cursor = p; @@ -754,15 +753,13 @@ FT_UInt start_point, FT_UInt start_contour ) { - zone->n_points = (FT_UShort)load->outline.n_points + 4 - - (FT_UShort)start_point; - zone->n_contours = load->outline.n_contours - - (FT_Short)start_contour; + zone->n_points = load->outline.n_points + 4 - (FT_UShort)start_point; + zone->n_contours = load->outline.n_contours - (FT_UShort)start_contour; zone->org = load->extra_points + start_point; zone->cur = load->outline.points + start_point; zone->orus = load->extra_points2 + start_point; - zone->tags = (FT_Byte*)load->outline.tags + start_point; - zone->contours = (FT_UShort*)load->outline.contours + start_contour; + zone->tags = load->outline.tags + start_point; + zone->contours = load->outline.contours + start_contour; zone->first_point = (FT_UShort)start_point; } @@ -1046,7 +1043,7 @@ current.points = gloader->base.outline.points + num_base_points; current.n_points = gloader->base.outline.n_points - - (short)num_base_points; + (FT_UShort)num_base_points; have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE | WE_HAVE_AN_XY_SCALE | @@ -1059,7 +1056,7 @@ /* get offset */ if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) ) { - FT_UInt num_points = (FT_UInt)gloader->base.outline.n_points; + FT_UInt num_points = gloader->base.outline.n_points; FT_UInt k = (FT_UInt)subglyph->arg1; FT_UInt l = (FT_UInt)subglyph->arg2; FT_Vector* p1; @@ -1721,8 +1718,8 @@ FT_List_Add( &loader->composites, node ); } - start_point = (FT_UInt)gloader->base.outline.n_points; - start_contour = (FT_UInt)gloader->base.outline.n_contours; + start_point = gloader->base.outline.n_points; + start_contour = gloader->base.outline.n_contours; /* for each subglyph, read composite header */ error = face->read_composite_glyph( loader ); @@ -1741,14 +1738,14 @@ if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) || FT_IS_VARIATION( FT_FACE( face ) ) ) { - short i, limit; + FT_UShort i, limit; FT_SubGlyph subglyph; FT_Outline outline = { 0, 0, NULL, NULL, NULL, 0 }; FT_Vector* unrounded = NULL; - limit = (short)gloader->current.num_subglyphs; + limit = (FT_UShort)gloader->current.num_subglyphs; /* construct an outline structure for */ /* communication with `TT_Vary_Apply_Glyph_Deltas' */ @@ -1874,7 +1871,7 @@ linear_hadvance = loader->linear; linear_vadvance = loader->vadvance; - num_base_points = (FT_UInt)gloader->base.outline.n_points; + num_base_points = gloader->base.outline.n_points; error = load_truetype_glyph( loader, (FT_UInt)subglyph->index, @@ -1898,7 +1895,7 @@ loader->vadvance = linear_vadvance; } - num_points = (FT_UInt)gloader->base.outline.n_points; + num_points = gloader->base.outline.n_points; if ( num_points == num_base_points ) continue; @@ -2313,7 +2310,7 @@ * * 1) we have a `tricky' font that heavily relies on the interpreter to * render glyphs correctly, for example DFKai-SB, or - * 2) FT_RENDER_MODE_MONO (i.e, monochome rendering) is requested. + * 2) FT_RENDER_MODE_MONO (i.e, monochrome rendering) is requested. * * In those cases, backward compatibility needs to be turned off to get * correct rendering. The rendering is then completely up to the @@ -2719,7 +2716,7 @@ size->metrics->y_ppem < 24 ) glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; - FT_TRACE1(( " subglyphs = %u, contours = %hd, points = %hd," + FT_TRACE1(( " subglyphs = %u, contours = %hu, points = %hu," " flags = 0x%.3x\n", loader.gloader->base.num_subglyphs, glyph->outline.n_contours, diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.h b/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.h index f18637dce330b..22ea967f30133 100644 --- a/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.h +++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.h @@ -4,7 +4,7 @@ * * TrueType Glyph Loader (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c b/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c index 9d149ea365cf1..4f0083c96b7c4 100644 --- a/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c +++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c @@ -4,7 +4,7 @@ * * TrueType GX Font Variation loader * - * Copyright (C) 2004-2023 by + * Copyright (C) 2004-2024 by * David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. * * This file is part of the FreeType project, and may only be used, @@ -129,9 +129,6 @@ * stream :: * The data stream. * - * size :: - * The size of the table holding the data. - * * @Output: * point_cnt :: * The number of points read. A zero value means that @@ -144,14 +141,14 @@ */ static FT_UShort* ft_var_readpackedpoints( FT_Stream stream, - FT_ULong size, FT_UInt *point_cnt ) { FT_UShort *points = NULL; FT_UInt n; - FT_UInt runcnt; + FT_UInt runcnt, cnt; FT_UInt i, j; FT_UShort first; + FT_Byte* p; FT_Memory memory = stream->memory; FT_Error error; @@ -169,56 +166,60 @@ n |= FT_GET_BYTE(); } - if ( n > size ) - { - FT_TRACE1(( "ft_var_readpackedpoints: number of points too large\n" )); + if ( FT_QNEW_ARRAY( points, n ) ) return NULL; - } - - /* in the nested loops below we increase `i' twice; */ - /* it is faster to simply allocate one more slot */ - /* than to add another test within the loop */ - if ( FT_QNEW_ARRAY( points, n + 1 ) ) - return NULL; - - *point_cnt = n; + p = stream->cursor; first = 0; i = 0; while ( i < n ) { - runcnt = FT_GET_BYTE(); + if ( p >= stream->limit ) + goto Fail; + + runcnt = FT_NEXT_BYTE( p ); + cnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK; + + /* first point not included in run count */ + cnt++; + if ( cnt > n - i ) + cnt = n - i; + if ( runcnt & GX_PT_POINTS_ARE_WORDS ) { - runcnt &= GX_PT_POINT_RUN_COUNT_MASK; - first += FT_GET_USHORT(); - points[i++] = first; + if ( 2 * cnt > (FT_UInt)( stream->limit - p ) ) + goto Fail; - /* first point not included in run count */ - for ( j = 0; j < runcnt; j++ ) + for ( j = 0; j < cnt; j++ ) { - first += FT_GET_USHORT(); + first += FT_NEXT_USHORT( p ); points[i++] = first; - if ( i >= n ) - break; } } else { - first += FT_GET_BYTE(); - points[i++] = first; + if ( cnt > (FT_UInt)( stream->limit - p ) ) + goto Fail; - for ( j = 0; j < runcnt; j++ ) + for ( j = 0; j < cnt; j++ ) { - first += FT_GET_BYTE(); + first += FT_NEXT_BYTE( p ); points[i++] = first; - if ( i >= n ) - break; } } } + stream->cursor = p; + + *point_cnt = n; + return points; + + Fail: + FT_TRACE1(( "ft_var_readpackedpoints: invalid table\n" )); + + FT_FREE( points ); + return NULL; } @@ -240,9 +241,6 @@ * stream :: * The data stream. * - * size :: - * The size of the table holding the data. - * * delta_cnt :: * The number of deltas to be read. * @@ -258,13 +256,12 @@ */ static FT_Fixed* ft_var_readpackeddeltas( FT_Stream stream, - FT_ULong size, FT_UInt delta_cnt ) { FT_Fixed *deltas = NULL; FT_UInt runcnt, cnt; FT_UInt i, j; - FT_UInt bytes_used; + FT_Byte* p; FT_Memory memory = stream->memory; FT_Error error; @@ -272,68 +269,51 @@ if ( FT_QNEW_ARRAY( deltas, delta_cnt ) ) return NULL; - i = 0; - bytes_used = 0; - - while ( i < delta_cnt && bytes_used < size ) + p = stream->cursor; + i = 0; + while ( i < delta_cnt ) { - runcnt = FT_GET_BYTE(); + if ( p >= stream->limit ) + goto Fail; + + runcnt = FT_NEXT_BYTE( p ); cnt = runcnt & GX_DT_DELTA_RUN_COUNT_MASK; - bytes_used++; + /* first point not included in run count */ + cnt++; + if ( cnt > delta_cnt - i ) + cnt = delta_cnt - i; if ( runcnt & GX_DT_DELTAS_ARE_ZERO ) { - /* `cnt` + 1 zeroes get added */ - for ( j = 0; j <= cnt && i < delta_cnt; j++ ) + for ( j = 0; j < cnt; j++ ) deltas[i++] = 0; } else if ( runcnt & GX_DT_DELTAS_ARE_WORDS ) { - /* `cnt` + 1 shorts from the stack */ - bytes_used += 2 * ( cnt + 1 ); - if ( bytes_used > size ) - { - FT_TRACE1(( "ft_var_readpackeddeltas:" - " number of short deltas too large\n" )); + if ( 2 * cnt > (FT_UInt)( stream->limit - p ) ) goto Fail; - } - for ( j = 0; j <= cnt && i < delta_cnt; j++ ) - deltas[i++] = FT_intToFixed( FT_GET_SHORT() ); + for ( j = 0; j < cnt; j++ ) + deltas[i++] = FT_intToFixed( FT_NEXT_SHORT( p ) ); } else { - /* `cnt` + 1 signed bytes from the stack */ - bytes_used += cnt + 1; - if ( bytes_used > size ) - { - FT_TRACE1(( "ft_var_readpackeddeltas:" - " number of byte deltas too large\n" )); + if ( cnt > (FT_UInt)( stream->limit - p ) ) goto Fail; - } - for ( j = 0; j <= cnt && i < delta_cnt; j++ ) - deltas[i++] = FT_intToFixed( FT_GET_CHAR() ); - } - - if ( j <= cnt ) - { - FT_TRACE1(( "ft_var_readpackeddeltas:" - " number of deltas too large\n" )); - goto Fail; + for ( j = 0; j < cnt; j++ ) + deltas[i++] = FT_intToFixed( FT_NEXT_CHAR( p ) ); } } - if ( i < delta_cnt ) - { - FT_TRACE1(( "ft_var_readpackeddeltas: not enough deltas\n" )); - goto Fail; - } + stream->cursor = p; return deltas; Fail: + FT_TRACE1(( "ft_var_readpackeddeltas: invalid table\n" )); + FT_FREE( deltas ); return NULL; } @@ -596,7 +576,7 @@ for ( j = 0; j < itemStore->axisCount; j++ ) { - FT_Short start, peak, end; + FT_Int start, peak, end; if ( FT_READ_SHORT( start ) || @@ -604,6 +584,10 @@ FT_READ_SHORT( end ) ) goto Exit; + /* immediately tag invalid ranges with special peak = 0 */ + if ( ( start < 0 && end > 0 ) || start > peak || peak > end ) + peak = 0; + axisCoords[j].startCoord = FT_fdot14ToFixed( start ); axisCoords[j].peakCoord = FT_fdot14ToFixed( peak ); axisCoords[j].endCoord = FT_fdot14ToFixed( end ); @@ -1024,6 +1008,9 @@ if ( innerIndex >= varData->itemCount ) return 0; /* Out of range. */ + if ( varData->regionIdxCount == 0 ) + return 0; /* Avoid "applying zero offset to null pointer". */ + if ( varData->regionIdxCount < 16 ) { deltaSet = deltaSetStack; @@ -1074,43 +1061,32 @@ /* inner loop steps through axes in this region */ for ( j = 0; j < itemStore->axisCount; j++, axis++ ) { - /* compute the scalar contribution of this axis; */ - /* ignore invalid ranges */ - if ( axis->startCoord > axis->peakCoord || - axis->peakCoord > axis->endCoord ) - continue; + FT_Fixed ncv = ttface->blend->normalizedcoords[j]; - else if ( axis->startCoord < 0 && - axis->endCoord > 0 && - axis->peakCoord != 0 ) - continue; - /* peak of 0 means ignore this axis */ - else if ( axis->peakCoord == 0 ) - continue; - - else if ( ttface->blend->normalizedcoords[j] == axis->peakCoord ) + /* compute the scalar contribution of this axis */ + /* with peak of 0 used for invalid axes */ + if ( axis->peakCoord == ncv || + axis->peakCoord == 0 ) continue; /* ignore this region if coords are out of range */ - else if ( ttface->blend->normalizedcoords[j] <= axis->startCoord || - ttface->blend->normalizedcoords[j] >= axis->endCoord ) + else if ( ncv <= axis->startCoord || + ncv >= axis->endCoord ) { scalar = 0; break; } /* cumulative product of all the axis scalars */ - else if ( ttface->blend->normalizedcoords[j] < axis->peakCoord ) - scalar = - FT_MulDiv( scalar, - ttface->blend->normalizedcoords[j] - axis->startCoord, - axis->peakCoord - axis->startCoord ); - else - scalar = - FT_MulDiv( scalar, - axis->endCoord - ttface->blend->normalizedcoords[j], - axis->endCoord - axis->peakCoord ); + else if ( ncv < axis->peakCoord ) + scalar = FT_MulDiv( scalar, + ncv - axis->startCoord, + axis->peakCoord - axis->startCoord ); + else /* ncv > axis->peakCoord */ + scalar = FT_MulDiv( scalar, + axis->endCoord - ncv, + axis->endCoord - axis->peakCoord ); } /* per-axis loop */ @@ -1920,32 +1896,27 @@ for ( i = 0; i < blend->num_axis; i++ ) { - FT_TRACE6(( " axis %d coordinate %.5f:\n", - i, (double)blend->normalizedcoords[i] / 65536 )); + FT_Fixed ncv = blend->normalizedcoords[i]; + + + FT_TRACE6(( " axis %d coordinate %.5f:\n", i, (double)ncv / 65536 )); /* It's not clear why (for intermediate tuples) we don't need */ /* to check against start/end -- the documentation says we don't. */ /* Similarly, it's unclear why we don't need to scale along the */ /* axis. */ - if ( tuple_coords[i] == 0 ) + if ( tuple_coords[i] == ncv ) { - FT_TRACE6(( " tuple coordinate is zero, ignore\n" )); + FT_TRACE6(( " tuple coordinate %.5f fits perfectly\n", + (double)tuple_coords[i] / 65536 )); + /* `apply' does not change */ continue; } - if ( blend->normalizedcoords[i] == 0 ) - { - FT_TRACE6(( " axis coordinate is zero, stop\n" )); - apply = 0; - break; - } - - if ( blend->normalizedcoords[i] == tuple_coords[i] ) + if ( tuple_coords[i] == 0 ) { - FT_TRACE6(( " tuple coordinate %.5f fits perfectly\n", - (double)tuple_coords[i] / 65536 )); - /* `apply' does not change */ + FT_TRACE6(( " tuple coordinate is zero, ignore\n" )); continue; } @@ -1953,27 +1924,27 @@ { /* not an intermediate tuple */ - if ( blend->normalizedcoords[i] < FT_MIN( 0, tuple_coords[i] ) || - blend->normalizedcoords[i] > FT_MAX( 0, tuple_coords[i] ) ) + if ( ( tuple_coords[i] > ncv && ncv > 0 ) || + ( tuple_coords[i] < ncv && ncv < 0 ) ) + { + FT_TRACE6(( " tuple coordinate %.5f fits\n", + (double)tuple_coords[i] / 65536 )); + apply = FT_MulDiv( apply, ncv, tuple_coords[i] ); + } + else { FT_TRACE6(( " tuple coordinate %.5f is exceeded, stop\n", (double)tuple_coords[i] / 65536 )); apply = 0; break; } - - FT_TRACE6(( " tuple coordinate %.5f fits\n", - (double)tuple_coords[i] / 65536 )); - apply = FT_MulDiv( apply, - blend->normalizedcoords[i], - tuple_coords[i] ); } else { /* intermediate tuple */ - if ( blend->normalizedcoords[i] <= im_start_coords[i] || - blend->normalizedcoords[i] >= im_end_coords[i] ) + if ( ncv <= im_start_coords[i] || + ncv >= im_end_coords[i] ) { FT_TRACE6(( " intermediate tuple range ]%.5f;%.5f[ is exceeded," " stop\n", @@ -1986,13 +1957,13 @@ FT_TRACE6(( " intermediate tuple range ]%.5f;%.5f[ fits\n", (double)im_start_coords[i] / 65536, (double)im_end_coords[i] / 65536 )); - if ( blend->normalizedcoords[i] < tuple_coords[i] ) + if ( ncv < tuple_coords[i] ) apply = FT_MulDiv( apply, - blend->normalizedcoords[i] - im_start_coords[i], + ncv - im_start_coords[i], tuple_coords[i] - im_start_coords[i] ); - else + else /* ncv > tuple_coords[i] */ apply = FT_MulDiv( apply, - im_end_coords[i] - blend->normalizedcoords[i], + im_end_coords[i] - ncv, im_end_coords[i] - tuple_coords[i] ); } } @@ -2141,11 +2112,12 @@ outerIndex, innerIndex ); - v += delta << 2; + /* Convert delta in F2DOT14 to 16.16 before adding. */ + v += MUL_INT( delta, 4 ); - /* Clamp value range. */ - v = v >= 0x10000L ? 0x10000 : v; - v = v <= -0x10000L ? -0x10000 : v; + /* Clamp value to range [-1, 1]. */ + v = v >= 0x10000L ? 0x10000 : v; + v = v <= -0x10000L ? -0x10000 : v; new_normalized[i] = v; } @@ -2721,9 +2693,8 @@ FT_UInt n; - if ( FT_ALLOC( mmvar, ttface->blend->mmvar_len ) ) + if ( FT_DUP( mmvar, ttface->blend->mmvar, ttface->blend->mmvar_len ) ) goto Exit; - FT_MEM_COPY( mmvar, ttface->blend->mmvar, ttface->blend->mmvar_len ); axis_flags = (FT_UShort*)( (char*)mmvar + mmvar_size ); @@ -3533,9 +3504,10 @@ FT_ULong here; FT_UInt i, j; - FT_Fixed* tuple_coords = NULL; - FT_Fixed* im_start_coords = NULL; - FT_Fixed* im_end_coords = NULL; + FT_Fixed* peak_coords = NULL; + FT_Fixed* tuple_coords; + FT_Fixed* im_start_coords; + FT_Fixed* im_end_coords; GX_Blend blend = face->blend; @@ -3556,16 +3528,16 @@ { FT_TRACE2(( "\n" )); FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" )); - error = FT_Err_Ok; - goto Exit; + + return FT_Err_Ok; } if ( !face->cvt ) { FT_TRACE2(( "\n" )); FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" )); - error = FT_Err_Ok; - goto Exit; + + return FT_Err_Ok; } error = face->goto_table( face, TTAG_cvar, stream, &table_len ); @@ -3573,15 +3545,11 @@ { FT_TRACE2(( "is missing\n" )); - error = FT_Err_Ok; - goto Exit; + return FT_Err_Ok; } if ( FT_FRAME_ENTER( table_len ) ) - { - error = FT_Err_Ok; - goto Exit; - } + return FT_Err_Ok; table_start = FT_Stream_FTell( stream ); if ( FT_GET_LONG() != 0x00010000L ) @@ -3594,11 +3562,6 @@ FT_TRACE2(( "loaded\n" )); - if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) - goto FExit; - tupleCount = FT_GET_USHORT(); offsetToData = FT_GET_USHORT(); @@ -3621,9 +3584,8 @@ FT_Stream_SeekSet( stream, offsetToData ); - sharedpoints = ft_var_readpackedpoints( stream, - table_len, - &spoint_count ); + sharedpoints = ft_var_readpackedpoints( stream, &spoint_count ); + offsetToData = FT_Stream_FTell( stream ); FT_Stream_SeekSet( stream, here ); @@ -3634,8 +3596,12 @@ tupleCount & GX_TC_TUPLE_COUNT_MASK, ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "" : "s" )); - if ( FT_NEW_ARRAY( cvt_deltas, face->cvt_size ) ) - goto FExit; + if ( FT_QNEW_ARRAY( peak_coords, 3 * blend->num_axis ) || + FT_NEW_ARRAY( cvt_deltas, face->cvt_size ) ) + goto Exit; + + im_start_coords = peak_coords + blend->num_axis; + im_end_coords = im_start_coords + blend->num_axis; for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ ) { @@ -3652,32 +3618,19 @@ if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { for ( j = 0; j < blend->num_axis; j++ ) - tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() ); + peak_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() ); + tuple_coords = peak_coords; } - else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) + else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) < blend->tuplecount ) + tuple_coords = blend->tuplecoords + + ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis; + else { FT_TRACE2(( "tt_face_vary_cvt:" " invalid tuple index\n" )); error = FT_THROW( Invalid_Table ); - goto FExit; - } - else - { - if ( !blend->tuplecoords ) - { - FT_TRACE2(( "tt_face_vary_cvt:" - " no valid tuple coordinates available\n" )); - - error = FT_THROW( Invalid_Table ); - goto FExit; - } - - FT_MEM_COPY( - tuple_coords, - blend->tuplecoords + - ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis, - blend->num_axis * sizeof ( FT_Fixed ) ); + goto Exit; } if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) @@ -3706,9 +3659,7 @@ if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) { - localpoints = ft_var_readpackedpoints( stream, - table_len, - &point_count ); + localpoints = ft_var_readpackedpoints( stream, &point_count ); points = localpoints; } else @@ -3719,7 +3670,6 @@ } deltas = ft_var_readpackeddeltas( stream, - table_len, point_count == 0 ? face->cvt_size : point_count ); @@ -3820,22 +3770,20 @@ for ( i = 0; i < face->cvt_size; i++ ) face->cvt[i] += FT_fixedToFdot6( cvt_deltas[i] ); - FExit: - FT_FRAME_EXIT(); + /* Iterate over all `FT_Size` objects and set `cvt_ready` to -1 */ + /* to trigger rescaling of all CVT values. */ + FT_List_Iterate( &root->sizes_list, + tt_cvt_ready_iterator, + NULL ); Exit: if ( sharedpoints != ALL_POINTS ) FT_FREE( sharedpoints ); - FT_FREE( tuple_coords ); - FT_FREE( im_start_coords ); - FT_FREE( im_end_coords ); FT_FREE( cvt_deltas ); + FT_FREE( peak_coords ); - /* iterate over all FT_Size objects and set `cvt_ready' to -1 */ - /* to trigger rescaling of all CVT values */ - FT_List_Iterate( &root->sizes_list, - tt_cvt_ready_iterator, - NULL ); + FExit: + FT_FRAME_EXIT(); return error; @@ -4099,9 +4047,10 @@ FT_ULong here; FT_UInt i, j; - FT_Fixed* tuple_coords = NULL; - FT_Fixed* im_start_coords = NULL; - FT_Fixed* im_end_coords = NULL; + FT_Fixed* peak_coords = NULL; + FT_Fixed* tuple_coords; + FT_Fixed* im_start_coords; + FT_Fixed* im_end_coords; GX_Blend blend = face->blend; @@ -4136,27 +4085,17 @@ return FT_Err_Ok; } - if ( FT_NEW_ARRAY( points_org, n_points ) || - FT_NEW_ARRAY( points_out, n_points ) || - FT_NEW_ARRAY( has_delta, n_points ) ) - goto Fail1; - dataSize = blend->glyphoffsets[glyph_index + 1] - blend->glyphoffsets[glyph_index]; if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) || FT_FRAME_ENTER( dataSize ) ) - goto Fail1; + return error; glyph_start = FT_Stream_FTell( stream ); /* each set of glyph variation data is formatted similarly to `cvar' */ - if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || - FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) - goto Fail2; - tupleCount = FT_GET_USHORT(); offsetToData = FT_GET_USHORT(); @@ -4168,7 +4107,7 @@ " invalid glyph variation array header\n" )); error = FT_THROW( Invalid_Table ); - goto Fail2; + goto FExit; } offsetToData += glyph_start; @@ -4179,9 +4118,8 @@ FT_Stream_SeekSet( stream, offsetToData ); - sharedpoints = ft_var_readpackedpoints( stream, - blend->gvar_size, - &spoint_count ); + sharedpoints = ft_var_readpackedpoints( stream, &spoint_count ); + offsetToData = FT_Stream_FTell( stream ); FT_Stream_SeekSet( stream, here ); @@ -4192,9 +4130,16 @@ tupleCount & GX_TC_TUPLE_COUNT_MASK, ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "" : "s" )); - if ( FT_NEW_ARRAY( point_deltas_x, n_points ) || - FT_NEW_ARRAY( point_deltas_y, n_points ) ) - goto Fail3; + if ( FT_QNEW_ARRAY( peak_coords, 3 * blend->num_axis ) || + FT_NEW_ARRAY( point_deltas_x, 2 * n_points ) || + FT_QNEW_ARRAY( points_org, n_points ) || + FT_QNEW_ARRAY( points_out, n_points ) || + FT_QNEW_ARRAY( has_delta, n_points ) ) + goto Exit; + + im_start_coords = peak_coords + blend->num_axis; + im_end_coords = im_start_coords + blend->num_axis; + point_deltas_y = point_deltas_x + n_points; for ( j = 0; j < n_points; j++ ) { @@ -4217,22 +4162,20 @@ if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { for ( j = 0; j < blend->num_axis; j++ ) - tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() ); + peak_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() ); + tuple_coords = peak_coords; } - else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) + else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) < blend->tuplecount ) + tuple_coords = blend->tuplecoords + + ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis; + else { FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" " invalid tuple index\n" )); error = FT_THROW( Invalid_Table ); - goto Fail3; + goto Exit; } - else - FT_MEM_COPY( - tuple_coords, - blend->tuplecoords + - ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis, - blend->num_axis * sizeof ( FT_Fixed ) ); if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { @@ -4260,9 +4203,7 @@ if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) { - localpoints = ft_var_readpackedpoints( stream, - blend->gvar_size, - &point_count ); + localpoints = ft_var_readpackedpoints( stream, &point_count ); points = localpoints; } else @@ -4272,11 +4213,9 @@ } deltas_x = ft_var_readpackeddeltas( stream, - blend->gvar_size, point_count == 0 ? n_points : point_count ); deltas_y = ft_var_readpackeddeltas( stream, - blend->gvar_size, point_count == 0 ? n_points : point_count ); @@ -4460,23 +4399,17 @@ unrounded[n_points - 2].y ) / 64; } - Fail3: - FT_FREE( point_deltas_x ); - FT_FREE( point_deltas_y ); - - Fail2: + Exit: if ( sharedpoints != ALL_POINTS ) FT_FREE( sharedpoints ); - FT_FREE( tuple_coords ); - FT_FREE( im_start_coords ); - FT_FREE( im_end_coords ); - - FT_FRAME_EXIT(); - - Fail1: FT_FREE( points_org ); FT_FREE( points_out ); FT_FREE( has_delta ); + FT_FREE( peak_coords ); + FT_FREE( point_deltas_x ); + + FExit: + FT_FRAME_EXIT(); return error; } diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.h b/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.h index e3da6d1705cc7..9326011e3a243 100644 --- a/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.h +++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.h @@ -4,7 +4,7 @@ * * TrueType GX Font Variation loader (specification) * - * Copyright (C) 2004-2023 by + * Copyright (C) 2004-2024 by * David Turner, Robert Wilhelm, Werner Lemberg and George Williams. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c b/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c index 79df4555d9431..951891dbf51c4 100644 --- a/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c +++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c @@ -4,7 +4,7 @@ * * TrueType bytecode interpreter (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -5270,11 +5270,11 @@ FT_UShort refp; FT_F26Dot6 dx, dy; - FT_Short contour, bounds; + FT_UShort contour, bounds; FT_UShort start, limit, i; - contour = (FT_Short)args[0]; + contour = (FT_UShort)args[0]; bounds = ( exc->GS.gep2 == 0 ) ? 1 : exc->zp2.n_contours; if ( BOUNDS( contour, bounds ) ) @@ -5290,15 +5290,13 @@ if ( contour == 0 ) start = 0; else - start = (FT_UShort)( exc->zp2.contours[contour - 1] + 1 - - exc->zp2.first_point ); + start = exc->zp2.contours[contour - 1] + 1 - exc->zp2.first_point; /* we use the number of points if in the twilight zone */ if ( exc->GS.gep2 == 0 ) limit = exc->zp2.n_points; else - limit = (FT_UShort)( exc->zp2.contours[contour] - - exc->zp2.first_point + 1 ); + limit = exc->zp2.contours[contour] + 1 - exc->zp2.first_point; for ( i = start; i < limit; i++ ) { @@ -5341,9 +5339,9 @@ /* Normal zone's `n_points' includes phantoms, so must */ /* use end of last contour. */ if ( exc->GS.gep2 == 0 ) - limit = (FT_UShort)exc->zp2.n_points; + limit = exc->zp2.n_points; else if ( exc->GS.gep2 == 1 && exc->zp2.n_contours > 0 ) - limit = (FT_UShort)( exc->zp2.contours[exc->zp2.n_contours - 1] + 1 ); + limit = exc->zp2.contours[exc->zp2.n_contours - 1] + 1; else limit = 0; diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.h b/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.h index e98e258fe7edb..4f1a9bbc6794b 100644 --- a/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.h +++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.h @@ -4,7 +4,7 @@ * * TrueType bytecode interpreter (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.c b/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.c index 5b56af711df47..d0ac31812045f 100644 --- a/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.c +++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.c @@ -4,7 +4,7 @@ * * Objects manager (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -115,7 +115,7 @@ FT_LOCAL_DEF( FT_Error ) tt_glyphzone_new( FT_Memory memory, FT_UShort maxPoints, - FT_Short maxContours, + FT_UShort maxContours, TT_GlyphZone zone ) { FT_Error error; @@ -152,18 +152,20 @@ static const FT_String* tt_skip_pdffont_random_tag( const FT_String* name ) { - unsigned int i; - - - if ( ft_strlen( name ) < 8 || name[6] != '+' ) - return name; - - for ( i = 0; i < 6; i++ ) - if ( !ft_isupper( name[i] ) ) - return name; + if ( ft_isupper( name[0] ) && + ft_isupper( name[1] ) && + ft_isupper( name[2] ) && + ft_isupper( name[3] ) && + ft_isupper( name[4] ) && + ft_isupper( name[5] ) && + '+' == name[6] && + name[7] ) + { + FT_TRACE7(( "name without randomization tag: %s\n", name + 7 )); + return name + 7; + } - FT_TRACE7(( "name without randomization tag: %s\n", name + 7 )); - return name + 7; + return name; } @@ -254,17 +256,20 @@ { FT_Error error; FT_UInt32 checksum = 0; - FT_UInt i; + FT_Byte* p; + FT_Int shift; if ( FT_FRAME_ENTER( length ) ) return 0; + p = (FT_Byte*)stream->cursor; + for ( ; length > 3; length -= 4 ) - checksum += (FT_UInt32)FT_GET_ULONG(); + checksum += FT_NEXT_ULONG( p ); - for ( i = 3; length > 0; length--, i-- ) - checksum += (FT_UInt32)FT_GET_BYTE() << ( i * 8 ); + for ( shift = 24; length > 0; length--, shift -=8 ) + checksum += (FT_UInt32)FT_NEXT_BYTE( p ) << shift; FT_FRAME_EXIT(); @@ -782,8 +787,7 @@ FT_UInt instance_index = (FT_UInt)face_index >> 16; - if ( FT_HAS_MULTIPLE_MASTERS( ttface ) && - instance_index > 0 ) + if ( FT_HAS_MULTIPLE_MASTERS( ttface ) ) { error = FT_Set_Named_Instance( ttface, instance_index ); if ( error ) @@ -990,16 +994,16 @@ FT_Error error; FT_UInt i; - /* unscaled CVT values are already stored in 26.6 format */ - FT_Fixed scale = size->ttmetrics.scale >> 6; - /* Scale the cvt values to the new ppem. */ /* By default, we use the y ppem value for scaling. */ FT_TRACE6(( "CVT values:\n" )); for ( i = 0; i < size->cvt_size; i++ ) { - size->cvt[i] = FT_MulFix( face->cvt[i], scale ); + /* Unscaled CVT values are already stored in 26.6 format. */ + /* Note that this scaling operation is very sensitive to rounding; */ + /* the integer division by 64 must be applied to the first argument. */ + size->cvt[i] = FT_MulFix( face->cvt[i] / 64, size->ttmetrics.scale ); FT_TRACE6(( " %3d: %f (%f)\n", i, (double)face->cvt[i] / 64, (double)size->cvt[i] / 64 )); } diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.h b/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.h index 40eb37b4c43ea..9c36ca783620e 100644 --- a/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.h +++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.h @@ -4,7 +4,7 @@ * * Objects manager (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -105,7 +105,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) tt_glyphzone_new( FT_Memory memory, FT_UShort maxPoints, - FT_Short maxContours, + FT_UShort maxContours, TT_GlyphZone zone ); #endif /* TT_USE_BYTECODE_INTERPRETER */ diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.c b/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.c index 54a64c7b462fc..9505b5f179f26 100644 --- a/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.c +++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.c @@ -4,7 +4,7 @@ * * TrueType-specific tables loader (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.h b/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.h index ed229fa4616df..bc32b58020c33 100644 --- a/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.h +++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.h @@ -4,7 +4,7 @@ * * TrueType-specific tables loader (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1afm.c b/src/java.desktop/share/native/libfreetype/src/type1/t1afm.c index d9b9398b013ad..a63cd4dc48af1 100644 --- a/src/java.desktop/share/native/libfreetype/src/type1/t1afm.c +++ b/src/java.desktop/share/native/libfreetype/src/type1/t1afm.c @@ -4,7 +4,7 @@ * * AFM support for Type 1 fonts (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1afm.h b/src/java.desktop/share/native/libfreetype/src/type1/t1afm.h index e0d5aa5a88277..7f5cdda191f4b 100644 --- a/src/java.desktop/share/native/libfreetype/src/type1/t1afm.h +++ b/src/java.desktop/share/native/libfreetype/src/type1/t1afm.h @@ -4,7 +4,7 @@ * * AFM support for Type 1 fonts (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1driver.c b/src/java.desktop/share/native/libfreetype/src/type1/t1driver.c index a4cdf372a9e31..8ed01914a5a58 100644 --- a/src/java.desktop/share/native/libfreetype/src/type1/t1driver.c +++ b/src/java.desktop/share/native/libfreetype/src/type1/t1driver.c @@ -4,7 +4,7 @@ * * Type 1 driver interface (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -312,10 +312,7 @@ { retval = ft_strlen( type1->glyph_names[idx] ) + 1; if ( value && value_len >= retval ) - { ft_memcpy( value, (void *)( type1->glyph_names[idx] ), retval ); - ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; - } } break; @@ -344,11 +341,8 @@ { retval = ft_strlen( type1->encoding.char_name[idx] ) + 1; if ( value && value_len >= retval ) - { ft_memcpy( value, (void *)( type1->encoding.char_name[idx] ), - retval - 1 ); - ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; - } + retval ); } break; diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1driver.h b/src/java.desktop/share/native/libfreetype/src/type1/t1driver.h index ee7fcf43e01db..5ff52b55b1a86 100644 --- a/src/java.desktop/share/native/libfreetype/src/type1/t1driver.h +++ b/src/java.desktop/share/native/libfreetype/src/type1/t1driver.h @@ -4,7 +4,7 @@ * * High-level Type 1 driver interface (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1errors.h b/src/java.desktop/share/native/libfreetype/src/type1/t1errors.h index 2fbd1e513f3ec..8aeb24ae188b3 100644 --- a/src/java.desktop/share/native/libfreetype/src/type1/t1errors.h +++ b/src/java.desktop/share/native/libfreetype/src/type1/t1errors.h @@ -4,7 +4,7 @@ * * Type 1 error codes (specification only). * - * Copyright (C) 2001-2023 by + * Copyright (C) 2001-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1gload.c b/src/java.desktop/share/native/libfreetype/src/type1/t1gload.c index a32a4649d6d53..c29e682510c25 100644 --- a/src/java.desktop/share/native/libfreetype/src/type1/t1gload.c +++ b/src/java.desktop/share/native/libfreetype/src/type1/t1gload.c @@ -4,7 +4,7 @@ * * Type 1 Glyph Loader (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1gload.h b/src/java.desktop/share/native/libfreetype/src/type1/t1gload.h index c06484758a597..17a6a5941e32a 100644 --- a/src/java.desktop/share/native/libfreetype/src/type1/t1gload.h +++ b/src/java.desktop/share/native/libfreetype/src/type1/t1gload.h @@ -4,7 +4,7 @@ * * Type 1 Glyph Loader (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1load.c b/src/java.desktop/share/native/libfreetype/src/type1/t1load.c index be7cd0fd5e97e..ee7fb42a517a7 100644 --- a/src/java.desktop/share/native/libfreetype/src/type1/t1load.c +++ b/src/java.desktop/share/native/libfreetype/src/type1/t1load.c @@ -4,7 +4,7 @@ * * Type 1 font loader (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -751,6 +751,7 @@ PS_DesignMap dmap = blend->design_map + n; + FT_FREE( dmap->blend_points ); FT_FREE( dmap->design_points ); dmap->num_points = 0; } @@ -1043,9 +1044,9 @@ } /* allocate design map data */ - if ( FT_QNEW_ARRAY( map->design_points, num_points * 2 ) ) + if ( FT_QNEW_ARRAY( map->design_points, num_points ) || + FT_QNEW_ARRAY( map->blend_points, num_points ) ) goto Exit; - map->blend_points = map->design_points + num_points; map->num_points = (FT_Byte)num_points; for ( p = 0; p < num_points; p++ ) @@ -1876,9 +1877,8 @@ } /* t1_decrypt() shouldn't write to base -- make temporary copy */ - if ( FT_QALLOC( temp, size ) ) + if ( FT_DUP( temp, base, size ) ) goto Fail; - FT_MEM_COPY( temp, base, size ); psaux->t1_decrypt( temp, size, 4330 ); size -= (FT_ULong)t1face->type1.private_dict.lenIV; error = T1_Add_Table( table, @@ -2090,9 +2090,8 @@ } /* t1_decrypt() shouldn't write to base -- make temporary copy */ - if ( FT_QALLOC( temp, size ) ) + if ( FT_DUP( temp, base, size ) ) goto Fail; - FT_MEM_COPY( temp, base, size ); psaux->t1_decrypt( temp, size, 4330 ); size -= (FT_ULong)t1face->type1.private_dict.lenIV; error = T1_Add_Table( code_table, @@ -2284,7 +2283,7 @@ T1_FIELD_DICT_PRIVATE ) #endif - { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } + T1_FIELD_ZERO }; @@ -2392,18 +2391,13 @@ T1_Field keyword = (T1_Field)t1_keywords; - for (;;) + while ( keyword->len ) { - FT_Byte* name; + FT_Byte* name = (FT_Byte*)keyword->ident; - name = (FT_Byte*)keyword->ident; - if ( !name ) - break; - - if ( cur[0] == name[0] && - len == ft_strlen( (const char *)name ) && - ft_memcmp( cur, name, len ) == 0 ) + if ( keyword->len == len && + ft_memcmp( cur, name, len ) == 0 ) { /* We found it -- run the parsing callback! */ /* We record every instance of every field */ diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1load.h b/src/java.desktop/share/native/libfreetype/src/type1/t1load.h index d8c9d2d8abe93..a45efa7cb7ba7 100644 --- a/src/java.desktop/share/native/libfreetype/src/type1/t1load.h +++ b/src/java.desktop/share/native/libfreetype/src/type1/t1load.h @@ -4,7 +4,7 @@ * * Type 1 font loader (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1objs.c b/src/java.desktop/share/native/libfreetype/src/type1/t1objs.c index 69e4fd5065e5f..b1b27c31fe3b6 100644 --- a/src/java.desktop/share/native/libfreetype/src/type1/t1objs.c +++ b/src/java.desktop/share/native/libfreetype/src/type1/t1objs.c @@ -4,7 +4,7 @@ * * Type 1 objects manager (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1objs.h b/src/java.desktop/share/native/libfreetype/src/type1/t1objs.h index 03847b27e96ac..3809370c1e085 100644 --- a/src/java.desktop/share/native/libfreetype/src/type1/t1objs.h +++ b/src/java.desktop/share/native/libfreetype/src/type1/t1objs.h @@ -4,7 +4,7 @@ * * Type 1 objects manager (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1parse.c b/src/java.desktop/share/native/libfreetype/src/type1/t1parse.c index 6dec6c16c3e70..3717ea7c57207 100644 --- a/src/java.desktop/share/native/libfreetype/src/type1/t1parse.c +++ b/src/java.desktop/share/native/libfreetype/src/type1/t1parse.c @@ -4,7 +4,7 @@ * * Type 1 parser (body). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1parse.h b/src/java.desktop/share/native/libfreetype/src/type1/t1parse.h index 0d9a2865df08e..a0a2134d45c02 100644 --- a/src/java.desktop/share/native/libfreetype/src/type1/t1parse.h +++ b/src/java.desktop/share/native/libfreetype/src/type1/t1parse.h @@ -4,7 +4,7 @@ * * Type 1 parser (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1tokens.h b/src/java.desktop/share/native/libfreetype/src/type1/t1tokens.h index 40f3609262203..5a3d2f1ef0874 100644 --- a/src/java.desktop/share/native/libfreetype/src/type1/t1tokens.h +++ b/src/java.desktop/share/native/libfreetype/src/type1/t1tokens.h @@ -4,7 +4,7 @@ * * Type 1 tokenizer (specification). * - * Copyright (C) 1996-2023 by + * Copyright (C) 1996-2024 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, From 03828f8616b5d11491176b54bf6adb5e024581a6 Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Wed, 12 Mar 2025 16:18:47 +0000 Subject: [PATCH 031/846] 8350616: Skip ValidateHazardPtrsClosure in non-debug builds Backport-of: e43960a0170bf29b28ff4733e1c8c927947fb0bb --- src/hotspot/share/runtime/threadSMR.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hotspot/share/runtime/threadSMR.cpp b/src/hotspot/share/runtime/threadSMR.cpp index fc90da14ddcbd..ecf4cbaeec538 100644 --- a/src/hotspot/share/runtime/threadSMR.cpp +++ b/src/hotspot/share/runtime/threadSMR.cpp @@ -367,6 +367,7 @@ class ScanHazardPtrPrintMatchingThreadsClosure : public ThreadClosure { } }; +#ifdef ASSERT // Closure to validate hazard ptrs. // class ValidateHazardPtrsClosure : public ThreadClosure { @@ -387,6 +388,7 @@ class ValidateHazardPtrsClosure : public ThreadClosure { p2i(thread)); } }; +#endif // Closure to determine if the specified JavaThread is found by // threads_do(). @@ -928,8 +930,10 @@ void ThreadsSMRSupport::free_list(ThreadsList* threads) { log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::free_list: threads=" INTPTR_FORMAT " is not freed.", os::current_thread_id(), p2i(threads)); } +#ifdef ASSERT ValidateHazardPtrsClosure validate_cl; threads_do(&validate_cl); +#endif delete scan_table; } From f39ce948644ec218906674eb3e7e715134f362b4 Mon Sep 17 00:00:00 2001 From: Roman Marchenko Date: Thu, 13 Mar 2025 16:23:34 +0000 Subject: [PATCH 032/846] 8309841: Jarsigner should print a warning if an entry is removed Reviewed-by: yan Backport-of: bdfb41f977258831e4b0ceaef5d016d095ab6e7f --- .../sun/security/tools/jarsigner/Main.java | 16 ++++ .../security/tools/jarsigner/Resources.java | 2 + .../tools/jarsigner/RemovedFiles.java | 94 +++++++++++++++++++ .../jdk/test/lib/util/JarUtilsTest.java | 77 +++++++++++++++ test/lib/jdk/test/lib/util/JarUtils.java | 53 ++++++++++- 5 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 test/jdk/sun/security/tools/jarsigner/RemovedFiles.java create mode 100644 test/lib-test/jdk/test/lib/util/JarUtilsTest.java diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java index 6957939cae4ba..d17615309e83a 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java @@ -180,6 +180,7 @@ public static void main(String args[]) throws Exception { private boolean hasExpiringCert = false; private boolean hasExpiringTsaCert = false; private boolean noTimestamp = true; + private boolean hasNonexistentEntries = false; // Expiration date. The value could be null if signed by a trusted cert. private Date expireDate = null; @@ -706,6 +707,7 @@ void verifyJar(String jarName) Map sigMap = new HashMap<>(); Map sigNameMap = new HashMap<>(); Map unparsableSignatures = new HashMap<>(); + Map> entriesInSF = new HashMap<>(); try { jf = new JarFile(jarName, true); @@ -753,6 +755,7 @@ void verifyJar(String jarName) break; } } + entriesInSF.put(alias, sf.getEntries().keySet()); if (!found) { unparsableSignatures.putIfAbsent(alias, String.format( @@ -851,6 +854,9 @@ void verifyJar(String jarName) sb.append('\n'); } } + for (var signed : entriesInSF.values()) { + signed.remove(name); + } } else if (showcerts && !verbose.equals("all")) { // Print no info for unsigned entries when -verbose:all, // to be consistent with old behavior. @@ -1044,6 +1050,13 @@ void verifyJar(String jarName) if (verbose != null) { System.out.println(history); } + var signed = entriesInSF.get(s); + if (!signed.isEmpty()) { + if (verbose != null) { + System.out.println(rb.getString("history.nonexistent.entries") + signed); + } + hasNonexistentEntries = true; + } } else { unparsableSignatures.putIfAbsent(s, String.format( rb.getString("history.nobk"), s)); @@ -1287,6 +1300,9 @@ private void displayMessagesAndResult(boolean isSigning) { } } + if (hasNonexistentEntries) { + warnings.add(rb.getString("nonexistent.entries.found")); + } if (extraAttrsDetected) { warnings.add(rb.getString("extra.attributes.detected")); } diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java index 2b74856b7ce37..4185c786aecb8 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java @@ -165,6 +165,7 @@ public class Resources extends java.util.ListResourceBundle { {"history.with.ts", "- Signed by \"%1$s\"\n Digest algorithm: %2$s\n Signature algorithm: %3$s, %4$s\n Timestamped by \"%6$s\" on %5$tc\n Timestamp digest algorithm: %7$s\n Timestamp signature algorithm: %8$s, %9$s"}, {"history.without.ts", "- Signed by \"%1$s\"\n Digest algorithm: %2$s\n Signature algorithm: %3$s, %4$s"}, + {"history.nonexistent.entries", " Warning: nonexistent signed entries: "}, {"history.unparsable", "- Unparsable signature-related file %s"}, {"history.nosf", "- Missing signature-related file META-INF/%s.SF"}, {"history.nobk", "- Missing block file for signature-related file META-INF/%s.SF"}, @@ -175,6 +176,7 @@ public class Resources extends java.util.ListResourceBundle { {"key.bit.weak", "%d-bit key (weak)"}, {"key.bit.disabled", "%d-bit key (disabled)"}, {"unknown.size", "unknown size"}, + {"nonexistent.entries.found", "This jar contains signed entries for files that do not exist. See the -verbose output for more details."}, {"extra.attributes.detected", "POSIX file permission and/or symlink attributes detected. These attributes are ignored when signing and are not protected by the signature."}, {"jarsigner.", "jarsigner: "}, diff --git a/test/jdk/sun/security/tools/jarsigner/RemovedFiles.java b/test/jdk/sun/security/tools/jarsigner/RemovedFiles.java new file mode 100644 index 0000000000000..7a4e566efa68b --- /dev/null +++ b/test/jdk/sun/security/tools/jarsigner/RemovedFiles.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 8309841 + * @summary Jarsigner should print a warning if an entry is removed + * @library /test/lib + */ + +import jdk.test.lib.SecurityTools; +import jdk.test.lib.util.JarUtils; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +public class RemovedFiles { + + private static final String NONEXISTENT_ENTRIES_FOUND + = "This jar contains signed entries for files that do not exist. See the -verbose output for more details."; + + public static void main(String[] args) throws Exception { + JarUtils.createJarFile( + Path.of("a.jar"), + Path.of("."), + Files.writeString(Path.of("a"), "a"), + Files.writeString(Path.of("b"), "b")); + SecurityTools.keytool("-genkeypair -storepass changeit -keystore ks -alias x -dname CN=x -keyalg ed25519"); + SecurityTools.jarsigner("-storepass changeit -keystore ks a.jar x"); + + // All is fine at the beginning. + SecurityTools.jarsigner("-verify a.jar") + .shouldNotContain(NONEXISTENT_ENTRIES_FOUND); + + // Remove an entry after signing. There will be a warning. + JarUtils.deleteEntries(Path.of("a.jar"), "a"); + SecurityTools.jarsigner("-verify a.jar") + .shouldContain(NONEXISTENT_ENTRIES_FOUND); + SecurityTools.jarsigner("-verify -verbose a.jar") + .shouldContain(NONEXISTENT_ENTRIES_FOUND) + .shouldContain("Warning: nonexistent signed entries: [a]"); + + // Remove one more entry. + JarUtils.deleteEntries(Path.of("a.jar"), "b"); + SecurityTools.jarsigner("-verify a.jar") + .shouldContain(NONEXISTENT_ENTRIES_FOUND); + SecurityTools.jarsigner("-verify -verbose a.jar") + .shouldContain(NONEXISTENT_ENTRIES_FOUND) + .shouldContain("Warning: nonexistent signed entries: [a, b]"); + + // Re-sign will not clear the warning. + SecurityTools.jarsigner("-storepass changeit -keystore ks a.jar x"); + SecurityTools.jarsigner("-verify a.jar") + .shouldContain(NONEXISTENT_ENTRIES_FOUND); + + // Unfortunately, if there is a non-file entry in manifest, there will be + // a false alarm. See https://bugs.openjdk.org/browse/JDK-8334261. + var man = new Manifest(); + man.getMainAttributes().putValue("Manifest-Version", "1.0"); + man.getEntries().computeIfAbsent("Hello", key -> new Attributes()) + .putValue("Foo", "Bar"); + JarUtils.createJarFile(Path.of("b.jar"), + man, + Path.of("."), + Path.of("a")); + SecurityTools.jarsigner("-storepass changeit -keystore ks b.jar x"); + SecurityTools.jarsigner("-verbose -verify b.jar") + .shouldContain("Warning: nonexistent signed entries: [Hello]") + .shouldContain(NONEXISTENT_ENTRIES_FOUND); + + } +} diff --git a/test/lib-test/jdk/test/lib/util/JarUtilsTest.java b/test/lib-test/jdk/test/lib/util/JarUtilsTest.java new file mode 100644 index 0000000000000..eb9dced32569a --- /dev/null +++ b/test/lib-test/jdk/test/lib/util/JarUtilsTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 8309841 + * @summary Unit Test for a common Test API in jdk.test.lib.util.JarUtils + * @library /test/lib + */ + +import jdk.test.lib.Asserts; +import jdk.test.lib.util.JarUtils; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.stream.Collectors; + +public class JarUtilsTest { + public static void main(String[] args) throws Exception { + Files.createDirectory(Path.of("bx")); + JarUtils.createJarFile(Path.of("a.jar"), + Path.of("."), + Files.writeString(Path.of("a"), ""), + Files.writeString(Path.of("b1"), ""), + Files.writeString(Path.of("b2"), ""), + Files.writeString(Path.of("bx/x"), ""), + Files.writeString(Path.of("c"), ""), + Files.writeString(Path.of("e1"), ""), + Files.writeString(Path.of("e2"), "")); + checkContent("a", "b1", "b2", "bx/x", "c", "e1", "e2"); + + JarUtils.deleteEntries(Path.of("a.jar"), "a"); + checkContent("b1", "b2", "bx/x", "c", "e1", "e2"); + + // Note: b* covers everything starting with b, even bx/x + JarUtils.deleteEntries(Path.of("a.jar"), "b*"); + checkContent("c", "e1", "e2"); + + // d* does not match + JarUtils.deleteEntries(Path.of("a.jar"), "d*"); + checkContent("c", "e1", "e2"); + + // multiple patterns + JarUtils.deleteEntries(Path.of("a.jar"), "d*", "e*"); + checkContent("c"); + } + + static void checkContent(String... expected) throws IOException { + try (var jf = new JarFile("a.jar")) { + Asserts.assertEquals(Set.of(expected), + jf.stream().map(JarEntry::getName).collect(Collectors.toSet())); + } + } +} diff --git a/test/lib/jdk/test/lib/util/JarUtils.java b/test/lib/jdk/test/lib/util/JarUtils.java index e1b3ccac19fc5..3aa4ada5197ad 100644 --- a/test/lib/jdk/test/lib/util/JarUtils.java +++ b/test/lib/jdk/test/lib/util/JarUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -320,6 +320,57 @@ public static void updateManifest(String src, String dest, Manifest man) updateJar(src, dest, Map.of(JarFile.MANIFEST_NAME, bout.toByteArray())); } + /** + * Remove entries from a ZIP file. + * + * Each entry can be a name or a name ending with "*". + * + * @return number of removed entries + * @throws IOException if there is any I/O error + */ + public static int deleteEntries(Path jarfile, String... patterns) + throws IOException { + Path tmpfile = Files.createTempFile("jar", "jar"); + int count = 0; + + try (OutputStream out = Files.newOutputStream(tmpfile); + JarOutputStream jos = new JarOutputStream(out)) { + try (JarFile jf = new JarFile(jarfile.toString())) { + Enumeration jentries = jf.entries(); + top: while (jentries.hasMoreElements()) { + JarEntry jentry = jentries.nextElement(); + String name = jentry.getName(); + for (String pattern : patterns) { + if (pattern.endsWith("*")) { + if (name.startsWith(pattern.substring( + 0, pattern.length() - 1))) { + // Go directly to next entry. This + // one is not written into `jos` and + // therefore removed. + count++; + continue top; + } + } else { + if (name.equals(pattern)) { + // Same as above + count++; + continue top; + } + } + } + // No pattern matched, file retained + jos.putNextEntry(copyEntry(jentry)); + jf.getInputStream(jentry).transferTo(jos); + } + } + } + + // replace the original JAR file + Files.move(tmpfile, jarfile, StandardCopyOption.REPLACE_EXISTING); + + return count; + } + private static void updateEntry(JarOutputStream jos, String name, Object content) throws IOException { if (content instanceof Boolean) { From f04bc19d85b35cb0cf74a75d5a36822ac3085c3c Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Thu, 13 Mar 2025 19:10:54 +0000 Subject: [PATCH 033/846] 8251505: Use of types in compiler shared code should be consistent. Backport-of: b6935dfb86a1c011355d2dfb2140be26ec536351 --- src/hotspot/share/code/nmethod.hpp | 6 ++--- src/hotspot/share/compiler/compileBroker.cpp | 2 +- src/hotspot/share/compiler/compileBroker.hpp | 6 ++--- src/hotspot/share/jvmci/jvmciEnv.cpp | 2 +- src/hotspot/share/jvmci/jvmciEnv.hpp | 2 +- .../share/runtime/interfaceSupport.cpp | 2 +- .../share/runtime/interfaceSupport.inline.hpp | 2 +- src/hotspot/share/runtime/sweeper.cpp | 27 ++++++++++--------- src/hotspot/share/runtime/sweeper.hpp | 12 ++++----- src/hotspot/share/runtime/vmStructs.cpp | 3 ++- 10 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/hotspot/share/code/nmethod.hpp b/src/hotspot/share/code/nmethod.hpp index ea5e92845fff3..21f20b44d2469 100644 --- a/src/hotspot/share/code/nmethod.hpp +++ b/src/hotspot/share/code/nmethod.hpp @@ -256,7 +256,7 @@ class nmethod : public CompiledMethod { // stack. An not_entrant method can be removed when there are no // more activations, i.e., when the _stack_traversal_mark is less than // current sweep traversal index. - volatile long _stack_traversal_mark; + volatile int64_t _stack_traversal_mark; // The _hotness_counter indicates the hotness of a method. The higher // the value the hotter the method. The hotness counter of a nmethod is @@ -546,8 +546,8 @@ class nmethod : public CompiledMethod { void fix_oop_relocations() { fix_oop_relocations(NULL, NULL, false); } // Sweeper support - long stack_traversal_mark() { return _stack_traversal_mark; } - void set_stack_traversal_mark(long l) { _stack_traversal_mark = l; } + int64_t stack_traversal_mark() { return _stack_traversal_mark; } + void set_stack_traversal_mark(int64_t l) { _stack_traversal_mark = l; } // On-stack replacement support int osr_entry_bci() const { assert(is_osr_method(), "wrong kind of nmethod"); return _entry_bci; } diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index b77ab569bdd87..1d7c6c6b55434 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -185,7 +185,7 @@ int CompileBroker::_sum_standard_bytes_compiled = 0; int CompileBroker::_sum_nmethod_size = 0; int CompileBroker::_sum_nmethod_code_size = 0; -long CompileBroker::_peak_compilation_time = 0; +jlong CompileBroker::_peak_compilation_time = 0; CompilerStatistics CompileBroker::_stats_per_level[CompLevel_full_optimization]; diff --git a/src/hotspot/share/compiler/compileBroker.hpp b/src/hotspot/share/compiler/compileBroker.hpp index adf7a3c6a45ac..91e48217cf132 100644 --- a/src/hotspot/share/compiler/compileBroker.hpp +++ b/src/hotspot/share/compiler/compileBroker.hpp @@ -223,7 +223,7 @@ class CompileBroker: AllStatic { static int _sum_standard_bytes_compiled; static int _sum_nmethod_size; static int _sum_nmethod_code_size; - static long _peak_compilation_time; + static jlong _peak_compilation_time; static CompilerStatistics _stats_per_level[]; @@ -416,8 +416,8 @@ class CompileBroker: AllStatic { static int get_sum_standard_bytes_compiled() { return _sum_standard_bytes_compiled; } static int get_sum_nmethod_size() { return _sum_nmethod_size;} static int get_sum_nmethod_code_size() { return _sum_nmethod_code_size; } - static long get_peak_compilation_time() { return _peak_compilation_time; } - static long get_total_compilation_time() { return _t_total_compilation.milliseconds(); } + static jlong get_peak_compilation_time() { return _peak_compilation_time; } + static jlong get_total_compilation_time() { return _t_total_compilation.milliseconds(); } // Log that compilation profiling is skipped because metaspace is full. static void log_metaspace_failure(); diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index b3397bdd3fb75..80a9a7363fa47 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -569,7 +569,7 @@ void JVMCIEnv::put_int_at(JVMCIPrimitiveArray array, int index, jint value) { } } -long JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) { +jlong JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) { if (is_hotspot()) { return HotSpotJVMCI::resolve(array)->long_at(index); } else { diff --git a/src/hotspot/share/jvmci/jvmciEnv.hpp b/src/hotspot/share/jvmci/jvmciEnv.hpp index 18a80accd8bc4..61b7cd4e3312b 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.hpp +++ b/src/hotspot/share/jvmci/jvmciEnv.hpp @@ -251,7 +251,7 @@ class JVMCIEnv : public ResourceObj { jint get_int_at(JVMCIPrimitiveArray array, int index); void put_int_at(JVMCIPrimitiveArray array, int index, jint value); - long get_long_at(JVMCIPrimitiveArray array, int index); + jlong get_long_at(JVMCIPrimitiveArray array, int index); void put_long_at(JVMCIPrimitiveArray array, int index, jlong value); void copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length); diff --git a/src/hotspot/share/runtime/interfaceSupport.cpp b/src/hotspot/share/runtime/interfaceSupport.cpp index cfdc6e2a717e7..db02febef4870 100644 --- a/src/hotspot/share/runtime/interfaceSupport.cpp +++ b/src/hotspot/share/runtime/interfaceSupport.cpp @@ -78,7 +78,7 @@ VMNativeEntryWrapper::~VMNativeEntryWrapper() { unsigned int InterfaceSupport::_scavenge_alot_counter = 1; unsigned int InterfaceSupport::_fullgc_alot_counter = 1; -int InterfaceSupport::_fullgc_alot_invocation = 0; +intx InterfaceSupport::_fullgc_alot_invocation = 0; void InterfaceSupport::gc_alot() { Thread *thread = Thread::current(); diff --git a/src/hotspot/share/runtime/interfaceSupport.inline.hpp b/src/hotspot/share/runtime/interfaceSupport.inline.hpp index 3cae644d63a56..116eb6c3a154e 100644 --- a/src/hotspot/share/runtime/interfaceSupport.inline.hpp +++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp @@ -54,7 +54,7 @@ class InterfaceSupport: AllStatic { public: static unsigned int _scavenge_alot_counter; static unsigned int _fullgc_alot_counter; - static int _fullgc_alot_invocation; + static intx _fullgc_alot_invocation; // Helper methods used to implement +ScavengeALot and +FullGCALot static void check_gc_alot() { if (ScavengeALot || FullGCALot) gc_alot(); } diff --git a/src/hotspot/share/runtime/sweeper.cpp b/src/hotspot/share/runtime/sweeper.cpp index 93fac19effee3..e0674de5f7add 100644 --- a/src/hotspot/share/runtime/sweeper.cpp +++ b/src/hotspot/share/runtime/sweeper.cpp @@ -55,9 +55,9 @@ // Sweeper logging code class SweeperRecord { public: - int traversal; + int64_t traversal; int compile_id; - long traversal_mark; + int64_t traversal_mark; int state; const char* kind; address vep; @@ -65,8 +65,8 @@ class SweeperRecord { int line; void print() { - tty->print_cr("traversal = %d compile_id = %d %s uep = " PTR_FORMAT " vep = " - PTR_FORMAT " state = %d traversal_mark %ld line = %d", + tty->print_cr("traversal = " INT64_FORMAT " compile_id = %d %s uep = " PTR_FORMAT " vep = " + PTR_FORMAT " state = %d traversal_mark " INT64_FORMAT " line = %d", traversal, compile_id, kind == NULL ? "" : kind, @@ -107,8 +107,8 @@ void NMethodSweeper::init_sweeper_log() { #endif CompiledMethodIterator NMethodSweeper::_current(CompiledMethodIterator::all_blobs); // Current compiled method -long NMethodSweeper::_traversals = 0; // Stack scan count, also sweep ID. -long NMethodSweeper::_total_nof_code_cache_sweeps = 0; // Total number of full sweeps of the code cache +int64_t NMethodSweeper::_traversals = 0; // Stack scan count, also sweep ID. +int64_t NMethodSweeper::_total_nof_code_cache_sweeps = 0; // Total number of full sweeps of the code cache int NMethodSweeper::_seen = 0; // Nof. nmethod we have currently processed in current pass of CodeCache size_t NMethodSweeper::_sweep_threshold_bytes = 0; // Threshold for when to sweep. Updated after ergonomics @@ -119,8 +119,8 @@ volatile size_t NMethodSweeper::_bytes_changed = 0; // Counts the tot // 2) not_entrant -> zombie int NMethodSweeper::_hotness_counter_reset_val = 0; -long NMethodSweeper::_total_nof_methods_reclaimed = 0; // Accumulated nof methods flushed -long NMethodSweeper::_total_nof_c2_methods_reclaimed = 0; // Accumulated nof methods flushed +int64_t NMethodSweeper::_total_nof_methods_reclaimed = 0; // Accumulated nof methods flushed +int64_t NMethodSweeper::_total_nof_c2_methods_reclaimed = 0; // Accumulated nof methods flushed size_t NMethodSweeper::_total_flushed_size = 0; // Total number of bytes flushed from the code cache Tickspan NMethodSweeper::_total_time_sweeping; // Accumulated time sweeping Tickspan NMethodSweeper::_total_time_this_sweep; // Total time this sweep @@ -187,7 +187,7 @@ CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() { _total_time_this_sweep = Tickspan(); if (PrintMethodFlushing) { - tty->print_cr("### Sweep: stack traversal %ld", _traversals); + tty->print_cr("### Sweep: stack traversal " INT64_FORMAT, _traversals); } return &mark_activation_closure; } @@ -217,7 +217,7 @@ void NMethodSweeper::sweeper_loop() { { ThreadBlockInVM tbivm(JavaThread::current()); MonitorLocker waiter(CodeSweeper_lock, Mutex::_no_safepoint_check_flag); - const long wait_time = 60*60*24 * 1000; + const int64_t wait_time = 60*60*24 * 1000; timeout = waiter.wait(wait_time); } if (!timeout && (_should_sweep || _force_sweep)) { @@ -649,7 +649,7 @@ void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { CodeCache::log_state(&s); ttyLocker ttyl; - xtty->begin_elem("sweeper state='%s' traversals='" INTX_FORMAT "' ", msg, (intx)traversal_count()); + xtty->begin_elem("sweeper state='%s' traversals='" INT64_FORMAT "' ", msg, traversal_count()); if (format != NULL) { va_list ap; va_start(ap, format); @@ -667,8 +667,9 @@ void NMethodSweeper::print(outputStream* out) { out = (out == NULL) ? tty : out; out->print_cr("Code cache sweeper statistics:"); out->print_cr(" Total sweep time: %1.0lf ms", (double)_total_time_sweeping.value()/1000000); - out->print_cr(" Total number of full sweeps: %ld", _total_nof_code_cache_sweeps); - out->print_cr(" Total number of flushed methods: %ld (thereof %ld C2 methods)", _total_nof_methods_reclaimed, + out->print_cr(" Total number of full sweeps: " INT64_FORMAT, _total_nof_code_cache_sweeps); + out->print_cr(" Total number of flushed methods: " INT64_FORMAT " (thereof " INT64_FORMAT " C2 methods)", + _total_nof_methods_reclaimed, _total_nof_c2_methods_reclaimed); out->print_cr(" Total size of flushed methods: " SIZE_FORMAT " kB", _total_flushed_size/K); } diff --git a/src/hotspot/share/runtime/sweeper.hpp b/src/hotspot/share/runtime/sweeper.hpp index 5f4e0ed7796d7..06daf37ee3a7e 100644 --- a/src/hotspot/share/runtime/sweeper.hpp +++ b/src/hotspot/share/runtime/sweeper.hpp @@ -66,8 +66,8 @@ class NMethodSweeper : public AllStatic { MadeZombie, Flushed }; - static long _traversals; // Stack scan count, also sweep ID. - static long _total_nof_code_cache_sweeps; // Total number of full sweeps of the code cache + static int64_t _traversals; // Stack scan count, also sweep ID. + static int64_t _total_nof_code_cache_sweeps; // Total number of full sweeps of the code cache static CompiledMethodIterator _current; // Current compiled method static int _seen; // Nof. nmethod we have currently processed in current pass of CodeCache static size_t _sweep_threshold_bytes; // The threshold for when to invoke sweeps @@ -78,8 +78,8 @@ class NMethodSweeper : public AllStatic { // 1) alive -> not_entrant // 2) not_entrant -> zombie // Stat counters - static long _total_nof_methods_reclaimed; // Accumulated nof methods flushed - static long _total_nof_c2_methods_reclaimed; // Accumulated nof C2-compiled methods flushed + static int64_t _total_nof_methods_reclaimed; // Accumulated nof methods flushed + static int64_t _total_nof_c2_methods_reclaimed; // Accumulated nof C2-compiled methods flushed static size_t _total_flushed_size; // Total size of flushed methods static int _hotness_counter_reset_val; @@ -97,10 +97,10 @@ class NMethodSweeper : public AllStatic { static void do_stack_scanning(); static void sweep(); public: - static long traversal_count() { return _traversals; } + static int64_t traversal_count() { return _traversals; } static size_t sweep_threshold_bytes() { return _sweep_threshold_bytes; } static void set_sweep_threshold_bytes(size_t threshold) { _sweep_threshold_bytes = threshold; } - static int total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; } + static int64_t total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; } static const Tickspan total_time_sweeping() { return _total_time_sweeping; } static const Tickspan peak_sweep_time() { return _peak_sweep_time; } static const Tickspan peak_sweep_fraction_time() { return _peak_sweep_fraction_time; } diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index 33de84a68c155..28dbd337eecba 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -687,7 +687,7 @@ typedef HashtableEntry KlassHashtableEntry; nonstatic_field(nmethod, _verified_entry_point, address) \ nonstatic_field(nmethod, _osr_entry_point, address) \ volatile_nonstatic_field(nmethod, _lock_count, jint) \ - volatile_nonstatic_field(nmethod, _stack_traversal_mark, long) \ + volatile_nonstatic_field(nmethod, _stack_traversal_mark, int64_t) \ nonstatic_field(nmethod, _compile_id, int) \ nonstatic_field(nmethod, _comp_level, int) \ \ @@ -1224,6 +1224,7 @@ typedef HashtableEntry KlassHashtableEntry; declare_integer_type(ssize_t) \ declare_integer_type(intx) \ declare_integer_type(intptr_t) \ + declare_integer_type(int64_t) \ declare_unsigned_integer_type(uintx) \ declare_unsigned_integer_type(uintptr_t) \ declare_unsigned_integer_type(uint8_t) \ From a16057a6df2bdee1e141cf470e9932ec25f61020 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 10:42:20 +0000 Subject: [PATCH 034/846] 8280820: Clean up bug8033699 and bug8075609.java tests: regtesthelpers aren't used Backport-of: fd8a3dcc52dc5d6b62edd83eacef5934f6294e80 --- .../JRadioButton/8033699/bug8033699.java | 63 +++++++++---------- .../JRadioButton/8075609/bug8075609.java | 60 +++++++++--------- 2 files changed, 62 insertions(+), 61 deletions(-) diff --git a/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java b/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java index 06622f718197d..9365e6ba45b25 100644 --- a/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java +++ b/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -21,11 +21,9 @@ * questions. */ - /* +/* * @test * @key headful - * @library ../../regtesthelpers - * @build Util * @bug 8033699 8154043 8167160 8208640 8226892 * @summary Incorrect radio button behavior when pressing tab key * @run main bug8033699 @@ -34,8 +32,7 @@ import java.awt.Robot; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; -import java.util.logging.Level; -import java.util.logging.Logger; + import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; @@ -45,7 +42,6 @@ import javax.swing.JRadioButton; import javax.swing.SwingUtilities; import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; public class bug8033699 { @@ -59,7 +55,7 @@ public class bug8033699 { private static JRadioButton radioBtn3; private static JRadioButton radioBtnSingle; - public static void main(String args[]) throws Throwable { + public static void main(String[] args) throws Throwable { SwingUtilities.invokeAndWait(() -> { changeLAF(); createAndShowGUI(); @@ -67,6 +63,7 @@ public static void main(String args[]) throws Throwable { robot = new Robot(); Thread.sleep(100); + robot.waitForIdle(); robot.setAutoDelay(100); @@ -76,7 +73,7 @@ public static void main(String args[]) throws Throwable { // tab key test non-grouped radio button runTest2(); - // shift tab key test grouped and non grouped radio button + // shift tab key test grouped and non-grouped radio button runTest3(); // left/up key test in grouped radio button @@ -152,16 +149,16 @@ private static void createAndShowGUI() { mainFrame.setLayout(new BoxLayout(mainFrame.getContentPane(), BoxLayout.Y_AXIS)); mainFrame.setSize(300, 300); - mainFrame.setLocation(200, 200); + mainFrame.setLocationRelativeTo(null); mainFrame.setVisible(true); mainFrame.toFront(); } // Radio button Group as a single component when traversing through tab key private static void runTest1() throws Exception { - hitKey(robot, KeyEvent.VK_TAB); - hitKey(robot, KeyEvent.VK_TAB); - hitKey(robot, KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtnSingle) { @@ -173,7 +170,7 @@ private static void runTest1() throws Exception { // Non-Grouped Radio button as a single component when traversing through tab key private static void runTest2() throws Exception { - hitKey(robot, KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != btnEnd) { System.out.println("Non Grouped Radio Button Go To Next Component through Tab Key failed"); @@ -184,9 +181,9 @@ private static void runTest2() throws Exception { // Non-Grouped Radio button and Group Radio button as a single component when traversing through shift-tab key private static void runTest3() throws Exception { - hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); - hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); - hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn1) { System.out.println("Radio button Group/Non Grouped Radio Button SHIFT-Tab Key Test failed"); @@ -197,8 +194,8 @@ private static void runTest3() throws Exception { // Using arrow key to move focus in radio button group private static void runTest4() throws Exception { - hitKey(robot, KeyEvent.VK_DOWN); - hitKey(robot, KeyEvent.VK_RIGHT); + hitKey(KeyEvent.VK_DOWN); + hitKey(KeyEvent.VK_RIGHT); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) { System.out.println("Radio button Group UP/LEFT Arrow Key Move Focus Failed"); @@ -208,8 +205,8 @@ private static void runTest4() throws Exception { } private static void runTest5() throws Exception { - hitKey(robot, KeyEvent.VK_UP); - hitKey(robot, KeyEvent.VK_LEFT); + hitKey(KeyEvent.VK_UP); + hitKey(KeyEvent.VK_LEFT); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn1) { System.out.println("Radio button Group Left/Up Arrow Key Move Focus Failed"); @@ -219,8 +216,8 @@ private static void runTest5() throws Exception { } private static void runTest6() throws Exception { - hitKey(robot, KeyEvent.VK_UP); - hitKey(robot, KeyEvent.VK_UP); + hitKey(KeyEvent.VK_UP); + hitKey(KeyEvent.VK_UP); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn2) { System.out.println("Radio button Group Circle Back To First Button Test"); @@ -230,7 +227,7 @@ private static void runTest6() throws Exception { } private static void runTest7() throws Exception { - hitKey(robot, KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != btnMiddle) { System.out.println("Separate Component added in button group layout"); @@ -240,7 +237,7 @@ private static void runTest7() throws Exception { } private static void runTest8() throws Exception { - hitKey(robot, KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtnSingle) { System.out.println("Separate Component added in button group layout"); @@ -249,9 +246,9 @@ private static void runTest8() throws Exception { }); } - private static Boolean actRB1 = false; - private static Boolean actRB2 = false; - private static Boolean actRB3 = false; + private static boolean actRB1 = false; + private static boolean actRB2 = false; + private static boolean actRB3 = false; // JDK-8226892: Verify that ActionListener is called when a RadioButton is selected using arrow key. private static void runTest9() throws Exception { @@ -268,9 +265,9 @@ private static void runTest9() throws Exception { radioBtn2.addActionListener(actLrRB2); radioBtn3.addActionListener(actLrRB3); - hitKey(robot, KeyEvent.VK_DOWN); - hitKey(robot, KeyEvent.VK_DOWN); - hitKey(robot, KeyEvent.VK_DOWN); + hitKey(KeyEvent.VK_DOWN); + hitKey(KeyEvent.VK_DOWN); + hitKey(KeyEvent.VK_DOWN); String failMessage = "ActionListener not invoked when selected using arrow key."; if (!actRB2) { @@ -288,13 +285,13 @@ private static void runTest9() throws Exception { radioBtn3.removeActionListener(actLrRB3); } - private static void hitKey(Robot robot, int keycode) { + private static void hitKey(int keycode) { robot.keyPress(keycode); robot.keyRelease(keycode); robot.waitForIdle(); } - private static void hitKey(Robot robot, int mode, int keycode) { + private static void hitKey(int mode, int keycode) { robot.keyPress(mode); robot.keyPress(keycode); robot.keyRelease(keycode); diff --git a/test/jdk/javax/swing/JRadioButton/8075609/bug8075609.java b/test/jdk/javax/swing/JRadioButton/8075609/bug8075609.java index 31c99206b7a9b..4c29a33ffa004 100644 --- a/test/jdk/javax/swing/JRadioButton/8075609/bug8075609.java +++ b/test/jdk/javax/swing/JRadioButton/8075609/bug8075609.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -21,44 +21,49 @@ * questions. */ - /* +/* * @test * @key headful - * @library ../../regtesthelpers - * @build Util * @bug 8075609 * @summary IllegalArgumentException when transferring focus from JRadioButton using tab - * @author Vivi An * @run main bug8075609 */ - -import javax.swing.*; -import javax.swing.event.*; -import java.awt.event.*; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Robot; +import java.awt.event.KeyEvent; + +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JTextField; +import javax.swing.LayoutFocusTraversalPolicy; +import javax.swing.SwingUtilities; public class bug8075609 { private static Robot robot; private static JTextField textField; private static JFrame mainFrame; - public static void main(String args[]) throws Throwable { + public static void main(String[] args) throws Throwable { try { - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - createAndShowGUI(); - } - }); + SwingUtilities.invokeAndWait(bug8075609::createAndShowGUI); robot = new Robot(); Thread.sleep(100); + robot.waitForIdle(); robot.setAutoDelay(100); // Radio button group tab key test runTest1(); } finally { - if (mainFrame != null) SwingUtilities.invokeAndWait(() -> mainFrame.dispose()); + SwingUtilities.invokeAndWait(() -> { + if (mainFrame != null) { + mainFrame.dispose(); + } + }); } } @@ -91,26 +96,25 @@ private static void createAndShowGUI() { mainFrame.add(rootPanel); mainFrame.pack(); + mainFrame.setLocationRelativeTo(null); mainFrame.setVisible(true); mainFrame.toFront(); } // Radio button Group as a single component when traversing through tab key - private static void runTest1() throws Exception{ - hitKey(robot, KeyEvent.VK_TAB); - - robot.delay(1000 ); - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - if (!textField.hasFocus()) { - System.out.println("Radio Button Group Go To Next Component through Tab Key failed"); - throw new RuntimeException("Focus is not on textField as Expected"); - } + private static void runTest1() throws Exception { + hitKey(KeyEvent.VK_TAB); + + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + if (!textField.hasFocus()) { + System.out.println("Radio Button Group Go To Next Component through Tab Key failed"); + throw new RuntimeException("Focus is not on textField as Expected"); } }); } - private static void hitKey(Robot robot, int keycode) { + private static void hitKey(int keycode) { robot.keyPress(keycode); robot.keyRelease(keycode); robot.waitForIdle(); From e58f33a96b4d0c286ca0aab76699eba385532bf2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 10:44:27 +0000 Subject: [PATCH 035/846] 8280468: Crashes in getConfigColormap, getConfigVisualId, XVisualIDFromVisual on Linux Backport-of: 05dac5a23ed2813b2f4f2e4f007ebb93b4ae23ef --- .../unix/classes/sun/awt/X11/XCanvasPeer.java | 41 +++++++++---------- .../classes/sun/awt/X11GraphicsDevice.java | 14 +++++-- .../native/libawt_xawt/awt/awt_GraphicsEnv.c | 41 ++++++++++--------- 3 files changed, 51 insertions(+), 45 deletions(-) diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XCanvasPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XCanvasPeer.java index c7725bfb4046e..2045288bce45f 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XCanvasPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XCanvasPeer.java @@ -62,36 +62,33 @@ public GraphicsConfiguration getAppropriateGraphicsConfiguration( if (graphicsConfig == null || gc == null) { return gc; } - // Opt: Only need to do if we're not using the default GC - int screenNum = ((X11GraphicsDevice)gc.getDevice()).getScreen(); + final X11GraphicsDevice newDev = getSameScreenDevice(gc); + final int visualToLookFor = graphicsConfig.getVisual(); - X11GraphicsConfig parentgc; - // save vis id of current gc - int visual = graphicsConfig.getVisual(); - - X11GraphicsDevice newDev = (X11GraphicsDevice) GraphicsEnvironment. - getLocalGraphicsEnvironment(). - getScreenDevices()[screenNum]; - - for (int i = 0; i < newDev.getNumConfigs(screenNum); i++) { - if (visual == newDev.getConfigVisualId(i, screenNum)) { - // use that - graphicsConfig = (X11GraphicsConfig)newDev.getConfigurations()[i]; - break; + final GraphicsConfiguration[] configurations = newDev.getConfigurations(); + for (final GraphicsConfiguration config : configurations) { + final X11GraphicsConfig x11gc = (X11GraphicsConfig) config; + if (visualToLookFor == x11gc.getVisual()) { + graphicsConfig = x11gc; } } - // just in case... - if (graphicsConfig == null) { - graphicsConfig = (X11GraphicsConfig) GraphicsEnvironment. - getLocalGraphicsEnvironment(). - getScreenDevices()[screenNum]. - getDefaultConfiguration(); - } return graphicsConfig; } + private X11GraphicsDevice getSameScreenDevice(GraphicsConfiguration gc) { + XToolkit.awtLock(); // so that the number of screens doesn't change during + try { + final int screenNum = ((X11GraphicsDevice) gc.getDevice()).getScreen(); + return (X11GraphicsDevice) GraphicsEnvironment. + getLocalGraphicsEnvironment(). + getScreenDevices()[screenNum]; + } finally { + XToolkit.awtUnlock(); + } + } + protected boolean shouldFocusOnClick() { // Canvas should always be able to be focused by mouse clicks. return true; diff --git a/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java b/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java index 736a0d468f86b..847386c9b0d37 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java +++ b/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java @@ -41,6 +41,7 @@ import sun.awt.util.ThreadGroupUtils; import sun.java2d.SunGraphicsEnvironment; import sun.java2d.loops.SurfaceType; +import sun.awt.X11.XToolkit; import sun.java2d.opengl.GLXGraphicsConfig; import sun.java2d.pipe.Region; import sun.java2d.xr.XRGraphicsConfig; @@ -63,7 +64,6 @@ public final class X11GraphicsDevice extends GraphicsDevice private static AWTPermission fullScreenExclusivePermission; private static Boolean xrandrExtSupported; - private final Object configLock = new Object(); private SunDisplayChanger topLevels = new SunDisplayChanger(); private DisplayMode origDisplayMode; private boolean shutdownHookRegistered; @@ -150,8 +150,11 @@ public String getIDstring() { @Override public GraphicsConfiguration[] getConfigurations() { if (configs == null) { - synchronized (configLock) { + XToolkit.awtLock(); + try { makeConfigurations(); + } finally { + XToolkit.awtUnlock(); } } return configs.clone(); @@ -238,8 +241,11 @@ private void addDoubleBufferVisual(int visNum) { @Override public GraphicsConfiguration getDefaultConfiguration() { if (defaultConfig == null) { - synchronized (configLock) { + XToolkit.awtLock(); + try { makeDefaultConfiguration(); + } finally { + XToolkit.awtUnlock(); } } return defaultConfig; @@ -571,6 +577,8 @@ public String toString() { } public void invalidate(X11GraphicsDevice device) { + assert XToolkit.isAWTLockHeldByCurrentThread(); + screen = device.screen; } } diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c b/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c index eb2befffa30ee..63699bf0aa475 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c +++ b/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c @@ -292,6 +292,8 @@ makeDefaultConfig(JNIEnv *env, int screen) { static void getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) { + // NB: should be invoked only while holding the AWT lock + DASSERT(screen >= 0 && screen < awt_numScreens); int i; int n8p=0, n12p=0, n8s=0, n8gs=0, n8sg=0, n1sg=0, nTrue=0; @@ -314,8 +316,6 @@ getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) { xinawareScreen = screen; } - AWT_LOCK (); - viTmp.screen = xinawareScreen; viTmp.depth = 8; @@ -372,7 +372,6 @@ getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) { if (graphicsConfigs == NULL) { JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL); - AWT_UNLOCK(); return; } @@ -382,6 +381,9 @@ getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) { * been reset, so we need to recreate the default config here. */ screenDataPtr->defaultConfig = makeDefaultConfig(env, screen); + if (screenDataPtr->defaultConfig == NULL) { + return; + } } defaultConfig = screenDataPtr->defaultConfig; @@ -581,7 +583,6 @@ getAllConfigs (JNIEnv *env, int screen, AwtScreenDataPtr screenDataPtr) { XFree (pVI1sg); if (nTrue != 0) XFree (pVITrue); - AWT_UNLOCK (); } /* @@ -770,6 +771,7 @@ JNIEnv *env, jobject this) } static void ensureConfigsInited(JNIEnv* env, int screen) { + // NB: should be invoked only while holding the AWT lock if (x11Screens[screen].numConfigs == 0) { if (env == NULL) { env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); @@ -780,6 +782,8 @@ static void ensureConfigsInited(JNIEnv* env, int screen) { AwtGraphicsConfigDataPtr getDefaultConfig(int screen) { + // NB: should be invoked only while holding the AWT lock + DASSERT(screen >= 0 && screen < awt_numScreens); ensureConfigsInited(NULL, screen); return x11Screens[screen].defaultConfig; } @@ -973,11 +977,11 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11GraphicsDevice_getNumConfigs( JNIEnv *env, jobject this, jint screen) { - AWT_LOCK(); + // NB: should be invoked only while holding the AWT lock + DASSERT(screen >= 0 && screen < awt_numScreens); ensureConfigsInited(env, screen); - int configs = x11Screens[screen].numConfigs; - AWT_UNLOCK(); - return configs; + return x11Screens[screen].numConfigs; + } /* @@ -989,12 +993,11 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11GraphicsDevice_getConfigVisualId( JNIEnv *env, jobject this, jint index, jint screen) { - int visNum; - AWT_LOCK(); + // NB: should be invoked only while holding the AWT lock + DASSERT(screen >= 0 && screen < awt_numScreens); ensureConfigsInited(env, screen); jint id = (jint) (index == 0 ? x11Screens[screen].defaultConfig : x11Screens[screen].configs[index])->awt_visInfo.visualid; - AWT_UNLOCK(); return id; } @@ -1007,12 +1010,11 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11GraphicsDevice_getConfigDepth( JNIEnv *env, jobject this, jint index, jint screen) { - int visNum; - AWT_LOCK(); + // NB: should be invoked only while holding the AWT lock + DASSERT(screen >= 0 && screen < awt_numScreens); ensureConfigsInited(env, screen); jint depth = (jint) (index == 0 ? x11Screens[screen].defaultConfig : x11Screens[screen].configs[index])->awt_visInfo.depth; - AWT_UNLOCK(); return depth; } @@ -1025,12 +1027,11 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11GraphicsDevice_getConfigColormap( JNIEnv *env, jobject this, jint index, jint screen) { - int visNum; - AWT_LOCK(); + // NB: should be invoked only while holding the AWT lock + DASSERT(screen >= 0 && screen < awt_numScreens); ensureConfigsInited(env, screen); jint colormap = (jint) (index == 0 ? x11Screens[screen].defaultConfig : x11Screens[screen].configs[index])->awt_cmap; - AWT_UNLOCK(); return colormap; } @@ -1140,8 +1141,10 @@ JNIEXPORT void JNICALL Java_sun_awt_X11GraphicsConfig_init( JNIEnv *env, jobject this, jint visualNum, jint screen) { + // NB: should be invoked only while holding the AWT lock + DASSERT(screen >= 0 && screen < awt_numScreens); + AwtGraphicsConfigData *adata = NULL; - AWT_LOCK(); AwtScreenData asd = x11Screens[screen]; int i, n; int depth; @@ -1163,7 +1166,6 @@ JNIEnv *env, jobject this, jint visualNum, jint screen) /* If didn't find the visual, throw an exception... */ if (adata == (AwtGraphicsConfigData *) NULL) { - AWT_UNLOCK(); JNU_ThrowIllegalArgumentException(env, "Unknown Visual Specified"); return; } @@ -1182,7 +1184,6 @@ JNIEnv *env, jobject this, jint visualNum, jint screen) (*env)->SetIntField(env, this, x11GraphicsConfigIDs.bitsPerPixel, (jint)tempImage->bits_per_pixel); XDestroyImage(tempImage); - AWT_UNLOCK(); } /* From 1b6b8df69774fcb9d403c38f67794e369ba256ea Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 10:45:19 +0000 Subject: [PATCH 036/846] 8300645: Handle julong values in logging of GET_CONTAINER_INFO macros Backport-of: 53ae4c07fda69358fc0b2edadf8dbfe6428de619 --- .../os/linux/cgroupSubsystem_linux.hpp | 8 ++++-- .../os/linux/cgroupV1Subsystem_linux.cpp | 28 +++++++++---------- .../os/linux/cgroupV2Subsystem_linux.cpp | 9 +++--- .../docker/TestMemoryAwareness.java | 26 +++++++++++++++++ .../docker/TestMemoryWithCgroupV1.java | 2 +- 5 files changed, 51 insertions(+), 22 deletions(-) diff --git a/src/hotspot/os/linux/cgroupSubsystem_linux.hpp b/src/hotspot/os/linux/cgroupSubsystem_linux.hpp index d4efc0f3d83cc..24634fe861f9a 100644 --- a/src/hotspot/os/linux/cgroupSubsystem_linux.hpp +++ b/src/hotspot/os/linux/cgroupSubsystem_linux.hpp @@ -147,8 +147,10 @@ template int subsystem_file_line_contents(CgroupController* c, } PRAGMA_DIAG_POP +// log_fmt can be different than scan_fmt. For example +// cpu_period() for cgv2 uses log_fmt='%d' and scan_fmt='%*s %d' #define GET_CONTAINER_INFO(return_type, subsystem, filename, \ - logstring, scan_fmt, variable) \ + logstring, log_fmt, scan_fmt, variable) \ return_type variable; \ { \ int err; \ @@ -158,11 +160,11 @@ PRAGMA_DIAG_POP scan_fmt, \ &variable); \ if (err != 0) { \ - log_trace(os, container)(logstring, (return_type) OSCONTAINER_ERROR); \ + log_trace(os, container)(logstring "%d", OSCONTAINER_ERROR); \ return (return_type) OSCONTAINER_ERROR; \ } \ \ - log_trace(os, container)(logstring, variable); \ + log_trace(os, container)(logstring log_fmt, variable); \ } #define GET_CONTAINER_INFO_CPTR(return_type, subsystem, filename, \ diff --git a/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp index 2f72bcc9c3d0a..bc7d3ada7ac1a 100644 --- a/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp @@ -76,7 +76,7 @@ void CgroupV1Controller::set_subsystem_path(char *cgroup_path) { */ jlong CgroupV1MemoryController::uses_mem_hierarchy() { GET_CONTAINER_INFO(jlong, this, "/memory.use_hierarchy", - "Use Hierarchy is: " JLONG_FORMAT, JLONG_FORMAT, use_hierarchy); + "Use Hierarchy is: ", JLONG_FORMAT, JLONG_FORMAT, use_hierarchy); return use_hierarchy; } @@ -90,7 +90,7 @@ void CgroupV1MemoryController::set_subsystem_path(char *cgroup_path) { jlong CgroupV1Subsystem::read_memory_limit_in_bytes() { GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.limit_in_bytes", - "Memory Limit is: " JULONG_FORMAT, JULONG_FORMAT, memlimit); + "Memory Limit is: ", JULONG_FORMAT, JULONG_FORMAT, memlimit); if (memlimit >= os::Linux::physical_memory()) { log_trace(os, container)("Non-Hierarchical Memory Limit is: Unlimited"); @@ -116,7 +116,7 @@ jlong CgroupV1Subsystem::read_memory_limit_in_bytes() { jlong CgroupV1Subsystem::memory_and_swap_limit_in_bytes() { julong host_total_memsw; GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.memsw.limit_in_bytes", - "Memory and Swap Limit is: " JULONG_FORMAT, JULONG_FORMAT, memswlimit); + "Memory and Swap Limit is: ", JULONG_FORMAT, JULONG_FORMAT, memswlimit); host_total_memsw = os::Linux::host_swap() + os::Linux::physical_memory(); if (memswlimit >= host_total_memsw) { log_trace(os, container)("Non-Hierarchical Memory and Swap Limit is: Unlimited"); @@ -154,13 +154,13 @@ jlong CgroupV1Subsystem::memory_and_swap_limit_in_bytes() { jlong CgroupV1Subsystem::read_mem_swappiness() { GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.swappiness", - "Swappiness is: " JULONG_FORMAT, JULONG_FORMAT, swappiness); + "Swappiness is: ", JULONG_FORMAT, JULONG_FORMAT, swappiness); return swappiness; } jlong CgroupV1Subsystem::memory_soft_limit_in_bytes() { GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.soft_limit_in_bytes", - "Memory Soft Limit is: " JULONG_FORMAT, JULONG_FORMAT, memsoftlimit); + "Memory Soft Limit is: ", JULONG_FORMAT, JULONG_FORMAT, memsoftlimit); if (memsoftlimit >= os::Linux::physical_memory()) { log_trace(os, container)("Memory Soft Limit is: Unlimited"); return (jlong)-1; @@ -180,7 +180,7 @@ jlong CgroupV1Subsystem::memory_soft_limit_in_bytes() { */ jlong CgroupV1Subsystem::memory_usage_in_bytes() { GET_CONTAINER_INFO(jlong, _memory->controller(), "/memory.usage_in_bytes", - "Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, memusage); + "Memory Usage is: ", JLONG_FORMAT, JLONG_FORMAT, memusage); return memusage; } @@ -194,20 +194,20 @@ jlong CgroupV1Subsystem::memory_usage_in_bytes() { */ jlong CgroupV1Subsystem::memory_max_usage_in_bytes() { GET_CONTAINER_INFO(jlong, _memory->controller(), "/memory.max_usage_in_bytes", - "Maximum Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, memmaxusage); + "Maximum Memory Usage is: ", JLONG_FORMAT, JLONG_FORMAT, memmaxusage); return memmaxusage; } jlong CgroupV1Subsystem::kernel_memory_usage_in_bytes() { GET_CONTAINER_INFO(jlong, _memory->controller(), "/memory.kmem.usage_in_bytes", - "Kernel Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, kmem_usage); + "Kernel Memory Usage is: ", JLONG_FORMAT, JLONG_FORMAT, kmem_usage); return kmem_usage; } jlong CgroupV1Subsystem::kernel_memory_limit_in_bytes() { GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.kmem.limit_in_bytes", - "Kernel Memory Limit is: " JULONG_FORMAT, JULONG_FORMAT, kmem_limit); + "Kernel Memory Limit is: ", JULONG_FORMAT, JULONG_FORMAT, kmem_limit); if (kmem_limit >= os::Linux::physical_memory()) { return (jlong)-1; } @@ -216,7 +216,7 @@ jlong CgroupV1Subsystem::kernel_memory_limit_in_bytes() { jlong CgroupV1Subsystem::kernel_memory_max_usage_in_bytes() { GET_CONTAINER_INFO(jlong, _memory->controller(), "/memory.kmem.max_usage_in_bytes", - "Maximum Kernel Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, kmem_max_usage); + "Maximum Kernel Memory Usage is: ", JLONG_FORMAT, JLONG_FORMAT, kmem_max_usage); return kmem_max_usage; } @@ -254,13 +254,13 @@ char * CgroupV1Subsystem::cpu_cpuset_memory_nodes() { */ int CgroupV1Subsystem::cpu_quota() { GET_CONTAINER_INFO(int, _cpu->controller(), "/cpu.cfs_quota_us", - "CPU Quota is: %d", "%d", quota); + "CPU Quota is: ", "%d", "%d", quota); return quota; } int CgroupV1Subsystem::cpu_period() { GET_CONTAINER_INFO(int, _cpu->controller(), "/cpu.cfs_period_us", - "CPU Period is: %d", "%d", period); + "CPU Period is: ", "%d", "%d", period); return period; } @@ -276,7 +276,7 @@ int CgroupV1Subsystem::cpu_period() { */ int CgroupV1Subsystem::cpu_shares() { GET_CONTAINER_INFO(int, _cpu->controller(), "/cpu.shares", - "CPU Shares is: %d", "%d", shares); + "CPU Shares is: ", "%d", "%d", shares); // Convert 1024 to no shares setup if (shares == 1024) return -1; @@ -316,6 +316,6 @@ jlong CgroupV1Subsystem::pids_max() { jlong CgroupV1Subsystem::pids_current() { if (_pids == NULL) return OSCONTAINER_ERROR; GET_CONTAINER_INFO(jlong, _pids, "/pids.current", - "Current number of tasks is: " JLONG_FORMAT, JLONG_FORMAT, pids_current); + "Current number of tasks is: ", JLONG_FORMAT, JLONG_FORMAT, pids_current); return pids_current; } diff --git a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp index eb90714f57f84..2fd9a9c0beafd 100644 --- a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp @@ -36,7 +36,7 @@ */ int CgroupV2Subsystem::cpu_shares() { GET_CONTAINER_INFO(int, _unified, "/cpu.weight", - "Raw value for CPU Shares is: %d", "%d", shares); + "Raw value for CPU Shares is: ", "%d", "%d", shares); // Convert default value of 100 to no shares setup if (shares == 100) { log_debug(os, container)("CPU Shares is: %d", -1); @@ -109,7 +109,7 @@ char * CgroupV2Subsystem::cpu_cpuset_memory_nodes() { int CgroupV2Subsystem::cpu_period() { GET_CONTAINER_INFO(int, _unified, "/cpu.max", - "CPU Period is: %d", "%*s %d", period); + "CPU Period is: ", "%d", "%*s %d", period); return period; } @@ -124,7 +124,7 @@ int CgroupV2Subsystem::cpu_period() { */ jlong CgroupV2Subsystem::memory_usage_in_bytes() { GET_CONTAINER_INFO(jlong, _unified, "/memory.current", - "Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, memusage); + "Memory Usage is: ", JLONG_FORMAT, JLONG_FORMAT, memusage); return memusage; } @@ -158,6 +158,7 @@ jlong CgroupV2Subsystem::memory_and_swap_limit_in_bytes() { assert(memory_limit >= 0, "swap limit without memory limit?"); return memory_limit + swap_limit; } + log_trace(os, container)("Memory and Swap Limit is: " JLONG_FORMAT, swap_limit); return swap_limit; } @@ -251,6 +252,6 @@ jlong CgroupV2Subsystem::pids_max() { */ jlong CgroupV2Subsystem::pids_current() { GET_CONTAINER_INFO(jlong, _unified, "/pids.current", - "Current number of tasks is: " JLONG_FORMAT, JLONG_FORMAT, pids_current); + "Current number of tasks is: ", JLONG_FORMAT, JLONG_FORMAT, pids_current); return pids_current; } diff --git a/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java b/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java index 6b817d7255c51..f6826a17ead24 100644 --- a/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java +++ b/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java @@ -75,6 +75,7 @@ public static void main(String[] args) throws Exception { testMemorySoftLimit("500m", "524288000"); testMemorySoftLimit("1g", "1073741824"); + testMemorySwapLimitSanity(); // Add extra 10 Mb to allocator limit, to be sure to cause OOM testOOM("256m", 256 + 10); @@ -153,6 +154,31 @@ private static void testMemorySoftLimit(String valueToSet, String expectedTraceV .shouldMatch("Memory Soft Limit.*" + expectedTraceValue); } + /* + * This test verifies that no confusingly large positive numbers get printed on + * systems with swapaccount=0 kernel option. On some systems -2 were converted + * to unsigned long and printed that way. Ensure this oddity doesn't occur. + */ + private static void testMemorySwapLimitSanity() throws Exception { + String valueToSet = "500m"; + String expectedTraceValue = "524288000"; + Common.logNewTestCase("memory swap sanity: " + valueToSet); + + DockerRunOptions opts = Common.newOpts(imageName, "PrintContainerInfo"); + Common.addWhiteBoxOpts(opts); + opts.addDockerOpts("--memory=" + valueToSet); + opts.addDockerOpts("--memory-swap=" + valueToSet); + + String neg2InUnsignedLong = "18446744073709551614"; + + Common.run(opts) + .shouldMatch("Memory Limit is:.*" + expectedTraceValue) + // Either for cgroup v1: a_1) same as memory limit, or b_1) -2 on systems with swapaccount=0 + // Either for cgroup v2: a_2) 0, or b_2) -2 on systems with swapaccount=0 + .shouldMatch("Memory and Swap Limit is:.*(" + expectedTraceValue + "|-2|0)") + .shouldNotMatch("Memory and Swap Limit is:.*" + neg2InUnsignedLong); + } + // provoke OOM inside the container, see how VM reacts private static void testOOM(String dockerMemLimit, int sizeToAllocInMb) throws Exception { diff --git a/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java b/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java index b62f96ee801eb..cf62ef9ecba8c 100644 --- a/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java +++ b/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java @@ -84,7 +84,7 @@ private static void testMemoryLimitWithSwappiness(String dockerMemLimit, String OutputAnalyzer out = Common.run(opts); // in case of warnings like : "Your kernel does not support swap limit // capabilities or the cgroup is not mounted. Memory limited without swap." - // we only have Memory and Swap Limit is: in the output + // we only have 'Memory and Swap Limit is: -2' in the output try { if (out.getOutput().contains("memory_and_swap_limit_in_bytes: not supported")) { System.out.println("memory_and_swap_limit_in_bytes not supported, avoiding Memory and Swap Limit check"); From 0990347bb9d36dacf430df80ac5e969b055a3109 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 10:46:34 +0000 Subject: [PATCH 037/846] 8305578: X11GraphicsDevice.pGetBounds() is slow in remote X11 sessions Backport-of: d7245f70e7bac1236bbcdcd9b25346ca22ab8bb2 --- .../unix/classes/sun/awt/X11/XToolkit.java | 35 +++++++++++++++++-- .../classes/sun/awt/X11GraphicsDevice.java | 28 +++++++++++++-- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java index 8d5586741f277..acd5ddde6116b 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -116,6 +116,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; @@ -358,6 +359,11 @@ public void dispatchEvent(XEvent ev) { } finally { awtLock(); } + } else { + final XAtom XA_NET_WORKAREA = XAtom.get("_NET_WORKAREA"); + final boolean rootWindowWorkareaResized = (ev.get_type() == XConstants.PropertyNotify + && ev.get_xproperty().get_atom() == XA_NET_WORKAREA.getAtom()); + if (rootWindowWorkareaResized) resetScreenInsetsCache(); } } }); @@ -848,8 +854,7 @@ private static Rectangle getWorkArea(long root, int scale) * When two screens overlap and the first contains a dock(*****), then * _NET_WORKAREA may start at point x1,y1 and end at point x2,y2. */ - @Override - public Insets getScreenInsets(final GraphicsConfiguration gc) { + private Insets getScreenInsetsImpl(final GraphicsConfiguration gc) { GraphicsDevice gd = gc.getDevice(); XNETProtocol np = XWM.getWM().getNETProtocol(); if (np == null || !(gd instanceof X11GraphicsDevice) || !np.active()) { @@ -877,6 +882,30 @@ public Insets getScreenInsets(final GraphicsConfiguration gc) { } } + private void resetScreenInsetsCache() { + final GraphicsDevice[] devices = ((X11GraphicsEnvironment)GraphicsEnvironment. + getLocalGraphicsEnvironment()).getScreenDevices(); + for (var gd : devices) { + ((X11GraphicsDevice)gd).resetInsets(); + } + } + + @Override + public Insets getScreenInsets(final GraphicsConfiguration gc) { + final X11GraphicsDevice device = (X11GraphicsDevice) gc.getDevice(); + Insets insets = device.getInsets(); + if (insets == null) { + synchronized (device) { + insets = device.getInsets(); + if (insets == null) { + insets = getScreenInsetsImpl(gc); + device.setInsets(insets); + } + } + } + return (Insets) insets.clone(); + } + /* * The current implementation of disabling background erasing for * canvases is that we don't set any native background color diff --git a/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java b/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java index 847386c9b0d37..4b05b387a891f 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java +++ b/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -30,6 +30,7 @@ import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; +import java.awt.Insets; import java.awt.Rectangle; import java.awt.Window; import java.security.AccessController; @@ -37,6 +38,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.Objects; import sun.awt.util.ThreadGroupUtils; import sun.java2d.SunGraphicsEnvironment; @@ -66,12 +68,15 @@ public final class X11GraphicsDevice extends GraphicsDevice private static Boolean xrandrExtSupported; private SunDisplayChanger topLevels = new SunDisplayChanger(); private DisplayMode origDisplayMode; + private volatile Rectangle bounds; + private volatile Insets insets; private boolean shutdownHookRegistered; private int scale; public X11GraphicsDevice(int screennum) { this.screen = screennum; this.scale = initScaleFactor(); + this.bounds = getBoundsImpl(); } /** @@ -118,7 +123,7 @@ public int scaleDown(int x) { return Region.clipRound(x / (double)getScaleFactor()); } - public Rectangle getBounds() { + private Rectangle getBoundsImpl() { Rectangle rect = pGetBounds(getScreen()); if (getScaleFactor() != 1) { rect.x = scaleDown(rect.x); @@ -129,6 +134,23 @@ public Rectangle getBounds() { return rect; } + public Rectangle getBounds() { + return bounds.getBounds(); + } + + public Insets getInsets() { + return insets; + } + + public void setInsets(Insets newInsets) { + Objects.requireNonNull(newInsets); + insets = newInsets; + } + + public void resetInsets() { + insets = null; + } + /** * Returns the identification string associated with this graphics * device. @@ -516,6 +538,8 @@ private synchronized DisplayMode getMatchingDisplayMode(DisplayMode dm) { @Override public synchronized void displayChanged() { scale = initScaleFactor(); + bounds = getBoundsImpl(); + insets = null; // On X11 the visuals do not change, and therefore we don't need // to reset the defaultConfig, config, doubleBufferVisuals, // neither do we need to reset the native data. From 6f3624762b9d6863d366b22ea6397730f23a3bb2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 12:36:06 +0000 Subject: [PATCH 038/846] 8308875: java/awt/Toolkit/GetScreenInsetsCustomGC/GetScreenInsetsCustomGC.java failed with 'Cannot invoke "sun.awt.X11GraphicsDevice.getInsets()" because "device" is null' Reviewed-by: rschmelter, mbaesken Backport-of: 41bf2ad159d274574285a0f55c4a0f582cd93648 --- .../unix/classes/sun/awt/X11/XToolkit.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java index acd5ddde6116b..91872d7d59bda 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java @@ -892,18 +892,22 @@ private void resetScreenInsetsCache() { @Override public Insets getScreenInsets(final GraphicsConfiguration gc) { - final X11GraphicsDevice device = (X11GraphicsDevice) gc.getDevice(); - Insets insets = device.getInsets(); - if (insets == null) { - synchronized (device) { - insets = device.getInsets(); - if (insets == null) { - insets = getScreenInsetsImpl(gc); - device.setInsets(insets); + final GraphicsDevice gd = gc.getDevice(); + if (gd instanceof X11GraphicsDevice x11Device) { + Insets insets = x11Device.getInsets(); + if (insets == null) { + synchronized (x11Device) { + insets = x11Device.getInsets(); + if (insets == null) { + insets = getScreenInsetsImpl(gc); + x11Device.setInsets(insets); + } } } + return (Insets) insets.clone(); + } else { + return super.getScreenInsets(gc); } - return (Insets) insets.clone(); } /* From e6d5db62a8b3a192b0a307648ea307df857b9172 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 12:40:08 +0000 Subject: [PATCH 039/846] 8316061: Open source several Swing RootPane and Slider related tests Backport-of: 138542de7889e8002df0e15a79e31d824c6a0473 --- .../jdk/javax/swing/JRootPane/bug4207333.java | 70 ++++++++++++++++ .../jdk/javax/swing/JRootPane/bug4224113.java | 41 +++++++++ .../jdk/javax/swing/JRootPane/bug4627806.java | 65 +++++++++++++++ test/jdk/javax/swing/JSlider/bug4200901.java | 44 ++++++++++ test/jdk/javax/swing/JSlider/bug4203754.java | 83 +++++++++++++++++++ 5 files changed, 303 insertions(+) create mode 100644 test/jdk/javax/swing/JRootPane/bug4207333.java create mode 100644 test/jdk/javax/swing/JRootPane/bug4224113.java create mode 100644 test/jdk/javax/swing/JRootPane/bug4627806.java create mode 100644 test/jdk/javax/swing/JSlider/bug4200901.java create mode 100644 test/jdk/javax/swing/JSlider/bug4203754.java diff --git a/test/jdk/javax/swing/JRootPane/bug4207333.java b/test/jdk/javax/swing/JRootPane/bug4207333.java new file mode 100644 index 0000000000000..b93438eae50b9 --- /dev/null +++ b/test/jdk/javax/swing/JRootPane/bug4207333.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1999, 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. + */ + +import javax.swing.JButton; +import javax.swing.JRootPane; +import java.lang.reflect.Field; + +/* + * @test + * @bug 4207333 + * @summary Inadvertant API regression in JRootPane + * @run main bug4207333 + */ + +public class bug4207333 { + public static void main(String[] argv) { + TestableRootPane rp = new TestableRootPane(); + rp.setDefaultButton(new JButton("Default, eh?")); + + if (!rp.test("defaultPressAction")) { + throw new RuntimeException("Failed test for bug 4207333"); + } + if (!rp.test("defaultReleaseAction")) { + throw new RuntimeException("Failed test for bug 4207333"); + } + System.out.println("Test Passed!"); + } + + private static class TestableRootPane extends JRootPane { + public boolean test(String fieldName) { + boolean result = false; + try { + Class superClass = getClass().getSuperclass(); + Field field = superClass.getDeclaredField(fieldName); + Class fieldClass = field.getType(); + Class actionClass = Class.forName("javax.swing.Action"); + + // Is the Field an Action? + result = actionClass.isAssignableFrom(fieldClass); + } catch (NoSuchFieldException pe) { + // Not a bug if the fields are removed since their + // type was a package private class! + result = true; + } catch (Exception iae) { + System.out.println("Exception " + iae); + } + return result; + } + } +} diff --git a/test/jdk/javax/swing/JRootPane/bug4224113.java b/test/jdk/javax/swing/JRootPane/bug4224113.java new file mode 100644 index 0000000000000..e52b369a88687 --- /dev/null +++ b/test/jdk/javax/swing/JRootPane/bug4224113.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 1999, 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. + */ + +import javax.swing.plaf.RootPaneUI; + +/* + * @test + * @bug 4224113 + * @summary Tests the presence of RootPaneUI + * @run main bug4224113 + */ + +public class bug4224113 { + public static class TestRootPaneUI extends RootPaneUI { + } + + public static void main(String[] args) { + TestRootPaneUI r = new TestRootPaneUI(); + System.out.println("Test Passed!"); + } +} diff --git a/test/jdk/javax/swing/JRootPane/bug4627806.java b/test/jdk/javax/swing/JRootPane/bug4627806.java new file mode 100644 index 0000000000000..cd6d64213a2e0 --- /dev/null +++ b/test/jdk/javax/swing/JRootPane/bug4627806.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2002, 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. + */ + +import javax.swing.JFrame; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JRootPane; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +/* + * @test + * @bug 4627806 + * @key headful + * @summary MetalRootPaneUI calls validate() instead of revalidate() + * @run main bug4627806 + */ + +public class bug4627806 { + private static JFrame frame; + + public static void main(String[] args) throws Exception { + try { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("Test"); + JPanel p = new JPanel(); + JMenuItem c = new JMenuItem(); + p.add(c); + frame.getContentPane().add(p); + frame.pack(); + c.getUI().uninstallUI(c); + JRootPane rootPane = frame.getRootPane(); + rootPane.getUI().uninstallUI(rootPane); + System.out.println("Test Passed!"); + }); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/javax/swing/JSlider/bug4200901.java b/test/jdk/javax/swing/JSlider/bug4200901.java new file mode 100644 index 0000000000000..cf4810a54cad3 --- /dev/null +++ b/test/jdk/javax/swing/JSlider/bug4200901.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1999, 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. + */ + +import javax.swing.JSlider; + +/* + * @test + * @bug 4200901 + * @summary Test to check if JSlider.createStandardLabels() throws Exception + * @run main bug4200901 + */ + +public class bug4200901 { + public static void main(String[] args) { + try { + JSlider slider = new JSlider(); + slider.createStandardLabels( -1 ); + } catch ( IllegalArgumentException e ) { + System.out.println("Test Passed!"); + return; + } + throw new RuntimeException( "TEST FAILED!"); + } +} diff --git a/test/jdk/javax/swing/JSlider/bug4203754.java b/test/jdk/javax/swing/JSlider/bug4203754.java new file mode 100644 index 0000000000000..21eb898d27573 --- /dev/null +++ b/test/jdk/javax/swing/JSlider/bug4203754.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2004, 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. + */ + +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JSlider; +import javax.swing.SwingUtilities; +import java.awt.FlowLayout; +import java.awt.Robot; +import java.util.Dictionary; +import java.util.Hashtable; + +/* + * @test + * @bug 4203754 + * @key headful + * @summary Labels in a JSlider don't disable or enable with the slider + * @run main bug4203754 + */ + +public class bug4203754 { + private static JFrame frame; + private static Robot robot; + private static JLabel label; + + public static void main(String[] argv) throws Exception { + try { + robot = new Robot(); + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("Test"); + frame.getContentPane().setLayout(new FlowLayout()); + JSlider slider = new JSlider(0, 100, 25); + frame.getContentPane().add(slider); + + label = new JLabel("0", JLabel.CENTER) { + public void setEnabled(boolean b) { + super.setEnabled(b); + } + }; + + Dictionary labels = new Hashtable(); + labels.put(Integer.valueOf(0), label); + slider.setLabelTable(labels); + slider.setPaintLabels(true); + slider.setEnabled(false); + frame.setSize(250, 150); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + if (label.isEnabled()) { + throw new RuntimeException("Label should be disabled"); + } + System.out.println("Test Passed!"); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} From e087bb2e18c0280a1ba8770ed95960159ec11c59 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 12:42:09 +0000 Subject: [PATCH 040/846] 8315742: Open source several Swing Scroll related tests Backport-of: f0ff001dd7db33eb492f01cfa08b11705956ebcd --- .../javax/swing/JScrollBar/bug4495822.java | 62 ++++++++++++ .../javax/swing/JScrollBar/bug4696826.java | 66 +++++++++++++ .../javax/swing/JScrollBar/bug4842792.java | 69 +++++++++++++ .../javax/swing/JScrollPane/bug4247092.java | 42 ++++++++ .../javax/swing/JScrollPane/bug4264640.java | 81 +++++++++++++++ .../javax/swing/JScrollPane/bug4467063.java | 98 +++++++++++++++++++ 6 files changed, 418 insertions(+) create mode 100644 test/jdk/javax/swing/JScrollBar/bug4495822.java create mode 100644 test/jdk/javax/swing/JScrollBar/bug4696826.java create mode 100644 test/jdk/javax/swing/JScrollBar/bug4842792.java create mode 100644 test/jdk/javax/swing/JScrollPane/bug4247092.java create mode 100644 test/jdk/javax/swing/JScrollPane/bug4264640.java create mode 100644 test/jdk/javax/swing/JScrollPane/bug4467063.java diff --git a/test/jdk/javax/swing/JScrollBar/bug4495822.java b/test/jdk/javax/swing/JScrollBar/bug4495822.java new file mode 100644 index 0000000000000..01f3024b1a4e1 --- /dev/null +++ b/test/jdk/javax/swing/JScrollBar/bug4495822.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2003, 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. + */ + +import java.awt.Robot; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import javax.swing.JScrollBar; +import javax.swing.SwingUtilities; + +/* + * @test + * @bug 4495822 + * @summary AdjustmentEvent.getValueIsAdjusting() always returns false + * @run main bug4495822 + */ + +public class bug4495822 { + public static volatile boolean isAdjusted = false; + + public static void main(String[] args) throws Exception { + + SwingUtilities.invokeAndWait(() -> { + JScrollBar scrollBar = new JScrollBar(JScrollBar.HORIZONTAL); + scrollBar.addAdjustmentListener(new AdjustmentListener() { + public void adjustmentValueChanged(AdjustmentEvent e) { + if (e.getValueIsAdjusting() != scrollBar.getValueIsAdjusting()) { + throw new RuntimeException("The AdjustmentEvent has incorrect \"valueIsAdjusting\" value"); + } + + isAdjusted = true; + } + }); + + scrollBar.setValueIsAdjusting(true); + }); + Thread.sleep(1000); + if (!isAdjusted) { + throw new RuntimeException("adjustmentValueChanged() not invoked!"); + } + System.out.println("Test Passed!"); + } +} diff --git a/test/jdk/javax/swing/JScrollBar/bug4696826.java b/test/jdk/javax/swing/JScrollBar/bug4696826.java new file mode 100644 index 0000000000000..f82ad6dfa73e1 --- /dev/null +++ b/test/jdk/javax/swing/JScrollBar/bug4696826.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2003, 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. + */ + +import javax.swing.JComponent; +import javax.swing.JScrollBar; +import javax.swing.SwingUtilities; +import javax.swing.plaf.basic.BasicScrollBarUI; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; + +/* + * @test + * @bug 4696826 + * @summary BasicScrollBarUI should check if it needs to paint the thumb + * @run main bug4696826 + */ + +public class bug4696826 { + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + JScrollBar sb = new JScrollBar(); + sb.setBounds(new Rectangle(0, 0, 20, 20)); + + TestScrollBarUI ui = new TestScrollBarUI(); + sb.setUI(ui); + ui.setThumbBounds(0, 0, 20, 20); + + BufferedImage image = new BufferedImage(100, 100, + BufferedImage.TYPE_3BYTE_BGR); + Graphics g = image.getGraphics(); + g.setClip(200, 200, 100, 100); + sb.paint(g); + }); + System.out.println("Test Passed!"); + } + + static class TestScrollBarUI extends BasicScrollBarUI { + protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) { + throw new RuntimeException("Thumb shouldn't be painted"); + } + public void setThumbBounds(int x, int y, int width, int height) { + super.setThumbBounds(x, y, width, height); + } + } +} diff --git a/test/jdk/javax/swing/JScrollBar/bug4842792.java b/test/jdk/javax/swing/JScrollBar/bug4842792.java new file mode 100644 index 0000000000000..09ada58315a73 --- /dev/null +++ b/test/jdk/javax/swing/JScrollBar/bug4842792.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2003, 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. + */ + +import javax.swing.JScrollBar; +import javax.swing.SwingUtilities; +import java.awt.Dimension; +import java.awt.event.MouseEvent; +import java.util.Date; + +/* + * @test + * @bug 4842792 + * @summary JScrollBar behaves incorrectly if "Block increment" value is big enough + * @run main bug4842792 + */ + +public class bug4842792 { + public static TestScrollBar scrollBar; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + scrollBar = new TestScrollBar(JScrollBar.HORIZONTAL, 10, 10, 0, 100); + scrollBar.setPreferredSize(new Dimension(200, 20)); + scrollBar.setBlockIncrement(Integer.MAX_VALUE); + + if (scrollBar.doTest() == 0) { + throw new RuntimeException("The scrollbar new value should not be 0"); + } + }); + System.out.println("Test Passed!"); + } + + static class TestScrollBar extends JScrollBar { + public TestScrollBar(int orientation, int value, int extent, + int min, int max) { + super(orientation, value, extent, min, max); + } + + public int doTest() { + MouseEvent mouseEvent = new MouseEvent(scrollBar, + MouseEvent.MOUSE_PRESSED, + (new Date()).getTime(), + MouseEvent.BUTTON1_DOWN_MASK, + 150, 10, 1, true); + processMouseEvent(mouseEvent); + return scrollBar.getValue(); + } + } +} diff --git a/test/jdk/javax/swing/JScrollPane/bug4247092.java b/test/jdk/javax/swing/JScrollPane/bug4247092.java new file mode 100644 index 0000000000000..a1fa369d67ea1 --- /dev/null +++ b/test/jdk/javax/swing/JScrollPane/bug4247092.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2002, 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. + */ + +import javax.swing.JScrollPane; + +/* + * @test + * @bug 4247092 + * @summary JScrollPane.setCorner(corner,null) causes NPE, but defolt getCorner() rtns null + * @run main bug4247092 + */ + +public class bug4247092 { + public static void main(String[] args) { + JScrollPane sp = new JScrollPane(); + sp.setCorner(JScrollPane.LOWER_RIGHT_CORNER, null); + if (sp.getCorner(JScrollPane.LOWER_RIGHT_CORNER) != null) { + throw new RuntimeException("The corner component should be null"); + } + System.out.println("Test Passed!"); + } +} diff --git a/test/jdk/javax/swing/JScrollPane/bug4264640.java b/test/jdk/javax/swing/JScrollPane/bug4264640.java new file mode 100644 index 0000000000000..ca1bfc146df5b --- /dev/null +++ b/test/jdk/javax/swing/JScrollPane/bug4264640.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2001, 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. + */ + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Robot; + +/* + * @test + * @bug 4264640 + * @summary Tests that JScrollPane sets correct position of its column header view + * @key headful + * @run main bug4264640 + */ + +public class bug4264640 { + public static JFrame frame; + public static JButton b; + public static Robot robot; + public static volatile int yPos; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("Scroll Pane test"); + JScrollPane scroller = new JScrollPane(); + b = new JButton("This is BUG !"); + b.setBounds(12, 12, 169, 133); + scroller.setColumnHeaderView(b); + + Container pane = frame.getContentPane(); + pane.setLayout(new BorderLayout()); + pane.add(scroller); + frame.setSize(200,200); + frame.setVisible(true); + }); + + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + yPos = b.getY(); + }); + if (yPos != 0) { + throw new RuntimeException("Failed: Y = " + yPos + " (should be 0)"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + System.out.println("Test Passed!"); + } +} diff --git a/test/jdk/javax/swing/JScrollPane/bug4467063.java b/test/jdk/javax/swing/JScrollPane/bug4467063.java new file mode 100644 index 0000000000000..8bce485e48dfe --- /dev/null +++ b/test/jdk/javax/swing/JScrollPane/bug4467063.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2003, 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. + */ + +import javax.swing.JButton; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; +import java.awt.ComponentOrientation; + +/* + * @test + * @bug 4467063 + * @summary JScrollPane.setCorner() causes IllegalArgumentException. (invalid corner key) + * @run main bug4467063 + */ + +public class bug4467063 { + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + JScrollPane sp = new JScrollPane(); + + //Test corners for left-to-right orientation + sp.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); + sp.setCorner(JScrollPane.LOWER_LEADING_CORNER, new JButton("0")); + sp.setCorner(JScrollPane.LOWER_TRAILING_CORNER, new JButton("1")); + sp.setCorner(JScrollPane.UPPER_LEADING_CORNER, new JButton("2")); + sp.setCorner(JScrollPane.UPPER_TRAILING_CORNER, new JButton("3")); + + if (!sp.getCorner(JScrollPane.LOWER_LEADING_CORNER).equals( + sp.getCorner(JScrollPane.LOWER_LEFT_CORNER))) { + throw new RuntimeException("Incorrect LOWER_LEADING_CORNER value"); + } + + if (!sp.getCorner(JScrollPane.LOWER_TRAILING_CORNER).equals( + sp.getCorner(JScrollPane.LOWER_RIGHT_CORNER))) { + throw new RuntimeException("Incorrect LOWER_TRAILING_CORNER value"); + } + + if (!sp.getCorner(JScrollPane.UPPER_LEADING_CORNER).equals( + sp.getCorner(JScrollPane.UPPER_LEFT_CORNER))) { + throw new RuntimeException("Incorrect UPPER_LEADING_CORNER value"); + } + + if (!sp.getCorner(JScrollPane.UPPER_TRAILING_CORNER).equals( + sp.getCorner(JScrollPane.UPPER_RIGHT_CORNER))) { + throw new RuntimeException("Incorrect UPPER_TRAILING_CORNER value"); + } + + //Test corners for right-to-left orientation + sp.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); + sp.setCorner(JScrollPane.LOWER_LEADING_CORNER, new JButton("0")); + sp.setCorner(JScrollPane.LOWER_TRAILING_CORNER, new JButton("1")); + sp.setCorner(JScrollPane.UPPER_LEADING_CORNER, new JButton("2")); + sp.setCorner(JScrollPane.UPPER_TRAILING_CORNER, new JButton("3")); + + if (!sp.getCorner(JScrollPane.LOWER_LEADING_CORNER).equals( + sp.getCorner(JScrollPane.LOWER_RIGHT_CORNER))) { + throw new RuntimeException("Incorrect LOWER_LEADING_CORNER value"); + } + + if (!sp.getCorner(JScrollPane.LOWER_TRAILING_CORNER).equals( + sp.getCorner(JScrollPane.LOWER_LEFT_CORNER))) { + throw new RuntimeException("Incorrect LOWER_TRAILING_CORNER value"); + } + + if (!sp.getCorner(JScrollPane.UPPER_LEADING_CORNER).equals( + sp.getCorner(JScrollPane.UPPER_RIGHT_CORNER))) { + throw new RuntimeException("Incorrect UPPER_LEADING_CORNER value"); + } + + if (!sp.getCorner(JScrollPane.UPPER_TRAILING_CORNER).equals( + sp.getCorner(JScrollPane.UPPER_LEFT_CORNER))) { + throw new RuntimeException("Incorrect UPPER_TRAILING_CORNER value"); + } + }); + System.out.println("Test Passed!"); + } +} From 8479f4e07cbca57eea98b1d6592ab69eb3ec8a68 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 12:43:06 +0000 Subject: [PATCH 041/846] 8328670: Automate and open source few closed manual applet test Backport-of: 38e3cda4420ef921cc6e43cb18338ec18c12011f --- .../jdk/javax/swing/JInternalFrame/Ctrli.java | 132 +++++++++++++++ .../swing/JMenuItem/JActionCommandTest.java | 159 ++++++++++++++++++ 2 files changed, 291 insertions(+) create mode 100644 test/jdk/javax/swing/JInternalFrame/Ctrli.java create mode 100644 test/jdk/javax/swing/JMenuItem/JActionCommandTest.java diff --git a/test/jdk/javax/swing/JInternalFrame/Ctrli.java b/test/jdk/javax/swing/JInternalFrame/Ctrli.java new file mode 100644 index 0000000000000..c97e87b7952b4 --- /dev/null +++ b/test/jdk/javax/swing/JInternalFrame/Ctrli.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +import javax.swing.JFrame; +import javax.swing.JComponent; +import javax.swing.SwingUtilities; + +/* + * @test + * @bug 4199401 + * @summary DefaultFocusManager interferes with comps that + * return true to isManagingFocus(). + * @key headful + * @run main Ctrli + */ + +public class Ctrli { + private static JFrame frame; + private static JComponent keyecho; + private static volatile boolean iPressed = false; + private static volatile Point compLoc; + private static volatile int compWidth; + private static volatile int compHeight; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(50); + robot.setAutoWaitForIdle(true); + try { + SwingUtilities.invokeAndWait(Ctrli::createAndShowUI); + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + compLoc = keyecho.getLocationOnScreen(); + compWidth = keyecho.getWidth(); + compHeight = keyecho.getHeight(); + }); + + robot.mouseMove(compLoc.x + compWidth / 2, compLoc.y + compHeight / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + + robot.keyPress(KeyEvent.VK_CONTROL); + robot.keyPress(KeyEvent.VK_I); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_I); + robot.keyRelease(KeyEvent.VK_CONTROL); + robot.waitForIdle(); + + if (!iPressed) { + throw new RuntimeException("Test failed: CTRL+I not pressed."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + frame = new JFrame("Test Ctrl+I operation"); + keyecho = new JComponent() { + public boolean isManagingFocus() { + return true; + } + }; + KeyListener keyListener = new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (((e.getModifiers() & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK) + && (e.getKeyCode() == 73)) + iPressed = true; + } + + public void keyTyped(KeyEvent e) { + if (!iPressed) { + throw new RuntimeException("Test failed: CTRL+I not pressed."); + } + } + }; + + MouseListener mouseListener = new MouseAdapter() { + public void mousePressed(MouseEvent e) { + keyecho.requestFocus(); + } + }; + + keyecho.addKeyListener(keyListener); + keyecho.addMouseListener(mouseListener); + frame.setLayout(new BorderLayout()); + frame.add(keyecho); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setVisible(true); + } +} diff --git a/test/jdk/javax/swing/JMenuItem/JActionCommandTest.java b/test/jdk/javax/swing/JMenuItem/JActionCommandTest.java new file mode 100644 index 0000000000000..0041a509a2f1b --- /dev/null +++ b/test/jdk/javax/swing/JMenuItem/JActionCommandTest.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JTextField; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; + +/* + * @test + * @bug 4159610 + * @key headful + * @summary Verifies that JMenuItem's shortcuts are not inserted in JTextField + * @run main JActionCommandTest + */ + +public class JActionCommandTest { + + private static Robot robot; + private static JMenu m; + private static JMenuItem mi; + private static JFrame f; + private static JTextField tf; + private static volatile Point menuLoc; + private static volatile Point menuItemLoc; + private static volatile Point textFieldLoc; + private static volatile int menuWidth; + private static volatile int menuHeight; + private static volatile int menuItemWidth; + private static volatile int menuItemHeight; + private static volatile int textFieldWidth; + private static volatile int textFieldHeight; + private static volatile boolean passed = false; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + robot.setAutoDelay(50); + robot.setAutoWaitForIdle(true); + try { + SwingUtilities.invokeAndWait(JActionCommandTest::createAndShowUI); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + menuLoc = m.getLocationOnScreen(); + menuWidth = m.getWidth(); + menuHeight = m.getHeight(); + + textFieldLoc = tf.getLocationOnScreen(); + textFieldWidth = tf.getWidth(); + textFieldHeight = tf.getHeight(); + }); + moveAndPressMouse(menuLoc.x, menuLoc.y, menuWidth, menuHeight); + + SwingUtilities.invokeAndWait(() -> { + menuItemLoc = mi.getLocationOnScreen(); + menuItemWidth = mi.getWidth(); + menuItemHeight = mi.getHeight(); + }); + moveAndPressMouse(menuItemLoc.x, menuItemLoc.y, menuItemWidth, menuItemHeight); + System.out.println("passed is: "+passed); + if (!passed) { + throw new RuntimeException("Test Failed: JMenuItem label is not" + + " equals to 'Testitem'."); + } + passed = false; + moveAndPressMouse(textFieldLoc.x, textFieldLoc.y, textFieldWidth, textFieldHeight); + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_T); + robot.keyRelease(KeyEvent.VK_T); + robot.keyRelease(KeyEvent.VK_ALT); + robot.waitForIdle(); + + System.out.println("passed is: "+passed); + System.out.println("tf.getText() is: "+tf.getText()); + if (!passed && tf.getText().equals("t")) { + throw new RuntimeException("Test Failed: Either JMenuItem label is not" + + " equal to 'Testitem' or JTextField contains text 't'. "); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + CustomActionListener customListener = new CustomActionListener(); + f = new JFrame("Test JMenuItem Shortcut"); + f.setLayout(new BorderLayout()); + tf = new JTextField(12); + tf.addActionListener(customListener); + JMenuBar mb = new JMenuBar(); + m = new JMenu("Test"); + mi = new JMenuItem("Testitem"); + KeyStroke ks = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_T, + java.awt.Event.ALT_MASK, false); + mi.setAccelerator(ks); + mi.addActionListener(customListener); + m.add(mi); + mb.add(m); + f.setJMenuBar(mb); + f.add("South", tf); + f.setSize(200, 200); + f.setLocationRelativeTo(null); + f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + f.setVisible(true); + } + + public static void moveAndPressMouse(int x, int y, int width, int height) { + robot.mouseMove(x + width / 2, y + height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + } + + static class CustomActionListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + if (e.getSource() == mi && e.getActionCommand().equals("Testitem")) { + System.out.println("MenuItem's label: " + e.getActionCommand()); + passed = true; + } + } + } +} From e0cfa2d030f194550a3f7f3744e219df11b8889c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 12:44:11 +0000 Subject: [PATCH 042/846] 8328648: Remove applet usage from JFileChooser tests bug4150029 Backport-of: 021ed6aea92f770ebeae65175d94797f7c418c82 --- .../JFileChooser/4150029/bug4150029.html | 43 ----- .../JFileChooser/4150029/bug4150029.java | 148 ++++++++++++------ 2 files changed, 96 insertions(+), 95 deletions(-) delete mode 100644 test/jdk/javax/swing/JFileChooser/4150029/bug4150029.html diff --git a/test/jdk/javax/swing/JFileChooser/4150029/bug4150029.html b/test/jdk/javax/swing/JFileChooser/4150029/bug4150029.html deleted file mode 100644 index 9677de3fc54ad..0000000000000 --- a/test/jdk/javax/swing/JFileChooser/4150029/bug4150029.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - -Follow the instructions below. -1.Go into 'subDir' folder. -2.Press BACKSPACE key. -3.Push OPEN button. -4.Push DONE button. - - diff --git a/test/jdk/javax/swing/JFileChooser/4150029/bug4150029.java b/test/jdk/javax/swing/JFileChooser/4150029/bug4150029.java index 5388ba106a637..d5c7dab4d8ec1 100644 --- a/test/jdk/javax/swing/JFileChooser/4150029/bug4150029.java +++ b/test/jdk/javax/swing/JFileChooser/4150029/bug4150029.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,73 +21,117 @@ * questions. */ -/* - bug 4150029 8006087 - summary BackSpace keyboard button does not lead to parent directory - author Oleg Mokhovikov -*/ +import java.awt.BorderLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.io.File; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; import jdk.test.lib.Platform; -import javax.swing.*; -import java.io.File; -import java.io.IOException; +/* + * @test + * @bug 4150029 8006087 + * @key headful + * @summary BackSpace keyboard button does not lead to parent directory + * @library /test/lib + * @build jdk.test.lib.Platform + * @run main bug4150029 + */ + +public class bug4150029 { + private static JFrame frame; + private static JFileChooser fileChooser; + private static Robot robot; + private static File prevDir; + private static File crntDir; + private static volatile Point p; -public class bug4150029 extends JApplet { - private boolean res; + public static void main(String[] args) throws Exception { + robot = new Robot(); + robot.setAutoDelay(100); - public void init() { - if (Platform.isOSX()) { - try { - UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); - } catch (Exception e) { - throw new RuntimeException(e); + try { + if (Platform.isOSX()) { + try { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + } catch (Exception e) { + throw new RuntimeException(e); + } } - } - String tmpDir = System.getProperty("java.io.tmpdir"); + String tmpDir = System.getProperty("java.io.tmpdir"); - if (tmpDir.length() == 0) {//'java.io.tmpdir' isn't guaranteed to be defined - tmpDir = System.getProperty("user.home"); + //'java.io.tmpdir' isn't guaranteed to be defined + if (tmpDir.length() == 0) { + tmpDir = System.getProperty("user.home"); + } + System.out.println("Temp directory: " + tmpDir); + + File testDir = new File(tmpDir, "testDir"); + testDir.mkdir(); + testDir.deleteOnExit(); + System.out.println("Created directory: " + testDir); + + File subDir = new File(testDir, "subDir"); + subDir.mkdir(); + subDir.deleteOnExit(); + System.out.println("Created sub-directory: " + subDir); + + SwingUtilities.invokeAndWait(() -> { + createAndShowUI(); + fileChooser.setCurrentDirectory(subDir); + }); + + doTesting(); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); } + } - System.out.println("Temp directory: " + tmpDir); - - File testDir = new File(tmpDir, "testDir"); - - testDir.mkdir(); - - File subDir = new File(testDir, "subDir"); - - subDir.mkdir(); - - System.out.println("Created directory: " + testDir); - System.out.println("Created sub-directory: " + subDir); - - JFileChooser fileChooser = new JFileChooser(testDir); + private static void createAndShowUI() { + frame = new JFrame("Backspace Shortcut for Directory Navigation Test"); + frame.setLayout(new BorderLayout()); + fileChooser = new JFileChooser(); + fileChooser.setControlButtonsAreShown(false); + frame.add(fileChooser, BorderLayout.CENTER); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setVisible(true); + } - fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + private static void doTesting() throws Exception { + SwingUtilities.invokeAndWait(() -> { + p = frame.getLocationOnScreen(); + }); + robot.mouseMove(p.x + 200, p.y + 200); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); - try { - res = fileChooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION || - testDir.getCanonicalPath().equals(fileChooser.getSelectedFile().getCanonicalPath()); - } catch (IOException e) { - res = false; + robot.waitForIdle(); - e.printStackTrace(); - } + // check backspace key at subDir level + clickBackSpace(); - try { - subDir.delete(); - testDir.delete(); - } catch (SecurityException e) { - e.printStackTrace(); + if (prevDir.equals(crntDir)) { + throw new RuntimeException("BackSpace does not lead to parent directory"); } } - public void destroy() { - if (!res) { - throw new RuntimeException("BackSpace keyboard button does not lead to parent directory"); - } + private static void clickBackSpace() { + prevDir = fileChooser.getCurrentDirectory(); + robot.keyPress(KeyEvent.VK_BACK_SPACE); + robot.keyRelease(KeyEvent.VK_BACK_SPACE); + crntDir = fileChooser.getCurrentDirectory(); } } From 153fcd0a36ec22c6bb9c371a0342ac739b1b4255 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 12:44:28 +0000 Subject: [PATCH 043/846] 8328482: Convert and Open source few manual applet test to main based Backport-of: bea9acc55a7b0463a1b0b4dcb557f8ea17d8fe8c --- test/jdk/ProblemList.txt | 1 + .../java/awt/Frame/FrameMaximizedTest.java | 62 ++++ .../jdk/java/awt/Frame/FrameMinimizeTest.java | 59 ++++ .../awt/Frame/MegaIconTest/MegaIconTest.java | 273 ++++++++++++++++++ .../java/awt/Frame/MegaIconTest/dukeWave.gif | Bin 0 -> 1661 bytes .../java/awt/Frame/MegaIconTest/duke_404.gif | Bin 0 -> 5529 bytes .../jdk/java/awt/Frame/MegaIconTest/fight.gif | Bin 0 -> 3737 bytes .../jdk/java/awt/Frame/SizeMinimizedTest.java | 140 +++++++++ 8 files changed, 535 insertions(+) create mode 100644 test/jdk/java/awt/Frame/FrameMaximizedTest.java create mode 100644 test/jdk/java/awt/Frame/FrameMinimizeTest.java create mode 100644 test/jdk/java/awt/Frame/MegaIconTest/MegaIconTest.java create mode 100644 test/jdk/java/awt/Frame/MegaIconTest/dukeWave.gif create mode 100644 test/jdk/java/awt/Frame/MegaIconTest/duke_404.gif create mode 100644 test/jdk/java/awt/Frame/MegaIconTest/fight.gif create mode 100644 test/jdk/java/awt/Frame/SizeMinimizedTest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 2d1624a6c58c1..9013ba49dfdbe 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -823,6 +823,7 @@ java/awt/event/MouseEvent/SpuriousExitEnter/SpuriousExitEnter.java 8254841 macos java/awt/Focus/AppletInitialFocusTest/AppletInitialFocusTest1.java 8256289 windows-x64 java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java 8258103 linux-all java/awt/Focus/FrameMinimizeTest/FrameMinimizeTest.java 8016266 linux-x64 +java/awt/Frame/SizeMinimizedTest.java 8305915 linux-x64 ############################################################################ diff --git a/test/jdk/java/awt/Frame/FrameMaximizedTest.java b/test/jdk/java/awt/Frame/FrameMaximizedTest.java new file mode 100644 index 0000000000000..368132937fb4b --- /dev/null +++ b/test/jdk/java/awt/Frame/FrameMaximizedTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Frame; +import java.awt.Label; + +/* + * @test + * @bug 4106068 + * @summary Test to verify maximized window is not too big + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual FrameMaximizedTest + */ + +public class FrameMaximizedTest { + public static void main (String[] args) throws Exception { + String INSTRUCTIONS = """ + Maximize the frame window. Check that the right and bottom edges of the + window are not off the edge of the screen. If they are not, the test + is successful and the bug is fixed. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows(4) + .columns(40) + .testUI(new TestFrame()) + .build() + .awaitAndCheck(); + } +} + +class TestFrame extends Frame { + public TestFrame() { + setTitle("FrameMaximizedTest"); + setSize(500, 300); + add("North", new Label("Maximize me and check if my " + + "bottom and right edge are on screen.")); + } +} diff --git a/test/jdk/java/awt/Frame/FrameMinimizeTest.java b/test/jdk/java/awt/Frame/FrameMinimizeTest.java new file mode 100644 index 0000000000000..cd3459a78418d --- /dev/null +++ b/test/jdk/java/awt/Frame/FrameMinimizeTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Frame; + +/* + * @test + * @bug 4172782 + * @summary Test if non-resizable frame is minimizable + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual FrameMinimizeTest + */ + +public class FrameMinimizeTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + When the blank FrameMinimizeTest frame is shown, verify that + 1. It is not resizable; + 2. It is minimizable. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows(4) + .columns(35) + .testUI(FrameMinimizeTest::initialize) + .build() + .awaitAndCheck(); + } + + public static Frame initialize() { + Frame f = new Frame("FrameMinimizeTest"); + f.setSize(200, 200); + f.setResizable(false); + return f; + } +} diff --git a/test/jdk/java/awt/Frame/MegaIconTest/MegaIconTest.java b/test/jdk/java/awt/Frame/MegaIconTest/MegaIconTest.java new file mode 100644 index 0000000000000..3132d49df564a --- /dev/null +++ b/test/jdk/java/awt/Frame/MegaIconTest/MegaIconTest.java @@ -0,0 +1,273 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GridLayout; +import java.awt.Image; +import java.awt.Label; +import java.awt.MediaTracker; +import java.awt.Panel; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.ImageProducer; +import java.net.URL; + +/* + * @test + * @bug 4175560 + * @summary Test use of user-defined icons + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MegaIconTest + */ + +public class MegaIconTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Each of the buttons in the main window represents a test + of certain icon functionality - background transparency/opacity + of the icon, scaling etc. + Clicking on each button brings up a window displaying the graphic + that should appear in the corresponding icon. + Click on each button, minimize the resulting window, and check that + the icon is displayed as the test name indicates. + On Win32, icons should also be displayed correctly in the title bar. + If all the test pass, then this test passes, else fail. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows(10) + .columns(35) + .testUI(MegaIconTest::initialize) + .build() + .awaitAndCheck(); + } + + public static Frame initialize() { + //Create the iconTestFrames and add to IconTestButtons + IconTestButtons itb = new IconTestButtons(new IconTestFrame[]{ + new IconTestFrame("Opaque, Scaled Icon Test", + "duke_404.gif"), + + new IconTestFrame("Transparent Icon", + "dukeWave.gif"), + + new IconTestFrameBG("Transparent, Scaled Icon with bg", + "fight.gif", Color.red), + + new IconTestFrameDlg("Transparent icon w/ Dialog", + "dukeWave.gif") + }); + itb.pack(); + return itb; + } +} + +class IconTestButtons extends Frame { + public IconTestButtons(IconTestFrame[] iconTests) { + IconTestFrame tempTest; + Button newBtn; + Panel newPnl; + DoneLabel newLbl; + + setTitle("MegaIconTest"); + + setLayout(new GridLayout(iconTests.length, 1)); + + //For each icon test frame + //Get name, add button with name and action to + //display the window, and add label "done" after + + for (int i = 0; i < iconTests.length; i++) { + tempTest = iconTests[i]; + newBtn = new Button(tempTest.getTestName()); + newLbl = new DoneLabel(); + newBtn.addActionListener(new IconTestActionListener(tempTest, + newLbl)); + newPnl = new Panel(); + newPnl.add(newBtn); + newPnl.add(newLbl); + add(newPnl); + } + } + + protected class DoneLabel extends Label { + public DoneLabel() { + super("Done"); + setVisible(false); + } + } + + protected class IconTestActionListener implements ActionListener { + IconTestFrame f; + DoneLabel l; + + public IconTestActionListener(IconTestFrame frame, DoneLabel label) { + this.f = frame; + this.l = label; + } + + public void actionPerformed(ActionEvent e) { + f.pack(); + f.setVisible(true); + l.setVisible(true); + IconTestButtons.this.pack(); + } + } +} + +class IconTestFrame extends Frame { + private String testName; + int width, height; + Image iconImage; + MediaTracker tracker; + + public IconTestFrame(String testName, String iconFileName) { + super(testName); + this.testName = testName; + tracker = new MediaTracker(this); + + //Set icon image + URL url = MegaIconTest.class.getResource(iconFileName); + Toolkit tk = Toolkit.getDefaultToolkit(); + if (tk == null) { + System.out.println("Toolkit is null!"); + } + if (url == null) { + System.out.println("Can't load icon is null!"); + return; + } + try { + iconImage = tk.createImage((ImageProducer) url.getContent()); + } catch (java.io.IOException e) { + System.out.println("Unable to load icon image from url: " + url); + } + tracker.addImage(iconImage, 0); + try { + tracker.waitForAll(); + } catch (java.lang.InterruptedException e) { + System.err.println(e); + } + width = iconImage.getWidth(this); + height = iconImage.getHeight(this); + setIconImage(iconImage); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + setVisible(false); + } + }); + + setLayout(new BorderLayout()); + setBackground(Color.YELLOW); + + //Add the icon graphic and instructions to the Frame + add(new IconCanvas(), "Center"); + pack(); + } + + class IconCanvas extends Canvas { + public void paint(Graphics g) { + if (IconTestFrame.this.iconImage == null) { + throw new NullPointerException(); + } + g.drawImage(IconTestFrame.this.iconImage, 0, 0, this); + } + + public Dimension getPreferredSize() { + return new Dimension(IconTestFrame.this.width, + IconTestFrame.this.height); + } + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + public Dimension getMaximumSize() { + return getPreferredSize(); + } + } + + public String getTestName() { + return testName; + } +} + +class IconTestFrameBG extends IconTestFrame { + public IconTestFrameBG(String testName, String iconFileName, Color bg) { + super(testName, iconFileName); + setBackground(bg); + Panel p = new Panel(); + p.setLayout(new GridLayout(3, 1)); + p.add(new Label("The background of this window has been set.")); + p.add(new Label("Unless the default icon background is the same color,")); + p.add(new Label("the icon background should NOT be this color.")); + add(p, "North"); + pack(); + } +} + +class IconTestFrameDlg extends IconTestFrame implements ActionListener { + Dialog dlg; + Button dlgBtn; + + public IconTestFrameDlg(String testName, String iconFilename) { + super(testName, iconFilename); + Panel p = new Panel(); + p.setLayout(new GridLayout(4, 1)); + p.add(new Label("Click on the button below to display a child dialog.")); + p.add(new Label("On Win32, the Dialog's titlebar icon should match")); + p.add(new Label("the titlebar icon of this window.")); + p.add(new Label("Minimizing this Frame should yield only one icon.")); + add(p, "North"); + + dlg = new Dialog(this); + dlg.setSize(200, 200); + dlg.add(new Label("Dialog stuff.")); + dlg.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + setVisible(false); + } + }); + + dlgBtn = new Button("Display Dialog"); + dlgBtn.addActionListener(this); + add(dlgBtn, "South"); + } + + public void actionPerformed(ActionEvent e) { + dlg.setVisible(true); + } +} diff --git a/test/jdk/java/awt/Frame/MegaIconTest/dukeWave.gif b/test/jdk/java/awt/Frame/MegaIconTest/dukeWave.gif new file mode 100644 index 0000000000000000000000000000000000000000..52ada7979ef573053a282c44b707759e7e47d24c GIT binary patch literal 1661 zcmdUu{ZA8j9LK*!S`HtN0($b`I16ZbQ0v1&b#Cnm3SEs_(CPUETy?`Uj(F(As#Cau zO1BieD3LC!&YK$Pq|;MzIjm4l5xt-x)fvP$($N5{|>2DDURof?JeC&dE7>Cu3u1hNfuBLRv_QBus>!(ChR%T#I8khGHm! zA^-s>jRgZVyW<$2a_hv|diFvPI2EaVX+39|8m0P!Fv zq-8k{;z4rA4=q^WoFt(Uy~zaCKtWIwKoE|HX=Nwx#&B&g1ef|DfSq&FjE$lhlZ6yS z3GNt_5tbxb5JY}3jVMY`p3}**tR1F+Mr}40s{PL~lntdq>rg)|!DJ#~8?X~tjwJd; zLDK68zZ`J$0)&prZ$N|wU%A!n>l#RAA z6hoV6(JqLr+fFccl(1uj4bj;VJqd6Y(P03w0WAx(7JxAW6RjSgB*1I{#{ohCj0HFi zFzvuIOh0hLuW*jg0AXMy0C>G#c>j+M{w7iZKqtr=$UN{*0OUQWi%!aKab2uNVl!4; zZaLIZi)u{He9z&|I&8%FdWYxd_C(+A=od@tyM}9{zI}~!H5~D!WbKJR5;N^#bsgDK zlp4!;y%{sMuZ=ryEj@TpxmR(#)vH-hx+s07k&HzPlCqT3>vN8-H7kZ~^i>qcn6G`N zzP4p$w>m9PyXsQzimuJixxMplKB`=LHeHifHOar`Zp&oFXQ}U0YxBR!jyMqU_S024 zzfATha!RdP)EjSm=Kf`B@87*AqDJAfCp=S=uRE{kD!XpapqETqfj>`KpR~_mm^5S4 z7uNaBR}+hVEp6SHm+8;yjo3T-bw{NlMK$7Wob|z@1ukNY=RNx1dd+UWsAb8F+D%Uv zcULWMIB&*kZ;hEqn_H{m>%#8k=f0~zj63WfuO`aT!YgSUqGn#DdQ0D&Mj@x z)1|Rd>Aj0Hn|of~&F*j*s-nlEukzCsX5nURT}9)L{|M#S#~r_LrUvNo(7o-0N62KIKO6eKJ)j~ZR^u7CK(E^Ka8 zXO_;;@@W5+s^;Xjd;1j8zNZ~!#*br1x-R9n~5S&cj8lyfNd0<`jw&eExL*?=LFp%!M!3MWVl3mAc^vZu>_19G-bb zSMu%tVVdM)N?j7yA5mVD%BeKy>7jF0j!I5foN1cl+IEI8p|Qr}=F{6<_Y??jRQOih z>rsDFWOx#{?DFF|KRW83I^xE0iC)#rySOHSLW;dh)Rl`2t=Wyc%JN*vJwxPEiJjnS SYv`|cL2uOLZ9#5C@(K>XYx)-NeKppymWcs``g#**;)0yd+MuK)!p5{PMlCzR{ly){}mMUpS3jw zj<7@$L$!=D39JB&)-MX>2O6DdA6vi5yNF;eC0d-(GkrBNH(GV!H(q%I(VDRezO1Pk zvMr(RxcvFV-E*6A#x+U3+PY#2L9JHzrk`qI?@H6r?z(ub%-DR7IeYQdRC-#lj7*te z+XndA^hnN~bK#a3*`(}XrELkm-GBYBd7m$DSjh>5+R%u_?rwh@tJX%dZ*O!D9Jo=@D5?H5F6e(Ab2* z)t)>hZ$9190>Jd(a6OPL#vSXyXuv9IJ!nGf;O|$jozZR}ftTvhU_?vtJg3Ln1+T%YV{8ZFxSjM z?*qtir%~zny4-q(MzEb>DV}C;n>yS6@m5*j16|__c^^2XTE^i$%SXIR$Lf7T>S(Ze zj+acIOz#jFd2@6bREXCmTDSrRBgNrjxLeq` zodjEYZ`l7RQejg|kP|RYQa{T&%N+L9kPIa%b56Gk8e)!uEZfXY+j}|S5aQ~=4>-B8 zrLZr7vJ8@hULpw~S#NhrA$KXlQrOBEBj-nDr}g5$(LRh+7OXe7;v5I$q6CcCqzm^V zuaJxkdYtg&VeSp}quu|F9s~ER_@0WB+9U=5bB=HXH&I>=QwH&b zt3$YRezbVIW*RHIXUI=4v~?&@H{Ix|AN5j-%#T`rNvnh$o8K#<65LdYh`q13{0S0@ z=x@yF9yL04ZHl+_YijKF4!KQY-fnJmz zT3@Q@f3OKw9~BiiUINY}JsZ{8{ci5vn$Qc6Zs}&$t{YvG=_U;Tb#IzM2tECj2OTHr z{Is~e{tTFG5RmTyz9cci&bPkbSa!ob7x(=7j$d-+$PYh@-r*DA&NMXw{z_0%fyb=e z);r`RNF0f*OZ)q7rA5gQk`zs?t}-39$TEuRdz5K`PL%SQdi+cw%JreeCq9|aU{x{b z-uG;siSM%O;`)xk&Q_4hA}2QQOwY8}8TM{@%sbP%%OIr}=HpujYwhxXVhC0MOhUB1 z1E5HGc}Kr4Tep`erpw%-w|Fq6aDTkkC^bEycF%Ph4{DYWSPi%14*d$o zQ*}eyj}(LYYi6i4UByq0b0ks?NK+jLm3R3?&`}q*%9B&MNUj~f6KatsZjrRufQ%Ekp|%O+hX`vAp-j4)gAI~s_#g= zlN}E>kCel7ifjj5xNv{EnlPtwC{M`v}?z26y3(J8h8M3UlWR^#@L5kT9`}_aPBv*a68=oS_cn5zAE}T^X#uk7(>T&;cs@`X7BvTNUojZ$Udf470lMx>$qj6TpfS&rQVDYW5ZQ}f%1 zZufHn)cgIXFXQdJbG}l%$a@utH8)l3Y%m|UUgx7M8Ht2s?3#D>SX@m-x|*^Epd&bi^x;RlVcd-(DhP+oPiz2k@gYI>5BinIDCD!Kbxb6>FnT6}QwgvVZR76z@!c`5p&|2d+YC zA+v(s^4W9VS>@Z#*irW_1;b){VWRLmPRuqIa^Ul25nMIu6aBtVXGU7gMx@<4&~e%N zc5&lzFF2s5fPmhMWw_-A@3iBiAXp3oejG}cW*`ojXrx}IjN#RAh= zP%!JbjtW_P?8A3wXN=mib8}N`eWAaNHm^U*DwCRP!Gc@!{Ie&_eq;tNg&)KUfHWZJ zxe+=W3VJF7(-gXYGSRR4cJ=ZR>5$bD8GLG^w(ztKTuI1(rm}_sj-5=5%~CkZNyKdk zy>Egcs5l?(_I@B+H`Vg=Wz$BSCM^c+HV=!1t$l2b5lnZYwP#6gBirz1CX~&^{1W3bPp{^; zZg#==y<-MLr#I@JK?X=sVSrgW8@+Z5+K>x;6of2FB0lxy)Whj{7fR1MMY|`^L|@A< zL{wbLuNX)sy47aik^}qeE3Bu&XZRY5h^<@+!F2(<5>jdV&!)G^4TK(B%fgK#8Sx)p zRosiP1yp$%EkHH~a6WqANrc)ECJo4HHLuKojr0(AT;}+nUH8(|&V-6bjbeyx*e#T5 zdwAfCltm?JM%m{clN$V>IlQ#ZXnK?L3}~YSaj*$KH)7 z5oKvMEx?k?>OigNSZw7%N}Wf4?wPau#SM|i&S?HrYW~N7-?&&8^Q7+bOs(Jw7R`eN z6vR&*)ijBZGFGY^s-8qu{R2A~8GFmAy1@prRKl%R;A~QYK{&#i)MU*_|Mf}MQPc2k zN0fPnQ^iQsb$fnGPQ@O71FR5n+6Uv(gUIK&v=+E<9imusnw^a??hIG`wy3L=#)IGM z2WDh{L4dXhL(z&K*GBx4gWV7w*QtG6l7-+8#ds?bzkhC0P@=y;6*ayF-<>eFBo}Q~ zY62XV)9CPBNH!mjo3&rVl_J+EqpC+-o#T;TMSy!oxzA;yxzyQKY0e|Ltb9IcFN8CK z;~J-6vnfu`jFHcbUHw%}_Q5Chd3dKg0vuqXt1@V0`1eXgbW&=eOCN?& zb=-@Z6L0++dv_VDKZkGXAVnFy3XGEW7ki^6VjzW$$^salw5?DK&H+5o{@WEPQK+dv>i5(j$!X!XzjY@rAAjU_2$Gtn7k`SiYk_YkwD>x zIyyz}JM33q162LG301FHbT5zGSZb zo$HiqK>oxX1M;LO#!A&!hFCY=d!l+sk-@T&gn+X!9WL%$p^ASia7%Cp*XJ^jg#Q znn@|biYctfwta9#<3M6cWTl}lAnR2C)H~FmzFXxgAO%7PNx{TQH%mBOtaJP9GXi=q zz9g~$-cKX}CVGkhceuIeYi{7MZE_$6zXF`p0|XYv9G)=}>YY^rqfK1hBo16k;00-5MRWjpf;fG+r>?NAwv^M;Gx9GhoNzpdJuV^T?+t~HsQ-8Y_&cvZi{~`D)gT0UtDouh{5ndipo&jtkf%#H&0S|1=qmF#FUgIPw6XbD(_op*PP1o1H z%V)p;@kgH!X1^b!b`znw560%ud*{$32y%!~G)*TJYxB(N znZV4EJC*t7EuZeldF%7uVwC%b-mwK~*%O7*iHpO9Aq^yLlABtDdNmq|0R!V~@&?ihAZvdJdw1YQKATa(nsUQc`9{b$--d_HAzOBCkG`p1T8bsS%6+71j_ATNU1(tg$`_jZOSY{9xYXl zTSLj#aT?e{sGw97Rh!M^6w3xUGkG}&u7O}!6)7o zr^}IkRwixv#2@4r_n;Y&W|A4=U+-gs4Ye7SJ=|W;Dqig$e^TW!fN2*~b@$ldT+A}MGZGsZmfQ_|D~8#(H~=> zf$llYH2-$NDleu?$9TCY7X9@sQkT8>H2Hz2Q|USP!w-ih|8*+uh~6HnLPyt<8 literal 0 HcmV?d00001 diff --git a/test/jdk/java/awt/Frame/MegaIconTest/fight.gif b/test/jdk/java/awt/Frame/MegaIconTest/fight.gif new file mode 100644 index 0000000000000000000000000000000000000000..6be1b4972d0de57286ce645cee8f01633e9686a6 GIT binary patch literal 3737 zcmc)M`(G0I{s-^@5eJoR04c;9;~ledyd-p6K{O<75k-wUrD3i{c`zy~Y6C?y#lplc zE@xBH%^QW5)o!N(Q;xRfu}stI>w4*8m+fj>dpn--{1e~jygr|Ke?IS-$NVz$c+BdA zcosV=AIJti%>uKiPoF;hZ~FA?&784kZ-$>e`}77~JwuJ5$Fs3H!(;tpWA?FORA>LN z@oN8Y|C~m9ztL{*@3*52SM55pU1Pp#@4t$Y89V2gJI%wLjcEEiMH(}@Mm6@EjcDv< zfwIxuILByjG+u2qpy_O6%Nm&yW2147;i}QlX*3v&x=y3cY()2AfsuxWYlPSaW1|73 zGaGb`294REX*4Jd23TM~TM(i{Z$g_WO`}d@)M<1&rBO#ibZ84i!_>@CYLrHe(x6f5 zG)lBqXcPtwSEPYp4MfvGkOo9FAXAA_7?cW~QlU_CMM@f|gg_;TDA5)`Q=nuTg-ods zi4<&s0%0qdOa+W6Xovzr11dnKOren}WOJk%nN%s0Dr6Fo43WwZrVOOX08lEGNl_Ao zR3ejtutXx0phW0ZQVEwU0caw0C6bCz0;xzK5eWn$5EcQjKp;U&0g5XUa0LPc5kNEn zK;sHTTrL^`7sVEE*<3Dya6y<0(%5VPo6TjT5H1^Gv(X)ZhMo}w4T3P)2opgd7=dUA z1R(&#M7T_Z&151>6pS!oCKG^QCJg^?z%&@9(O{4U0}u^H(2_O>qCqe^(EtcSOB4t} zXbpf6fDRhE0#N`Oz-qMu{~zGra2Nm>0Yc{NS=`-&wP*-Tr8Ud+W_Z^DnPAvf!3-D>q?DY>i+)pVYGU==rTF z+moJ0)LnArMx1dhj>#R^(`=|rD8`%DFPwcVj7tp@OMNx-%;#%u;C5d5&9ur_R_7=; z$Dfuq_tjhmjwR#gTW)ESTt;zzV};JymeTl=)VdhVOL6YRzVhrr8izO_<~U{%ySrl; zuO@8y43#i8)a0ts#h(=Jnb1Yv{amYrwbV6B7u{n`0S=${)MNXzrJD}V+gtbeXyQJ- zjWCpbeswP6pC^(7gHrXJ>J7X50=`K;Oxg&IGN!VRul6M*JCJyK+p&#y<}+jBHA2uo zHnlX96FkII-+rgU3xrxVF>t!x_qm}q!4KR<)J@y-|eD#Y(CxVD_9ipD1{BJuJMp&b8nG6 z_;L zVQ=3rcXAY}ihZMk$74LtW`9`Y;u3aZlcD7v)S#dEh4!us8wG@y!51+E)jI30USzvU zUKD~wFdn%mv)dZjWE& zO~+g;NhDLYEN!9}!{0s*{_`!JdW6z3lFiW96B&vdiHVIp&!Mvq+~%LU_wCFx0V5u| z731AdRFplrCXTwf9Qn2S#q&4W`}l!$zDH)vbq~k}J&tvC8=u7SFXRW@d~qs$71fkF z@Kw4cM(cyqln8OLg+7OXu2*5^yx+J*^mRWAmSz?2PU;bRE!V2?CNSY~CN4Z#?aY@u zBn7u&dwU(BSqVio@6S3-<8Kw6ya^1TXL{sQ`Uq*s8b@p|;dB%JS6mU{M5;afWvzg; zvr5hNl$M#>t*$dYOAZEL=BfH{VE!=uObt&o(iC&ww@5c%#lXQMxAR*vTOHnU9gpw0 znZgRFNxK?AIjPd-H3&=N`7mMo%mVr~240e>Ivh!l!P_%0CVp;r^d2F3JBo^(1UQ_H z#VHqcYcjSWlytf6`}~34DbGN*%T8{{TI*$|A^wZNrY>?!vHD98OE}gW54#NnzE$M_ zoRK3D4^&I(dl`PK;IjG)=_C#HD8qZ&alQ&6T-x?ZT)?D<*&z+%0^m1vIezI`c-E4g z>PKb-tFZI|?5gHTTwSUM5cYn#I(HG4@o+OQMz~VUGdZu`Y6~G#>M&krh_vwN3GSeZ zPKyMIw5Cb7t@VkyO^iiNoPT47>NCr@)RPusId6hw7dsrNvIMSa-Cd;P-*ZU5N3lr4 zLbJc^-PhL%2v?b_R6@T0Cj<2^2mabj+U|6)c`Rhes_(j6Qky-mi%ug2Ws-HuW zA7YOP14wb(4^%8$_zxcSM!;gztKRCv!S{EGK9qm_uA<5Gz5Up|xO?BskF&kPmXn8l zYYK<%X(z;f#;L#hX4>NV@9$-hPg*tmBie6T+U`pvM7JlP$vO3r3KznvaM?NHv`8?o zj^E=!$U1H{Wb|RY=Qd5(b>#(;ok#xcc1dA|nyfF6fC~mCmsds;AEi zLI5#b_(c$-#l~Kr33|3xR9$xs41M8p^u1)SUqxrH_qFoMpb=np|JsQse;xgBYT*p$ zpDg6{$q3)UAJO+_vHsQ;jpfe90@s-H>j_|ZsxHOYwLst&9=?NDj(stX&(Fm#&;oVI z^%m=UJ#P&eh;h&$D7My{K3N^0XSXd9Pvu6@um7_siE5%oNM2AwyZQq-G?@a0e3 zyszIRv`#BHzsg;cHq`HpQ{lp<%PWyYhXr2XZQMTV%c~mrzz~Stc#uq3(7#tLy!@f9 z*j7qnysubNW()2==`0P-TItE!e5p0AwF;XFED>Ggx2POr2i+HM$fn=FuKn_RiZy`I_5|S&lZ)?L$cPwD0_?fvxzoD(utb zJyj|0T>)F)mPu)FB<`}6o>ZN1BuKq{1<6qsdM~Z=!lk_V94+;MrF7*580=`{7FONC z5zehiZ|iWL?_5R5*?DEE_Rn;hFX!L%&j{B4`oO!*>Cwe|I(>Vs`|{-uMTk)DTFt=F zY-4NEv(!|RMVt4lN`)IxJ9|IVTyKz9r0+iyU&W1&;@LEp9T>5Pv_Bt#J4(4KMs$b& zs~Fz`N9y>azg_D-Mad{AN_=FB6lG!nw@eon`fr6DxZ%~1S-ve*UCX`t)byM}nCHK9 zC3w?5=(S8A`EVtrM9A~Mr5)p6#^6&5Zp=bD#h2aw_zK3u*hs!t$zs(=R?alevZ8Ha!?^1zRl(pFYD02M{^NW!o|MiqN@p z9Q>}%aTUdNsLqM}-ix6kS=x7oJ`v?a(THKbgP)+~WEZDo%y}VEo0%&NQ)7x8|89w> zO~(+&F=n1acO>lE?l&X^SB9sZ`Xma4A*!6xw+qUd??V+j+Qwb4)PY;voIR;uc^be` zYtDycu{jxdTfmy^3hXNsyNV(Af#4;d1tofKu-*j>V(cq()C!3m_0C^#l0OzCl>p+d z9?b$%L?{xw^)6tV)jL<~!BRO`t#`g+aS{w-J;HrBddy<2t5S$5WBF0_q!C}YqOKg0 zJha1~-xVKR#t3N^8=Y5=Dx?Pz-MFTc@53l#U+znv9F8tE!GFEi)a-dwwiF;du8)ukEHI U)zYBCAN*CnNe(bc7!0udzewrFYybcN literal 0 HcmV?d00001 diff --git a/test/jdk/java/awt/Frame/SizeMinimizedTest.java b/test/jdk/java/awt/Frame/SizeMinimizedTest.java new file mode 100644 index 0000000000000..2520cf42892f7 --- /dev/null +++ b/test/jdk/java/awt/Frame/SizeMinimizedTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +/* + * @test + * @key headful + * @bug 4065534 + * @summary Frame.setSize() doesn't change size if window is in an iconified state + * @run main SizeMinimizedTest + */ + +public class SizeMinimizedTest { + private static Frame frame; + private static final int INITIAL_SIZE = 100; + private static final int INITIAL_X = 150; + private static final int INITIAL_Y = 50; + private static final int RESET_SIZE = 200; + private static final int OFFSET = 10; + private static int iterationCnt = 0; + private static Dimension expectedSize; + private static Dimension frameSize; + private static Point expectedLoc; + private static Point frameLoc; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + try { + EventQueue.invokeAndWait(() -> { + createUI(); + }); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + frame.setState(Frame.ICONIFIED); + }); + robot.waitForIdle(); + robot.delay(100); + + EventQueue.invokeAndWait(() -> { + frame.setSize(RESET_SIZE, RESET_SIZE); + }); + robot.waitForIdle(); + robot.delay(100); + + for (int i = 0; i < 5; i++) { + EventQueue.invokeAndWait(() -> { + Point pt = frame.getLocation(); + frame.setLocation(pt.x + OFFSET, pt.y); + }); + iterationCnt++; + robot.waitForIdle(); + robot.delay(100); + } + EventQueue.invokeAndWait(() -> { + frame.setState(Frame.NORMAL); + }); + robot.waitForIdle(); + robot.delay(100); + + System.out.println("Test Passed!"); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public static void createUI() { + frame = new Frame("Frame size test"); + frame.setSize(INITIAL_SIZE, INITIAL_SIZE); + frame.setLocation(INITIAL_X, INITIAL_Y); + + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowOpened(WindowEvent e) { + System.out.println("Initial Frame Size: " + frame.getSize()); + System.out.println("Initial Frame Location: " + + frame.getLocationOnScreen()); + } + }); + + frame.addWindowStateListener(new WindowAdapter() { + @Override + public void windowStateChanged(WindowEvent e) { + if (e.getNewState() == Frame.NORMAL) { + System.out.println("Frame Size: " + frame.getSize()); + System.out.println("Frame Location: " + + frame.getLocationOnScreen()); + expectedSize = new Dimension(RESET_SIZE, RESET_SIZE); + frameSize = frame.getSize(); + + if (!expectedSize.equals(frameSize)) { + throw new RuntimeException("Test Failed due to size mismatch."); + } + + expectedLoc = new Point(INITIAL_X + OFFSET * iterationCnt, + INITIAL_Y); + frameLoc = frame.getLocationOnScreen(); + + if (!expectedLoc.equals(frameLoc)) { + throw new RuntimeException("Test Failed due to " + + "location mismatch."); + } + } + } + }); + frame.setVisible(true); + } +} From 5556f74265d2e27519e334cf4e959182acba9c43 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 12:45:26 +0000 Subject: [PATCH 044/846] 8339727: Open source several AWT focus tests - series 1 Backport-of: 358ff196336407484b1b892f08936e9378701959 --- test/jdk/ProblemList.txt | 3 + .../Focus/ActivateOnProperAppContextTest.java | 245 ++++++++++++++++++ test/jdk/java/awt/Focus/KillFocusTest.java | 80 ++++++ .../awt/Focus/TestDisabledAutoTransfer.java | 156 +++++++++++ .../Focus/TestDisabledAutoTransferSwing.java | 165 ++++++++++++ 5 files changed, 649 insertions(+) create mode 100644 test/jdk/java/awt/Focus/ActivateOnProperAppContextTest.java create mode 100644 test/jdk/java/awt/Focus/KillFocusTest.java create mode 100644 test/jdk/java/awt/Focus/TestDisabledAutoTransfer.java create mode 100644 test/jdk/java/awt/Focus/TestDisabledAutoTransferSwing.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 9013ba49dfdbe..63ccf6548438c 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -134,6 +134,9 @@ java/awt/Focus/NoAutotransferToDisabledCompTest/NoAutotransferToDisabledCompTest java/awt/Focus/TypeAhead/TestFocusFreeze.java 8198622,6447537 macosx-all,windows-all,linux-all java/awt/Focus/ToFrontFocusTest/ToFrontFocus.java 7156130 linux-all java/awt/Focus/WrongKeyTypedConsumedTest/WrongKeyTypedConsumedTest.java 8169096 macosx-all +java/awt/Focus/TestDisabledAutoTransfer.java 8159871 macosx-all,windows-all +java/awt/Focus/TestDisabledAutoTransferSwing.java 6962362 windows-all +java/awt/Focus/ActivateOnProperAppContextTest.java 8136516 macosx-all java/awt/event/KeyEvent/CorrectTime/CorrectTime.java 6626492 generic-all java/awt/EventQueue/6980209/bug6980209.java 8198615 macosx-all java/awt/grab/EmbeddedFrameTest1/EmbeddedFrameTest1.java 7080150 macosx-all diff --git a/test/jdk/java/awt/Focus/ActivateOnProperAppContextTest.java b/test/jdk/java/awt/Focus/ActivateOnProperAppContextTest.java new file mode 100644 index 0000000000000..ab08398332147 --- /dev/null +++ b/test/jdk/java/awt/Focus/ActivateOnProperAppContextTest.java @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6385277 +* @key headful +* @summary Tests that activation happens on correct AppContext. +* @modules java.desktop/sun.awt +* @run main ActivateOnProperAppContextTest +*/ + +import sun.awt.AppContext; +import sun.awt.SunToolkit; + +import java.awt.Button; +import java.awt.Component; +import java.awt.Container; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.InputEvent; +import java.util.concurrent.atomic.AtomicBoolean; + +public class ActivateOnProperAppContextTest { + static Robot robot; + SunToolkit toolkit; + + ThreadGroup threadGroup = new ThreadGroup("Test_Thread_Group"); + AppContext appContext; + Frame frame; + volatile boolean passed = true; + AtomicBoolean cond = new AtomicBoolean(false); + + public static void main(String[] args) throws Exception { + ActivateOnProperAppContextTest app = new ActivateOnProperAppContextTest(); + robot = new Robot(); + app.start(); + } + + public void start() { + toolkit = (SunToolkit)Toolkit.getDefaultToolkit(); + + Runnable runnable = new Runnable() { + public void run() { + test(); + + synchronized (cond) { + cond.set(true); + cond.notifyAll(); + } + } + }; + + Thread thread = new Thread(threadGroup, runnable, "Test Thread"); + + synchronized (cond) { + + thread.start(); + + while (!cond.get()) { + try { + cond.wait(); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + } + + if (passed) { + System.out.println("Test passed."); + } else { + throw new TestFailedException("Test failed!"); + } + } + + void test() { + appContext = SunToolkit.createNewAppContext(); + System.out.println("Created new AppContext: " + appContext); + + frame = new Frame("ActivateOnProperAppContextTest Frame") { + public boolean isActive() { + verifyAppContext("Frame.isActive()"); + return super.isActive(); + } + public boolean isFocused() { + verifyAppContext("Frame.isFocused()"); + return super.isFocused(); + } + public boolean isFocusable() { + verifyAppContext("Frame.isFocusable()"); + return super.isFocusable(); + } + public Window getOwner() { + verifyAppContext("Frame.getOwner()"); + return super.getOwner(); + } + public boolean isEnabled() { + verifyAppContext("Frame.isEnabled()"); + return super.isEnabled(); + } + public boolean isVisible() { + verifyAppContext("Frame.isVisible()"); + return super.isVisible(); + } + public Container getParent() { + verifyAppContext("Frame.getParent()"); + return super.getParent(); + } + public Cursor getCursor() { + verifyAppContext("Frame.getCursor()"); + return super.getCursor(); + } + public Point getLocation() { + verifyAppContext("Frame.getLocation()"); + return super.getLocation(); + } + public Point getLocationOnScreen() { + verifyAppContext("Frame.getLocationOnScreen()"); + return super.getLocationOnScreen(); + } + }; + Window window = new Window(frame) { + public boolean isFocused() { + verifyAppContext("Window.isFocused()"); + return super.isFocused(); + } + public boolean isFocusable() { + verifyAppContext("Window.isFocusable()"); + return super.isFocusable(); + } + public Window getOwner() { + verifyAppContext("Window.getOwner()"); + return super.getOwner(); + } + public boolean isEnabled() { + verifyAppContext("Window.isEnabled()"); + return super.isEnabled(); + } + public boolean isVisible() { + verifyAppContext("Window.isVisible()"); + return super.isVisible(); + } + public Container getParent() { + verifyAppContext("Window.getParent()"); + return super.getParent(); + } + public Cursor getCursor() { + verifyAppContext("Window.getCursor()"); + return super.getCursor(); + } + public Point getLocation() { + verifyAppContext("Window.getLocation()"); + return super.getLocation(); + } + public Point getLocationOnScreen() { + verifyAppContext("Window.getLocationOnScreen()"); + return super.getLocationOnScreen(); + } + }; + Button button = new Button("button"); + Label label = new Label("label"); + + window.setLayout(new FlowLayout()); + window.add(button); + window.add(label); + window.setLocation(800, 0); + window.pack(); + window.setVisible(true); + + frame.setBounds(800, 100, 100, 50); + frame.setVisible(true); + + toolkit.realSync(); + + /* + * When the label is clicked in the window some of + * the owner's public method get called. + */ + clickOn(label); + } + + void verifyAppContext(String methodName) { + AppContext ac = AppContext.getAppContext(); + println(methodName + " called on AppContext: " + ac); + + if (ac != appContext) { + passed = false; + System.err.println("Test failed: " + methodName + " is called on wrong AppContext!"); + Thread.dumpStack(); + } + } + + void clickOn(Component c) { + Point p = c.getLocationOnScreen(); + Dimension d = c.getSize(); + + robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + (int)(d.getHeight()/2)); + + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(20); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + toolkit.realSync(); + } + + void println(final String msg) { + SunToolkit.executeOnEventHandlerThread(frame, new Runnable() { + public void run() { + System.out.println(msg); + } + }); + } +} + +class TestFailedException extends RuntimeException { + TestFailedException(String msg) { + super(msg); + } +} diff --git a/test/jdk/java/awt/Focus/KillFocusTest.java b/test/jdk/java/awt/Focus/KillFocusTest.java new file mode 100644 index 0000000000000..f61c18971f6f9 --- /dev/null +++ b/test/jdk/java/awt/Focus/KillFocusTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4402942 + * @summary After deactivation and activation of frame, focus should be restored correctlty + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual KillFocusTest +*/ + +import java.awt.Frame; +import java.awt.TextField; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; + +public class KillFocusTest { + + private static final String INSTRUCTIONS = """ + After starting the test you should see \"Test Frame\" + with the \"Click me\" text field. + Click on this text field and try to type something in it. + Make sure that the field receives focus and you can enter text in it. + Click on any non-java window. + Click on \"Click me\" text field to return focus to it + If the caret is in the text field and you are able to type + in it then press pass else press fail."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("KillFocusTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(KillFocusTest::createTestUI) + .logArea() + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + + Frame frame = new Frame("KillFocusTest Frame"); + TextField textField = new TextField("Click me", 10); + textField.addFocusListener(new FocusListener() { + public void focusGained(FocusEvent fe) { + PassFailJFrame.log("Focus gained"); + } + public void focusLost(FocusEvent fe) { + PassFailJFrame.log("Focus lost"); + } + }); + frame.add(textField); + frame.setSize(200, 100); + return frame; + } + + +} + diff --git a/test/jdk/java/awt/Focus/TestDisabledAutoTransfer.java b/test/jdk/java/awt/Focus/TestDisabledAutoTransfer.java new file mode 100644 index 0000000000000..d7928b7db1c70 --- /dev/null +++ b/test/jdk/java/awt/Focus/TestDisabledAutoTransfer.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6180261 + * @summary Test that auto-transfer doesn't happen when there are pending focus requests + * @key headful + * @run main TestDisabledAutoTransfer +*/ + +import java.awt.Button; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.InputEvent; +import java.util.concurrent.atomic.AtomicBoolean; + +public class TestDisabledAutoTransfer { + static Frame frame; + static Robot robot; + Button b1; + Button desired; + AtomicBoolean focused = new AtomicBoolean(); + ActionListener mover; + volatile Point loc; + volatile Dimension dim; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + try { + TestDisabledAutoTransfer test = new TestDisabledAutoTransfer(); + test.createTestUI(); + robot.waitForIdle(); + robot.delay(1000); + test.doTest(); + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + + public void createTestUI() { + frame = new Frame("TestDisabledAutoTransfer"); + frame.setLayout(new FlowLayout()); + desired = new Button("Desired"); + FocusAdapter watcher = new FocusAdapter() { + public void focusGained(FocusEvent e) { + synchronized(focused) { + focused.set(true); + } + } + }; + b1 = new Button("Press to disable"); + mover = new ActionListener() { + public void actionPerformed(ActionEvent e) { + desired.requestFocus(); + ((Component)e.getSource()).setEnabled(false); + } + }; + b1.addFocusListener(watcher); + desired.addFocusListener(watcher); + frame.add(b1); + Button misc = new Button("Next"); + frame.add(misc); + misc.addFocusListener(watcher); + frame.add(desired); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + + } + + public void doTest() { + + loc = b1.getLocationOnScreen(); + dim = b1.getSize(); + robot.mouseMove(loc.x + dim.width / 2, loc.y + dim.height / 2); + robot.waitForIdle(); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + b1.requestFocus(); + + try { + synchronized(focused) { + if (!focused.get()) { + focused.wait(1000); + } + } + } catch (InterruptedException ie) { + throw new RuntimeException("Test was interrupted"); + } + + if (!focused.get()) { + throw new RuntimeException("b1 didn't get focus"); + } + focused.set(false); + + b1.addActionListener(mover); + robot.mouseMove(loc.x + dim.width / 2, loc.y + dim.height / 2); + robot.waitForIdle(); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + + try { + synchronized(focused) { + if (!focused.get()) { + focused.wait(1000); + } + } + } catch (InterruptedException ie) { + throw new RuntimeException("Test was interrupted"); + } + + if (!focused.get()) { + throw new RuntimeException("none got focus"); + } + + if (!desired.isFocusOwner()) { + throw new RuntimeException("desired didn't get focus"); + } + } + +} + diff --git a/test/jdk/java/awt/Focus/TestDisabledAutoTransferSwing.java b/test/jdk/java/awt/Focus/TestDisabledAutoTransferSwing.java new file mode 100644 index 0000000000000..0793316a989cd --- /dev/null +++ b/test/jdk/java/awt/Focus/TestDisabledAutoTransferSwing.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6180261 + * @summary Test that auto-transfer doesn't happen when there are pending focus requests + * @key headful + * @run main TestDisabledAutoTransferSwing +*/ + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Point; +import java.awt.Robot; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.util.concurrent.atomic.AtomicBoolean; + +public class TestDisabledAutoTransferSwing { + static JFrame frame; + static Robot robot; + JButton b1; + JButton desired; + AtomicBoolean focused = new AtomicBoolean(); + ActionListener mover; + volatile Point loc; + volatile Dimension dim; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + try { + TestDisabledAutoTransferSwing test = new TestDisabledAutoTransferSwing(); + SwingUtilities.invokeAndWait(() -> { + test.createTestUI(); + }); + robot.waitForIdle(); + robot.delay(1000); + test.doTest(); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public void createTestUI() { + frame = new JFrame("TestDisabledAutoTransferSwing"); + frame.setLayout (new FlowLayout ()); + desired = new JButton("Desired"); + FocusAdapter watcher = new FocusAdapter() { + public void focusGained(FocusEvent e) { + synchronized(focused) { + focused.set(true); + } + } + }; + b1 = new JButton("Press to disable"); + mover = new ActionListener() { + public void actionPerformed(ActionEvent e) { + desired.requestFocus(); + ((Component)e.getSource()).setEnabled(false); + } + }; + b1.addFocusListener(watcher); + desired.addFocusListener(watcher); + frame.add(b1); + JButton misc = new JButton("Next"); + frame.add(misc); + misc.addFocusListener(watcher); + frame.add(desired); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + + } + + public void doTest() throws Exception { + + SwingUtilities.invokeAndWait(() -> { + loc = b1.getLocationOnScreen(); + dim = b1.getSize(); + }); + robot.mouseMove(loc.x + dim.width / 2, loc.y + dim.height / 2); + robot.waitForIdle(); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + SwingUtilities.invokeAndWait(() -> { + b1.requestFocus(); + }); + + try { + synchronized(focused) { + if (!focused.get()) { + focused.wait(2000); + } + } + } catch (InterruptedException ie) { + throw new RuntimeException("Test was interrupted"); + } + + if (!focused.get()) { + throw new RuntimeException("b1 didn't get focus"); + } + focused.set(false); + + SwingUtilities.invokeAndWait(() -> { + b1.addActionListener(mover); + }); + robot.mouseMove(loc.x + dim.width / 2, loc.y + dim.height / 2); + robot.waitForIdle(); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + + try { + synchronized(focused) { + if (!focused.get()) { + focused.wait(2000); + } + } + } catch (InterruptedException ie) { + throw new RuntimeException("Test was interrupted"); + } + + if (!focused.get()) { + throw new RuntimeException("none got focus"); + } + + if (!desired.isFocusOwner()) { + throw new RuntimeException("desired didn't get focus"); + } + } + +} From 8ff0f3ce2696c6c7485c6f9a14814ad3fe6ba41b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 12:46:35 +0000 Subject: [PATCH 045/846] 8339842: Open source several AWT focus tests - series 2 Backport-of: 4b7906375b4bd11a480665110561180825c2dd9c --- .../awt/Focus/FocusChangeOnResizeTest.java | 122 ++++++++ .../awt/Focus/LightweightFocusLostTest.java | 261 ++++++++++++++++++ test/jdk/java/awt/Focus/MixedWeightFocus.java | 207 ++++++++++++++ .../java/awt/Focus/NextFocusHelperTest.java | 111 ++++++++ 4 files changed, 701 insertions(+) create mode 100644 test/jdk/java/awt/Focus/FocusChangeOnResizeTest.java create mode 100644 test/jdk/java/awt/Focus/LightweightFocusLostTest.java create mode 100644 test/jdk/java/awt/Focus/MixedWeightFocus.java create mode 100644 test/jdk/java/awt/Focus/NextFocusHelperTest.java diff --git a/test/jdk/java/awt/Focus/FocusChangeOnResizeTest.java b/test/jdk/java/awt/Focus/FocusChangeOnResizeTest.java new file mode 100644 index 0000000000000..a9fa9e5edfd07 --- /dev/null +++ b/test/jdk/java/awt/Focus/FocusChangeOnResizeTest.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4060975 + * @summary tests that a component doesn't lose focus on resize + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual FocusChangeOnResizeTest +*/ + +import java.util.List; + +import java.awt.Button; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.TextField; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; + +public class FocusChangeOnResizeTest { + + private static final String INSTRUCTIONS = """ + For the Frame and the Dialog: + Press the LOWER BUTTON to resize the Frame or Dialog programmatically. + Give the focus to the LOWER BUTTON and resize the Frame or Dialog manually. + If the LOWER BUTTON always has focus after resize + (for both frame and dialog) the test passes."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("PopupMenu Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(FocusChangeOnResizeTest::createTestUI) + .logArea() + .build() + .awaitAndCheck(); + } + + private static List createTestUI() { + Frame frame = new Frame("FocusChangeOnResizeTest frame"); + Dialog dialog = new Dialog(frame, "Test dialog"); + frame.add(new TestPanel(frame)); + dialog.add(new TestPanel(dialog)); + frame.setBounds (150, 200, 200, 200); + dialog.setBounds (150, 500, 200, 200); + return List.of(frame, dialog); + } + + static FocusListener eventLogger = new FocusListener() { + public void focusGained(FocusEvent e) { + PassFailJFrame.log(e.toString()); + } + public void focusLost(FocusEvent e) { + PassFailJFrame.log(e.toString()); + } + }; +} + +class TestPanel extends Panel { + + TextField textField = new TextField("TEXT FIELD"); + Button button1 = new Button("UPPER BUTTON"); + Button button2 = new Button("LOWER BUTTON"); + + public TestPanel(Window parent) { + setLayout(new GridLayout(3, 1)); + add(textField); + add(button1); + add(button2); + textField.setName("TEXT FIELD"); + button1.setName("UPPER BUTTON"); + button2.setName("LOWER BUTTON"); + textField.addFocusListener(FocusChangeOnResizeTest.eventLogger); + button1.addFocusListener(FocusChangeOnResizeTest.eventLogger); + button2.addFocusListener(FocusChangeOnResizeTest.eventLogger); + + button2.addActionListener(new Resizer(parent)); + } +} + +class Resizer implements ActionListener { + Window target; + + public Resizer(Window window) { + target = window; + } + + public void actionPerformed(ActionEvent e) { + target.setSize(200, 100); + target.doLayout(); + target.pack(); + } +} + diff --git a/test/jdk/java/awt/Focus/LightweightFocusLostTest.java b/test/jdk/java/awt/Focus/LightweightFocusLostTest.java new file mode 100644 index 0000000000000..aff2e5e3b2eb8 --- /dev/null +++ b/test/jdk/java/awt/Focus/LightweightFocusLostTest.java @@ -0,0 +1,261 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4124119 + * @summary Checks that lightweight components do not lose focus after + dragging the frame by using the mouse. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual LightweightFocusLostTest +*/ + +import java.awt.AWTEvent; +import java.awt.AWTEventMulticaster; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Label; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.SystemColor; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + + +public class LightweightFocusLostTest { + + private static final String INSTRUCTIONS = """ + Steps to try to reproduce this problem: + When this test is run a window will display (Test Focus). + Click in the text field to give it the focus (a blinking cursor + will appear) and then move the frame with the mouse. The text field + (component which uses a lightweight component) should still have focus. + You should still see the blinking cursor in the text field after the + frame has been moved. If this is the behavior that you observe, the + test has passed, Press the Pass button. Otherwise the test has failed, + Press the Fail button."""; + + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("LightweightFocusLostTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 5) + .columns(35) + .testUI(LightweightFocusLostTest::createTestUI) + .logArea() + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Frame f = new Frame("LightweightFocusLostTest"); + f.setLayout(new BorderLayout()); + String sLabel = "Lightweight component below (text field)"; + Label TFL = new Label(sLabel, Label.LEFT); + f.add(TFL, BorderLayout.NORTH); + SimpleTextField canvas = new SimpleTextField(30, 5); + f.add(canvas, BorderLayout.CENTER); + f.setSize(new Dimension(300,125)); + f.requestFocus(); + return f; + + } + +} + +class SimpleTextField extends Component implements Runnable { + int border; + int length; + Font font; + FontMetrics fontM; + char[] buffer; + int bufferIx; + + boolean hasFocus; + boolean cursorOn; + + SimpleTextField(int len, int bor) { + super(); + border = bor; + length = len; + buffer = new char[len]; + font = getFont(); + if (font == null) { + font = new Font("Dialog", Font.PLAIN, 20); + } + fontM = getFontMetrics(font); + + // Listen for key and mouse events. + this.addMouseListener(new MouseEventHandler()); + this.addFocusListener(new FocusEventHandler()); + this.addKeyListener(new KeyEventHandler()); + + // Set text cursor. + setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); + + // Start the thread that blinks the cursor. + (new Thread(this)).start(); + } + + public Dimension getMinimumSize() { + // The minimum height depends on the point size. + int w = fontM.charWidth('m') * length; + return new Dimension(w + 2 * border, fontM.getHeight() + 2 * border); + } + public Dimension getPreferredSize() { + return getMinimumSize(); + } + public Dimension getMaximumSize() { + return new Dimension(Short.MAX_VALUE, getPreferredSize().height); + } + + public boolean isFocusTraversable() { + return true; + } + + public void paint(Graphics g) { + int y = (getSize().height-fontM.getHeight())/2; + + // Clear the background using the text background color. + g.setColor(SystemColor.text); + g.fillRect(0, 0, getSize().width, getSize().height); + + g.setFont(font); + g.setColor(SystemColor.textText); + g.drawChars(buffer, 0, bufferIx, border, y + fontM.getAscent()); + + // Draw blinking cursor. + int x = fontM.charsWidth(buffer, 0, bufferIx) + border; + int w = fontM.charWidth('c'); + if (hasFocus) { + g.setColor(getForeground()); + g.fillRect(x, y, w, fontM.getHeight()); + if (cursorOn) { + if (bufferIx < buffer.length) { + g.setColor(SystemColor.text); + g.fillRect(x + 2, y + 2, w - 4, fontM.getHeight() - 4); + } + } + } + } + + // Event handlers + class MouseEventHandler extends MouseAdapter { + public void mousePressed(MouseEvent evt) { + requestFocus(); + } + } + class FocusEventHandler extends FocusAdapter { + public void focusGained(FocusEvent evt) { + PassFailJFrame.log("Focus gained: " + evt); + + hasFocus = true; + repaint(); + } + public void focusLost(FocusEvent evt) { + PassFailJFrame.log("Focus lost: " + evt); + hasFocus = false; + repaint(); + } + } + class KeyEventHandler extends KeyAdapter { + public void keyPressed(KeyEvent evt) { + switch (evt.getKeyCode()) { + case KeyEvent.VK_DELETE: + case KeyEvent.VK_BACK_SPACE: + if (bufferIx > 0) { + bufferIx--; + repaint(); + } + break; + case KeyEvent.VK_ENTER: + ActionEvent action = + new ActionEvent(SimpleTextField.this, + ActionEvent.ACTION_PERFORMED, + String.valueOf(buffer, 0, bufferIx)); + // Send contents of buffer to listeners + processEvent(action); + break; + default: + repaint(); + } + } + public void keyTyped(KeyEvent evt) { + if (bufferIx < buffer.length + && !evt.isActionKey() + && !Character.isISOControl(evt.getKeyChar())) { + buffer[bufferIx++] = evt.getKeyChar(); + } + } + } + + // Support for Action Listener. + ActionListener actionListener; + + public void addActionListener(ActionListener l) { + actionListener = AWTEventMulticaster.add(actionListener, l); + } + + // Override processEvent() to deal with ActionEvent. + protected void processEvent(AWTEvent evt) { + if (evt instanceof ActionEvent) { + processActionEvent((ActionEvent)evt); + } else { + super.processEvent(evt); + } + } + + // Supply method to process Action event. + protected void processActionEvent(ActionEvent evt) { + if (actionListener != null) { + actionListener.actionPerformed(evt); + } + } + + public void run() { + while (true) { + try { + // If component has focus, blink the cursor every 1/2 second. + Thread.sleep(500); + cursorOn = !cursorOn; + if (hasFocus) { + repaint(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} + diff --git a/test/jdk/java/awt/Focus/MixedWeightFocus.java b/test/jdk/java/awt/Focus/MixedWeightFocus.java new file mode 100644 index 0000000000000..4b434e4b66d7e --- /dev/null +++ b/test/jdk/java/awt/Focus/MixedWeightFocus.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4098290 4140890 + * @summary Using non-opaque windows - popups are initially not painted correctly + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MixedWeightFocus +*/ + +import java.util.List; +import java.awt.AWTEvent; +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.FlowLayout; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.FocusEvent; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class MixedWeightFocus { + + static FocusFrame f; + + private static final String INSTRUCTIONS = """ + This tests that permanent FOCUS_LOST messages are sent to lightweight + components when the focus shifts to a heavyweight component. It also + tests that components retain the focus when their parent window is + deactivated and activated. + + 1. Tab or mouse between the light and heavyweight buttons in this test + and verify that the focus rectangle on the lightweight components + disappears when focus shifts to a heavyweight button. + + 2. Activate another application then reactivate the test frame window. + Verify that the component that had the focus (light or heavy) when + the frame was deactivated regains the focus when it's reactivated. Do + the same thing for the modeless dialog. Also test this by moving the + activation between the dialog and the frame. + + 3. Verify that lightweight components with the focus in a deactivated + window draw their focus rectangles in gray instead of blue-- this indicates + they received temporary instead of permanent FOCUS_LOST events. + + NOTE: There is currently another problem with lightweight components + where if you click on one to activate its frame window, the lightweight + that previously had the focus will not get a FOCUS_LOST event. This + may manifest itself with a gray focus rectangle not getting erased. + Ignore this for now (Win32 only)."""; + + public static void main(String[] argv) throws Exception { + PassFailJFrame.builder() + .title("MixedWeightFocus Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 5) + .columns(45) + .testUI(MixedWeightFocus::createTestUI) + .build() + .awaitAndCheck(); + } + + private static List createTestUI() { + FocusFrame f = new FocusFrame(); + ModelessDialog dlg = new ModelessDialog(f); + + return List.of(f, dlg); + } +} + +class FocusFrame extends Frame { + public FocusFrame() { + super("FocusFrame"); + Panel p = new Panel(); + + p.add(new Button("button 1")); + p.add(new LightweightComp("lw 1")); + p.add(new Button("button 2")); + p.add(new LightweightComp("lw 2")); + add(p); + + pack(); + setLocation(100, 100); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent ev) { + dispose(); + } + }); + } + +} + +class ModelessDialog extends Dialog { + public ModelessDialog(Frame frame) { + super(frame, "ModelessDialog", false); + setLayout( new FlowLayout() ); + add(new Button("button 1")); + add(new LightweightComp("lw 1")); + pack(); + setLocation(100, 400); + } +} + +// simple lightweight component, focus traversable, highlights upon focus +class LightweightComp extends Component { + FontMetrics fm; + String label; + private static final int FOCUS_GONE = 0; + private static final int FOCUS_TEMP = 1; + private static final int FOCUS_HAVE = 2; + int focusLevel = FOCUS_GONE; + public static int nameCounter = 0; + + public LightweightComp(String lwLabel ) { + label = lwLabel; + enableEvents(AWTEvent.FOCUS_EVENT_MASK|AWTEvent.MOUSE_EVENT_MASK); + setName("lw"+Integer.toString(nameCounter++)); + } + + public Dimension getPreferredSize() { + if (fm == null) { + fm = Toolkit.getDefaultToolkit().getFontMetrics(getFont()); + } + return new Dimension(fm.stringWidth(label) + 2, fm.getHeight() + 2); + } + + public void paint(Graphics g) { + Dimension s=getSize(); + + // erase the background + g.setColor(getBackground()); + g.fillRect(0, 0, s.width, s.height); + + g.setColor(getForeground()); + + // draw the string + g.drawString(label, 2, fm.getHeight()); + + // draw a focus rectangle + if (focusLevel > FOCUS_GONE) { + if (focusLevel == FOCUS_TEMP) { + g.setColor(Color.gray); + } else { + g.setColor(Color.blue); + } + g.drawRect(1,1,s.width-2,s.height-2); + } + } + + + public boolean isFocusTraversable() { + return true; + } + + protected void processFocusEvent(FocusEvent e) { + super.processFocusEvent(e); + if (e.getID() == FocusEvent.FOCUS_GAINED) { + focusLevel = FOCUS_HAVE; + } else { + if (e.isTemporary()) { + focusLevel = FOCUS_TEMP; + } else { + focusLevel = FOCUS_GONE; + } + } + repaint(); + } + + protected void processMouseEvent(MouseEvent e) { + + if (e.getID()==MouseEvent.MOUSE_PRESSED) { + requestFocus(); + } + super.processMouseEvent(e); + } +} diff --git a/test/jdk/java/awt/Focus/NextFocusHelperTest.java b/test/jdk/java/awt/Focus/NextFocusHelperTest.java new file mode 100644 index 0000000000000..5b3015da63017 --- /dev/null +++ b/test/jdk/java/awt/Focus/NextFocusHelperTest.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4474893 + * @summary Component.nextFocusHelper should search for first visible focus cycle root ancst + * @key headful + * @run main NextFocusHelperTest +*/ + +import java.awt.Button; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.FlowLayout; +import java.awt.KeyboardFocusManager; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; + +public class NextFocusHelperTest { + static Panel panel; + static Frame frame; + static Button btn1; + static Button btn3; + static Button hideButton; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + try { + EventQueue.invokeAndWait(() -> createTestUI()); + robot.waitForIdle(); + robot.delay(1000); + + Point loc = btn1.getLocationOnScreen(); + Dimension dim = btn1.getSize(); + robot.mouseMove(loc.x + dim.width/2, loc.y + dim.height/2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.delay(500); + + Point loc1 = hideButton.getLocationOnScreen(); + Dimension dim1 = hideButton.getSize(); + robot.mouseMove(loc1.x + dim1.width/2, loc1.y + dim1.height/2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() + instanceof Button btn) { + if (!btn.getLabel().equals("Button 3")) { + throw new RuntimeException("Wrong button has focus"); + } + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createTestUI() { + frame = new Frame("NextFocusHelperTest Frame"); + frame.setLayout(new FlowLayout()); + + panel = new Panel(); + panel.setFocusCycleRoot(true); + btn1 = new Button("Button In Panel"); + panel.add(btn1); + + hideButton = new Button("Hide Panel"); + hideButton.setFocusable(false); + hideButton.addActionListener(e -> { + panel.setVisible(false); + }); + + frame.add(new Button("Button 1")); + frame.add(panel); + frame.add(new Button("Button 3")); + frame.add(hideButton); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } +} + From d1522b9568278e4fb32e251cdf705473922722c2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 12:48:57 +0000 Subject: [PATCH 046/846] 8339984: Open source AWT MenuItem related tests Backport-of: f4e401791efb920b9773f2886b34904c95106727 --- test/jdk/java/awt/MenuItem/GiantFontTest.java | 83 +++++++++++++ .../awt/MenuItem/LotsOfMenuItemsTest.java | 117 ++++++++++++++++++ .../java/awt/MenuItem/MenuSetFontTest.java | 72 +++++++++++ .../MenuItem/NullOrEmptyStringLabelTest.java | 105 ++++++++++++++++ .../awt/MenuItem/UnicodeMenuItemTest.java | 91 ++++++++++++++ 5 files changed, 468 insertions(+) create mode 100644 test/jdk/java/awt/MenuItem/GiantFontTest.java create mode 100644 test/jdk/java/awt/MenuItem/LotsOfMenuItemsTest.java create mode 100644 test/jdk/java/awt/MenuItem/MenuSetFontTest.java create mode 100644 test/jdk/java/awt/MenuItem/NullOrEmptyStringLabelTest.java create mode 100644 test/jdk/java/awt/MenuItem/UnicodeMenuItemTest.java diff --git a/test/jdk/java/awt/MenuItem/GiantFontTest.java b/test/jdk/java/awt/MenuItem/GiantFontTest.java new file mode 100644 index 0000000000000..f1e352373bb1e --- /dev/null +++ b/test/jdk/java/awt/MenuItem/GiantFontTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Font; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; + +/* + * @test + * @bug 4700350 + * @requires os.family != "mac" + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Tests menu item font is big + * @run main/manual GiantFontTest + */ + +public class GiantFontTest { + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + A frame with one menu will appear. + On Linux, the menu's (present on menu bar) font should + be quite large (48 point). + If not, test fails. + + On Windows, the menu's (present on menu bar) font + should be normal size. + If the menu text is clipped by the title bar, or is painted over + the title bar or client area, the test fails. + + On both Windows and Linux, the menu items in the popup + menu should be large. + + If so, test passes."""; + + PassFailJFrame.builder() + .title("GiantFontTest") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(40) + .testUI(GiantFontTest::createAndShowUI) + .build() + .awaitAndCheck(); + } + + private static Frame createAndShowUI() { + Font giantFont = new Font("Dialog", Font.PLAIN, 48); + Frame f = new Frame("GiantFontTest"); + MenuBar mb = new MenuBar(); + Menu m = new Menu("My font is too big!"); + m.setFont(giantFont); + for (int i = 0; i < 5; i++) { + m.add(new MenuItem("Some MenuItems")); + } + mb.add(m); + f.setMenuBar(mb); + f.setSize(450, 400); + return f; + } +} diff --git a/test/jdk/java/awt/MenuItem/LotsOfMenuItemsTest.java b/test/jdk/java/awt/MenuItem/LotsOfMenuItemsTest.java new file mode 100644 index 0000000000000..7a528205d27d8 --- /dev/null +++ b/test/jdk/java/awt/MenuItem/LotsOfMenuItemsTest.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; + +/* + * @test + * @bug 4175790 + * @requires os.family == "windows" + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Win32: Running out of command ids for menu items + * @run main/manual LotsOfMenuItemsTest + */ + +public class LotsOfMenuItemsTest extends ComponentAdapter { + private static final int NUM_WINDOWS = 400; + private static TestFrame firstFrame; + + public static void main(String[] args) throws Exception { + LotsOfMenuItemsTest obj = new LotsOfMenuItemsTest(); + String INSTRUCTIONS = """ + This test creates lots of frames with menu bars. + When it's done you will see two frames. + Try to select menu items from each of them. + + If everything seems to work - test passed. + Click "Pass" button in the test harness window. + + If test crashes on you - test failed."""; + + PassFailJFrame.builder() + .title("LotsOfMenuItemsTest") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(40) + .testUI(obj::createAndShowUI) + .build() + .awaitAndCheck(); + } + + private Frame createAndShowUI() { + firstFrame = new TestFrame("First frame"); + firstFrame.addComponentListener(this); + return firstFrame; + } + + @Override + public void componentShown(ComponentEvent e) { + final int x = firstFrame.getX(); + final int y = firstFrame.getY() + firstFrame.getHeight() + 8; + TestFrame testFrame; + for (int i = 1; i < NUM_WINDOWS - 1; ++i) { + testFrame = new TestFrame("Running(" + i + ")...", x, y); + testFrame.setVisible(false); + testFrame.dispose(); + } + testFrame = new TestFrame("Last Frame", x, y); + PassFailJFrame.addTestWindow(testFrame); + } + + private static class TestFrame extends Frame { + static int n = 0; + + public TestFrame(String title) { + this(title, 0, 0, false); + } + + public TestFrame(String s, int x, int y) { + this(s, x, y, true); + } + + private TestFrame(String title, int x, int y, boolean visible) { + super(title); + MenuBar mb = new MenuBar(); + for (int i = 0; i < 10; ++i) { + Menu m = new Menu("Menu_" + (i + 1)); + for (int j = 0; j < 20; ++j) { + MenuItem mi = new MenuItem("Menu item " + ++n); + m.add(mi); + } + mb.add(m); + } + setMenuBar(mb); + setLocation(x, y); + setSize(450, 150); + if (visible) { + setVisible(true); + } + } + } +} diff --git a/test/jdk/java/awt/MenuItem/MenuSetFontTest.java b/test/jdk/java/awt/MenuItem/MenuSetFontTest.java new file mode 100644 index 0000000000000..9a4e8f8583905 --- /dev/null +++ b/test/jdk/java/awt/MenuItem/MenuSetFontTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Font; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; + +/* + * @test + * @bug 4066657 8009454 + * @requires os.family != "mac" + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Tests that setting a font on the Menu with MenuItem takes effect. + * @run main/manual MenuSetFontTest + */ + +public class MenuSetFontTest { + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Look at the menu in the upper left corner of the 'SetFont Test' frame. + Click on the "File" menu. You will see "menu item" item. + Press Pass if menu item is displayed using bold and large font, + otherwise press Fail. + If you do not see menu at all, press Fail."""; + + PassFailJFrame.builder() + .title("MenuSetFontTest") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(40) + .testUI(MenuSetFontTest::createAndShowUI) + .build() + .awaitAndCheck(); + } + + private static Frame createAndShowUI() { + Frame frame = new Frame("SetFont Test"); + MenuBar menuBar = new MenuBar(); + Menu menu = new Menu("File"); + MenuItem item = new MenuItem("menu item"); + menu.add(item); + menuBar.add(menu); + menuBar.setFont(new Font(Font.MONOSPACED, Font.BOLD, 24)); + frame.setMenuBar(menuBar); + frame.setSize(300, 200); + return frame; + } +} diff --git a/test/jdk/java/awt/MenuItem/NullOrEmptyStringLabelTest.java b/test/jdk/java/awt/MenuItem/NullOrEmptyStringLabelTest.java new file mode 100644 index 0000000000000..79d4c02ad246a --- /dev/null +++ b/test/jdk/java/awt/MenuItem/NullOrEmptyStringLabelTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/* + * @test + * @bug 4251036 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary MenuItem setLabel(null/"") behaves differently under Win32 and Solaris + * @run main/manual NullOrEmptyStringLabelTest + */ + +public class NullOrEmptyStringLabelTest { + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + The bug is reproducible under Win32 and Solaris. + Setting 'null' and "" as a label of menu item + should set blank label on all platforms according to the specification. + But under Solaris setting "" as a label of menu item used to + cause some garbage to be set as label. + Under Win32 setting 'null' as a label used to result in + throwing NullPointerException. + + If you see any of these things happen test fails otherwise + it passes."""; + + PassFailJFrame.builder() + .title("NullOrEmptyStringLabelTest") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(40) + .testUI(NullOrEmptyStringLabelTest::createAndShowUI) + .build() + .awaitAndCheck(); + } + + private static Frame createAndShowUI() { + Frame frame = new Frame("Null Or Empty String Label Test"); + Menu menu = new Menu("Menu"); + MenuItem mi = new MenuItem("Item"); + MenuBar mb = new MenuBar(); + Button button1 = new Button("Set MenuItem label to 'null'"); + Button button2 = new Button("Set MenuItem label to \"\""); + Button button3 = new Button("Set MenuItem label to 'text'"); + button1.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent ev) { + System.out.println("Setting MenuItem label to null"); + mi.setLabel(null); + } + }); + button2.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent ev) { + System.out.println("Setting MenuItem label to \"\""); + mi.setLabel(""); + } + }); + button3.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent ev) { + System.out.println("Setting MenuItem label to 'text'"); + mi.setLabel("text"); + } + }); + menu.add(mi); + mb.add(menu); + frame.add(button1, BorderLayout.NORTH); + frame.add(button2, BorderLayout.CENTER); + frame.add(button3, BorderLayout.SOUTH); + frame.setMenuBar(mb); + frame.setSize(200, 135); + return frame; + } +} diff --git a/test/jdk/java/awt/MenuItem/UnicodeMenuItemTest.java b/test/jdk/java/awt/MenuItem/UnicodeMenuItemTest.java new file mode 100644 index 0000000000000..b73fe954af6db --- /dev/null +++ b/test/jdk/java/awt/MenuItem/UnicodeMenuItemTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; + +/* + * @test + * @bug 4099695 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary menu items with Unicode labels treated as separators + * @run main/manual UnicodeMenuItemTest + */ + +public class UnicodeMenuItemTest { + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Click on the "Menu" on the top-left corner of frame. + + The menu should have four entries: + 1) a row of five unicode characters: \u00c4\u00cb\u00cf\u00d6\u00dc + 2) a menu separator + 3) a unicode character: \u012d + 4) a unicode character: \u022d + + If the menu items look like the list above, the test passes. + It is okay if the unicode characters look like empty boxes + or something - as long as they are not separators. + + If either of the last two menu items show up as separators, + the test FAILS. + + Press 'Pass' if above instructions hold good else press 'Fail'."""; + + PassFailJFrame.builder() + .title("UnicodeMenuItemTest") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(40) + .testUI(UnicodeMenuItemTest::createAndShowUI) + .build() + .awaitAndCheck(); + } + private static Frame createAndShowUI() { + Frame frame = new Frame("Unicode MenuItem Test"); + MenuBar mb = new MenuBar(); + Menu m = new Menu("Menu"); + + MenuItem mi1 = new MenuItem("\u00c4\u00cb\u00cf\u00d6\u00dc"); + m.add(mi1); + + MenuItem separator = new MenuItem("-"); + m.add(separator); + + MenuItem mi2 = new MenuItem("\u012d"); + m.add(mi2); + + MenuItem mi3 = new MenuItem("\u022d"); + m.add(mi3); + + mb.add(m); + + frame.setMenuBar(mb); + frame.setSize(450, 150); + return frame; + } +} From faefbe407d7b6326726fd36793b1ddcd21638ebf Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 12:49:20 +0000 Subject: [PATCH 047/846] 8340393: Open source closed choice tests #2 Backport-of: a9b0f9ccbf98c6b90626fcd7087fa8eeb0c168eb --- test/jdk/java/awt/Choice/CheckChoiceTest.java | 92 +++++++++++++++++++ test/jdk/java/awt/Choice/ChoiceBigTest.java | 70 ++++++++++++++ test/jdk/java/awt/Choice/ChoiceFocusTest.java | 81 ++++++++++++++++ test/jdk/java/awt/Choice/DisabledList.java | 79 ++++++++++++++++ 4 files changed, 322 insertions(+) create mode 100644 test/jdk/java/awt/Choice/CheckChoiceTest.java create mode 100644 test/jdk/java/awt/Choice/ChoiceBigTest.java create mode 100644 test/jdk/java/awt/Choice/ChoiceFocusTest.java create mode 100644 test/jdk/java/awt/Choice/DisabledList.java diff --git a/test/jdk/java/awt/Choice/CheckChoiceTest.java b/test/jdk/java/awt/Choice/CheckChoiceTest.java new file mode 100644 index 0000000000000..3e2e06b1c9557 --- /dev/null +++ b/test/jdk/java/awt/Choice/CheckChoiceTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Choice; +import java.awt.Frame; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +/* + * @test + * @bug 4151949 + * @summary Verifies that Components are reshaped to their preferred size + * when their Container is packed. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual CheckChoiceTest + */ + +public class CheckChoiceTest { + + private static JComponent componentToFocus; + + private static final String INSTRUCTIONS = """ + Verify that the widths of the Choice components are all the same + and that none is the minimum possible size. + (The Choices should be at least as wide as the Frame.) + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame passFailJFrame = PassFailJFrame.builder() + .title("CheckChoiceTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 3) + .columns(45) + .testUI(CheckChoiceTest::createAndShowUI) + .splitUIBottom(CheckChoiceTest::createComponentToFocus) + .build(); + + // focus away from the window with choices + Thread.sleep(300); + SwingUtilities.invokeAndWait(() -> componentToFocus.requestFocus()); + + passFailJFrame.awaitAndCheck(); + } + + private static JComponent createComponentToFocus() { + componentToFocus = new JPanel(); + return componentToFocus; + } + + private static Frame createAndShowUI() { + Frame f = new Frame("Check Choice"); + f.setLayout(new BorderLayout()); + + Choice choice1 = new Choice(); + Choice choice2 = new Choice(); + Choice choice3 = new Choice(); + + f.add(choice1, BorderLayout.NORTH); + f.add(choice3, BorderLayout.CENTER); + f.add(choice2, BorderLayout.SOUTH); + f.pack(); + + choice1.add("I am Choice, yes I am : 0"); + choice2.add("I am the same, yes I am : 0"); + choice3.add("I am the same, yes I am : 0"); + + return f; + } +} diff --git a/test/jdk/java/awt/Choice/ChoiceBigTest.java b/test/jdk/java/awt/Choice/ChoiceBigTest.java new file mode 100644 index 0000000000000..be82ed2a40db1 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceBigTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Choice; +import java.awt.Frame; +import java.awt.FlowLayout; +import java.awt.Window; + +/* + * @test + * @bug 4288285 + * @summary Verifies choice works with many items + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ChoiceBigTest + */ + +public class ChoiceBigTest { + private static final String INSTRUCTIONS = """ + Click the Choice button, press Pass if: + + - all looks good. + - if you can select the item 1000 + + Otherwise press Fail. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("ChoiceBigTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 3) + .columns(45) + .testUI(ChoiceBigTest::createAndShowUI) + .build() + .awaitAndCheck(); + } + + private static Window createAndShowUI() { + Frame frame = new Frame("Check Choice"); + frame.setLayout(new FlowLayout()); + Choice choice = new Choice(); + frame.setSize(400, 200); + for (int i = 1; i < 1001; ++i) { + choice.add("I am Choice, yes I am : " + i); + } + frame.add(choice); + return frame; + } +} diff --git a/test/jdk/java/awt/Choice/ChoiceFocusTest.java b/test/jdk/java/awt/Choice/ChoiceFocusTest.java new file mode 100644 index 0000000000000..3ca895f88e6e9 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceFocusTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Choice; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Window; + +/* + * @test + * @bug 4927930 + * @summary Verify that the focus is set to the selected item after calling the java.awt.Choice.select() method + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ChoiceFocusTest + */ + +public class ChoiceFocusTest { + + private static final String INSTRUCTIONS = """ + 1. Use the mouse to select Item 5 in the Choice list. + 2. Click on the Choice. Item5 is now selected and highlighted. This is the correct behavior. + 3. Select Item 1 in the Choice list. + 4. Click the "choice.select(5)" button. This causes a call to Choice.select(5). Item 5 is now selected. + 5. Click on the Choice. + 6. If the cursor and focus are on item 5, the test passes. Otherwise, it fails. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("ChoiceFocusTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 3) + .columns(50) + .testUI(ChoiceFocusTest::createAndShowUI) + .build() + .awaitAndCheck(); + } + + private static Window createAndShowUI() { + Panel panel = new Panel(); + Choice choice = new Choice(); + Button button = new Button("choice.select(5);"); + + for (int i = 0; i < 10; i++) { + choice.add(String.valueOf(i)); + } + + button.addActionListener(e -> choice.select(5)); + + panel.add(button); + panel.add(choice); + + Frame frame = new Frame("ChoiceFocusTest"); + frame.add(panel); + frame.pack(); + + return frame; + } +} diff --git a/test/jdk/java/awt/Choice/DisabledList.java b/test/jdk/java/awt/Choice/DisabledList.java new file mode 100644 index 0000000000000..d028527303f7a --- /dev/null +++ b/test/jdk/java/awt/Choice/DisabledList.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Checkbox; +import java.awt.Choice; +import java.awt.Frame; +import java.awt.Window; +import java.awt.event.ItemEvent; + +/* + * @test + * @bug 6476183 + * @summary Drop down of a Choice changed to enabled state has a disabled like appearance + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DisabledList + */ + +public class DisabledList { + + private static final String INSTRUCTIONS = """ + 1) Select the checkbox + 2) Open Choice + 3) Drag mouse over the scrollbar or drag out it the choice + 4) If choice's items become disabled press fail, otherwise pass + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("DisabledList Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 3) + .columns(45) + .testUI(DisabledList::createAndShowUI) + .logArea(4) + .build() + .awaitAndCheck(); + } + + private static Window createAndShowUI() { + Frame frame = new Frame("DisabledList"); + frame.setSize(200, 200); + frame.validate(); + Checkbox checkbox = new Checkbox("checkbox"); + final Choice choice = new Choice(); + choice.setEnabled(false); + for (int i = 0; i < 15; i++) { + choice.addItem("Item" + i); + } + checkbox.addItemListener(event -> { + PassFailJFrame.log("CheckBox.itemStateChanged occurred"); + choice.setEnabled(event.getStateChange() == ItemEvent.SELECTED); + }); + frame.add(BorderLayout.NORTH, checkbox); + frame.add(BorderLayout.CENTER, choice); + return frame; + } +} From c469450fdd485b5843f4cd2fa6dbe3c6d8a3b72f Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 12:50:30 +0000 Subject: [PATCH 048/846] 8339935: Open source several AWT focus tests - series 5 Backport-of: b1f8d2ea76322a89eea84851a1e791f52c31261b --- test/jdk/java/awt/Focus/DeiconifyTest.java | 79 +++++++++++++++++ .../java/awt/Focus/HiddenTraversalTest.java | 72 +++++++++++++++ .../java/awt/Focus/LightweightPopupTest.java | 87 +++++++++++++++++++ .../java/awt/Focus/ProxiedWindowHideTest.java | 77 ++++++++++++++++ 4 files changed, 315 insertions(+) create mode 100644 test/jdk/java/awt/Focus/DeiconifyTest.java create mode 100644 test/jdk/java/awt/Focus/HiddenTraversalTest.java create mode 100644 test/jdk/java/awt/Focus/LightweightPopupTest.java create mode 100644 test/jdk/java/awt/Focus/ProxiedWindowHideTest.java diff --git a/test/jdk/java/awt/Focus/DeiconifyTest.java b/test/jdk/java/awt/Focus/DeiconifyTest.java new file mode 100644 index 0000000000000..e87b13b8e65fa --- /dev/null +++ b/test/jdk/java/awt/Focus/DeiconifyTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4380809 + * @summary Focus disappears after deiconifying frame + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DeiconifyTest +*/ + +import java.awt.Button; +import java.awt.Frame; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; + +public class DeiconifyTest { + + private static final String INSTRUCTIONS = """ + 1. Activate frame \"Main frame\" + be sure that button has focus + 2. Minimize frame and then restore it. + If the button has focus then test passed, else failed"""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("DeiconifyTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int)INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(DeiconifyTest::createTestUI) + .logArea() + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Frame frame = new Frame("Main frame"); + Button button = new Button("button"); + button.addFocusListener(new FocusListener() { + public void focusGained(FocusEvent fe) { + println("focus gained"); + } + public void focusLost(FocusEvent fe) { + println("focus lost"); + } + }); + frame.add(button); + frame.setSize(300, 100); + + return frame; + } + + static void println(String messageIn) { + PassFailJFrame.log(messageIn); + } +} + diff --git a/test/jdk/java/awt/Focus/HiddenTraversalTest.java b/test/jdk/java/awt/Focus/HiddenTraversalTest.java new file mode 100644 index 0000000000000..59e7f477945e5 --- /dev/null +++ b/test/jdk/java/awt/Focus/HiddenTraversalTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4157017 + * @summary Checks whether focus can be traversed when component not visible + within parent container. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual HiddenTraversalTest +*/ + +import java.awt.Button; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Panel; + +public class HiddenTraversalTest { + + private static final String INSTRUCTIONS = """ + Examine the Frame. If six buttons are visible, resize the frame + so that only four are visible. If fewer than six buttons are + visible, do nothing.\n + Now, repeatedly press the tab key. Focus should cycle through the + visible and invisible buttons. If after six presses of the tab + button 'Button 0' has focus, the test passes. If focus is instead + stuck at 'Button 3', the test fails."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("HiddenTraversalTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(HiddenTraversalTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Frame f = new Frame("Focus test"); + Panel p = new Panel(new FlowLayout()); + for (int i = 0; i < 6; i++) { + p.add(new Button("Button " + i)); + } + f.add(p); + f.setSize(200, 100); + return f; + } + +} + diff --git a/test/jdk/java/awt/Focus/LightweightPopupTest.java b/test/jdk/java/awt/Focus/LightweightPopupTest.java new file mode 100644 index 0000000000000..bc3dd0d038b9b --- /dev/null +++ b/test/jdk/java/awt/Focus/LightweightPopupTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4472032 + * @summary Switching between lightweight menus by horizontal arrow key works incorrect + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual LightweightPopupTest +*/ + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; + +public class LightweightPopupTest { + + private static final String INSTRUCTIONS = """ + When the test starts, you will see a frame titled + 'Lightweight Popup Test', which contains a button + (titled 'JButton') and two menus ('Menu 1' and 'Menu 2'). + Make sure that both menus, when expanded, fit entirely + into the frame. Now take the following steps: + 1. Click on 'JButton' to focus it. + 2. Click 'Menu 1' to expand it. + 3. Press right arrow to select 'Menu 2'. + Now check where the focus is. If it is on 'JButton' + (you can press space bar to see if it is there), then + the test failed. If 'JButton' is not focused, then + the test passed."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("LightweightPopupTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int)INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(LightweightPopupTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createTestUI() { + + JFrame frame = new JFrame("Lightweight Popup Test"); + JButton button = new JButton("JButton"); + JMenuBar menuBar = new JMenuBar(); + JMenu menu1 = new JMenu("Menu 1"); + menu1.add(new JMenuItem("Menu Item 1")); + menu1.add(new JMenuItem("Menu Item 2")); + menuBar.add(menu1); + JMenu menu2 = new JMenu("Menu 2"); + menu2.add(new JMenuItem("Menu Item 3")); + menu2.add(new JMenuItem("Menu Item 4")); + menuBar.add(menu2); + + frame.add(button); + frame.setJMenuBar(menuBar); + frame.setSize(300, 200); + return frame; + } + +} + diff --git a/test/jdk/java/awt/Focus/ProxiedWindowHideTest.java b/test/jdk/java/awt/Focus/ProxiedWindowHideTest.java new file mode 100644 index 0000000000000..a99ec4f0a0d90 --- /dev/null +++ b/test/jdk/java/awt/Focus/ProxiedWindowHideTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4396407 + * @summary Tests that after a proxied window is hidden, focus is being restored correctly + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ProxiedWindowHideTest +*/ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Container; +import javax.swing.Box; +import javax.swing.JComboBox; +import javax.swing.JFrame; + +public class ProxiedWindowHideTest { + + private static final String INSTRUCTIONS = """ + You will see a JFrame. + Click on JComboBox, list will expand then select any item in it. + After selection, list should collapse. + Click on Button('Push'). + If you are able to make it focused by mouse click, + (black rectangle will appear around it) the test is PASSED, + otherwise the test is FAILED."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("ProxiedWindowHideTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(ProxiedWindowHideTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createTestUI() { + JFrame frame = new JFrame("ProxiedWindowHideTest frame"); + String[] petStrings = { "Bird", "Cat", "Dog", "Rabbit", "Pig" }; + JComboBox cb = new JComboBox(petStrings); + + cb.setLightWeightPopupEnabled(false); + Container parent = Box.createVerticalBox(); + parent.add(new Button("Push")); + parent.add(cb); + frame.add(parent, BorderLayout.CENTER); + frame.pack(); + return frame; + } + +} + From 4bcd0e0d9be310f06ec815785481fa9cc94c5eba Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 12:51:29 +0000 Subject: [PATCH 049/846] 8340907: Open source closed frame tests # 2 Backport-of: f2a767f59b1f66966665bc8601273b532961395a --- test/jdk/ProblemList.txt | 1 + .../jdk/java/awt/Frame/DeiconifyClipTest.java | 140 ++++++++++++++++++ .../java/awt/Frame/FrameSetCursorTest.java | 100 +++++++++++++ .../java/awt/Frame/InitialIconifiedTest.java | 98 ++++++++++++ .../java/awt/Frame/InsetCorrectionTest.java | 102 +++++++++++++ 5 files changed, 441 insertions(+) create mode 100644 test/jdk/java/awt/Frame/DeiconifyClipTest.java create mode 100644 test/jdk/java/awt/Frame/FrameSetCursorTest.java create mode 100644 test/jdk/java/awt/Frame/InitialIconifiedTest.java create mode 100644 test/jdk/java/awt/Frame/InsetCorrectionTest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 63ccf6548438c..66d367107d5a9 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -121,6 +121,7 @@ java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusToFrontTest.java 6848406 gen java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusSetVisibleTest.java 6848407 generic-all java/awt/Frame/MaximizedUndecorated/MaximizedUndecorated.java 8022302 generic-all java/awt/Frame/FrameLocation/FrameLocation.java 8233703 linux-all +java/awt/Frame/InitialIconifiedTest.java 8203920 macosx-all,linux-all java/awt/FileDialog/FileDialogIconTest/FileDialogIconTest.java 8160558 windows-all java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java 8060176 windows-all,macosx-all java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java 8060176 windows-all,macosx-all diff --git a/test/jdk/java/awt/Frame/DeiconifyClipTest.java b/test/jdk/java/awt/Frame/DeiconifyClipTest.java new file mode 100644 index 0000000000000..c650355f3ec73 --- /dev/null +++ b/test/jdk/java/awt/Frame/DeiconifyClipTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +/* + * DeiconifyClipTest.java + * + * summary: + * + * What happens is that we call AwtWindow::UpdateInsets when + * processing WM_NCCALCSIZE delivered on programmatic deiconification. + * At this point IsIconic returns false (so UpdateInsets proceeds), + * but the rect sizes still seems to be those weird of the iconic + * state. Based on them we compute insets with top = left = 0 (and + * bottom and right that are completely bogus) and pass them to + * PaintUpdateRgn which results in incorrect clip origin. Immediately + * after that we do UpdateInsets again during WM_SIZE processing and + * get real values. + */ + +import javax.swing.BoxLayout; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Insets; + +/* + * @test + * @bug 4792958 + * @summary Incorrect clip region after programmatic restore + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DeiconifyClipTest +*/ + +public class DeiconifyClipTest { + private static final String INSTRUCTIONS = """ + This test creates a frame that is automatically iconified/deiconified + in a cycle. + + The test FAILS if after deiconfication the frame has a greyed-out area + in the lower-right corner. + If the frame contents is drawn completely - the test PASSES. + + Press PASS or FAIL button accordingly. + """; + + static TestFrame testFrame; + static volatile boolean shouldContinue = true; + + public static void main(String[] args) throws Exception { + PassFailJFrame passFailJFrame = PassFailJFrame.builder() + .title("DeiconifyClipTest Instructions") + .instructions(INSTRUCTIONS) + .columns(45) + .testUI(DeiconifyClipTest::createAndShowUI) + .build(); + try { + runThread(); + } finally { + passFailJFrame.awaitAndCheck(); + shouldContinue = false; + } + } + + private static void runThread() { + new Thread(() -> { + for (int i = 0; i < 1000 && shouldContinue; ++i) { + try { + Thread.sleep(3000); + SwingUtilities.invokeAndWait(() -> { + if ((testFrame.getExtendedState() & Frame.ICONIFIED) + != 0) { + testFrame.setExtendedState(Frame.NORMAL); + } else { + testFrame.setState(Frame.ICONIFIED); + } + }); + } catch (Exception ignored) { + } + } + }).start(); + } + + static Frame createAndShowUI() { + testFrame = new TestFrame(); + testFrame.getContentPane().setLayout(new BoxLayout(testFrame.getContentPane(), + BoxLayout.Y_AXIS)); + testFrame.getContentPane().setBackground(Color.yellow); + testFrame.setSize(300, 300); + return testFrame; + } + + static class TestFrame extends JFrame { + public TestFrame() { + super("DeiconifyClipTest"); + } + + // make it more visible if the clip is wrong. + public void paint(Graphics g) { + Insets b = getInsets(); + Dimension d = getSize(); + + int x = b.left; + int y = b.top; + int w = d.width - x - b.right; + int h = d.height - y - b.bottom; + + g.setColor(Color.white); + g.fillRect(0, 0, d.width, d.height); + + g.setColor(Color.green); + g.drawRect(x, y, w-1, h-1); + g.drawLine(x, y, x+w, y+h); + g.drawLine(x, y+h, x+w, y); + } + } +} diff --git a/test/jdk/java/awt/Frame/FrameSetCursorTest.java b/test/jdk/java/awt/Frame/FrameSetCursorTest.java new file mode 100644 index 0000000000000..98968a8fbab82 --- /dev/null +++ b/test/jdk/java/awt/Frame/FrameSetCursorTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Cursor; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.event.ActionListener; +import java.lang.Exception; +import java.lang.InterruptedException; +import java.lang.Object; +import java.lang.String; +import java.lang.Thread; + +/* + * @test + * @bug 4097226 + * @summary Frame.setCursor() sometimes doesn't update the cursor until user moves the mouse + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual FrameSetCursorTest + */ + +public class FrameSetCursorTest { + private static final String INSTRUCTIONS = """ + 1. Keep the instruction dialog and TestFrame side by side so that + you can read the instructions while doing the test + 2. Click on the 'Start Busy' button on the frame titled 'TestFrame' + and DO NOT MOVE THE MOUSE ANYWHERE till you complete the steps below + 3. The cursor on the TestFrame changes to busy cursor + 4. If you don't see the busy cursor press 'Fail' after + the `done sleeping` message + 5. If the busy cursor is seen, after 5 seconds the message + 'done sleeping' is displayed in the message window + 6. Check for the cursor type after the display of 'done sleeping' + 7. If the cursor on the TestFrame has changed back to default cursor + (without you touching or moving the mouse), then press 'Pass' + else if the frame still shows the busy cursor press 'Fail' + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("FrameSetCursorTest Instructions") + .instructions(INSTRUCTIONS) + .columns(45) + .testUI(FrameSetCursorTest::createAndShowUI) + .logArea(5) + .build() + .awaitAndCheck(); + + } + + static Frame createAndShowUI() { + Frame frame = new Frame("TestFrame"); + Panel panel = new Panel(); + Button busyButton = new Button("Start Busy"); + + ActionListener actionListener = event -> { + Object source = event.getSource(); + if (source == busyButton) { + frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + try { + Thread.sleep(5000); + } catch (InterruptedException ignored) {} + PassFailJFrame.log("done sleeping"); + frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + }; + + busyButton.addActionListener(actionListener); + panel.setLayout(new BorderLayout()); + panel.add("North", busyButton); + + frame.add(panel); + frame.pack(); + frame.setSize(200, 200); + return frame; + } +} \ No newline at end of file diff --git a/test/jdk/java/awt/Frame/InitialIconifiedTest.java b/test/jdk/java/awt/Frame/InitialIconifiedTest.java new file mode 100644 index 0000000000000..f3f43929e7b16 --- /dev/null +++ b/test/jdk/java/awt/Frame/InitialIconifiedTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.imageio.ImageIO; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +/* + * @test + * @key headful + * @bug 4851435 + * @summary Frame is not shown initially iconified after pack + */ + +public class InitialIconifiedTest { + + private static Frame backgroundFrame; + private static Frame testedFrame; + + private static final Rectangle backgroundFrameBounds = + new Rectangle(100, 100, 200, 200); + private static final Rectangle testedFrameBounds = + new Rectangle(150, 150, 100, 100); + + private static Robot robot; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + + try { + EventQueue.invokeAndWait(InitialIconifiedTest::initAndShowGui); + robot.waitForIdle(); + robot.delay(500); + test(); + } finally { + EventQueue.invokeAndWait(() -> { + backgroundFrame.dispose(); + testedFrame.dispose(); + }); + } + } + + private static void initAndShowGui() { + backgroundFrame = new Frame("DisposeTest background"); + backgroundFrame.setUndecorated(true); + backgroundFrame.setBackground(Color.RED); + backgroundFrame.setBounds(backgroundFrameBounds); + backgroundFrame.setVisible(true); + + testedFrame = new Frame("Should have started ICONIC"); + testedFrame.setExtendedState(Frame.ICONIFIED); + testedFrame.setBounds(testedFrameBounds); + testedFrame.setVisible(true); + } + + private static void test() { + BufferedImage bi = robot.createScreenCapture(backgroundFrameBounds); + int redPix = Color.RED.getRGB(); + + for (int x = 0; x < bi.getWidth(); x++) { + for (int y = 0; y < bi.getHeight(); y++) { + if (bi.getRGB(x, y) != redPix) { + try { + ImageIO.write(bi, "png", + new File("failure.png")); + } catch (IOException ignored) {} + throw new RuntimeException("Test failed"); + } + } + } + } +} diff --git a/test/jdk/java/awt/Frame/InsetCorrectionTest.java b/test/jdk/java/awt/Frame/InsetCorrectionTest.java new file mode 100644 index 0000000000000..1ea6f03b24b15 --- /dev/null +++ b/test/jdk/java/awt/Frame/InsetCorrectionTest.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/* + * @test + * @bug 4091426 + * @key headful + * @summary Test inset correction when setVisible(true) BEFORE setSize(), setLocation() + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual InsetCorrectionTest + */ + +public class InsetCorrectionTest { + private static final String INSTRUCTIONS = """ + There is a frame of size 300x300 at location (100,100). + It has a menubar with one menu, 'File', but the frame + is otherwise empty. In particular, there should be no + part of the frame that is not shown in the background color. + Upon test completion, click Pass or Fail appropriately. + """; + + private static InsetCorrection testFrame; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> testFrame = new InsetCorrection()); + + try { + PassFailJFrame passFailJFrame = PassFailJFrame.builder() + .title("InsetCorrectionTest Instructions") + .instructions(INSTRUCTIONS) + .columns(45) + .logArea(3) + .build(); + EventQueue.invokeAndWait(() -> + PassFailJFrame.log("frame location: " + testFrame.getBounds())); + passFailJFrame.awaitAndCheck(); + } finally { + EventQueue.invokeAndWait(testFrame::dispose); + } + } + + static class InsetCorrection extends Frame + implements ActionListener { + MenuBar mb; + Menu file; + MenuItem cause_bug_b; + + public InsetCorrection() { + super("InsetCorrection"); + mb = new MenuBar(); + file = new Menu("File"); + mb.add(file); + cause_bug_b = new MenuItem("cause bug"); + file.add(cause_bug_b); + setMenuBar(mb); + cause_bug_b.addActionListener(this); + + // Making the frame visible before setSize and setLocation() + // are being called causes sometimes strange behaviour with + // JDK1.1.5G. The frame is then sometimes to large and the + // excess areas are drawn in black. This only happens + // sometimes. + setVisible(true); + setSize(300, 300); + setLocation(100, 100); + } + + public void actionPerformed(ActionEvent e) { + setVisible(false); + setVisible(true); + } + } +} From 60f29ac8edde37a53f365e553be59d0357d0089c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 12:58:12 +0000 Subject: [PATCH 050/846] 8340966: Open source few Checkbox and Cursor tests - Set1 Backport-of: 3d38cd97eff2228e2172bfdbf5cc21cf2060f871 --- .../DynamicChangeTest/DynamicChangeTest.java | 72 ++++++++ .../Cursor/CursorDragTest/ListDragCursor.java | 84 ++++++++++ .../HiddenDialogParentTest.java | 72 ++++++++ .../InvalidImageCustomCursorTest.java | 95 +++++++++++ .../Cursor/NullCursorTest/NullCursorTest.java | 154 ++++++++++++++++++ 5 files changed, 477 insertions(+) create mode 100644 test/jdk/java/awt/Checkbox/DynamicChangeTest/DynamicChangeTest.java create mode 100644 test/jdk/java/awt/Cursor/CursorDragTest/ListDragCursor.java create mode 100644 test/jdk/java/awt/Cursor/HiddenDialogParentTest/HiddenDialogParentTest.java create mode 100644 test/jdk/java/awt/Cursor/InvalidImageCustomCursorTest/InvalidImageCustomCursorTest.java create mode 100644 test/jdk/java/awt/Cursor/NullCursorTest/NullCursorTest.java diff --git a/test/jdk/java/awt/Checkbox/DynamicChangeTest/DynamicChangeTest.java b/test/jdk/java/awt/Checkbox/DynamicChangeTest/DynamicChangeTest.java new file mode 100644 index 0000000000000..b62255efa4589 --- /dev/null +++ b/test/jdk/java/awt/Checkbox/DynamicChangeTest/DynamicChangeTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6225679 + * @summary Tests that checkbox changes into radiobutton dynamically + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DynamicChangeTest + */ + +import java.awt.Checkbox; +import java.awt.CheckboxGroup; +import java.awt.Frame; +import java.awt.GridLayout; + +public class DynamicChangeTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + This test is primarily for Windows platform, but should pass + on other platforms as well. Ensure that 'This is checkbox' is + checkbox, and 'This is radiobutton' is radiobutton. + If it is so, press pass else fail. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(DynamicChangeTest::createUI) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame f = new Frame("Dynamic Change Checkbox Test"); + f.setSize(200, 200); + + f.setLayout(new GridLayout(2, 1)); + Checkbox ch1 = new Checkbox("This is checkbox", + new CheckboxGroup(), true); + f.add(ch1); + Checkbox ch2 = new Checkbox("This is radiobutton", null, true); + f.add(ch2); + + ch1.setCheckboxGroup(null); + ch2.setCheckboxGroup(new CheckboxGroup()); + return f; + } +} diff --git a/test/jdk/java/awt/Cursor/CursorDragTest/ListDragCursor.java b/test/jdk/java/awt/Cursor/CursorDragTest/ListDragCursor.java new file mode 100644 index 0000000000000..32923f1d78b0a --- /dev/null +++ b/test/jdk/java/awt/Cursor/CursorDragTest/ListDragCursor.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4313052 + * @summary Test cursor changes after mouse dragging ends + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ListDragCursor + */ + +import java.awt.Cursor; +import java.awt.Frame; +import java.awt.List; +import java.awt.Panel; +import java.awt.TextArea; + +public class ListDragCursor { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Move mouse to the TextArea. + 2. Press the left mouse button. + 3. Drag mouse to the list. + 4. Release the left mouse button. + + If the mouse cursor starts as a Text Line Cursor and changes + to a regular Pointer Cursor, then Hand Cursor when hovering + the list, pass the test. This test fails if the cursor does + not update at all when pointing over the different components. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(ListDragCursor::createUI) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame frame = new Frame("Cursor change after drag"); + Panel panel = new Panel(); + + List list = new List(2); + list.add("List1"); + list.add("List2"); + list.add("List3"); + list.add("List4"); + list.setCursor(new Cursor(Cursor.HAND_CURSOR)); + + TextArea textArea = new TextArea(3, 5); + textArea.setCursor(new Cursor(Cursor.TEXT_CURSOR)); + + panel.add(textArea); + panel.add(list); + + frame.add(panel); + frame.setBounds(300, 100, 300, 150); + return frame; + } +} diff --git a/test/jdk/java/awt/Cursor/HiddenDialogParentTest/HiddenDialogParentTest.java b/test/jdk/java/awt/Cursor/HiddenDialogParentTest/HiddenDialogParentTest.java new file mode 100644 index 0000000000000..7450f4ec3bb77 --- /dev/null +++ b/test/jdk/java/awt/Cursor/HiddenDialogParentTest/HiddenDialogParentTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 5079694 + * @summary Test if JDialog respects setCursor + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual HiddenDialogParentTest + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Cursor; + +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.border.LineBorder; + +public class HiddenDialogParentTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + You can see a label area in the center of JDialog. + Verify that the cursor is a hand cursor in this area. + If so, press pass, else press fail. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(HiddenDialogParentTest::createUI) + .build() + .awaitAndCheck(); + } + + public static JDialog createUI() { + JDialog dialog = new JDialog(); + dialog.setTitle("JDialog Cursor Test"); + dialog.setLayout(new BorderLayout()); + JLabel centerLabel = new JLabel("Cursor should be a hand in this " + + "label area"); + centerLabel.setBorder(new LineBorder(Color.BLACK)); + centerLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + dialog.add(centerLabel, BorderLayout.CENTER); + dialog.setSize(300, 200); + + return dialog; + } +} diff --git a/test/jdk/java/awt/Cursor/InvalidImageCustomCursorTest/InvalidImageCustomCursorTest.java b/test/jdk/java/awt/Cursor/InvalidImageCustomCursorTest/InvalidImageCustomCursorTest.java new file mode 100644 index 0000000000000..9877df342ec60 --- /dev/null +++ b/test/jdk/java/awt/Cursor/InvalidImageCustomCursorTest/InvalidImageCustomCursorTest.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4212593 + * @summary The Toolkit.createCustomCursor does not check absence of the + * image of cursor + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual InvalidImageCustomCursorTest + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Frame; +import java.awt.Image; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Toolkit; + +public class InvalidImageCustomCursorTest { + static Cursor cursor; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Press 'Hide' button to hide (set transparent) cursor for the + green panel. Move the pointer over the green panel - pointer + should disappear. Press 'Default' button to set default cursor + for the green panel. + + If you see any exceptions or cursor is not transparent, + test failed, otherwise it passed. + """; + + Toolkit tk = Toolkit.getDefaultToolkit(); + Image image = tk.getImage("NON_EXISTING_FILE.gif"); + Point p = new Point(0, 0); + + cursor = tk.createCustomCursor(image, p, "Test"); + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(InvalidImageCustomCursorTest::createUI) + .logArea(5) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame f = new Frame("Invalid Cursor Image Test"); + f.setLayout(new BorderLayout()); + f.setSize(200, 200); + + Button def = new Button("Default"); + Button hide = new Button("Hide"); + Panel panel = new Panel(); + + def.addActionListener(e -> panel.setCursor(Cursor.getDefaultCursor())); + hide.addActionListener(e -> panel.setCursor(cursor)); + + panel.setBackground(Color.green); + panel.setSize(100, 100); + f.add("Center", panel); + f.add("North", hide); + f.add("South", def); + + return f; + } +} diff --git a/test/jdk/java/awt/Cursor/NullCursorTest/NullCursorTest.java b/test/jdk/java/awt/Cursor/NullCursorTest/NullCursorTest.java new file mode 100644 index 0000000000000..c2398a80eb2b2 --- /dev/null +++ b/test/jdk/java/awt/Cursor/NullCursorTest/NullCursorTest.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4111379 + * @summary Test for setting cursor to null for lightweight components + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual NullCursorTest + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Cursor; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class NullCursorTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Hover over each colored area as described: + Green area shows a CrossCursor. + Red area shows a TextCursor. + Yellow area shows a HandCursor. + 2. Click once in red area, then: + Green area shows a HandCursor. + Red area shows a BusyCursor. + Yellow area shows a HandCursor. + 3. Click again in red area, then: + Green area shows a CrossCursor. + Red area shows a HandCursor. + Yellow area shows a HandCursor. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(NullCursorTest::createUI) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame f = new Frame("Null Cursor Test Frame"); + f.setSize(200, 200); + final Container p = f; + p.setName("parent"); + p.setLayout(null); + + final Component green = p.add(new Component() { + public void paint(Graphics g) { + Rectangle r = getBounds(); + g.setColor(Color.green); + g.fillRect(0, 0, r.width, r.height); + } + }); + green.setName("green"); + green.setBackground(Color.red); + green.setBounds(50, 50, 75, 75); + green.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); + + Container h = new Container() { + public void paint(Graphics g) { + Rectangle r = getBounds(); + g.setColor(Color.yellow); + g.fillRect(0, 0, r.width, r.height); + super.paint(g); + } + }; + h.setBounds(15, 25, 150, 150); + h.setName("container"); + h.setBackground(Color.yellow); + h.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + final Component red = new Component() { + public void paint(Graphics g) { + Rectangle r = getBounds(); + Color c = getBackground(); + g.setColor(c); + g.fillRect(0, 0, r.width, r.height); + super.paint(g); + } + }; + red.setName("red"); + red.setBackground(Color.red); + red.setBounds(10, 10, 120, 120); + red.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); + + final Button b = (Button)h.add(new Button("Test")); + b.setBounds(10, 10, 40, 20); + h.add(red); + p.add(h); + + b.addActionListener(new ActionListener() { + boolean f = false; + public void actionPerformed(ActionEvent e) { + if (f) { + b.setCursor(null); + } else { + b.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + f = !f; + } + }); + red.addMouseListener(new MouseAdapter() { + boolean f = true; + + public void mouseClicked(MouseEvent e) { + Component c = (Component)e.getSource(); + if (f) { + c.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + p.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); + green.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + f = false; + } else { + c.setCursor(null); + p.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + green.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); + f = true; + } + } + }); + return f; + } +} From ebd77db105289d3ce3438686e846980f7959762c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 14 Mar 2025 12:59:43 +0000 Subject: [PATCH 051/846] 8340713: Open source DnD tests - Set5 Backport-of: fc7244da96a9423146c4a46bcc3bbfc205900c3b --- test/jdk/ProblemList.txt | 3 + .../java/awt/dnd/DragExitBeforeDropTest.java | 257 ++++++++++++++++++ test/jdk/java/awt/dnd/DragThresholdTest.java | 134 +++++++++ .../java/awt/dnd/WinMoveFileToShellTest.java | 131 +++++++++ 4 files changed, 525 insertions(+) create mode 100644 test/jdk/java/awt/dnd/DragExitBeforeDropTest.java create mode 100644 test/jdk/java/awt/dnd/DragThresholdTest.java create mode 100644 test/jdk/java/awt/dnd/WinMoveFileToShellTest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 66d367107d5a9..b999b76a51354 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -127,6 +127,8 @@ java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java 8060176 java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java 8060176 windows-all,macosx-all java/awt/dnd/MissingEventsOnModalDialog/MissingEventsOnModalDialogTest.java 8164464 linux-all,macosx-all java/awt/dnd/URIListBetweenJVMsTest/URIListBetweenJVMsTest.java 8171510 macosx-all +java/awt/dnd/DragExitBeforeDropTest.java 8242805 macosx-all +java/awt/dnd/DragThresholdTest.java 8076299 macosx-all java/awt/Focus/ChoiceFocus/ChoiceFocus.java 8169103 windows-all,macosx-all java/awt/Focus/ClearLwQueueBreakTest/ClearLwQueueBreakTest.java 8198618 macosx-all java/awt/Focus/ConsumeNextKeyTypedOnModalShowTest/ConsumeNextKeyTypedOnModalShowTest.java 6986252 macosx-all @@ -828,6 +830,7 @@ java/awt/Focus/AppletInitialFocusTest/AppletInitialFocusTest1.java 8256289 windo java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java 8258103 linux-all java/awt/Focus/FrameMinimizeTest/FrameMinimizeTest.java 8016266 linux-x64 java/awt/Frame/SizeMinimizedTest.java 8305915 linux-x64 +java/awt/dnd/WinMoveFileToShellTest.java 8341665 windows-all ############################################################################ diff --git a/test/jdk/java/awt/dnd/DragExitBeforeDropTest.java b/test/jdk/java/awt/dnd/DragExitBeforeDropTest.java new file mode 100644 index 0000000000000..2ef778a18ba46 --- /dev/null +++ b/test/jdk/java/awt/dnd/DragExitBeforeDropTest.java @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetContext; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/* + * @test + * @bug 4395290 + * @key headful + * @summary tests that dragExit() is not called before drop() + */ + +public class DragExitBeforeDropTest { + private static Frame frame; + private static final DragSourceButton dragSourceButton = new DragSourceButton(); + private static final DropTargetPanel dropTargetPanel = new DropTargetPanel(); + private static volatile Point srcPoint; + private static volatile Point dstPoint; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + EventQueue.invokeAndWait(DragExitBeforeDropTest::createAndShowUI); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + Point p = dragSourceButton.getLocationOnScreen(); + Dimension d = dragSourceButton.getSize(); + p.translate(d.width / 2, d.height / 2); + srcPoint = p; + + p = dropTargetPanel.getLocationOnScreen(); + d = dropTargetPanel.getSize(); + p.translate(d.width / 2, d.height / 2); + dstPoint = p; + }); + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (; !srcPoint.equals(dstPoint); + srcPoint.translate(sign(dstPoint.x - srcPoint.x), + sign(dstPoint.y - srcPoint.y))) { + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.delay(10); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + robot.waitForIdle(); + robot.delay(1000); + + if (!dropTargetPanel.getStatus()) { + throw new RuntimeException("The test failed: dragExit()" + + " is called before drop()"); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + frame = new Frame("DragExitBeforeDropTest"); + frame.setLayout(new GridLayout(2, 1)); + frame.add(dragSourceButton); + frame.add(dropTargetPanel); + frame.setLocationRelativeTo(null); + frame.setSize(300, 400); + frame.setVisible(true); + } + + public static int sign(int n) { + return Integer.compare(n, 0); + } + + private static class DragSourceButton extends Button implements Serializable, + Transferable, + DragGestureListener, + DragSourceListener { + private final DataFlavor dataflavor = + new DataFlavor(Button.class, "DragSourceButton"); + + public DragSourceButton() { + this("DragSourceButton"); + } + + public DragSourceButton(String str) { + super(str); + + DragSource ds = DragSource.getDefaultDragSource(); + ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, + this); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, this, this); + } + + public void dragEnter(DragSourceDragEvent dsde) {} + + public void dragExit(DragSourceEvent dse) {} + + public void dragOver(DragSourceDragEvent dsde) {} + + public void dragDropEnd(DragSourceDropEvent dsde) {} + + public void dropActionChanged(DragSourceDragEvent dsde) {} + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, IOException { + + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } + + Object retObj; + + ByteArrayOutputStream baoStream = new ByteArrayOutputStream(); + ObjectOutputStream ooStream = new ObjectOutputStream(baoStream); + ooStream.writeObject(this); + + ByteArrayInputStream baiStream = + new ByteArrayInputStream(baoStream.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(baiStream); + try { + retObj = ois.readObject(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + throw new RuntimeException(e.toString()); + } + + return retObj; + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { dataflavor }; + } + + public boolean isDataFlavorSupported(DataFlavor dflavor) { + return dataflavor.equals(dflavor); + } + } + + private static class DropTargetPanel extends Panel implements DropTargetListener { + + final Dimension preferredDimension = new Dimension(200, 100); + volatile boolean testPassed = true; + + public DropTargetPanel() { + setDropTarget(new DropTarget(this, this)); + } + + public boolean getStatus() { + return testPassed; + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragEnter(DropTargetDragEvent dtde) {} + + public void dragExit(DropTargetEvent dte) { + testPassed = false; + } + + public void dragOver(DropTargetDragEvent dtde) {} + + public void dropActionChanged(DropTargetDragEvent dtde) {} + + public void drop(DropTargetDropEvent dtde) { + DropTargetContext dtc = dtde.getDropTargetContext(); + + if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY) != 0) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + } else { + dtde.rejectDrop(); + } + + DataFlavor[] dfs = dtde.getCurrentDataFlavors(); + Component comp = null; + + if(dfs != null && dfs.length >= 1) { + Transferable transfer = dtde.getTransferable(); + + try { + comp = (Component)transfer.getTransferData(dfs[0]); + } catch (Throwable e) { + e.printStackTrace(); + dtc.dropComplete(false); + } + } + dtc.dropComplete(true); + add(comp); + } + } +} + + + diff --git a/test/jdk/java/awt/dnd/DragThresholdTest.java b/test/jdk/java/awt/dnd/DragThresholdTest.java new file mode 100644 index 0000000000000..bcb3bbf91c2ce --- /dev/null +++ b/test/jdk/java/awt/dnd/DragThresholdTest.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; + +/* + @test + @key headful + @bug 4415175 + @summary tests DragSource.getDragThreshold() and + that the AWT default drag gesture recognizers + honor the drag gesture motion threshold +*/ + +public class DragThresholdTest { + private static Frame frame; + private static Panel panel; + private static MouseEvent lastMouseEvent; + private static volatile boolean failed; + private static volatile Point startPoint; + private static volatile Point endPoint; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + + EventQueue.invokeAndWait(DragThresholdTest::createAndShowDnD); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + Point p = panel.getLocationOnScreen(); + p.translate(50, 50); + startPoint = p; + endPoint = new Point(p.x + 2 * DragSource.getDragThreshold(), + p.y + 2 * DragSource.getDragThreshold()); + }); + + robot.mouseMove(startPoint.x, startPoint.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (Point p = new Point(startPoint); !p.equals(endPoint); + p.translate(sign(endPoint.x - p.x), + sign(endPoint.y - p.y))) { + robot.mouseMove(p.x, p.y); + robot.delay(100); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.delay(200); + + if (failed) { + throw new RuntimeException("drag gesture recognized too early"); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createAndShowDnD() { + frame = new Frame("DragThresholdTest"); + panel = new Panel(); + // Mouse motion listener mml is added to the panel first. + // We rely on it that this listener will be called first. + panel.addMouseMotionListener(new MouseMotionAdapter() { + public void mouseDragged(MouseEvent evt) { + lastMouseEvent = evt; + System.out.println(evt); + } + }); + frame.add(panel); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + + DragGestureListener dgl = dge -> { + Point dragOrigin = dge.getDragOrigin(); + int diffx = Math.abs(dragOrigin.x - lastMouseEvent.getX()); + int diffy = Math.abs(dragOrigin.y - lastMouseEvent.getY()); + System.out.println("dragGestureRecognized(): " + + " diffx=" + diffx + " diffy=" + diffy + + " DragSource.getDragThreshold()=" + + DragSource.getDragThreshold()); + if (diffx <= DragSource.getDragThreshold() && + diffy <= DragSource.getDragThreshold()) { + failed = true; + System.out.println("drag gesture recognized too early!"); + } + }; + + // Default drag gesture recognizer is a mouse motion listener. + // It is added to the panel second. + new DragSource().createDefaultDragGestureRecognizer( + panel, + DnDConstants.ACTION_COPY_OR_MOVE, dgl); + frame.setVisible(true); + } + + private static int sign(int n) { + return Integer.compare(n, 0); + } +} diff --git a/test/jdk/java/awt/dnd/WinMoveFileToShellTest.java b/test/jdk/java/awt/dnd/WinMoveFileToShellTest.java new file mode 100644 index 0000000000000..5ae7dd3890d71 --- /dev/null +++ b/test/jdk/java/awt/dnd/WinMoveFileToShellTest.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Frame; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceListener; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/* + * @test + * @bug 4414739 + * @requires (os.family == "windows") + * @summary verifies that getDropSuccess() returns correct value for moving + a file from a Java drag source to the Windows shell + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual WinMoveFileToShellTest + */ + +public class WinMoveFileToShellTest { + private static final String INSTRUCTIONS = """ + Drag from the frame titled "Drag Frame" and drop on to Windows Desktop. + After Drag and Drop, check for "Drop Success" status in the log area. + If "Drop Success" is true press PASS else FAIL. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(WinMoveFileToShellTest::createAndShowUI) + .logArea(5) + .build() + .awaitAndCheck(); + } + + private static Frame createAndShowUI() { + Frame frame = new Frame("Drag Frame"); + final DragSourceListener dsl = new DragSourceAdapter() { + public void dragDropEnd(DragSourceDropEvent e) { + PassFailJFrame.log("Drop Success: " + e.getDropSuccess()); + } + }; + + DragGestureListener dgl = dge -> { + File file = new File(System.getProperty("test.classes", ".") + + File.separator + "move.me"); + try { + file.createNewFile(); + } catch (IOException exc) { + exc.printStackTrace(); + } + ArrayList list = new ArrayList<>(); + list.add(file); + dge.startDrag(null, new FileListSelection(list), dsl); + }; + + new DragSource().createDefaultDragGestureRecognizer(frame, + DnDConstants.ACTION_MOVE, dgl); + frame.setSize(200, 100); + return frame; + } + + private static class FileListSelection implements Transferable { + private static final int FL = 0; + + private static final DataFlavor[] flavors = + new DataFlavor[] { DataFlavor.javaFileListFlavor }; + + + private List data; + + public FileListSelection(List data) { + this.data = data; + } + + public DataFlavor[] getTransferDataFlavors() { + return flavors.clone(); + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + for (DataFlavor dataFlavor : flavors) { + if (flavor.equals(dataFlavor)) { + return true; + } + } + return false; + } + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, IOException + { + if (flavor.equals(flavors[FL])) { + return data; + } else { + throw new UnsupportedFlavorException(flavor); + } + } + } +} From 7bf2d44f531c8c127b372167b67c1d40db539586 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Sat, 15 Mar 2025 03:21:02 +0000 Subject: [PATCH 052/846] 8276995: Bug in jdk.jfr.event.gc.collection.TestSystemGC Backport-of: 91ce41f96d725a02f9566f87133ed64d448c80cc --- test/jdk/jdk/jfr/event/gc/collection/TestSystemGC.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestSystemGC.java b/test/jdk/jdk/jfr/event/gc/collection/TestSystemGC.java index 05b6aa45b8c38..baba7175860a6 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestSystemGC.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestSystemGC.java @@ -68,12 +68,12 @@ public static void main(String[] args) throws Exception { RecordedEvent event2 = events.get(1); Events.assertFrame(event2, Runtime.class, "gc"); Events.assertEventThread(event2, Thread.currentThread()); - Events.assertField(event1, "invokedConcurrent").isEqual(concurrent); + Events.assertField(event2, "invokedConcurrent").isEqual(concurrent); RecordedEvent event3 = events.get(2); // MemoryMXBean.class is an interface so can't assertFrame on it Events.assertEventThread(event3, Thread.currentThread()); - Events.assertField(event1, "invokedConcurrent").isEqual(concurrent); + Events.assertField(event3, "invokedConcurrent").isEqual(concurrent); } } } From 3a2a539915303161586d015a410e5621437a4e94 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Sat, 15 Mar 2025 20:20:21 +0000 Subject: [PATCH 053/846] 8340173: Open source some Component/Panel/EventQueue tests - Set2 Backport-of: 97ee8bbda2c7d7f76866690a34a5021fade2f438 --- test/jdk/ProblemList.txt | 1 + .../PushPopDeadlock/PushPopDeadlock.java | 97 ++++ .../MultipleAddNotifyTest.java | 118 +++++ .../PopupTest/PopupTest.java | 93 ++++ .../awt/Panel/PanelRepaint/PanelRepaint.java | 455 ++++++++++++++++++ 5 files changed, 764 insertions(+) create mode 100644 test/jdk/java/awt/EventQueue/PushPopDeadlock/PushPopDeadlock.java create mode 100644 test/jdk/java/awt/LightweightComponent/MultipleAddNotifyTest/MultipleAddNotifyTest.java create mode 100644 test/jdk/java/awt/LightweightComponent/PopupTest/PopupTest.java create mode 100644 test/jdk/java/awt/Panel/PanelRepaint/PanelRepaint.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index b999b76a51354..d7afa45a57db9 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -142,6 +142,7 @@ java/awt/Focus/TestDisabledAutoTransferSwing.java 6962362 windows-all java/awt/Focus/ActivateOnProperAppContextTest.java 8136516 macosx-all java/awt/event/KeyEvent/CorrectTime/CorrectTime.java 6626492 generic-all java/awt/EventQueue/6980209/bug6980209.java 8198615 macosx-all +java/awt/EventQueue/PushPopDeadlock/PushPopDeadlock.java 8024034 generic-all java/awt/grab/EmbeddedFrameTest1/EmbeddedFrameTest1.java 7080150 macosx-all java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java 8168646 generic-all java/awt/KeyboardFocusmanager/TypeAhead/TestDialogTypeAhead.java 8198626 macosx-all diff --git a/test/jdk/java/awt/EventQueue/PushPopDeadlock/PushPopDeadlock.java b/test/jdk/java/awt/EventQueue/PushPopDeadlock/PushPopDeadlock.java new file mode 100644 index 0000000000000..82ca54871848e --- /dev/null +++ b/test/jdk/java/awt/EventQueue/PushPopDeadlock/PushPopDeadlock.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4212687 + * @summary Verifies that calling EventQueue.push() and EventQueue.pop() + * does not deadlock. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual PushPopDeadlock + */ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Robot; +import java.awt.Toolkit; + +public class PushPopDeadlock { + static int counter = 0; + static Robot robot; + static Frame f; + static Label l; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + String INSTRUCTIONS = """ + Click rapidly in the Frame labeled 'Click Here!'. + The number in the Frame should continue to increase. If the number + stops increasing (remains at a constant value), the test fails. + """; + + PassFailJFrame pfJFrame = PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(PushPopDeadlock::createUI) + .build(); + PushPopDeadlock.test(); + pfJFrame.awaitAndCheck(); + } + + public static Frame createUI() { + f = new Frame("Click Here!"); + l = new Label("Counter: " + counter); + f.add(l); + f.setSize(200, 200); + return f; + } + + public static void test() { + EventQueue q = new EventQueue() { + public void push(EventQueue queue) { + super.push(queue); + pop(); + } + }; + EventQueue q2 = new EventQueue(); + + Toolkit.getDefaultToolkit().getSystemEventQueue().push(q); + + new Thread(() -> { + while (true) { + robot.delay(500); + l.setText("Counter: " + ++counter); + q.push(q2); + try { + Thread.currentThread().sleep(500); + } catch (InterruptedException e) { + return; + } + } + }).start(); + } +} diff --git a/test/jdk/java/awt/LightweightComponent/MultipleAddNotifyTest/MultipleAddNotifyTest.java b/test/jdk/java/awt/LightweightComponent/MultipleAddNotifyTest/MultipleAddNotifyTest.java new file mode 100644 index 0000000000000..fbbc2ae61854a --- /dev/null +++ b/test/jdk/java/awt/LightweightComponent/MultipleAddNotifyTest/MultipleAddNotifyTest.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4058400 + * @summary Tests that calling addNotify on a lightweight component more than + * once does not break event dispatching for that component. + * @key headful + * @run main MultipleAddNotifyTest + */ + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class MultipleAddNotifyTest { + static volatile boolean passFlag; + static volatile int posX; + static volatile int posY; + static Frame f; + static LightComponent l; + + public static void main(String[] args) throws Exception { + Robot r; + try { + r = new Robot(); + r.setAutoWaitForIdle(true); + passFlag = false; + + EventQueue.invokeAndWait(() -> { + f = new Frame("Multiple addNotify Test"); + l = new LightComponent(); + f.setLayout(new FlowLayout()); + l.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + System.out.println("Mouse Clicked"); + passFlag = true; + } + }); + f.add(l); + f.addNotify(); + f.addNotify(); + + if (!l.isVisible()) { + throw new RuntimeException("Test failed. LW Component " + + "not visible."); + } + f.setSize(200, 200); + f.setLocationRelativeTo(null); + f.setVisible(true); + }); + r.waitForIdle(); + r.delay(1000); + + EventQueue.invokeAndWait(() -> { + posX = f.getX() + l.getWidth() + (l.getWidth() / 2); + posY = f.getY() + l.getHeight(); + }); + + r.mouseMove(posX, posY); + r.delay(500); + + r.mousePress(InputEvent.BUTTON1_DOWN_MASK); + r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + r.delay(500); + + if (!passFlag) { + throw new RuntimeException("Test failed. MouseClicked event " + + "not working properly."); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } +} + +class LightComponent extends Component { + public void paint(Graphics g) { + setSize(100, 100); + Dimension d = getSize(); + g.setColor(Color.red); + g.fillRect(0, 0, d.width, d.height); + } +} diff --git a/test/jdk/java/awt/LightweightComponent/PopupTest/PopupTest.java b/test/jdk/java/awt/LightweightComponent/PopupTest/PopupTest.java new file mode 100644 index 0000000000000..beae4b4d9042e --- /dev/null +++ b/test/jdk/java/awt/LightweightComponent/PopupTest/PopupTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4476083 + * @summary Disabled components do not receive MouseEvent in Popups + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual PopupTest + */ + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Frame; + +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; + +public class PopupTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + PopupMenus should disappear when a disabled component is + clicked. + + Step 1. Pop down the popup menu by clicking on it. + Step 2. Click on the disabled component to make the menu + disappear. + + If the menu disappears when the disabled component is clicked, + the test passes, otherwise, the test fails. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(PopupTest::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + Frame f = new Frame("Disabled Component in Popup Test"); + f.setLayout(new BorderLayout()); + + JButton b = new JButton("step 1: press me to display menu"); + b.addActionListener(e -> { + JPopupMenu m = new JPopupMenu(); + m.add(new JMenuItem("item 1")); + m.add(new JMenuItem("item 2")); + m.add(new JMenuItem("item 3")); + m.add(new JMenuItem("item 4")); + m.add(new JMenuItem("item 5")); + m.add(new JMenuItem("item 6")); + m.show((Component) e.getSource(), 0, 10); + }); + + JLabel disabled = new JLabel("step 2: click me. the menu should be " + + "dismissed"); + disabled.setEnabled(false); + + JLabel enabled = new JLabel("step 3: there is no step 3"); + + f.add(BorderLayout.NORTH, b); + f.add(BorderLayout.CENTER, disabled); + f.add(BorderLayout.SOUTH, enabled); + f.setSize(300, 200); + return f; + } +} diff --git a/test/jdk/java/awt/Panel/PanelRepaint/PanelRepaint.java b/test/jdk/java/awt/Panel/PanelRepaint/PanelRepaint.java new file mode 100644 index 0000000000000..da8de3947be9a --- /dev/null +++ b/test/jdk/java/awt/Panel/PanelRepaint/PanelRepaint.java @@ -0,0 +1,455 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4148078 + * @summary Repainting problems in scrolled panel + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual PanelRepaint + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Scrollbar; +import java.awt.TextField; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; + +public class PanelRepaint extends Panel implements FocusListener { + static ScrollPanel sPanel; + static Panel panel; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Using scrollbars or tab keys to scroll the panel and + the panel is messy sometimes, e.g. one row bumps into + another. If all components painted correctly, the test passes. + Otherwise, the test fails. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(PanelRepaint::createUI) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame f = new Frame("Panel Repaint Test"); + f.setLayout(new FlowLayout()); + f.setSize(620, 288); + PanelRepaint pr = new PanelRepaint(); + + panel = new Panel(); + panel.setLayout(null); + panel.setSize(500, 500); + sPanel = new ScrollPanel(panel); + + Button btn = new Button("Open"); + pr.addComp(btn); + btn.setBounds(400, 10, 60, 20); + btn.setActionCommand("OPEN"); + + Button btn1 = new Button("Close"); + pr.addComp(btn1); + btn1.setBounds(400, 50, 60, 20); + btn1.setActionCommand("CLOSE"); + + TextField t1 = new TextField("1"); + pr.addComp(t1); + t1.setBounds(10, 10, 100, 20); + TextField t2 = new TextField("2"); + pr.addComp(t2); + t2.setBounds(10, 50, 100, 20); + TextField t3 = new TextField("3"); + pr.addComp(t3); + t3.setBounds(10, 90, 100, 20); + TextField t4 = new TextField("4"); + pr.addComp(t4); + t4.setBounds(10, 130, 100, 20); + TextField t5 = new TextField("5"); + pr.addComp(t5); + t5.setBounds(10, 170, 100, 20); + TextField t6 = new TextField("6"); + pr.addComp(t6); + t6.setBounds(10, 210, 100, 20); + TextField t7 = new TextField("7"); + pr.addComp(t7); + t7.setBounds(10, 250, 100, 20); + TextField t8 = new TextField("8"); + pr.addComp(t8); + t8.setBounds(10, 290, 100, 20); + TextField t9 = new TextField("9"); + pr.addComp(t9); + t9.setBounds(10, 330, 100, 20); + + TextField t11 = new TextField("1"); + pr.addComp(t11); + t11.setBounds(120, 10, 100, 20); + TextField t12 = new TextField("2"); + pr.addComp(t12); + t12.setBounds(120, 50, 100, 20); + TextField t13 = new TextField("3"); + pr.addComp(t13); + t13.setBounds(120, 90, 100, 20); + TextField t14 = new TextField("4"); + pr.addComp(t14); + t14.setBounds(120, 130, 100, 20); + TextField t15 = new TextField("5"); + pr.addComp(t15); + t15.setBounds(120, 170, 100, 20); + TextField t16 = new TextField("6"); + pr.addComp(t16); + t16.setBounds(120, 210, 100, 20); + TextField t17 = new TextField("7"); + pr.addComp(t17); + t17.setBounds(120, 250, 100, 20); + TextField t18 = new TextField("8"); + pr.addComp(t18); + t18.setBounds(120, 290, 100, 20); + TextField t19 = new TextField("9"); + pr.addComp(t19); + t19.setBounds(120, 330, 100, 20); + + + TextField t21 = new TextField("1"); + pr.addComp(t21); + t21.setBounds(240, 10, 100, 20); + TextField t22 = new TextField("2"); + pr.addComp(t22); + t22.setBounds(240, 50, 100, 20); + TextField t23 = new TextField("3"); + pr.addComp(t23); + t23.setBounds(240, 90, 100, 20); + TextField t24 = new TextField("4"); + pr.addComp(t24); + t24.setBounds(240, 130, 100, 20); + TextField t25 = new TextField("5"); + pr.addComp(t25); + t25.setBounds(240, 170, 100, 20); + TextField t26 = new TextField("6"); + pr.addComp(t26); + t26.setBounds(240, 210, 100, 20); + TextField t27 = new TextField("7"); + pr.addComp(t27); + t27.setBounds(240, 250, 100, 20); + TextField t28 = new TextField("8"); + pr.addComp(t28); + t28.setBounds(240, 290, 100, 20); + TextField t29 = new TextField("9"); + pr.addComp(t29); + t29.setBounds(240, 330, 100, 20); + + pr.add(sPanel); + f.add(pr); + sPanel.setBounds(100, 100, 500, 250); + sPanel.doLayout(); + return f; + } + + public void addComp(Component c) { + panel.add(c); + c.addFocusListener(this); + } + + public void focusGained(FocusEvent e) { + sPanel.showComponent(e.getComponent()); + } + + public void focusLost(FocusEvent e) { + } +} + +class ScrollPanel extends Panel implements AdjustmentListener { + /** + * Constructor + */ + public ScrollPanel(Component c) { + setLayout(null); + setBackground(Color.lightGray); + add(hScroll = new Scrollbar(Scrollbar.HORIZONTAL)); + add(vScroll = new Scrollbar(Scrollbar.VERTICAL)); + add(square = new Panel()); + square.setBackground(Color.lightGray); + add(c); + } + + /** + * Scroll up/down/left/right to show the component specified + * + * @param comp is the component to be shown + */ + public void showComponent(Component comp) { + Component view = getComponent(3); + Rectangle viewRect = view.getBounds(); + Rectangle scrollRect = getBounds(); + Rectangle rect = comp.getBounds(); + while (comp != null) { + Component parent = comp.getParent(); + if (parent == null || parent == view) { + break; + } + Point p = parent.getLocation(); + rect.x += p.x; + rect.y += p.y; + comp = parent; + } + + int i = viewRect.y + rect.y; + int j = (viewRect.y + rect.y + rect.height + ScrollPanel.H_HEIGHT) + - (scrollRect.height); + + if (i < 0) { + vertUpdate(i); + } else if (j > 0) { + vertUpdate(j); + } + + i = viewRect.x + rect.x; + j = (viewRect.x + rect.x + rect.width + (V_WIDTH * 2)) - (scrollRect.width); + + if (i < 0) { + horzUpdate(i); + } else if (j > 0) { + horzUpdate(j); + } + } + + /** + * Returns the panel component of ScrollPanel + * + * @return the panel component of ScrollPanel + */ + public Component getScrolled() { + return getComponent(3); + } + + /** + * updates the scroll panel vertically with value i passed + * + * @param i the value to be updated with + */ + public void vertUpdate(int i) { + update(true, vScroll.getValue() + i); + } + + /** + * updates the scroll panel horizontally with value i passed + * + * @param i the value to be updated with + */ + public void horzUpdate(int i) { + update(false, hScroll.getValue() + i); + } + + /** + * updates the scroll panel vertically if bVert is true else horizontally + * + * @param n is the value + */ + public void update(boolean bVert, int n) { + if (n < 0) n = 0; + if (bVert) { + if (n > max.height) { + n = max.height; + } + if (offset.y != n) { + offset.y = n; + vScroll.setValue(n); + } + } else { + if (n > max.width) { + n = max.width; + } + if (offset.x != n) { + offset.x = n; + hScroll.setValue(n); + } + } + getScrolled().setLocation(-offset.x, -offset.y); + } + + /** + * Implementation of AdjustmentListener + */ + public void adjustmentValueChanged(AdjustmentEvent e) { + boolean bVert = e.getSource() == vScroll; + update(bVert, e.getValue()); + } + + /** + * Reimplementation of Component Methods + */ + public void addNotify() { + super.addNotify(); + vScroll.addAdjustmentListener(this); + hScroll.addAdjustmentListener(this); + } + + public void removeNotify() { + super.removeNotify(); + vScroll.removeAdjustmentListener(this); + hScroll.removeAdjustmentListener(this); + } + + public void setBounds(int x, int y, int w, int h) { + super.setBounds(x, y, w, h); + doLayout(); + } + + public void doLayout() { + Component c = getScrolled(); + Dimension d = c.getSize(); + if (d.width == 0 || d.height == 0) { + d = c.getPreferredSize(); + } + vert = 0; + horz = 0; + Dimension m = getSize(); + if (d.height > m.height || isScroll(true, m.height - horz, 0, d.height)) { + vert = V_WIDTH; + } + if (d.width + vert > m.width || isScroll(false, m.width - vert, 0, d.width)) { + horz = H_HEIGHT; + } + if (d.height + horz > m.height || isScroll(true, m.height - horz, 0, d.height)) { + vert = V_WIDTH; + } + if (d.width + vert > m.width || isScroll(false, m.width - vert, 0, d.width)) { + horz = H_HEIGHT; + } + if (horz != 0) { + if (m.width <= 0) { + m.width = 1; + } + hScroll.setBounds(0, m.height - H_HEIGHT, m.width - vert, H_HEIGHT); + hScroll.setValues(offset.x, m.width - vert, 0, d.width); + int i = d.width / 10; + if (i < 2) { + i = 2; + } + hScroll.setBlockIncrement(i); + i = d.width / 50; + if (i < 1) { + i = 1; + } + hScroll.setUnitIncrement(i); + max.width = d.width; + hScroll.setVisible(true); + } else { + offset.x = 0; + } + if (vert != 0) { + if (m.height <= 0) { + m.height = 1; + } + vScroll.setBounds(m.width - V_WIDTH, 0, V_WIDTH, m.height - horz); + vScroll.setValues(offset.y, m.height - horz, 0, d.height); + int i = d.height / 10; + if (i < 2) i = 2; + vScroll.setBlockIncrement(i); + i = d.height / 50; + if (i < 1) i = 1; + vScroll.setUnitIncrement(i); + max.height = d.height; + vScroll.setVisible(true); + } else { + offset.y = 0; + } + if (horz != 0 && vert != 0) { + square.setBounds(m.width - V_WIDTH, m.height - H_HEIGHT, V_WIDTH, H_HEIGHT); + square.setVisible(true); + } else { + square.setVisible(false); + } + c.setBounds(-offset.x, -offset.y, d.width, d.height); + c.repaint(); + updateScroll(true, offset.y); + updateScroll(false, offset.x); + } + + public Dimension getPreferredSize() { + return getScrolled().getPreferredSize(); + } + + public Dimension getMinimumSize() { + return getScrolled().getMinimumSize(); + } + + boolean isScroll(boolean bVert, int visible, int min, int max) { + int tot = max - min; + int net = tot - visible; + if (net <= 0) { + return false; + } + return true; + } + + void updateScroll(boolean bVert, int n) { + Component c = getScrolled(); + Dimension d = c.getSize(); + Dimension m = getSize(); + m.width -= vert; + m.height -= horz; + if (bVert) { + if (n >= 0 && d.height > m.height) { + if (n + m.height > d.height) + n = d.height - m.height; + } else + n = 0; + update(true, n); + } else { + if (n >= 0 && d.width > m.width) { + if (n + m.width > d.width) + n = d.width - m.width; + } else + n = 0; + update(false, n); + } + } + + static Scrollbar hScroll; + static Scrollbar vScroll; + static int vert = 0; + static int horz = 0; + + static Point offset = new Point(); + static Dimension max = new Dimension(); + // ScrollTimer timer; + static Component square; + final static int V_WIDTH = 17; + final static int H_HEIGHT = 17; +} From fd50c1722380ce419bd5ac7f1318d1a808f87ec5 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Sat, 15 Mar 2025 20:21:19 +0000 Subject: [PATCH 054/846] 8340790: Open source several AWT Dialog tests - Batch 4 Backport-of: 6d7e67956b1722b4e3d33253d68c095058f39f02 --- test/jdk/ProblemList.txt | 1 + .../awt/Dialog/ChoiceModalDialogTest.java | 140 ++++++++++++++++ .../java/awt/Dialog/DialogBackgroundTest.java | 153 ++++++++++++++++++ .../jdk/java/awt/Dialog/EnabledResetTest.java | 145 +++++++++++++++++ .../awt/Dialog/FileDialogGetFileTest.java | 78 +++++++++ 5 files changed, 517 insertions(+) create mode 100644 test/jdk/java/awt/Dialog/ChoiceModalDialogTest.java create mode 100644 test/jdk/java/awt/Dialog/DialogBackgroundTest.java create mode 100644 test/jdk/java/awt/Dialog/EnabledResetTest.java create mode 100644 test/jdk/java/awt/Dialog/FileDialogGetFileTest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index d7afa45a57db9..b75d0260efd6c 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -485,6 +485,7 @@ java/awt/KeyboardFocusmanager/ConsumeNextMnemonicKeyTypedTest/ConsumeNextMnemoni java/awt/Window/GetScreenLocation/GetScreenLocationTest.java 8225787 linux-x64 java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 8266243 macosx-aarch64 +java/awt/Dialog/ChoiceModalDialogTest.java 8161475 macosx-all # Wayland related diff --git a/test/jdk/java/awt/Dialog/ChoiceModalDialogTest.java b/test/jdk/java/awt/Dialog/ChoiceModalDialogTest.java new file mode 100644 index 0000000000000..97ce5a83a96b7 --- /dev/null +++ b/test/jdk/java/awt/Dialog/ChoiceModalDialogTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6213128 + * @key headful + * @summary Tests that choice is releasing input capture when a modal + * dialog is shown + * @run main ChoiceModalDialogTest + */ + +import java.awt.Choice; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.TextField; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class ChoiceModalDialogTest { + static Frame f; + static Dialog d; + static volatile boolean keyOK; + static volatile boolean mouseOK; + static TextField tf; + static Choice c; + + public static void main(String[] args) throws Exception { + Robot r; + try { + r = new Robot(); + r.setAutoDelay(100); + EventQueue.invokeAndWait(() -> { + f = new Frame("Frame"); + c = new Choice(); + f.setBounds(100, 300, 300, 200); + f.setLayout(new FlowLayout()); + tf = new TextField(3); + f.add(tf); + + c.add("1"); + c.add("2"); + c.add("3"); + c.add("4"); + f.add(c); + + tf.addFocusListener(new FocusAdapter() { + public void focusLost(FocusEvent ev) { + d = new Dialog(f, "Dialog", true); + d.setBounds(300, 300, 200, 150); + d.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent ev) { + keyOK = true; + } + }); + d.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent ev) { + mouseOK = true; + } + }); + d.setVisible(true); + } + }); + + f.setVisible(true); + f.toFront(); + }); + r.waitForIdle(); + r.delay(1000); + EventQueue.invokeAndWait(() -> { + r.mouseMove(tf.getLocationOnScreen().x + tf.getSize().width / 2, + tf.getLocationOnScreen().y + tf.getSize().height / 2); + }); + r.waitForIdle(); + r.delay(500); + EventQueue.invokeAndWait(() -> { + r.mouseMove(c.getLocationOnScreen().x + c.getSize().width - 4, + c.getLocationOnScreen().y + c.getSize().height / 2); + r.mousePress(InputEvent.BUTTON1_DOWN_MASK); + r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + }); + r.waitForIdle(); + r.delay(500); + EventQueue.invokeAndWait(() -> { + r.mouseMove(d.getLocationOnScreen().x + d.getSize().width / 2, + d.getLocationOnScreen().y + d.getSize().height / 2); + r.mousePress(InputEvent.BUTTON1_DOWN_MASK); + r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + r.keyPress(KeyEvent.VK_A); + r.keyRelease(KeyEvent.VK_A); + }); + r.waitForIdle(); + r.delay(500); + if (!mouseOK) { + throw new RuntimeException("Test Failed due to Mouse release failure!"); + } + if (!keyOK) { + throw new RuntimeException("Test Failed due to Key release failure!"); + } + System.out.println("Test Passed!"); + } finally { + EventQueue.invokeAndWait(() -> { + if (d != null) { + d.dispose(); + } + if (f != null) { + f.dispose(); + } + }); + } + } +} diff --git a/test/jdk/java/awt/Dialog/DialogBackgroundTest.java b/test/jdk/java/awt/Dialog/DialogBackgroundTest.java new file mode 100644 index 0000000000000..793782fc43be8 --- /dev/null +++ b/test/jdk/java/awt/Dialog/DialogBackgroundTest.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4255230 4191946 + * @summary Tests to verify Dialog inherits background from its owner + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DialogBackgroundTest + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.Dialog; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.TextField; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class DialogBackgroundTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Perform the following steps: + 1) Select "New Frame" from the "File" menu of the + "TreeCopy Frame #1" frame. + 2) Select "Configure" from the "File" menu in the + *new* frame. + If label text "This is a label:" in the appeared + "Configuration Dialog" dialog has a grey background + test PASSES, otherwise it FAILS + """; + TreeCopy treeCopy = new TreeCopy(++TreeCopy.windowCount, null); + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(treeCopy) + .logArea(8) + .build() + .awaitAndCheck(); + } +} + +class TreeCopy extends Frame implements ActionListener { + TextField tfRoot; + ConfigDialog configDlg; + MenuItem miConfigure = new MenuItem("Configure..."); + MenuItem miNewWindow = new MenuItem("New Frame"); + static int windowCount = 0; + Window parent; + + public TreeCopy(int windowNum, Window myParent) { + super(); + setTitle("TreeCopy Frame #" + windowNum); + MenuBar mb = new MenuBar(); + Menu m = new Menu("File"); + configDlg = new ConfigDialog(this); + parent = myParent; + + m.add(miConfigure); + m.add(miNewWindow); + miConfigure.addActionListener(this); + miNewWindow.addActionListener(this); + mb.add(m); + setMenuBar(mb); + m.addActionListener(this); + + tfRoot = new TextField(); + tfRoot.setEditable(false); + add(tfRoot); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent we) { + dispose(); + } + }); + + setSize(200, 100); + setLocationRelativeTo(parent); + } + + public void actionPerformed(ActionEvent ae) { + Object source = ae.getSource(); + + if (source == miConfigure) { + configDlg.setVisible(true); + if (configDlg.getBackground() != configDlg.labelColor) + PassFailJFrame.log("FAIL: Test failed!!!"); + } else if (source == miNewWindow) { + new TreeCopy(++windowCount, this).setVisible(true); + } + } +} + +class ConfigDialog extends Dialog implements ActionListener { + public Button okButton; + public Button cancelButton; + public Label l2; + public Color labelColor; + + public ConfigDialog(Frame parent) { + super(parent, "Configuration Dialog"); + okButton = new Button("OK"); + cancelButton = new Button("Cancel"); + l2 = new Label("This is a label:"); + + setLayout(new FlowLayout()); + add(l2); + add(okButton); + add(cancelButton); + + okButton.addActionListener(this); + cancelButton.addActionListener(this); + + pack(); + labelColor = l2.getBackground(); + } + + public void actionPerformed(ActionEvent ae) { + dispose(); + } +} diff --git a/test/jdk/java/awt/Dialog/EnabledResetTest.java b/test/jdk/java/awt/Dialog/EnabledResetTest.java new file mode 100644 index 0000000000000..d71c9b1801b22 --- /dev/null +++ b/test/jdk/java/awt/Dialog/EnabledResetTest.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4232374 + * @summary Tests that dismissing a modal dialog does not enable + * disabled components + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual EnabledResetTest + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class EnabledResetTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Press "Create Child" twice to create three windows + Verify that the parent windows are disabled + 2. Press "Create Modal Dialog" + Verify that the parent windows are disabled + 3. Press "enable" + Verify that no windows accept mouse events + 4. Press "ok" + Verify that the first window is still disabled + If all the verifications are done, then test is + PASSED, else test fails. + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(new ChildDialog(1, null)) + .build() + .awaitAndCheck(); + } +} + +class ChildDialog extends Frame implements ActionListener { + Window parent; + int id; + Button b, c, d; + + public ChildDialog(int frameNumber, Window myParent) { + super(); + id = frameNumber; + parent = myParent; + + setTitle("Frame Number " + id); + + b = new Button("Dismiss me"); + c = new Button("Create Child"); + d = new Button("Create Modal Dialog"); + + setLayout(new BorderLayout()); + add("North", c); + add("Center", d); + add("South", b); + pack(); + + b.addActionListener(this); + c.addActionListener(this); + d.addActionListener(this); + } + + public void setVisible(boolean b) { + if (parent != null) { + if (b) { + parent.setEnabled(false); + } else { + parent.setEnabled(true); + parent.requestFocus(); + } + } + + super.setVisible(b); + } + + public void dispose() { + if (parent != null) { + parent.setEnabled(true); + parent.requestFocus(); + } + super.dispose(); + } + + + public void actionPerformed(ActionEvent evt) { + if (evt.getSource() == c) { + (new ChildDialog(id + 1, this)).setVisible(true); + } else if (evt.getSource() == d) { + Dialog D = new Dialog(this, "Modal Dialog "); + D.setLayout(new FlowLayout()); + Button b = new Button("ok"); + Button e = new Button("enable"); + D.add(b); + D.add(e); + D.setModal(true); + D.pack(); + b.addActionListener(this); + e.addActionListener(this); + D.setVisible(true); + } else if (evt.getSource() == b) { + dispose(); + } else if (evt.getSource() instanceof Button) { + if ("ok".equals(evt.getActionCommand())) { + Button target = (Button) evt.getSource(); + Window w = (Window) target.getParent(); + w.dispose(); + } + if ("enable".equals(evt.getActionCommand())) { + parent.setEnabled(true); + } + } + } +} diff --git a/test/jdk/java/awt/Dialog/FileDialogGetFileTest.java b/test/jdk/java/awt/Dialog/FileDialogGetFileTest.java new file mode 100644 index 0000000000000..d4670cceb601e --- /dev/null +++ b/test/jdk/java/awt/Dialog/FileDialogGetFileTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4414105 + * @summary Tests that FileDialog returns null when cancelled + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual FileDialogGetFileTest + */ + +import java.awt.Button; +import java.awt.FileDialog; +import java.awt.Frame; + +public class FileDialogGetFileTest { + static FileDialog fd; + static Frame frame; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Open FileDialog from "Show File Dialog" button. + 2. Click cancel button without selecting any file/folder. + 3. If FileDialog.getFile return null then test PASSES, + else test FAILS automatically. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .logArea(4) + .build() + .awaitAndCheck(); + } + + public static Frame initialize() { + frame = new Frame("FileDialog GetFile test"); + fd = new FileDialog(frame); + fd.setFile("FileDialogGetFileTest.html"); + fd.setBounds(100, 100, 400, 400); + Button showBtn = new Button("Show File Dialog"); + frame.add(showBtn); + frame.pack(); + showBtn.addActionListener(e -> { + fd.setVisible(true); + if (fd.getFile() != null) { + PassFailJFrame.forceFail("Test failed: FileDialog returned non-null value"); + } else { + PassFailJFrame.log("Test Passed!"); + } + }); + return frame; + } +} From 86975d6411bdfba1368760ba0fde44c098ddd7fd Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 18 Mar 2025 08:31:40 +0000 Subject: [PATCH 055/846] 8293503: gc/metaspace/TestMetaspacePerfCounters.java#Epsilon-64 failed assertGreaterThanOrEqual: expected MMM >= NNN Reviewed-by: mdoerr, rrich Backport-of: 04d7b7d5747d887e12797df8ca3f7608d73d41ff --- .../metaspace/TestMetaspacePerfCounters.java | 118 ++++++++++-------- 1 file changed, 63 insertions(+), 55 deletions(-) diff --git a/test/hotspot/jtreg/gc/metaspace/TestMetaspacePerfCounters.java b/test/hotspot/jtreg/gc/metaspace/TestMetaspacePerfCounters.java index 34cc36b9d51f0..b0f779109e15b 100644 --- a/test/hotspot/jtreg/gc/metaspace/TestMetaspacePerfCounters.java +++ b/test/hotspot/jtreg/gc/metaspace/TestMetaspacePerfCounters.java @@ -23,7 +23,7 @@ package gc.metaspace; -import java.lang.management.GarbageCollectorMXBean; +import java.lang.invoke.VarHandle; import java.util.List; import java.util.ArrayList; @@ -183,10 +183,44 @@ * @run main/othervm -XX:+UsePerfData -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC gc.metaspace.TestMetaspacePerfCounters */ +class PerfCounterSnapshot { + private static long getMinCapacity(String ns) throws Exception { + return PerfCounters.findByName(ns + ".minCapacity").longValue(); + } + + private static long getCapacity(String ns) throws Exception { + return PerfCounters.findByName(ns + ".capacity").longValue(); + } + + private static long getMaxCapacity(String ns) throws Exception { + return PerfCounters.findByName(ns + ".maxCapacity").longValue(); + } + + private static long getUsed(String ns) throws Exception { + return PerfCounters.findByName(ns + ".used").longValue(); + } + + public long minCapacity; + public long maxCapacity; + public long capacity; + public long used; + + public void get(String ns) throws Exception { + minCapacity = getMinCapacity(ns); + maxCapacity = getMaxCapacity(ns); + used = getUsed(ns); + capacity = getCapacity(ns); + } + + public boolean consistentWith(PerfCounterSnapshot other) { + return (minCapacity == other.minCapacity) && (maxCapacity == other.maxCapacity) && + (used == other.used) && (capacity == other.capacity); + } +} + public class TestMetaspacePerfCounters { public static Class fooClass = null; private static final String[] counterNames = {"minCapacity", "maxCapacity", "capacity", "used"}; - private static final List gcBeans = ManagementFactoryHelper.getGarbageCollectorMXBeans(); public static void main(String[] args) throws Exception { String metaspace = "sun.gc.metaspace"; @@ -204,32 +238,28 @@ public static void main(String[] args) throws Exception { } private static void checkPerfCounters(String ns) throws Exception { - long gcCountBefore; - long gcCountAfter; - long minCapacity; - long maxCapacity; - long capacity; - long used; - - // The perf counter values are updated during GC and to be able to - // do the assertions below we need to ensure that the values are from - // the same GC cycle. - do { - gcCountBefore = currentGCCount(); - - minCapacity = getMinCapacity(ns); - maxCapacity = getMaxCapacity(ns); - capacity = getCapacity(ns); - used = getUsed(ns); - - gcCountAfter = currentGCCount(); - assertGTE(gcCountAfter, gcCountBefore); - } while(gcCountAfter > gcCountBefore); - - assertGTE(minCapacity, 0L); - assertGTE(used, minCapacity); - assertGTE(capacity, used); - assertGTE(maxCapacity, capacity); + PerfCounterSnapshot snap1 = new PerfCounterSnapshot(); + PerfCounterSnapshot snap2 = new PerfCounterSnapshot(); + + final int MaxAttempts = 10; + + for (int attempts = 0; ; attempts++) { + snap1.get(ns); + VarHandle.fullFence(); + snap2.get(ns); + + if (snap1.consistentWith(snap2)) { + // Got a consistent snapshot for examination. + break; + } else if (attempts == MaxAttempts) { + throw new Exception("Failed to get stable reading of metaspace performance counters after " + attempts + " tries"); + } + } + + assertGTE(snap1.minCapacity, 0L); + assertGTE(snap1.used, snap1.minCapacity); + assertGTE(snap1.capacity, snap1.used); + assertGTE(snap1.maxCapacity, snap1.capacity); } private static void checkEmptyPerfCounters(String ns) throws Exception { @@ -243,12 +273,14 @@ private static void checkUsedIncreasesWhenLoadingClass(String ns) throws Excepti // Need to ensure that used is up to date and that all unreachable // classes are unloaded before doing this check. System.gc(); - long before = getUsed(ns); + PerfCounterSnapshot before = new PerfCounterSnapshot(); + before.get(ns); fooClass = compileAndLoad("Foo", "public class Foo { }"); System.gc(); - long after = getUsed(ns); + PerfCounterSnapshot after = new PerfCounterSnapshot(); + after.get(ns); - assertGT(after, before); + assertGT(after.used, before.used); } private static List countersInNamespace(String ns) throws Exception { @@ -267,28 +299,4 @@ private static Class compileAndLoad(String name, String source) throws Except private static boolean isUsingCompressedClassPointers() { return Platform.is64bit() && InputArguments.contains("-XX:+UseCompressedClassPointers"); } - - private static long getMinCapacity(String ns) throws Exception { - return PerfCounters.findByName(ns + ".minCapacity").longValue(); - } - - private static long getCapacity(String ns) throws Exception { - return PerfCounters.findByName(ns + ".capacity").longValue(); - } - - private static long getMaxCapacity(String ns) throws Exception { - return PerfCounters.findByName(ns + ".maxCapacity").longValue(); - } - - private static long getUsed(String ns) throws Exception { - return PerfCounters.findByName(ns + ".used").longValue(); - } - - private static long currentGCCount() { - long gcCount = 0; - for (GarbageCollectorMXBean bean : gcBeans) { - gcCount += bean.getCollectionCount(); - } - return gcCount; - } } From fa9886956ba3719c505051401fa2a0983bc9cd57 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 18 Mar 2025 08:32:54 +0000 Subject: [PATCH 056/846] 8256211: assert fired in java/net/httpclient/DependentPromiseActionsTest (infrequent) Backport-of: b1163bcc88a5b88b9a56d5584310f1d679690ab2 --- .../DependentPromiseActionsTest.java | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java b/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java index 4e17408ee6f50..32c594808a9c4 100644 --- a/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java +++ b/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,6 +73,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Flow; import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiPredicate; @@ -112,6 +113,7 @@ public class DependentPromiseActionsTest implements HttpServerAdapters { static volatile boolean tasksFailed; static final AtomicLong serverCount = new AtomicLong(); static final AtomicLong clientCount = new AtomicLong(); + static final AtomicInteger requestCount = new AtomicInteger(); static final long start = System.nanoTime(); public static String now() { long now = System.nanoTime() - start; @@ -244,14 +246,17 @@ HttpClient newHttpClient(boolean share) { } @Test(dataProvider = "noStalls") - public void testNoStalls(String uri, boolean sameClient) + public void testNoStalls(String rootUri, boolean sameClient) throws Exception { + if (!FAILURES.isEmpty()) return; HttpClient client = null; - out.printf("%ntestNoStalls(%s, %b)%n", uri, sameClient); + out.printf("%ntestNoStalls(%s, %b)%n", rootUri, sameClient); for (int i=0; i< ITERATION_COUNT; i++) { if (!sameClient || client == null) client = newHttpClient(sameClient); + String uri = rootUri + "/" + requestCount.incrementAndGet(); + out.printf("\tsending request %s%n", uri); HttpRequest req = HttpRequest.newBuilder(URI.create(uri)) .build(); BodyHandler> handler = @@ -331,6 +336,10 @@ private void testDependent(String name, String uri, boolean sameClient, SubscriberType subscriberType) throws Exception { + if (!FAILURES.isEmpty()) { + out.printf("%s: skipping test - previous failure detected%n", name); + return; + } out.printf("%n%s%s%n", now(), name); try { testDependent(uri, sameClient, handlers, finisher, @@ -341,7 +350,7 @@ private void testDependent(String name, String uri, boolean sameClient, } } - private void testDependent(String uri, boolean sameClient, + private void testDependent(String rootUri, boolean sameClient, Supplier> handlers, Finisher finisher, Extractor extractor, @@ -354,6 +363,8 @@ private void testDependent(String uri, boolean sameClient, if (!sameClient || client == null) client = newHttpClient(sameClient); + String uri = rootUri + "/" + requestCount.incrementAndGet(); + out.printf("\tsending request %s%n", uri); HttpRequest req = HttpRequest. newBuilder(URI.create(uri)) .build(); @@ -363,7 +374,13 @@ private void testDependent(String uri, boolean sameClient, System.out.println("try stalling in " + where); CompletableFuture> responseCF = client.sendAsync(req, handler, promiseHandler); - assert subscriberType == SubscriberType.LAZZY || !responseCF.isDone(); + // The body of the main response can be received before the body + // of the push promise handlers are received. + // The body of the main response doesn't stall, so the cf of + // the main response may be done here even for EAGER subscribers. + // We cannot make any assumption on the state of the main response + // cf here, so the only thing we can do is to call the finisher + // which will wait for them all. finisher.finish(where, responseCF, promiseHandler, extractor); } } From c2e5dc0f9a5f9b2651c6702741b7b61d8bf80a71 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 18 Mar 2025 08:34:16 +0000 Subject: [PATCH 057/846] 8340164: Open source few Component tests - Set1 Backport-of: 7e3978eab22f040995f5794b97417022532d375d --- .../LWParentMovedTest/LWParentMovedTest.java | 99 ++++++++++ .../LightWeightTabFocus.java | 154 +++++++++++++++ .../LightweightFontTest.java | 182 ++++++++++++++++++ 3 files changed, 435 insertions(+) create mode 100644 test/jdk/java/awt/LightweightComponent/LWParentMovedTest/LWParentMovedTest.java create mode 100644 test/jdk/java/awt/LightweightComponent/LightWeightTabFocus/LightWeightTabFocus.java create mode 100644 test/jdk/java/awt/LightweightComponent/LightweightFontTest/LightweightFontTest.java diff --git a/test/jdk/java/awt/LightweightComponent/LWParentMovedTest/LWParentMovedTest.java b/test/jdk/java/awt/LightweightComponent/LWParentMovedTest/LWParentMovedTest.java new file mode 100644 index 0000000000000..d46af3a0d5e51 --- /dev/null +++ b/test/jdk/java/awt/LightweightComponent/LWParentMovedTest/LWParentMovedTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4147246 + * @summary Simple check for peer != null in Component.componentMoved + * @key headful + * @run main LWParentMovedTest + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.Container; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Graphics; + +public class LWParentMovedTest { + static CMTFrame f; + + // test will throw an exception and fail if lwc is null + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> f = new CMTFrame()); + } finally { + if (f != null) { + EventQueue.invokeAndWait(() -> f.dispose()); + } + } + } +} + +class CMTFrame extends Frame { + Container lwc; + Button button; + + public CMTFrame() { + super("Moving LWC Test"); + setLayout(new FlowLayout()); + lwc = new LWSquare(Color.blue, 100, 100); + button = new Button(); + lwc.add(button); + add(lwc); + + setSize(400, 300); + setVisible(true); + + // queue up a bunch of COMPONENT_MOVED events + for (int i = 0; i < 1000; i++) { + lwc.setLocation(i, i); + } + + // remove heavyweight from lightweight container + lwc.remove(button); + } +} + +// +// Lightweight container +// +class LWSquare extends Container { + int width; + int height; + + public LWSquare(Color color, int w, int h) { + setBackground(color); + setLayout(new FlowLayout()); + width = w; + height = h; + setName("LWSquare-" + color.toString()); + } + + public void paint(Graphics g) { + g.setColor(getBackground()); + g.fillRect(0, 0, 1000, 1000); + } +} diff --git a/test/jdk/java/awt/LightweightComponent/LightWeightTabFocus/LightWeightTabFocus.java b/test/jdk/java/awt/LightweightComponent/LightWeightTabFocus/LightWeightTabFocus.java new file mode 100644 index 0000000000000..05889580fd423 --- /dev/null +++ b/test/jdk/java/awt/LightweightComponent/LightWeightTabFocus/LightWeightTabFocus.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4095214 + * @summary Test change of focus on lightweights using the tab key + * @key headful + * @run main LightWeightTabFocus + */ + +import java.awt.Button; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +public class LightWeightTabFocus { + private static Frame f; + private static LightweightButton btn1; + private static Button btn2; + private static Robot robot; + private static volatile Point point; + private static Point loc; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + robot.setAutoDelay(100); + try { + EventQueue.invokeAndWait(() -> createUI()); + robot.delay(1000); + EventQueue.invokeAndWait(() -> { + loc = f.getLocation(); + point = btn2.getLocation(); + }); + robot.mouseMove(loc.x + point.x, loc.y + point.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + // First TAB + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + if (!btn1.hasFocus()) { + new RuntimeException("First tab failed"); + } + // Second TAB + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + if (!btn2.hasFocus()) { + new RuntimeException("Second tab failed"); + } + // First SHIFT+TAB + robot.keyPress(KeyEvent.VK_SHIFT); + robot.keyPress(KeyEvent.VK_TAB); + robot.delay(100); + robot.keyRelease(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_SHIFT); + if (!btn1.hasFocus()) { + new RuntimeException("First shift+tab failed"); + } + // Second SHIFT+TAB + robot.keyPress(KeyEvent.VK_SHIFT); + robot.keyPress(KeyEvent.VK_TAB); + robot.delay(100); + robot.keyRelease(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_SHIFT); + if (!btn2.hasFocus()) { + new RuntimeException("Second shift+tab failed"); + } + + } catch (Exception e) { + e.printStackTrace(); + } finally { + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } + + private static Frame createUI() { + f = new Frame("TAB Focus Change on LW Test"); + f.setLayout(new FlowLayout()); + btn1 = new LightweightButton(); + f.add(btn1); + btn2 = new Button("Click Me To start"); + f.add(btn2); + f.pack(); + f.setVisible(true); + return f; + } +} + +class LightweightButton extends Component implements FocusListener { + boolean focus; + LightweightButton() { + focus = false; + addFocusListener(this); + } + + public Dimension getPreferredSize() + { + return new Dimension(100, 100); + } + + public void focusGained(FocusEvent e) { + focus = true; + repaint(); + } + + public void focusLost(FocusEvent e) { + focus = false; + repaint(); + } + + public void paint(Graphics g) { + if (focus) { + g.drawString("Has Focus", 10, 20); + } else { + g.drawString("Not Focused", 10, 20); + } + } + + public boolean isFocusable() { + return true; + } +} diff --git a/test/jdk/java/awt/LightweightComponent/LightweightFontTest/LightweightFontTest.java b/test/jdk/java/awt/LightweightComponent/LightweightFontTest/LightweightFontTest.java new file mode 100644 index 0000000000000..4fd90656d6124 --- /dev/null +++ b/test/jdk/java/awt/LightweightComponent/LightweightFontTest/LightweightFontTest.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4077709 4153989 + * @summary Lightweight component font settable test + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual LightweightFontTest + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Graphics; + + +public class LightweightFontTest { + static Font desiredFont = null; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + [ There are 7 steps to this test ] + 1. The 2 bordered labels (Emacs vs. vi) should be in a LARGE font + (approximately 1/2 inch tall) + 2. The labels should not overlap. + 3. Each button should be large enough to contain the entire label. + 4. The labels should have red backgrounds + 5. The text in the left label should be blue and the right yellow + 6. Resize the window to make it much smaller and larger + 7. The buttons should never overlap, and they should be large + enough to contain the entire label. + (although the button may disappear if there is not enough + room in the window)" + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(LightweightFontTest::createUI) + .logArea(5) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + Frame f = new Frame("Lightweight Font Test"); + f.setLayout(new FlowLayout()); + + desiredFont = new Font(Font.DIALOG, Font.PLAIN, 36); + Component component; + component = new BorderedLabel("Emacs or vi?"); + component.setFont(desiredFont); + component.setBackground(Color.red); + component.setForeground(Color.blue); + f.add(component); + component = new BorderedLabel("Vi or Emacs???"); + component.setFont(desiredFont); + component.setBackground(Color.red); + component.setForeground(Color.yellow); + f.add(component); + f.pack(); + return f; + } +} + +/** + * Lightweight component + */ +class BorderedLabel extends Component { + boolean superIsButton; + String labelString; + + BorderedLabel(String labelString) { + this.labelString = labelString; + + Component thisComponent = this; + superIsButton = (thisComponent instanceof Button); + if(superIsButton) { + ((Button)thisComponent).setLabel(labelString); + } + } + + public Dimension getMinimumSize() { + Dimension minSize = new Dimension(); + + if (superIsButton) { + minSize = super.getMinimumSize(); + } else { + + Graphics g = getGraphics(); + verifyFont(g); + FontMetrics metrics = g.getFontMetrics(); + + minSize.width = metrics.stringWidth(labelString) + 14; + minSize.height = metrics.getMaxAscent() + metrics.getMaxDescent() + 9; + + g.dispose(); + } + return minSize; + } + + public Dimension getPreferredSize() { + Dimension prefSize = new Dimension(); + if (superIsButton) { + prefSize = super.getPreferredSize(); + } else { + prefSize = getMinimumSize(); + } + return prefSize; + } + + public void paint(Graphics g) { + verifyFont(g); + super.paint(g); + if (superIsButton) { + return; + } + Dimension size = getSize(); + Color oldColor = g.getColor(); + + // draw border + g.setColor(getBackground()); + g.fill3DRect(0, 0, size.width, size.height, false); + g.fill3DRect(3, 3, size.width - 6, size.height - 6, true); + + // draw text + FontMetrics metrics = g.getFontMetrics(); + int centerX = size.width / 2; + int centerY = size.height / 2; + int textX = centerX - (metrics.stringWidth(labelString) / 2); + int textY = centerY + ((metrics.getMaxAscent() + + metrics.getMaxDescent()) / 2); + g.setColor(getForeground()); + g.drawString(labelString, textX, textY); + + g.setColor(oldColor); + } + + /** + * Verifies that the font is correct and prints a warning + * message and/or throws a RuntimeException if it is not. + */ + private void verifyFont(Graphics g) { + Font desiredFont = LightweightFontTest.desiredFont; + Font actualFont = g.getFont(); + if (!actualFont.equals(desiredFont)) { + PassFailJFrame.log("AWT BUG: FONT INFORMATION LOST!"); + PassFailJFrame.log(" Desired font: " + desiredFont); + PassFailJFrame.log(" Actual font: " + actualFont); + PassFailJFrame.forceFail(); + } + } +} From f8eaafcaa61420ba15d3655c2d3d788d8006f2b6 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 18 Mar 2025 08:35:55 +0000 Subject: [PATCH 058/846] 8340985: Open source some Desktop related tests Backport-of: 172f74466fe59ece816764112dba98e4604706b7 --- .../java/awt/Desktop/ActionSupportTest.java | 201 ++++++++++++++++++ test/jdk/java/awt/Desktop/BrowseTest.java | 90 ++++++++ .../java/awt/Desktop/DesktopSupportTest.java | 59 +++++ test/jdk/java/awt/Desktop/MailTest.java | 116 ++++++++++ test/jdk/java/awt/Desktop/OpenTest.java | 114 ++++++++++ 5 files changed, 580 insertions(+) create mode 100644 test/jdk/java/awt/Desktop/ActionSupportTest.java create mode 100644 test/jdk/java/awt/Desktop/BrowseTest.java create mode 100644 test/jdk/java/awt/Desktop/DesktopSupportTest.java create mode 100644 test/jdk/java/awt/Desktop/MailTest.java create mode 100644 test/jdk/java/awt/Desktop/OpenTest.java diff --git a/test/jdk/java/awt/Desktop/ActionSupportTest.java b/test/jdk/java/awt/Desktop/ActionSupportTest.java new file mode 100644 index 0000000000000..e5cdec0e42246 --- /dev/null +++ b/test/jdk/java/awt/Desktop/ActionSupportTest.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6255196 + * @key headful + * @summary Verifies the supported actions on different platforms. + * @library /test/lib + * @run main/othervm ActionSupportTest + */ + +import java.awt.Desktop; +import java.io.File; +import java.net.URI; +import javax.swing.JMenuBar; +import jtreg.SkippedException; + +import static java.awt.desktop.QuitStrategy.NORMAL_EXIT; + +public class ActionSupportTest { + + public static void main(String[] args) { + final File file = new File("nonExistentFile"); + final URI uri = URI.create("nonExistentSchema:anything"); + final StringBuilder error = new StringBuilder(); + + if (!Desktop.isDesktopSupported()) { + throw new SkippedException("Class java.awt.Desktop is not supported on " + + "current platform. Farther testing will not be performed"); + } + + Desktop desktop = Desktop.getDesktop(); + for (Desktop.Action action : Desktop.Action.values()) { + boolean supported = desktop.isSupported(action); + + try { + switch (action) { + case OPEN: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.open(file); + break; + case EDIT: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.edit(file); + break; + case PRINT: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.print(file); + break; + case MAIL: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.mail(uri); + break; + case BROWSE: + if (supported) { + continue; // prevent native message about strange schema + } + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.browse(uri); + break; + case APP_EVENT_FOREGROUND: + case APP_EVENT_HIDDEN: + case APP_EVENT_REOPENED: + case APP_EVENT_SCREEN_SLEEP: + case APP_EVENT_SYSTEM_SLEEP: + case APP_EVENT_USER_SESSION: + continue; // Has no effect if SystemEventListener's sub-type + // is unsupported on the current platform. + case APP_ABOUT: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.setAboutHandler(e -> { + }); + break; + case APP_PREFERENCES: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.setPreferencesHandler(e -> { + }); + break; + case APP_OPEN_FILE: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.setOpenFileHandler(e -> { + }); + break; + case APP_PRINT_FILE: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.setPrintFileHandler(e -> { + }); + break; + case APP_OPEN_URI: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.setOpenURIHandler(e -> { + }); + break; + case APP_QUIT_HANDLER: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.setQuitHandler((e, response) -> { + }); + break; + case APP_QUIT_STRATEGY: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.setQuitStrategy(NORMAL_EXIT); + break; + case APP_SUDDEN_TERMINATION: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.enableSuddenTermination(); + break; + case APP_REQUEST_FOREGROUND: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.requestForeground(true); + break; + case APP_HELP_VIEWER: + if (supported) { + continue; // prevent open separate window + } + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.openHelpViewer(); + break; + case APP_MENU_BAR: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.setDefaultMenuBar(new JMenuBar()); + break; + case BROWSE_FILE_DIR: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.browseFileDirectory(file); + break; + case MOVE_TO_TRASH: + // if not supported, an UnsupportedOperationException will be thrown. + // if supported, other exception might be thrown. + desktop.moveToTrash(file); + break; + } + // no exception has been thrown. + if (!supported) { + error.append("Action " + action.name() + " is an " + + "unsupported operation, but no exception has been thrown\n"); + } + } catch (UnsupportedOperationException uoe) { + if (!supported) { + System.out.println("Action " + action.name() + "is not supported."); + } else { + error.append("Action " + action.name() + " is a " + + "supported operation, " + + "but UnsupportedOperationException has been thrown\n"); + } + } catch (Exception e) { + if (supported) { + System.out.println("Action " + action.name() + "supported."); + } else { + error.append("Action " + action.name() + " is an " + + "unsupported operation, but " + + "UnsupportedOperationException has not been thrown\n"); + } + } + } + + if (!error.isEmpty()) { + System.err.println(error); + throw new RuntimeException("One or more tests failed. " + + "Look at the error output for details"); + } + System.out.println("Test completed"); + } +} diff --git a/test/jdk/java/awt/Desktop/BrowseTest.java b/test/jdk/java/awt/Desktop/BrowseTest.java new file mode 100644 index 0000000000000..1bdccace3fc87 --- /dev/null +++ b/test/jdk/java/awt/Desktop/BrowseTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6255196 + * @summary Verifies the function of method browse(java.net.URI uri). + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual BrowseTest + */ + +import java.awt.Desktop; +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import javax.swing.JPanel; + +public class BrowseTest extends JPanel { + static final String INSTRUCTIONS = """ + This test could launch default file manager to open user's home + directory, and default web browser to show the URL of java vendor. + After test execution close the native file manager and web browser + windows if they were launched by test. + Also check output for any unexpected EXCEPTIONS, + if you see any failure messages press Fail otherwise press Pass. + """; + + public BrowseTest() { + if (!Desktop.isDesktopSupported()) { + PassFailJFrame.log("Class java.awt.Desktop is not supported on " + + "current platform. Farther testing will not be performed"); + PassFailJFrame.forcePass(); + } + + Desktop desktop = Desktop.getDesktop(); + + URI dirURI = new File(System.getProperty("user.home")).toURI(); + URI webURI = URI.create(System.getProperty("java.vendor.url", "http://www.java.com")); + boolean failed = false; + try { + PassFailJFrame.log("Try to browse " + dirURI + " ..."); + desktop.browse(dirURI); + PassFailJFrame.log("Succeed.\n"); + } catch (Exception e) { + PassFailJFrame.log("EXCEPTION: " + e.getMessage()); + } + + try { + PassFailJFrame.log("Try to browse " + webURI + " ..."); + desktop.browse(webURI); + PassFailJFrame.log("Succeed.\n"); + } catch (Exception e) { + PassFailJFrame.log("EXCEPTION: " + e.getMessage()); + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Browser Test") + .splitUI(BrowseTest::new) + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 1) + .columns(40) + .logArea() + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/java/awt/Desktop/DesktopSupportTest.java b/test/jdk/java/awt/Desktop/DesktopSupportTest.java new file mode 100644 index 0000000000000..ec8b82ba5ef21 --- /dev/null +++ b/test/jdk/java/awt/Desktop/DesktopSupportTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6255196 + * @key headful + * @summary Verifies if class Desktop is supported on current platform. + * @run main DesktopSupportTest + */ + +import java.awt.Desktop; + +public class DesktopSupportTest { + public static void main(String[] args) { + boolean supported = Desktop.isDesktopSupported(); + try { + Desktop desktop = Desktop.getDesktop(); + if (!supported) { + throw new RuntimeException("UnsupportedOperationException " + + "should be thrown, as this class is not supported " + + "on current platform."); + } + } catch (UnsupportedOperationException uoe) { + if (supported) { + throw new RuntimeException("UnsupportedOperationException " + + "should NOT be thrown, as this class is supported " + + "on current platform."); + } + } catch (Exception e) { + if (!supported) { + throw new RuntimeException("UnsupportedOperationException " + + "should be thrown, as this class is not supported " + + "on current platform. But " + e.getClass().getName() + + " has been thrown instead."); + } + } + } +} diff --git a/test/jdk/java/awt/Desktop/MailTest.java b/test/jdk/java/awt/Desktop/MailTest.java new file mode 100644 index 0000000000000..15e5c0769a0dc --- /dev/null +++ b/test/jdk/java/awt/Desktop/MailTest.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6255196 + * @summary Verifies the function of methods mail() and mail(java.net.URI uri). + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MailTest + */ + +import java.awt.Desktop; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import javax.swing.JPanel; + +public class MailTest extends JPanel { + + static final String INSTRUCTIONS = """ + This test could launch the mail client to compose mail + with and without filling the message fields. + After test execution close the mail composing windows if they + were launched by test. + If you see any unexpected EXCEPTION messages in the output + press Fail. Otherwise press Pass. + """; + + private MailTest() { + if (!Desktop.isDesktopSupported()) { + PassFailJFrame.log("Class java.awt.Desktop is not supported on " + + "current platform. Farther testing will not be performed"); + PassFailJFrame.forcePass(); + } + + Desktop desktop = Desktop.getDesktop(); + if (!desktop.isSupported(Desktop.Action.MAIL)) { + PassFailJFrame.log("Action.MAIL is not supported."); + PassFailJFrame.forcePass(); + } + + /* + * Part 1: launch the mail composing window without a mailto URI. + */ + try { + desktop.mail(); + } catch (IOException e) { + PassFailJFrame.log("EXCEPTION: " + e.getMessage()); + } + + /* + * Part 2: launch the mail composing window with a mailto URI. + */ + URI testURI = null; + try { + testURI = new URI("mailto", "foo@bar.com?subject=test subject" + + "&cc=foocc@bar.com&body=test body", null); + desktop.mail(testURI); + } catch (IOException e) { + PassFailJFrame.log("EXCEPTION: " + e.getMessage()); + } catch (java.net.URISyntaxException use) { + // Should not reach here. + PassFailJFrame.log("EXCEPTION: " + use.getMessage()); + } + + /* + * Part 3: try to launch the mail composing window with a URI with a + * scheme which is not "mailto": + * http://java.net. + * An IOException should be thrown in this case. + */ + try { + testURI = URI.create("http://java.com"); + PassFailJFrame.log("Try to mail: " + testURI); + desktop.mail(testURI); + } catch (IllegalArgumentException e) { + PassFailJFrame.log("Caught expected IllegalArgumentException"); + } catch (IOException ioe) { + PassFailJFrame.log("EXCEPTION: " + ioe.getMessage()); + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Mail Test") + .splitUI(MailTest::new) + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 1) + .columns(40) + .logArea() + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/java/awt/Desktop/OpenTest.java b/test/jdk/java/awt/Desktop/OpenTest.java new file mode 100644 index 0000000000000..1ed29067d50e1 --- /dev/null +++ b/test/jdk/java/awt/Desktop/OpenTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6255196 + * @summary Verifies the function of method open(java.io.File file). + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual/othervm OpenTest + */ + +import java.awt.Desktop; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import javax.swing.JPanel; + +public class OpenTest extends JPanel { + + static final String INSTRUCTIONS = """ + This test could open the user's home directory and a .txt file. + After test execution, close the native application windows that + are used to open the directory and .txt file if they were launched + by the test. + If you see any unexpected EXCEPTION messages in the output press Fail. + Otherwise press Pass. + """; + + public OpenTest() { + if (!Desktop.isDesktopSupported()) { + PassFailJFrame.log("Class java.awt.Desktop is not supported on " + + "current platform. Further testing will not be performed"); + PassFailJFrame.forcePass(); + } + + Desktop desktop = Desktop.getDesktop(); + + /* + * Part 1: open a directory, which should launch the system default + * file explorer. + * + * On Windows platforms, the default file explorer is explorer; + * on UNIX platforms with Gnome installed and running, the default + * file explorer is Nautilus. + */ + File userHome = new File(System.getProperty("user.home")); + + try { + PassFailJFrame.log("Try to open " + userHome); + desktop.open(userHome); + PassFailJFrame.log("Succeed."); + } catch (IOException e) { + PassFailJFrame.log("EXCEPTION: " + e.getMessage()); + } + + /* + * Part 2: open a normal .txt file, which should launch the registered + * application for .txt files. + */ + // Create a temp .txt file for test. + File testFile = null; + try { + PassFailJFrame.log("Creating temporary file"); + testFile = File.createTempFile("JDIC-test", ".txt", + new File(System.getProperty("java.io.tmpdir"))); + testFile.deleteOnExit(); + } catch (java.io.IOException ioe) { + PassFailJFrame.log("EXCEPTION: " + ioe.getMessage()); + PassFailJFrame.log("Failed to create test file"); + } + + try { + PassFailJFrame.log("Try to open " + testFile); + desktop.open(testFile); + PassFailJFrame.log("Succeed."); + } catch (IOException e) { + PassFailJFrame.log("EXCEPTION: " + e.getMessage()); + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Mail Test") + .splitUI(OpenTest::new) + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 1) + .columns(40) + .logArea() + .build() + .awaitAndCheck(); + } +} From b9b9d7f14beb33feedd46776a0e12da273c4301b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 18 Mar 2025 08:37:22 +0000 Subject: [PATCH 059/846] 8341637: java/net/Socket/UdpSocket.java fails with "java.net.BindException: Address already in use" (macos-aarch64) Backport-of: ba3774dc5d27e762dfd61f8acf842ae11dec0cb7 --- test/jdk/java/net/Socket/UdpSocket.java | 27 ++++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/test/jdk/java/net/Socket/UdpSocket.java b/test/jdk/java/net/Socket/UdpSocket.java index a15f9255b450a..5d13c1f916a60 100644 --- a/test/jdk/java/net/Socket/UdpSocket.java +++ b/test/jdk/java/net/Socket/UdpSocket.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,8 @@ @Test public class UdpSocket { + private static final int MAX_RETRIES = 3; + /** * Test using the Socket API to send/receive datagrams */ @@ -133,16 +135,21 @@ public void testMaxSockets() throws Exception { } - private Socket newUdpSocket() throws IOException { - Socket s = null; - - try { - s = new Socket(InetAddress.getLoopbackAddress(), 8000, false); - } catch (BindException unexpected) { - System.out.println("BindException caught retry Socket creation"); - s = new Socket(InetAddress.getLoopbackAddress(), 8000, false); + private Socket newUdpSocket() throws IOException, InterruptedException { + BindException unexpected = null; + for (int i=0; i < MAX_RETRIES; i++) { + try { + return new Socket(InetAddress.getLoopbackAddress(), 8000, false); + } catch (BindException be) { + unexpected = be; + if (i != MAX_RETRIES - 1) { + System.out.printf("BindException caught: retry Socket creation [%s/%s]%n", + i + 1, MAX_RETRIES); + Thread.sleep(10 + 10 * i); + } + } } - return s; + throw unexpected; } private void closeAll(Deque sockets) throws IOException { From 552566a315093f819c425540907ea6654f7f83e6 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 18 Mar 2025 08:38:34 +0000 Subject: [PATCH 060/846] 8334644: Automate javax/print/attribute/PageRangesException.java Backport-of: 030149fec4f175e5571e053fa56d2921d95c6b13 --- .../print/attribute/PageRangesException.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 test/jdk/javax/print/attribute/PageRangesException.java diff --git a/test/jdk/javax/print/attribute/PageRangesException.java b/test/jdk/javax/print/attribute/PageRangesException.java new file mode 100644 index 0000000000000..81f9eb1a59289 --- /dev/null +++ b/test/jdk/javax/print/attribute/PageRangesException.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.print.attribute.standard.PageRanges; + +/* + * @test + * @bug 4433126 4433096 + * @key printer + * @summary The line "ERROR: " should NOT appear. + * @run main PageRangesException + */ + +public class PageRangesException { + public static void main(String[] args) throws Exception { + // test 4433126 + try { + PageRanges pr = new PageRanges("0:22"); + throw new RuntimeException("ERROR: no exceptions"); + } catch (IllegalArgumentException ie) { + System.out.println("OKAY: IllegalArgumentException " + ie); + } + + // test 4433096 + try { + int[][] m = null; + PageRanges pr = new PageRanges(m); + throw new RuntimeException("ERROR: NullPointerException expected"); + } catch (IllegalArgumentException ie) { + throw new RuntimeException("ERROR: IllegalArgumentException", ie); + } catch (NullPointerException e) { + System.out.println("OKAY: NullPointerException"); + } + } +} From 735747a9b25cf579256fd75a88fbad95629c792d Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 18 Mar 2025 08:40:10 +0000 Subject: [PATCH 061/846] 8346581: JRadioButton/ButtonGroupFocusTest.java fails in CI on Linux Backport-of: 57af52c57390f6f7413b5d3ffe64921c9b83aae4 --- .../ButtonGroupFocusTest.java | 150 +++++++++++++----- 1 file changed, 111 insertions(+), 39 deletions(-) diff --git a/test/jdk/javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java b/test/jdk/javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java index c696b166dd085..633b0356f85df 100644 --- a/test/jdk/javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java +++ b/test/jdk/javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -28,26 +28,53 @@ * @run main ButtonGroupFocusTest */ -import javax.swing.*; -import java.awt.*; +import java.awt.AWTEvent; +import java.awt.Container; +import java.awt.FlowLayout; +import java.awt.KeyboardFocusManager; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; +import java.io.File; +import java.util.concurrent.CountDownLatch; -public class ButtonGroupFocusTest { +import javax.imageio.ImageIO; +import javax.swing.ButtonGroup; +import javax.swing.JFrame; +import javax.swing.JRadioButton; +import javax.swing.SwingUtilities; + +import static java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +public final class ButtonGroupFocusTest { private static JRadioButton button1; private static JRadioButton button2; private static JRadioButton button3; private static JRadioButton button4; private static JRadioButton button5; - private static Robot robot; + + private static final CountDownLatch button2FocusLatch = new CountDownLatch(1); + private static final CountDownLatch button3FocusLatch = new CountDownLatch(1); + private static final CountDownLatch button4FocusLatch = new CountDownLatch(1); + + private static final CountDownLatch button2FocusLatch2 = new CountDownLatch(2); + + private static final long FOCUS_TIMEOUT = 4; + private static JFrame frame; public static void main(String[] args) throws Exception { - robot = new Robot(); - robot.setAutoDelay(100); + final Robot robot = new Robot(); SwingUtilities.invokeAndWait(() -> { - frame = new JFrame(); + frame = new JFrame("ButtonGroupFocusTest"); Container contentPane = frame.getContentPane(); contentPane.setLayout(new FlowLayout()); button1 = new JRadioButton("Button 1"); @@ -60,6 +87,7 @@ public static void main(String[] args) throws Exception { contentPane.add(button4); button5 = new JRadioButton("Button 5"); contentPane.add(button5); + ButtonGroup group = new ButtonGroup(); group.add(button1); group.add(button2); @@ -69,52 +97,96 @@ public static void main(String[] args) throws Exception { group.add(button4); group.add(button5); + button2.addFocusListener(new LatchFocusListener(button2FocusLatch)); + button3.addFocusListener(new LatchFocusListener(button3FocusLatch)); + button4.addFocusListener(new LatchFocusListener(button4FocusLatch)); + + button2.addFocusListener(new LatchFocusListener(button2FocusLatch2)); + button2.setSelected(true); + // Debugging aid: log focus owner changes... + KeyboardFocusManager focusManager = getCurrentKeyboardFocusManager(); + focusManager.addPropertyChangeListener("focusOwner", + e -> System.out.println(e.getPropertyName() + + "\n\t" + e.getOldValue() + + "\n\t" + e.getNewValue())); + + // ...and dispatched key events + Toolkit.getDefaultToolkit().addAWTEventListener( + e -> System.out.println("Dispatched " + e), + AWTEvent.KEY_EVENT_MASK); + frame.pack(); + frame.setLocationRelativeTo(null); frame.setVisible(true); }); - robot.waitForIdle(); - robot.delay(200); - - SwingUtilities.invokeAndWait(() -> { - if( !button2.hasFocus() ) { - frame.dispose(); - throw new RuntimeException( - "Button 2 should get focus after activation"); + try { + if (!button2FocusLatch.await(FOCUS_TIMEOUT, SECONDS)) { + throw new RuntimeException("Button 2 should get focus " + + "after activation"); } - }); + robot.waitForIdle(); + robot.delay(200); - robot.keyPress(KeyEvent.VK_TAB); - robot.keyRelease(KeyEvent.VK_TAB); + System.out.println("\n\n*** Tab 1st"); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); - robot.waitForIdle(); - robot.delay(200); + if (!button4FocusLatch.await(FOCUS_TIMEOUT, SECONDS)) { + throw new RuntimeException("Button 4 should get focus"); + } + robot.waitForIdle(); + robot.delay(200); - SwingUtilities.invokeAndWait(() -> { - if( !button4.hasFocus() ) { - frame.dispose(); - throw new RuntimeException( - "Button 4 should get focus"); + if (button2FocusLatch2.await(1, MILLISECONDS)) { + throw new RuntimeException("Focus moved back to Button 2"); } - button3.setSelected(true); - }); - robot.keyPress(KeyEvent.VK_TAB); - robot.keyRelease(KeyEvent.VK_TAB); + SwingUtilities.invokeAndWait(() -> button3.setSelected(true)); + robot.waitForIdle(); + robot.delay(200); - robot.waitForIdle(); - robot.delay(200); + System.out.println("\n\n*** Tab 2nd"); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); - SwingUtilities.invokeAndWait(() -> { - if( !button3.hasFocus() ) { - frame.dispose(); - throw new RuntimeException( - "selected Button 3 should get focus"); + if (!button3FocusLatch.await(FOCUS_TIMEOUT, SECONDS)) { + throw new RuntimeException("Selected Button 3 should get focus"); } - }); + } catch (Exception e) { + BufferedImage image = robot.createScreenCapture(getFrameBounds()); + ImageIO.write(image, "png", + new File("image.png")); + + SwingUtilities.invokeAndWait(() -> + System.err.println("Current focus owner: " + + getCurrentKeyboardFocusManager() + .getFocusOwner())); + + throw e; + } finally { + SwingUtilities.invokeAndWait(frame::dispose); + } + } + + private static Rectangle getFrameBounds() throws Exception { + Rectangle[] bounds = new Rectangle[1]; + SwingUtilities.invokeAndWait(() -> bounds[0] = frame.getBounds()); + return bounds[0]; + } + + private static final class LatchFocusListener extends FocusAdapter { + private final CountDownLatch focusGainedLatch; + + private LatchFocusListener(CountDownLatch focusGainedLatch) { + this.focusGainedLatch = focusGainedLatch; + } - SwingUtilities.invokeLater(frame::dispose); + @Override + public void focusGained(FocusEvent e) { + focusGainedLatch.countDown(); + } } } From 767e504cc059db7cde7d6811ae664e962ba5ecae Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 18 Mar 2025 08:41:27 +0000 Subject: [PATCH 062/846] 8347286: (fs) Remove some extensions from java/nio/file/Files/probeContentType/Basic.java Reviewed-by: rrich Backport-of: d002933c260921d0d582724516d15ebd130b851f --- .../nio/file/Files/probeContentType/Basic.java | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/test/jdk/java/nio/file/Files/probeContentType/Basic.java b/test/jdk/java/nio/file/Files/probeContentType/Basic.java index 28cda7b574e3c..8acfc97c738c0 100644 --- a/test/jdk/java/nio/file/Files/probeContentType/Basic.java +++ b/test/jdk/java/nio/file/Files/probeContentType/Basic.java @@ -38,7 +38,6 @@ import java.util.stream.Stream; import jdk.test.lib.Platform; -import jdk.test.lib.OSVersion; import jdk.internal.util.StaticProperty; /** @@ -188,18 +187,8 @@ public static void main(String[] args) throws IOException { exTypes.add(new ExType("xlsx", List.of("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))); // exTypes.add(new ExType("wasm", List.of("application/wasm"))); Note. "wasm" is added via JDK-8297609 (Java 20) which not exist in current java version yet - // extensions with content type that differs on Windows 11+ and - // Windows Server 2025 - if (Platform.isWindows() && - (System.getProperty("os.name").matches("^.*[11|2025]$") || - new OSVersion(10, 0).compareTo(OSVersion.current()) > 0)) { - System.out.println("Windows 11+ detected: using different types"); - exTypes.add(new ExType("bz2", List.of("application/bz2", "application/x-bzip2", "application/x-bzip", "application/x-compressed"))); - exTypes.add(new ExType("csv", List.of("text/csv", "application/vnd.ms-excel"))); - exTypes.add(new ExType("rar", List.of("application/rar", "application/vnd.rar", "application/x-rar", "application/x-rar-compressed", "application/x-compressed"))); - exTypes.add(new ExType("rtf", List.of("application/rtf", "text/rtf", "application/msword"))); - exTypes.add(new ExType("7z", List.of("application/x-7z-compressed", "application/x-compressed"))); - } else { + // extensions with consistent content type on Unix (but not on Windows) + if (!Platform.isWindows()) { exTypes.add(new ExType("bz2", List.of("application/bz2", "application/x-bzip2", "application/x-bzip"))); exTypes.add(new ExType("csv", List.of("text/csv"))); exTypes.add(new ExType("rar", List.of("application/rar", "application/vnd.rar", "application/x-rar", "application/x-rar-compressed"))); From 07d2927530c300e548835664d891e186e21521f7 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 18 Mar 2025 08:42:39 +0000 Subject: [PATCH 063/846] 8340784: Remove PassFailJFrame constructor with screenshots Backport-of: 50ca450417a5da7d4c6c08154515b8407bf656e8 --- .../awt/regtesthelpers/PassFailJFrame.java | 60 +++---------------- 1 file changed, 9 insertions(+), 51 deletions(-) diff --git a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java index 1426b97e3ca68..95d925d7b3db0 100644 --- a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java +++ b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -359,7 +359,7 @@ public enum Position {HORIZONTAL, VERTICAL, TOP_LEFT_CORNER} * the default values of {@value #ROWS} and {@value #COLUMNS} * for rows and columns. *

- * See {@link #PassFailJFrame(String,String,long,int,int,boolean)} for + * See {@link #PassFailJFrame(String,String,long,int,int)} for * more details. * * @param instructions the instructions for the tester @@ -382,7 +382,7 @@ public PassFailJFrame(String instructions) * and the default values of {@value #ROWS} and {@value #COLUMNS} * for rows and columns. *

- * See {@link #PassFailJFrame(String,String,long,int,int,boolean)} for + * See {@link #PassFailJFrame(String,String,long,int,int)} for * more details. * * @param instructions the instructions for the tester @@ -404,9 +404,8 @@ public PassFailJFrame(String instructions, long testTimeOut) * with the given title, instructions and timeout as well as * the default values of {@value #ROWS} and {@value #COLUMNS} * for rows and columns. - * The screenshot feature is not enabled, if you use this constructor. *

- * See {@link #PassFailJFrame(String,String,long,int,int,boolean)} for + * See {@link #PassFailJFrame(String,String,long,int,int)} for * more details. * * @param title the title of the instruction frame @@ -424,41 +423,11 @@ public PassFailJFrame(String title, String instructions, this(title, instructions, testTimeOut, ROWS, COLUMNS); } - /** - * Constructs a frame which displays test instructions and - * the Pass / Fail buttons - * with the given title, instructions, timeout, number of rows and columns. - * The screenshot feature is not enabled, if you use this constructor. - *

- * See {@link #PassFailJFrame(String,String,long,int,int,boolean)} for - * more details. - * - * @param title the title of the instruction frame - * @param instructions the instructions for the tester - * @param testTimeOut the test timeout in minutes - * @param rows the number of rows for the text component - * which displays test instructions - * @param columns the number of columns for the text component - * which displays test instructions - * - * @throws InterruptedException if the current thread is interrupted - * while waiting for EDT to finish creating UI components - * @throws InvocationTargetException if an exception is thrown while - * creating UI components on EDT - */ - public PassFailJFrame(String title, String instructions, - long testTimeOut, - int rows, int columns) - throws InterruptedException, InvocationTargetException { - this(title, instructions, testTimeOut, rows, columns, false); - } - /** * Constructs a frame which displays test instructions and * the Pass / Fail buttons * as well as supporting UI components with the given title, instructions, - * timeout, number of rows and columns, - * and screen capture functionality. + * timeout, number of rows and columns. * All the UI components are created on the EDT, so it is safe to call * the constructor on the main thread. *

@@ -483,12 +452,6 @@ public PassFailJFrame(String title, String instructions, * the size of a text component which displays the instructions. * The preferred size of the instructions is calculated by * creating {@code new JTextArea(rows, columns)}. - *

- * If you enable screenshots by setting the {@code screenCapture} - * parameter to {@code true}, a Screenshot button is added. - * Clicking the Screenshot button takes screenshots of - * all the monitors or all the windows registered with - * {@code PassFailJFrame}. * * @param title the title of the instruction frame * @param instructions the instructions for the tester @@ -497,8 +460,6 @@ public PassFailJFrame(String title, String instructions, * which displays test instructions * @param columns the number of columns for the text component * which displays test instructions - * @param screenCapture if set to {@code true}, enables screen capture - * functionality * * @throws InterruptedException if the current thread is interrupted * while waiting for EDT to finish creating UI components @@ -510,13 +471,11 @@ public PassFailJFrame(String title, String instructions, */ public PassFailJFrame(String title, String instructions, long testTimeOut, - int rows, int columns, - boolean screenCapture) + int rows, int columns) throws InterruptedException, InvocationTargetException { invokeOnEDT(() -> createUI(title, instructions, testTimeOut, - rows, columns, - screenCapture)); + rows, columns)); } /** @@ -613,8 +572,7 @@ private static void invokeOnEDTUncheckedException(Runnable doRun) { } private static void createUI(String title, String instructions, - long testTimeOut, int rows, int columns, - boolean enableScreenCapture) { + long testTimeOut, int rows, int columns) { frame = new JFrame(title); frame.setLayout(new BorderLayout()); @@ -623,7 +581,7 @@ private static void createUI(String title, String instructions, frame.add(createInstructionUIPanel(instructions, testTimeOut, rows, columns, - enableScreenCapture, + false, false, 0), BorderLayout.CENTER); frame.pack(); From 8ba5d8046e684203778a80183ec4a6f441631ba5 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 18 Mar 2025 08:48:00 +0000 Subject: [PATCH 064/846] 8352076: [21u] Problem list tests that fail in 21 and would be fixed by 8309622 Backport-of: 5ff88f61f6ab04ddf3936f8b249f9a48974f53d1 --- test/hotspot/jtreg/ProblemList.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index a588af5eaf0a1..613adf1ddb017 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -78,10 +78,13 @@ gc/epsilon/TestMemoryMXBeans.java 8206434 generic-all gc/g1/humongousObjects/objectGraphTest/TestObjectGraphAfterGC.java 8156755 generic-all gc/g1/logging/TestG1LoggingFailure.java 8169634 generic-all gc/g1/humongousObjects/TestHeapCounters.java 8178918 generic-all +gc/shenandoah/TestAllocIntArrays.java#aggressive 8309622 generic-all +gc/shenandoah/TestAllocIntArrays.java#iu-aggressive 8309622 generic-all gc/stress/CriticalNativeStress.java#id1 8312028 generic-all gc/stress/gclocker/TestExcessGCLockerCollections.java 8229120 generic-all gc/stress/gclocker/TestGCLockerWithParallel.java 8180622 generic-all gc/stress/gclocker/TestGCLockerWithG1.java 8180622 generic-all +gc/stress/gcold/TestGCOldWithShenandoah.java#iu-aggressive 8309622 generic-all gc/stress/TestJNIBlockFullGC/TestJNIBlockFullGC.java 8192647 generic-all applications/jcstress/acqrel.java 8277434 linux-aarch64 From 64fbb72efd256e5d5968edcfaaa905ff969d3892 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:18:08 +0000 Subject: [PATCH 065/846] 8254786: java/net/httpclient/CancelRequestTest.java failing intermittently Reviewed-by: mbaesken Backport-of: 710653ce1856d13161ae1786d7c5f71997536e78 --- .../jdk/internal/net/http/Exchange.java | 51 +++++++++++++++---- .../internal/net/http/Http2ClientImpl.java | 10 ++-- .../internal/net/http/Http2Connection.java | 4 ++ .../net/httpclient/CancelRequestTest.java | 2 +- 4 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java b/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java index 60d2b2b410acc..8c71795766c78 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java @@ -150,14 +150,45 @@ static final class ConnectionAborter { private volatile boolean closeRequested; void connection(HttpConnection connection) { - this.connection = connection; - if (closeRequested) closeConnection(); + boolean closeRequested; + synchronized (this) { + // check whether this new connection should be + // closed + closeRequested = this.closeRequested; + if (!closeRequested) { + this.connection = connection; + } else { + // assert this.connection == null + this.closeRequested = false; + } + } + if (closeRequested) closeConnection(connection); } void closeConnection() { - closeRequested = true; - HttpConnection connection = this.connection; - this.connection = null; + HttpConnection connection; + synchronized (this) { + connection = this.connection; + if (connection == null) { + closeRequested = true; + } else { + this.connection = null; + } + } + closeConnection(connection); + } + + HttpConnection disable() { + HttpConnection connection; + synchronized (this) { + connection = this.connection; + this.connection = null; + this.closeRequested = false; + } + return connection; + } + + private static void closeConnection(HttpConnection connection) { if (connection != null) { try { connection.close(); @@ -166,11 +197,6 @@ void closeConnection() { } } } - - void disable() { - connection = null; - closeRequested = false; - } } // Called for 204 response - when no body is permitted @@ -614,8 +640,11 @@ HttpResponse.BodySubscriber ignoreBody(HttpResponse.ResponseInfo hdrs) { client.client2(), this, e::drainLeftOverBytes) .thenCompose((Http2Connection c) -> { + HttpConnection connection = connectionAborter.disable(); boolean cached = c.offerConnection(); - if (cached) connectionAborter.disable(); + if (!cached && connection != null) { + connectionAborter.connection(connection); + } Stream s = c.getInitialStream(); if (s == null) { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java index 0f2db7738fccf..8da321ffab40a 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java @@ -28,7 +28,6 @@ import java.io.EOFException; import java.io.IOException; import java.io.UncheckedIOException; -import java.net.ConnectException; import java.net.InetSocketAddress; import java.net.URI; import java.util.Base64; @@ -100,7 +99,7 @@ CompletableFuture getConnectionFor(HttpRequestImpl req, Http2Connection connection = connections.get(key); if (connection != null) { try { - if (connection.closed + if (!connection.isOpen() || !connection.reserveStream(true, pushEnabled)) { if (debug.on()) debug.log("removing connection from pool since " + @@ -156,7 +155,7 @@ CompletableFuture getConnectionFor(HttpRequestImpl req, */ boolean offerConnection(Http2Connection c) { if (debug.on()) debug.log("offering to the connection pool: %s", c); - if (c.closed || c.finalStream()) { + if (!c.isOpen() || c.finalStream()) { if (debug.on()) debug.log("skipping offered closed or closing connection: %s", c); return false; @@ -164,6 +163,11 @@ boolean offerConnection(Http2Connection c) { String key = c.key(); synchronized(this) { + if (!c.isOpen()) { + if (debug.on()) + debug.log("skipping offered closed or closing connection: %s", c); + return false; + } Http2Connection c1 = connections.putIfAbsent(key, c); if (c1 != null) { if (c.serverPushEnabled() && !c1.serverPushEnabled()) { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java index f363231e1c82f..c1326789da06a 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java @@ -1073,6 +1073,10 @@ private void handleConnectionFrame(Http2Frame frame) } } + boolean isOpen() { + return !closed && connection.channel().isOpen(); + } + void resetStream(int streamid, int code) { try { if (connection.channel().isOpen()) { diff --git a/test/jdk/java/net/httpclient/CancelRequestTest.java b/test/jdk/java/net/httpclient/CancelRequestTest.java index f8fb80aedca81..651c5d0c3130f 100644 --- a/test/jdk/java/net/httpclient/CancelRequestTest.java +++ b/test/jdk/java/net/httpclient/CancelRequestTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8245462 8229822 + * @bug 8245462 8229822 8254786 * @summary Tests cancelling the request. * @library /test/lib /test/jdk/java/net/httpclient/lib * @key randomness From 387000195e4088b4bf43b38d7cb1b9b66cb8504e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:19:44 +0000 Subject: [PATCH 066/846] 8315669: Open source several Swing PopupMenu related tests Backport-of: 7c5f2a2db941d30a5425d358607a6b4e63879ab7 --- .../javax/swing/JPopupMenu/bug4236750.java | 106 +++++++++++++ .../javax/swing/JPopupMenu/bug4321273.java | 88 ++++++++++ .../javax/swing/JPopupMenu/bug4711693.java | 126 +++++++++++++++ .../javax/swing/JPopupMenu/bug4962731.java | 136 ++++++++++++++++ .../javax/swing/JPopupMenu/bug4966109.java | 144 +++++++++++++++++ .../javax/swing/JPopupMenu/bug5091257.java | 150 ++++++++++++++++++ 6 files changed, 750 insertions(+) create mode 100644 test/jdk/javax/swing/JPopupMenu/bug4236750.java create mode 100644 test/jdk/javax/swing/JPopupMenu/bug4321273.java create mode 100644 test/jdk/javax/swing/JPopupMenu/bug4711693.java create mode 100644 test/jdk/javax/swing/JPopupMenu/bug4962731.java create mode 100644 test/jdk/javax/swing/JPopupMenu/bug4966109.java create mode 100644 test/jdk/javax/swing/JPopupMenu/bug5091257.java diff --git a/test/jdk/javax/swing/JPopupMenu/bug4236750.java b/test/jdk/javax/swing/JPopupMenu/bug4236750.java new file mode 100644 index 0000000000000..2090c7feb23b9 --- /dev/null +++ b/test/jdk/javax/swing/JPopupMenu/bug4236750.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 1999, 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. + */ + +import javax.swing.Action; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.MenuElement; +import javax.swing.SwingUtilities; +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeListener; + +/* + * @test + * @bug 4236750 + * @summary Tests presence of JPopupMenu.insert(Action, int) + * @run main bug4236750 + */ + +public class bug4236750 { + private static MenuElement[] elements; + private static volatile boolean passed = true; + + /** + * Auxilliary class implementing Action + */ + static class NullAction implements Action { + public void addPropertyChangeListener( + PropertyChangeListener listener) { + } + + public void removePropertyChangeListener( + PropertyChangeListener listener) { + } + + public void setEnabled(boolean b) { + } + + public boolean isEnabled() { + return true; + } + + public void actionPerformed(ActionEvent e) { + } + + private String name; + + public NullAction(String s) { + name = s; + } + + public void putValue(String key, Object value) { + if (key.equals(Action.NAME)) { + name = (String) value; + } + } + + public Object getValue(String key) { + if (key.equals(Action.NAME)) { + return name; + } + return null; + } + } + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + JPopupMenu popup; + popup = new JPopupMenu("Test Popup"); + JMenuItem item0 = popup.add(new NullAction("0")); + JMenuItem item2 = popup.add(new NullAction("2")); + popup.insert(new NullAction("1"), 1); + elements = popup.getSubElements(); + for (int i = 0; i < 3; i++) { + JMenuItem mi = (JMenuItem) elements[i]; + if (!mi.getText().equals("" + i)) { + passed = false; + } + } + }); + + if (!passed) { + throw new RuntimeException("Failed: wrong order of menuitems"); + } + System.out.println("Test Passed!"); + } +} diff --git a/test/jdk/javax/swing/JPopupMenu/bug4321273.java b/test/jdk/javax/swing/JPopupMenu/bug4321273.java new file mode 100644 index 0000000000000..a19210373fd6f --- /dev/null +++ b/test/jdk/javax/swing/JPopupMenu/bug4321273.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2002, 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. + */ + +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.SwingUtilities; +import java.awt.Robot; +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; + + +/* + * @test + * @bug 4321273 + * @summary NotSerializableException during the menu serialization + * @key headful + * @run main bug4321273 +*/ + +public class bug4321273 { + public static JFrame frame; + public static JMenu menu; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + SwingUtilities.invokeAndWait(() -> { + JMenuBar menuBar = new JMenuBar(); + frame = new JFrame(); + frame.setJMenuBar(menuBar); + menu = new JMenu("Menu"); + menuBar.add(menu); + menu.add(new JMenuItem("item 1")); + menu.add(new JMenuItem("item 2")); + menu.add(new JMenuItem("item 3")); + frame.pack(); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + menu.doClick(); + try { + ByteArrayOutputStream byteArrayOutputStream = + new ByteArrayOutputStream(); + ObjectOutputStream oos = + new ObjectOutputStream(byteArrayOutputStream); + oos.writeObject(menu); + } catch (Exception se) { + throw new RuntimeException("NotSerializableException " + + "during the menu serialization", se); + } + }); + + robot.waitForIdle(); + robot.delay(100); + System.out.println("Test Passed!"); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/javax/swing/JPopupMenu/bug4711693.java b/test/jdk/javax/swing/JPopupMenu/bug4711693.java new file mode 100644 index 0000000000000..f24b2eb7c4298 --- /dev/null +++ b/test/jdk/javax/swing/JPopupMenu/bug4711693.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2002, 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. + */ + +import javax.swing.JFrame; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Insets; +import java.awt.Robot; +import java.awt.Window; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.InputEvent; + +/* + * @test + * @bug 4711693 + * @summary Pop-up doesn't stay up + * @key headful + * @run main bug4711693 + */ + +public class bug4711693 { + static JFrame fr; + static Robot robot; + static volatile boolean passed = true; + static volatile Dimension scr; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + SwingUtilities.invokeAndWait(() -> { + fr = new JFrame("Test 4711693"); + scr = new Dimension(); + fr.setSize(600, 600); + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] gs = ge.getScreenDevices(); + GraphicsConfiguration gc = null; + + for (int j = 0; j < gs.length; j++) { + GraphicsDevice gd = gs[j]; + gc = gd.getDefaultConfiguration(); + if (gc.getBounds().contains(100, 100)) break; + } + scr = Toolkit.getDefaultToolkit().getScreenSize(); + Insets ins = Toolkit.getDefaultToolkit().getScreenInsets(gc); + scr.width -= ins.right; + scr.height -= ins.bottom; + fr.setLocation(scr.width - 400, scr.height - 400); + fr.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + final JPopupMenu popupMenu = new JPopupMenu(); + final Component pane = fr.getContentPane(); + for (int i = 1; i < 10; i++) { + final String itemName = "Item " + i; + JMenuItem it = popupMenu.add(new JMenuItem(itemName)); + it.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent a) { + passed = false; + } + }); + } + + pane.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + if ((e.isAltDown() || + ((e.getModifiersEx() & + InputEvent.BUTTON3_DOWN_MASK) != 0))) { + Component parent = e.getComponent(); + while (parent != null && !(parent instanceof Window)) { + parent = parent.getParent(); + } + popupMenu.show(pane, e.getX(), e.getY()); + } + } + }); + }); + + robot.mouseMove(scr.width - 55, scr.height - 55); + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (fr != null) { + fr.dispose(); + } + }); + } + if (!passed) { + throw new RuntimeException("Test failed. Popup disposed on mouse release."); + } else { + System.out.println("Test Passed!"); + } + } +} diff --git a/test/jdk/javax/swing/JPopupMenu/bug4962731.java b/test/jdk/javax/swing/JPopupMenu/bug4962731.java new file mode 100644 index 0000000000000..651678cf3866c --- /dev/null +++ b/test/jdk/javax/swing/JPopupMenu/bug4962731.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2004, 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. + */ + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.plaf.PopupMenuUI; +import java.awt.BorderLayout; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/* + * @test + * @bug 4962731 + * @summary The PopupMenu is not repainted if the LAF is changed. + * @key headful + * @run main bug4962731 + */ + +public class bug4962731 { + + public static volatile boolean passed = false; + public static boolean isLafOk = true; + public static JFrame mainFrame; + public static JButton button; + public static MyPopup popup; + public static Robot robot; + + public static void main(String[] args) throws Exception { + + try { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); + } catch (Exception ex) { + System.err.println("Can not initialize Motif L&F. Testing skipped."); + isLafOk = false; + } + + try { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + } catch (Exception ex) { + System.err.println("Can not initialize Metal L&F. Testing skipped."); + isLafOk = false; + } + + if (isLafOk) { + try { + robot = new Robot(); + SwingUtilities.invokeAndWait(() -> { + mainFrame = new JFrame("Bug4962731"); + button = new JButton("Popup!"); + popup = new MyPopup(); + popup.add("one"); + popup.add("two"); + button.setComponentPopupMenu(popup); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + popup.show(button, 300, 300); + popup.engage(); + try { + Thread.sleep(1000); + } catch (InterruptedException e1) { + } + try { + UIManager.setLookAndFeel + ("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); + } catch (Exception ex) { + } + try { + Thread.sleep(1000); + } catch (InterruptedException e1) { + } + SwingUtilities.updateComponentTreeUI(mainFrame); + passed = popup.check(); + } + }); + mainFrame.setLayout(new BorderLayout()); + mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + mainFrame.add(button, BorderLayout.CENTER); + mainFrame.pack(); + mainFrame.setVisible(true); + }); + + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + button.doClick(); + }); + + if (!passed) { + throw new RuntimeException("The UI of popup was not changed"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (mainFrame != null) { + mainFrame.dispose(); + } + }); + } + } + System.out.println("test Passed!"); + } + + public static class MyPopup extends JPopupMenu { + PopupMenuUI thisUI; + + public void engage() { + thisUI = getUI(); + } + + public boolean check() { + return getUI() != thisUI; + } + } +} diff --git a/test/jdk/javax/swing/JPopupMenu/bug4966109.java b/test/jdk/javax/swing/JPopupMenu/bug4966109.java new file mode 100644 index 0000000000000..a643448a7bb4f --- /dev/null +++ b/test/jdk/javax/swing/JPopupMenu/bug4966109.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2004, 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. + */ + +import javax.swing.JLabel; +import javax.swing.JFrame; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import java.awt.BorderLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 4966109 + * @summary Popup is not populated by mouse actions on lightweight components without mouse + * @key headful + * @run main bug4966109 + */ + +public class bug4966109 { + public static JFrame mainFrame; + public static JPopupMenu popup; + public static JLabel label1; + public static JLabel label2; + public static Robot robot; + public static volatile Point loc; + public static volatile Boolean passed = true; + public static int popupTrigger; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + SwingUtilities.invokeAndWait(() -> { + mainFrame = new JFrame("Bug4966109"); + popup = new JPopupMenu(); + label1 = new JLabel("Label with the listener"); + label2 = new JLabel("Label w/o listener"); + mainFrame.setLayout(new BorderLayout()); + mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + mainFrame.add(label1, BorderLayout.NORTH); + mainFrame.add(label2, BorderLayout.SOUTH); + mainFrame.pack(); + mainFrame.setVisible(true); + popup.add("One"); + popup.add("Two"); + popup.add("Three"); + label1.setComponentPopupMenu(popup); + label1.addMouseListener(new MouseAdapter() { + }); + label2.setComponentPopupMenu(popup); + }); + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + loc = label1.getLocationOnScreen(); + loc.x = loc.x + (int) (label1.getWidth() / 2); + loc.y = loc.y + (int) (label1.getHeight() / 2); + }); + popupTrigger = MouseEvent.BUTTON2_DOWN_MASK; + robot.mouseMove(loc.x, loc.y); + robot.mousePress(popupTrigger); + robot.mouseRelease(popupTrigger); + robot.waitForIdle(); + robot.delay(100); + + SwingUtilities.invokeAndWait(() -> { + if (popup.isVisible()) { + System.out.println("ZAV: Good!!! BUTTON2 is the way to go."); + } else { + System.out.println("ZAV: Bad :( Let's try BUTTON3"); + popupTrigger = MouseEvent.BUTTON3_DOWN_MASK; + } + }); + + robot.mousePress(popupTrigger); + robot.mouseRelease(popupTrigger); + robot.waitForIdle(); + robot.delay(100); + + SwingUtilities.invokeAndWait(() -> { + if (popup.isVisible()) { + System.out.println("ZAV: Good!!! BUTTON3 is working. At last :)"); + popup.setVisible(false); + } else { + System.out.println("ZAV: Bad :( Very bad. Nothing is working..."); + passed = false; + } + }); + if (!passed) { + throw new RuntimeException("No popup trigger mouse events found"); + } + robot.waitForIdle(); + robot.delay(100); + + SwingUtilities.invokeAndWait(() -> { + loc = label2.getLocationOnScreen(); + loc.x = loc.x + (int) (label2.getWidth() / 2); + loc.y = loc.y + (int) (label2.getHeight() / 2); + }); + robot.mouseMove(loc.x, loc.y); + robot.mousePress(popupTrigger); + robot.mouseRelease(popupTrigger); + robot.waitForIdle(); + robot.delay(100); + + SwingUtilities.invokeAndWait(() -> { + if (!popup.isVisible()) { + passed = false; + } + }); + if (!passed) { + throw new RuntimeException("Regression: bug 4966109, popup is not visible"); + } + } finally { + if (mainFrame != null) { + mainFrame.dispose(); + } + } + System.out.println("test Passed!"); + } +} diff --git a/test/jdk/javax/swing/JPopupMenu/bug5091257.java b/test/jdk/javax/swing/JPopupMenu/bug5091257.java new file mode 100644 index 0000000000000..cd4d285f9cb71 --- /dev/null +++ b/test/jdk/javax/swing/JPopupMenu/bug5091257.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2004, 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. + */ + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import javax.swing.event.PopupMenuListener; +import javax.swing.event.PopupMenuEvent; +import java.awt.BorderLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 5091257 + * @summary Application key does not display a pop-up menu in users view. + * @key headful + * @run main bug5091257 + */ + +public class bug5091257 { + public static volatile boolean passed = false; + public static volatile boolean isKeyOk = false; + public static JFrame mainFrame; + public static JButton button; + public static Robot robot; + public static JPopupMenu popup; + public static volatile Point loc; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + robot.setAutoDelay(50); + SwingUtilities.invokeAndWait(() -> { + button = new JButton("Popup button"); + button.addKeyListener(new KeyListener() { + public void keyTyped(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU) { + isKeyOk = true; + } + } + + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU) { + isKeyOk = true; + } + } + + public void keyReleased(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU) { + isKeyOk = true; + } + } + }); + mainFrame = new JFrame("Bug5091257"); + mainFrame.setLayout(new BorderLayout()); + mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + mainFrame.add(button, BorderLayout.CENTER); + mainFrame.pack(); + mainFrame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + loc = button.getLocationOnScreen(); + loc.x = loc.x + (int) (button.getWidth() / 2); + loc.y = loc.y + (int) (button.getHeight() / 2); + }); + robot.mouseMove(loc.x, loc.y); + robot.mousePress(MouseEvent.BUTTON3_DOWN_MASK); + robot.mouseRelease(MouseEvent.BUTTON3_DOWN_MASK); + + robot.waitForIdle(); + robot.delay(100); + + try { + robot.keyPress(KeyEvent.VK_CONTEXT_MENU); + robot.keyRelease(KeyEvent.VK_CONTEXT_MENU); + } catch (IllegalArgumentException ex) { + isKeyOk = false; + } + + if (!isKeyOk) { + System.out.println("KeyEvent can't create or deliver " + + "VK_CONTEXT_MENU event to component. Testing skipped."); + passed = true; + } else { + SwingUtilities.invokeAndWait(() -> { + popup = new JPopupMenu(); + popup.add("Item to make popup not empty"); + popup.addPopupMenuListener(new PopupMenuListener() { + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + System.out.println("Popup menu became visible " + + "on context menu key press. Test passed."); + passed = true; + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + } + + public void popupMenuCanceled(PopupMenuEvent e) { + } + }); + button.setComponentPopupMenu(popup); + }); + robot.keyPress(KeyEvent.VK_CONTEXT_MENU); + robot.keyRelease(KeyEvent.VK_CONTEXT_MENU); + + robot.waitForIdle(); + robot.delay(100); + + if (!passed) { + throw new RuntimeException("Popup did not open on " + + "VK_CONTEXT_MENU press. Test failed."); + } + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (mainFrame != null) { + mainFrame.dispose(); + } + }); + } + } +} From d1ae41b89e07545eb48856d2da7d715e8959afcd Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:21:08 +0000 Subject: [PATCH 067/846] 8339678: Update runtime/condy tests to be executed with VM flags Backport-of: c3711dc90980fb3e63ff199612c201c4464626bf --- test/hotspot/jtreg/ProblemList-Xcomp.txt | 2 ++ test/hotspot/jtreg/runtime/condy/BadBSMUseTest.java | 7 +++---- test/hotspot/jtreg/runtime/condy/CondyLDCTest.java | 9 ++++----- .../jtreg/runtime/condy/CondyNewInvokeSpecialTest.java | 5 ++--- .../runtime/condy/escapeAnalysis/TestEscapeCondy.java | 5 ++--- .../runtime/condy/staticInit/TestInitException.java | 6 ++---- 6 files changed, 15 insertions(+), 19 deletions(-) diff --git a/test/hotspot/jtreg/ProblemList-Xcomp.txt b/test/hotspot/jtreg/ProblemList-Xcomp.txt index 0c8dfe3008e00..72a64a95ba62c 100644 --- a/test/hotspot/jtreg/ProblemList-Xcomp.txt +++ b/test/hotspot/jtreg/ProblemList-Xcomp.txt @@ -32,3 +32,5 @@ vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw001/TestDescription.java 8205957 vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java 8265295 linux-x64,windows-x64 vmTestbase/nsk/jvmti/scenarios/sampling/SP07/sp07t002/TestDescription.java 8245680 windows-x64 + +runtime/condy/escapeAnalysis/TestEscapeCondy.java 8339694 generic-all diff --git a/test/hotspot/jtreg/runtime/condy/BadBSMUseTest.java b/test/hotspot/jtreg/runtime/condy/BadBSMUseTest.java index a07c98caa6638..3e36d1aebd9c2 100644 --- a/test/hotspot/jtreg/runtime/condy/BadBSMUseTest.java +++ b/test/hotspot/jtreg/runtime/condy/BadBSMUseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 8186211 * @summary CONSTANT_Dynamic_info structure's tries to use a BSM index whose signature is for an invokedynamic and vice versa. - * @requires vm.flagless * @modules java.base/jdk.internal.misc * @library /test/lib * @compile CondyUsesIndyBSM.jcod @@ -42,7 +41,7 @@ public class BadBSMUseTest { public static void main(String args[]) throws Throwable { // 1. Test a CONSTANT_Dynamic_info's bootstrap_method_attr_index points // at a BSM meant for a CONSTANT_InvokeDynamic_info - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("CondyUsesIndyBSM"); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder("CondyUsesIndyBSM"); OutputAnalyzer oa = new OutputAnalyzer(pb.start()); oa.shouldContain("In Indybsm target CallSite method foo"); oa.shouldContain("BootstrapMethodError: bootstrap method initialization exception"); @@ -50,7 +49,7 @@ public static void main(String args[]) throws Throwable { // 2. Test a CONSTANT_InvokeDynamic_info's bootstrap_method_attr_index points // at a BSM meant for a CONSTANT_Dynamic_info - pb = ProcessTools.createLimitedTestJavaProcessBuilder("IndyUsesCondyBSM"); + pb = ProcessTools.createTestJavaProcessBuilder("IndyUsesCondyBSM"); oa = new OutputAnalyzer(pb.start()); oa.shouldContain("In Condybsm"); oa.shouldContain("BootstrapMethodError: bootstrap method initialization exception"); diff --git a/test/hotspot/jtreg/runtime/condy/CondyLDCTest.java b/test/hotspot/jtreg/runtime/condy/CondyLDCTest.java index 22cfb727eb8b8..1b045d1e36e76 100644 --- a/test/hotspot/jtreg/runtime/condy/CondyLDCTest.java +++ b/test/hotspot/jtreg/runtime/condy/CondyLDCTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 8186211 * @summary Tests various ldc, ldc_w, ldc2_w instructions of CONSTANT_Dynamic. - * @requires vm.flagless * @modules java.base/jdk.internal.misc * @library /test/lib * @compile CondyUseLDC_W.jasm @@ -42,7 +41,7 @@ public class CondyLDCTest { public static void main(String args[]) throws Throwable { // 1. Test a ldc_w instruction can be used with condy's which generate // loadable constants of the following types: byte, char, short, float, integer, boolean. - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xverify:all", + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder("-Xverify:all", "CondyUseLDC_W"); OutputAnalyzer oa = new OutputAnalyzer(pb.start()); oa.shouldNotContain("VerifyError"); @@ -50,7 +49,7 @@ public static void main(String args[]) throws Throwable { // 2. Test ldc2_w of a condy which returns a dynamically generated // float constant, generates a VerifyError. - pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xverify:all", + pb = ProcessTools.createTestJavaProcessBuilder("-Xverify:all", "CondyBadLDC2_W"); oa = new OutputAnalyzer(pb.start()); oa.shouldContain("java.lang.VerifyError: Illegal type at constant pool entry"); @@ -59,7 +58,7 @@ public static void main(String args[]) throws Throwable { // 3. Test a ldc of a condy which returns a dynamically generated // double constant, generates a VerifyError. - pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xverify:all", + pb = ProcessTools.createTestJavaProcessBuilder("-Xverify:all", "CondyBadLDC"); oa = new OutputAnalyzer(pb.start()); oa.shouldContain("java.lang.VerifyError: Illegal type at constant pool entry"); diff --git a/test/hotspot/jtreg/runtime/condy/CondyNewInvokeSpecialTest.java b/test/hotspot/jtreg/runtime/condy/CondyNewInvokeSpecialTest.java index 6e810d0d3b88c..ddada0edbf7b9 100644 --- a/test/hotspot/jtreg/runtime/condy/CondyNewInvokeSpecialTest.java +++ b/test/hotspot/jtreg/runtime/condy/CondyNewInvokeSpecialTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 8186211 * @summary Test CONSTANT_Dynamic where the BSM is invoked via a REF_newInvokeSpecial. - * @requires vm.flagless * @modules java.base/jdk.internal.misc * @library /test/lib * @compile CondyNewInvokeSpecial.jasm @@ -38,7 +37,7 @@ public class CondyNewInvokeSpecialTest { public static void main(String args[]) throws Throwable { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xverify:all", + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder("-Xverify:all", "CondyNewInvokeSpecial"); OutputAnalyzer oa = new OutputAnalyzer(pb.start()); oa.shouldContain("In CondyNewInvokeSpecial method"); diff --git a/test/hotspot/jtreg/runtime/condy/escapeAnalysis/TestEscapeCondy.java b/test/hotspot/jtreg/runtime/condy/escapeAnalysis/TestEscapeCondy.java index 877a805c445fd..a90b987db1461 100644 --- a/test/hotspot/jtreg/runtime/condy/escapeAnalysis/TestEscapeCondy.java +++ b/test/hotspot/jtreg/runtime/condy/escapeAnalysis/TestEscapeCondy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ * @bug 8216970 * @summary Ensure escape analysis can handle an ldc of a dynamic * constant whose return type is an array of boolean. - * @requires vm.flagless * @modules java.base/jdk.internal.misc * @library /test/lib * @compile TestEscapeThroughInvokeWithCondy$A.jasm @@ -43,7 +42,7 @@ public class TestEscapeCondy { public static void main(String args[]) throws Throwable { // 1. Test escape analysis of a method that contains // a ldc instruction of a condy whose return type is an array of boolean - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( "-XX:CompileCommand=dontinline,runtime.condy.TestEscapeThroughInvokeWithCondy::create", "runtime.condy.TestEscapeThroughInvokeWithCondy"); OutputAnalyzer oa = new OutputAnalyzer(pb.start()); diff --git a/test/hotspot/jtreg/runtime/condy/staticInit/TestInitException.java b/test/hotspot/jtreg/runtime/condy/staticInit/TestInitException.java index 2b572edb66fec..412a1639e69ce 100644 --- a/test/hotspot/jtreg/runtime/condy/staticInit/TestInitException.java +++ b/test/hotspot/jtreg/runtime/condy/staticInit/TestInitException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 8228485 * @summary Correctly handle initialization error for Condy BSM. - * @requires vm.flagless * @modules java.base/jdk.internal.misc * @library /test/lib * @compile Example.jasm @@ -38,7 +37,7 @@ public class TestInitException { public static void main(java.lang.String[] unused) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("Example"); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder("Example"); OutputAnalyzer oa = new OutputAnalyzer(pb.start()); // First call stack trace // shouldMatch is used to workaround CODETOOLS-7902686 @@ -52,4 +51,3 @@ public static void main(java.lang.String[] unused) throws Exception { oa.shouldHaveExitValue(1); } } - From 441bf39988a9f4514d43ede9e1f220ee93dac049 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:22:36 +0000 Subject: [PATCH 068/846] 8340433: Open source closed choice tests #3 Backport-of: 8c08c43a34b7a237c0281ef58594af4f263ba3ca --- test/jdk/java/awt/Choice/ChoicePosTest.java | 137 ++++++++++++++++++++ test/jdk/java/awt/Choice/DeadlockTest.java | 113 ++++++++++++++++ test/jdk/java/awt/Choice/SetFontTest.java | 91 +++++++++++++ 3 files changed, 341 insertions(+) create mode 100644 test/jdk/java/awt/Choice/ChoicePosTest.java create mode 100644 test/jdk/java/awt/Choice/DeadlockTest.java create mode 100644 test/jdk/java/awt/Choice/SetFontTest.java diff --git a/test/jdk/java/awt/Choice/ChoicePosTest.java b/test/jdk/java/awt/Choice/ChoicePosTest.java new file mode 100644 index 0000000000000..c585e4709bbe5 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoicePosTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Choice; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +/* + * @test + * @bug 4075194 + * @summary 4075194, Choice may not be displayed at the location requested + * @key headful + */ + +public class ChoicePosTest { + + private static Robot robot; + private static Frame frame; + private static final int GAP = 10; + private static volatile Choice c1,c2; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(ChoicePosTest::createAndShowGUI); + + robot = new Robot(); + robot.waitForIdle(); + robot.delay(500); + + captureAndTestChoices(); + } finally { + EventQueue.invokeAndWait(frame::dispose); + } + + System.out.println("Passed"); + } + + private static void createAndShowGUI() { + frame = new Frame("ChoicePosTest"); + Insets insets = frame.getInsets(); + frame.setSize( insets.left + 400 + insets.right, insets.top + 400 + insets.bottom ); + frame.setBackground(Color.RED); + frame.setLayout(null); + frame.setLocationRelativeTo(null); + + c1 = new Choice(); + c1.setBackground(Color.GREEN); + frame.add( c1 ); + c1.setBounds( 20, 50, 100, 100 ); + + c2 = new Choice(); + c2.setBackground(Color.GREEN); + frame.add(c2); + c2.addItem("One"); + c2.addItem("Two"); + c2.addItem("Three"); + c2.setBounds( 125, 50, 100, 100 ); + + frame.validate(); + frame.setVisible(true); + } + + private static void captureAndTestChoices() { + Point c1loc = c1.getLocationOnScreen(); + Point c2loc = c2.getLocationOnScreen(); + + int startX = c1loc.x - GAP; + int startY = c1loc.y - GAP; + int captureWidth = c2loc.x + c2.getWidth() + GAP - startX; + int captureHeight = c2loc.y + c2.getHeight() + GAP - startY; + + BufferedImage bi = robot.createScreenCapture( + new Rectangle(startX, startY, captureWidth, captureHeight) + ); + + int redPix = Color.RED.getRGB(); + + int lastNonRedCount = 0; + + for (int y = 0; y < captureHeight; y++) { + int nonRedCount = 0; + for (int x = 0; x < captureWidth; x++) { + int pix = bi.getRGB(x, y); + if (pix != redPix) { + nonRedCount++; + } + } + + if (nonRedCount > 0 && lastNonRedCount > 0) { + if (lastNonRedCount - nonRedCount > 0) { + System.err.printf( + "Failed at %d, nonRedCount: %d lastNonRedCount: %d\n", + y, nonRedCount, lastNonRedCount + ); + + try { + ImageIO.write(bi, "png", new File("choices.png")); + } catch (IOException ignored) { + } + + throw new RuntimeException("Choices are not aligned"); + } + } + + lastNonRedCount = nonRedCount; + } + } +} diff --git a/test/jdk/java/awt/Choice/DeadlockTest.java b/test/jdk/java/awt/Choice/DeadlockTest.java new file mode 100644 index 0000000000000..fdc6d94e6ba81 --- /dev/null +++ b/test/jdk/java/awt/Choice/DeadlockTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Choice; +import java.awt.Frame; +import jdk.test.lib.Platform; + +/* + * @test + * @bug 4134619 + * @summary Tests that the EventDispatchThread doesn't deadlock with + * user threads which are modifying a Choice component. + * @library /java/awt/regtesthelpers /test/lib + * @build PassFailJFrame jdk.test.lib.Platform + * @run main/manual DeadlockTest + */ + +public class DeadlockTest extends Thread { + + static volatile Choice choice1; + static volatile Choice choice2; + static volatile Choice choice3; + static volatile Frame frame; + static int itemCount = 0; + + private static final boolean isWindows = Platform.isWindows(); + + private static final String INSTRUCTIONS = """ + Click on the top Choice component and hold the mouse still briefly. + Then, without releasing the mouse button, move the cursor to a menu + item and then again hold the mouse still briefly. + %s + Release the button and repeat this process. + + Verify that this does not cause a deadlock + or crash within a reasonable amount of time. + """.formatted( + isWindows + ? "(menu can automatically collapse sometimes, this is ok)\n" + : "" + + ) ; + + public static void main(String[] args) throws Exception { + DeadlockTest deadlockTest = new DeadlockTest(); + PassFailJFrame passFailJFrame = PassFailJFrame.builder() + .title("DeadlockTest Instructions") + .instructions(INSTRUCTIONS) + .columns(45) + .testUI(deadlockTest::createAndShowUI) + .build(); + + deadlockTest.start(); + + passFailJFrame.awaitAndCheck(); + } + + public Frame createAndShowUI() { + frame = new Frame("Check Choice"); + frame.setLayout(new BorderLayout()); + choice1 = new Choice(); + choice2 = new Choice(); + choice3 = new Choice(); + frame.add(choice1, BorderLayout.NORTH); + frame.add(choice3, BorderLayout.CENTER); + frame.add(choice2, BorderLayout.SOUTH); + frame.pack(); + return frame; + } + + public void run() { + while (true) { + if (choice1 != null && itemCount < 40) { + choice1.add("I am Choice, yes I am : " + itemCount * itemCount); + choice2.add("I am the same, yes I am : " + itemCount * itemCount); + choice3.add("I am the same, yes I am : " + itemCount * itemCount); + itemCount++; + } + if (itemCount >= 20 && choice1 != null && + choice1.getItemCount() > 0) { + choice1.removeAll(); + choice2.removeAll(); + choice3.removeAll(); + itemCount = 0; + } + frame.validate(); + try { + Thread.sleep(1000); + } catch (Exception ignored) {} + } + } +} diff --git a/test/jdk/java/awt/Choice/SetFontTest.java b/test/jdk/java/awt/Choice/SetFontTest.java new file mode 100644 index 0000000000000..f38a34a7ed278 --- /dev/null +++ b/test/jdk/java/awt/Choice/SetFontTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Choice; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Panel; + +/* + * @test + * @bug 4293346 + * @summary Checks that Choice does update its dimensions on font change + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual SetFontTest + */ + +public class SetFontTest { + + private static final String INSTRUCTIONS = """ + Choice component used to not update its dimension on font change. + Select one of fonts on the choice pull down list. + Pull down the list after the font change; if items in the list are + shown correctly the test is passed, otherwise it failed. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("SetFontTest Instructions") + .instructions(INSTRUCTIONS) + .columns(45) + .testUI(SetFontTest::createAndShowUI) + .build() + .awaitAndCheck(); + } + + private static Frame createAndShowUI() { + Frame frame = new Frame("SetFontTest"); + Choice choice = new Choice(); + frame.setBounds(100, 400, 400, 100); + choice.addItem("dummy"); + choice.addItem("Set LARGE Font"); + choice.addItem("Set small Font"); + choice.addItem("addNewItem"); + choice.addItem("deleteItem"); + + choice.addItemListener(e -> { + if (e.getItem().toString().equals("addNewItem")) { + choice.addItem("very very very very long item"); + frame.validate(); + } else if (e.getItem().toString().equals("deleteItem")) { + if (choice.getItemCount() > 4) { + choice.remove(4); + frame.validate(); + } + } else if (e.getItem().toString().equals("Set LARGE Font")) { + choice.setFont(new Font("Dialog", Font.PLAIN, 24)); + frame.validate(); + } else if (e.getItem().toString().equals("Set small Font")) { + choice.setFont(new Font("Dialog", Font.PLAIN, 10)); + frame.validate(); + } + }); + Panel panel = new Panel(); + panel.add(choice); + frame.add(panel, BorderLayout.CENTER); + return frame; + } +} From be3e9931cf3e41b9238d8f412fcfbd446177e004 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:23:59 +0000 Subject: [PATCH 069/846] 8341004: Open source AWT FileDialog related tests Backport-of: 7d524d7e378430afb3a262e8fe544bd1be22748c --- .../awt/FileDialog/DoubleActionCloseX.java | 75 +++++++++++ .../java/awt/FileDialog/DoubleActionESC.java | 122 ++++++++++++++++++ .../FileDialog/TestFileDialogDupJNIRef.java | 82 ++++++++++++ 3 files changed, 279 insertions(+) create mode 100644 test/jdk/java/awt/FileDialog/DoubleActionCloseX.java create mode 100644 test/jdk/java/awt/FileDialog/DoubleActionESC.java create mode 100644 test/jdk/java/awt/FileDialog/TestFileDialogDupJNIRef.java diff --git a/test/jdk/java/awt/FileDialog/DoubleActionCloseX.java b/test/jdk/java/awt/FileDialog/DoubleActionCloseX.java new file mode 100644 index 0000000000000..5d3feaa42ed4b --- /dev/null +++ b/test/jdk/java/awt/FileDialog/DoubleActionCloseX.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.FileDialog; +import java.awt.Frame; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/* + * @test + * @bug 6227750 + * @summary Tests that FileDialog can be closed by clicking the 'close' (X) button + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DoubleActionCloseX + */ + +public class DoubleActionCloseX { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + NOTE: On Linux and Mac, there is no 'close'(X) button + when file dialog is visible, press Pass. + + Click the 'Open File Dialog' button to open FileDialog. + A file dialog will appear on the screen. + Click on the 'close'(X) button. + The dialog should be closed. + If not, the test failed, press Fail otherwise press Pass. + """; + + PassFailJFrame.builder() + .title("DoubleActionCloseX Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(DoubleActionCloseX::createUI) + .build() + .awaitAndCheck(); + } + public static Frame createUI() { + Frame f = new Frame("DoubleActionCloseX Test"); + Button b = new Button("Open File Dialog"); + FileDialog fd = new FileDialog(f); + b.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + fd.setVisible(true); + } + }); + f.add(b); + f.setSize(300, 200); + return f; + } +} diff --git a/test/jdk/java/awt/FileDialog/DoubleActionESC.java b/test/jdk/java/awt/FileDialog/DoubleActionESC.java new file mode 100644 index 0000000000000..748c3aeb5e446 --- /dev/null +++ b/test/jdk/java/awt/FileDialog/DoubleActionESC.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FileDialog; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.util.concurrent.CountDownLatch; + +/* + * @test + * @bug 5097243 + * @summary Tests that FileDialog can be closed by ESC any time + * @key headful + * @run main DoubleActionESC + */ + +public class DoubleActionESC { + private static Frame f; + private static Button showBtn; + private static FileDialog fd; + private static Robot robot; + private static volatile Point p; + private static volatile Dimension d; + private static volatile CountDownLatch latch; + private static final int REPEAT_COUNT = 2; + + public static void main(String[] args) throws Exception { + latch = new CountDownLatch(1); + + robot = new Robot(); + robot.setAutoDelay(100); + try { + EventQueue.invokeAndWait(() -> { + createAndShowUI(); + }); + + robot.delay(1000); + EventQueue.invokeAndWait(() -> { + p = showBtn.getLocationOnScreen(); + d = showBtn.getSize(); + }); + + for (int i = 0; i < REPEAT_COUNT; ++i) { + Thread thread = new Thread(() -> { + robot.mouseMove(p.x + d.width / 2, p.y + d.height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + }); + thread.start(); + robot.delay(3000); + + Thread thread1 = new Thread(() -> { + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.waitForIdle(); + }); + thread1.start(); + robot.delay(3000); + } + + latch.await(); + if (fd.isVisible()) { + throw new RuntimeException("File Dialog is not closed"); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } + + public static void createAndShowUI() { + f = new Frame("DoubleActionESC Test"); + showBtn = new Button("Show File Dialog"); + fd = new FileDialog(f); + showBtn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (e.getSource() == showBtn) { + fd.setSize(200, 200); + fd.setLocation(200, 200); + fd.setVisible(true); + latch.countDown(); + } + } + }); + f.add(showBtn); + f.setSize(300, 200); + f.setLocationRelativeTo(null); + f.setVisible(true); + } +} diff --git a/test/jdk/java/awt/FileDialog/TestFileDialogDupJNIRef.java b/test/jdk/java/awt/FileDialog/TestFileDialogDupJNIRef.java new file mode 100644 index 0000000000000..56b6c49214488 --- /dev/null +++ b/test/jdk/java/awt/FileDialog/TestFileDialogDupJNIRef.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Dialog; +import java.awt.FileDialog; +import java.awt.FlowLayout; +import java.awt.Frame; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/* + * @test + * @bug 4906972 + * @summary Tests using of JNI reference to peer object. + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual TestFileDialogDupJNIRef + */ + +public class TestFileDialogDupJNIRef { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + This is a crash test. + After test started you will see 'Test Frame' with one button. + 1. Click the button to open FileDialog. + 2. Go to the dialog and choose any directory with some files in it.. + 3. Click on any file to highlight it. + 4. Click on the file again to rename. + 5. Leave the file in edit mode and click Open button + + If there was no crash the test passed, Press Pass. + """; + + PassFailJFrame.builder() + .title("TestFileDialogDupJNIRef Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(TestFileDialogDupJNIRef::createUI) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame frame = new Frame("TestFileDialogDupJNIRef Test Frame"); + Button open = new Button("Open File Dialog"); + + open.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + FileDialog fd = new FileDialog(frame); + fd.setVisible(true); + } + }); + + frame.setLayout(new FlowLayout()); + frame.add(open); + frame.setSize(250, 70); + return frame; + } +} From 4913ddbbc1dbaeee7f24d3efa9786dc4be96a0af Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:25:23 +0000 Subject: [PATCH 070/846] 8341298: Open source more AWT window tests Backport-of: db61458da840123925cb3ba079cfaf8277880320 --- .../TestLocationByPlatformWithControls.java | 270 ++++++++++++++++++ .../Window/NoResizeEvent/NoResizeEvent.java | 82 ++++++ .../Window/ProxyCrash/PopupProxyCrash.java | 192 +++++++++++++ .../WindowToFrontTest/WindowToFrontTest.java | 83 ++++++ 4 files changed, 627 insertions(+) create mode 100644 test/jdk/java/awt/Window/LocationByPlatformWithControls/TestLocationByPlatformWithControls.java create mode 100644 test/jdk/java/awt/Window/NoResizeEvent/NoResizeEvent.java create mode 100644 test/jdk/java/awt/Window/ProxyCrash/PopupProxyCrash.java create mode 100644 test/jdk/java/awt/Window/WindowToFrontTest/WindowToFrontTest.java diff --git a/test/jdk/java/awt/Window/LocationByPlatformWithControls/TestLocationByPlatformWithControls.java b/test/jdk/java/awt/Window/LocationByPlatformWithControls/TestLocationByPlatformWithControls.java new file mode 100644 index 0000000000000..bfdba97e4eb99 --- /dev/null +++ b/test/jdk/java/awt/Window/LocationByPlatformWithControls/TestLocationByPlatformWithControls.java @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4102292 + * @summary Tests that location by platform works with other APIs + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual TestLocationByPlatformWithControls + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Checkbox; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Panel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.Vector; + +public class TestLocationByPlatformWithControls extends Frame + implements ActionListener, ItemListener { + Panel northP; + Panel centerP; + Checkbox undecoratedCB; + Checkbox defaultLocationCB; + Checkbox visibleCB; + Checkbox iconifiedCB; + Checkbox maximizedCB; + Button createB; + Button packB; + Button moveB; + Button resizeB; + Button reshapeB; + Button disposeB; + Vector frames; + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + This test is to check that LocationByPlatform works with other + controls API. + 1) Create New Frame by clicking on "Create" Button in + "TestLocationByPlatformWithControls" window. + 2) Initially this Frame will not be visible, Click on checkbox + "LocationByPlatform" to set default platform location for the frame + and then click on checkbox "Visible" to see that Frame is displayed + at default offsets. + 3) Now you can play with different controls like Iconified, + Maximized, Pack, Move, Resize and Reshape to verify that these + controls work properly with the Frame. + 4) At the end dispose the Frame by clicking on "Dispose" button. + 5) Also we can do verify this for Undecorated Frame but for that we + need to follow same steps but in step 2 before we click on checkbox + "Visible", select "Undecorated" checkbox along with + "LocationByPlatform". + 6) If everything works properly test is passed, otherwise failed. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(TestLocationByPlatformWithControls::new) + .logArea(4) + .build() + .awaitAndCheck(); + } + + public TestLocationByPlatformWithControls() { + northP = new Panel(); + centerP = new Panel(); + + undecoratedCB = new Checkbox("Undecorated"); + defaultLocationCB = new Checkbox("LocationByPlatform"); + visibleCB = new Checkbox("Visible"); + iconifiedCB = new Checkbox("Iconified"); + maximizedCB = new Checkbox("Maximized"); + + createB = new Button("Create"); + packB = new Button("Pack"); + moveB = new Button("Move"); + resizeB = new Button("Resize"); + reshapeB = new Button("Reshape"); + disposeB = new Button("Dispose"); + + frames = new Vector(10); + this.setTitle("TestLocationByPlatformWithControls"); + this.setLayout(new BorderLayout()); + this.add(northP, BorderLayout.NORTH); + + northP.add(new Label("New Frame")); + + createB.addActionListener(this); + northP.add(createB); + + centerP.setEnabled(false); + this.add(centerP, BorderLayout.CENTER); + + centerP.add(new Label("Last Frame")); + + centerP.add(defaultLocationCB); + defaultLocationCB.addItemListener(this); + + centerP.add(undecoratedCB); + undecoratedCB.addItemListener(this); + + centerP.add(iconifiedCB); + iconifiedCB.addItemListener(this); + + centerP.add(maximizedCB); + maximizedCB.addItemListener(this); + + centerP.add(visibleCB); + visibleCB.addItemListener(this); + + packB.addActionListener(this); + centerP.add(packB); + + moveB.addActionListener(this); + centerP.add(moveB); + + resizeB.addActionListener(this); + centerP.add(resizeB); + + reshapeB.addActionListener(this); + centerP.add(reshapeB); + + disposeB.addActionListener(this); + centerP.add(disposeB); + this.pack(); + } + + public void actionPerformed(ActionEvent e) { + if (e.getSource() == createB) { + Frame frame = new Frame(); + frame.setSize(200, 200); + frames.add(frame); + updateControls(frame); + Panel panel = new Panel(); + frame.add(panel); + panel.add(new Button ("Test Button")); + panel.add(new Button ("Test Button 1")); + panel.add(new Button ("Test Button 2")); + panel.add(new Button ("Test Button 3")); + centerP.setEnabled(true); + return; + } + + if (frames.isEmpty()) { + return; + } + + Frame last = (Frame)frames.lastElement(); + + if (e.getSource() == packB) { + last.pack(); + } else + if (e.getSource() == moveB) { + int x = (int)(Math.random() * 200); + int y = (int)(Math.random() * 200); + last.setLocation(x, y); + } else + if (e.getSource() == resizeB) { + int w = (int)(Math.random() * 200); + int h = (int)(Math.random() * 200); + last.setSize(w, h); + } else + if (e.getSource() == reshapeB) { + int x = (int)(Math.random() * 200); + int y = (int)(Math.random() * 200); + int w = (int)(Math.random() * 200); + int h = (int)(Math.random() * 200); + last.setBounds(x, y, w, h); + } else + if (e.getSource() == disposeB) { + last.dispose(); + frames.remove(frames.size() - 1); + if (frames.isEmpty()) { + updateControls(null); + centerP.setEnabled(false); + return; + } + last = (Frame)frames.lastElement(); + } + updateControls(last); + } + + public void updateControls(Frame f) { + undecoratedCB.setState(f != null ? + f.isUndecorated() : false); + defaultLocationCB.setState(f != null ? + f.isLocationByPlatform() : false); + visibleCB.setState(f != null ? + f.isVisible() : false); + iconifiedCB.setState(f != null ? + (f.getExtendedState() & Frame.ICONIFIED) != 0 : false); + maximizedCB.setState(f != null ? + (f.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0 : false); + } + + public void itemStateChanged(ItemEvent e) { + Frame last = (Frame)frames.lastElement(); + try { + boolean state = e.getStateChange() == ItemEvent.SELECTED; + if (e.getSource() == visibleCB) { + last.setVisible(state); + } else + if (e.getSource() == defaultLocationCB) { + last.setLocationByPlatform(state); + } else + if (e.getSource() == undecoratedCB) { + last.setUndecorated(state); + } else + if (e.getSource() == iconifiedCB) { + if (state) { + last.setExtendedState(last.getExtendedState() | + Frame.ICONIFIED); + } else { + last.setExtendedState(last.getExtendedState() & + ~Frame.ICONIFIED); + } + } else + if (e.getSource() == maximizedCB) { + if (state) { + last.setExtendedState(last.getExtendedState() | + Frame.MAXIMIZED_BOTH); + } else { + last.setExtendedState(last.getExtendedState() & + ~Frame.MAXIMIZED_BOTH); + } + } + } catch (Throwable ex) { + PassFailJFrame.log(ex.getMessage()); + } finally { + updateControls(last); + } + } + + @Override + public void dispose() { + while (!frames.isEmpty()) { + Frame last = (Frame)frames.lastElement(); + last.dispose(); + frames.remove(frames.size() - 1); + } + } +} diff --git a/test/jdk/java/awt/Window/NoResizeEvent/NoResizeEvent.java b/test/jdk/java/awt/Window/NoResizeEvent/NoResizeEvent.java new file mode 100644 index 0000000000000..50b264acde970 --- /dev/null +++ b/test/jdk/java/awt/Window/NoResizeEvent/NoResizeEvent.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4942457 + * @key headful + * @summary Verifies that filtering of resize events on native level works. + * I.E.after Frame is shown no additional resize events are generated. + * @library /java/awt/patchlib ../../regtesthelpers + * @build java.desktop/java.awt.Helper + * @build Util + * @run main NoResizeEvent + */ + +import test.java.awt.regtesthelpers.Util; + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; + +public class NoResizeEvent { + //Mutter can send window insets too late, causing additional resize events. + private static final boolean IS_MUTTER = Util.getWMID() == Util.MUTTER_WM; + private static final int RESIZE_COUNT_LIMIT = IS_MUTTER ? 5 : 3; + private static Frame frame; + static int resize_count = 0; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> createUI()); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + if (resize_count > RESIZE_COUNT_LIMIT) { + throw new RuntimeException("Resize event arrived: " + + resize_count + " times."); + } + } + } + + private static void createUI() { + frame = new Frame("NoResizeEvent"); + frame.addComponentListener(new ComponentAdapter() { + public void componentResized(ComponentEvent e) { + System.out.println(e); + resize_count++; + } + }); + frame.setVisible(true); + + try { + Thread.sleep(3000); + } catch (InterruptedException ie) { + } + System.out.println("Resize count: " + resize_count); + } +} diff --git a/test/jdk/java/awt/Window/ProxyCrash/PopupProxyCrash.java b/test/jdk/java/awt/Window/ProxyCrash/PopupProxyCrash.java new file mode 100644 index 0000000000000..b17b934a70280 --- /dev/null +++ b/test/jdk/java/awt/Window/ProxyCrash/PopupProxyCrash.java @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4381561 + * @key headful + * @summary Tests that when we show the popup window AWT doesn't crash due to + * the problems with focus proxy window code + * @run main PopupProxyCrash + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; + +import javax.swing.Box; +import javax.swing.JComboBox; +import javax.swing.JTextField; +import javax.swing.plaf.basic.BasicComboBoxUI; +import javax.swing.plaf.basic.BasicComboPopup; +import javax.swing.plaf.basic.ComboPopup; + +public class PopupProxyCrash implements ActionListener { + private static JTextField jtf; + private static Button tf; + private static Panel panel; + private static Font[] fonts; + private static Robot robot; + + private static JComboBox cb; + + private static MyComboBoxUI comboBoxUI; + private static Frame frame; + private static int TEST_COUNT = 10; + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + robot.setAutoDelay(100); + EventQueue.invokeAndWait(() -> createUI()); + robot.waitForIdle(); + runTest(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createUI() { + frame = new Frame("PopupProxyCrash"); + Font dialog = new Font("Dialog", Font.PLAIN, 12); + Font serif = new Font("Serif", Font.PLAIN, 12); + Font monospaced = new Font("Monospaced", Font.PLAIN, 12); + + fonts = new Font[] { dialog, serif, monospaced }; + + cb = new JComboBox(fonts); + + cb.setLightWeightPopupEnabled(false); + comboBoxUI = new MyComboBoxUI(); + cb.setUI(comboBoxUI); + jtf = new JTextField("JTextField"); + jtf.setFont(fonts[1]); + tf = new Button("TextField"); + tf.setFont(fonts[1]); + cb.addActionListener(new PopupProxyCrash()); + + panel = new Panel() { + public Dimension getPreferredSize() { + return new Dimension(100, 20); + } + public void paint(Graphics g) { + System.out.println("Painting with font " + getFont()); + g.setColor(Color.white); + g.fillRect(0, 0, getWidth(), getHeight()); + g.setColor(Color.black); + g.setFont(getFont()); + g.drawString("LightWeight", 10, 10); + } + }; + panel.setFont(fonts[1]); + + Container parent = Box.createVerticalBox(); + parent.add(jtf); + parent.add(tf); + parent.add(panel); + parent.add(cb); + + frame.add(parent, BorderLayout.CENTER); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + private static Point getComboBoxLocation() throws Exception { + final Point[] result = new Point[1]; + + EventQueue.invokeAndWait(() -> { + Point point = cb.getLocationOnScreen(); + Dimension size = cb.getSize(); + + point.x += size.width / 2; + point.y += size.height / 2; + result[0] = point; + }); + return result[0]; + } + + private static Point getItemPointToClick(final int item) throws Exception { + final Point[] result = new Point[1]; + + EventQueue.invokeAndWait(() -> { + BasicComboPopup popup = (BasicComboPopup)comboBoxUI.getComboPopup(); + Point point = popup.getLocationOnScreen(); + Dimension size = popup.getSize(); + + int step = size.height / fonts.length; + point.x += size.width / 2; + point.y += step / 2 + step * item; + result[0] = point; + }); + return result[0]; + } + + static void runTest() throws Exception { + for (int i = 0; i < TEST_COUNT; i++) { + Point point = getComboBoxLocation(); + robot.mouseMove(point.x, point.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.delay(500); + + point = getItemPointToClick(i % fonts.length); + robot.mouseMove(point.x, point.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.delay(500); + } + } + public void actionPerformed(ActionEvent ae) { + System.out.println("Font selected"); + Font font = fonts[((JComboBox)ae.getSource()).getSelectedIndex()]; + + tf.setFont(font); + jtf.setFont(font); + panel.setFont(font); + panel.repaint(); + } + + private static class MyComboBoxUI extends BasicComboBoxUI { + public ComboPopup getComboPopup() { + return popup; + } + } +} diff --git a/test/jdk/java/awt/Window/WindowToFrontTest/WindowToFrontTest.java b/test/jdk/java/awt/Window/WindowToFrontTest/WindowToFrontTest.java new file mode 100644 index 0000000000000..e6bbadcb546db --- /dev/null +++ b/test/jdk/java/awt/Window/WindowToFrontTest/WindowToFrontTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4488209 + * @summary JFrame toFront causes the entire frame to be repainted, causes UI + * to flash + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual WindowToFrontTest + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class WindowToFrontTest implements ActionListener { + static Frame frame; + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1) Click the "toFront" button, this causes the + "WindowToFrontTest" frame to move front and gets repainted + completely. + 2) Move "WindowToFrontTest" window and continue to click on "toFront + multiple times. If the "WindowToFrontTest" Frame content is not + drawn properly and continues to blink, test is failed + otherwise passed. + """; + + PassFailJFrame passFailJFrame = PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows(13) + .columns(40) + .build(); + EventQueue.invokeAndWait(() -> createUI()); + passFailJFrame.awaitAndCheck(); + } + + private static void createUI() { + frame = new Frame("WindowToFrontTest"); + frame.setLayout(new BorderLayout()); + frame.setSize(512, 512); + PassFailJFrame.addTestWindow(frame); + frame.setVisible(true); + + Frame buttonFrame = new Frame("Test Button"); + Button push = new Button("toFront"); + push.addActionListener(new WindowToFrontTest()); + buttonFrame.add(push); + buttonFrame.pack(); + PassFailJFrame.addTestWindow(buttonFrame); + buttonFrame.setVisible(true); + } + + public void actionPerformed(ActionEvent e) { + frame.toFront(); + } +} From 4fa11fe7554c094447c7026a243e0b1622e25396 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:26:46 +0000 Subject: [PATCH 071/846] 8340809: Open source few more AWT PopupMenu tests Backport-of: 313f4a962148331c9958618054109284470d1c9f --- .../awt/PopupMenu/ActivePopupCrashTest.java | 220 ++++++++++++++++++ .../java/awt/PopupMenu/KeyTraversalCrash.java | 126 ++++++++++ .../awt/PopupMenu/MultiplePopupMenusTest.java | 86 +++++++ .../java/awt/PopupMenu/PopupMenuCrash.java | 106 +++++++++ test/jdk/java/awt/PopupMenu/StressTest.java | 142 +++++++++++ 5 files changed, 680 insertions(+) create mode 100644 test/jdk/java/awt/PopupMenu/ActivePopupCrashTest.java create mode 100644 test/jdk/java/awt/PopupMenu/KeyTraversalCrash.java create mode 100644 test/jdk/java/awt/PopupMenu/MultiplePopupMenusTest.java create mode 100644 test/jdk/java/awt/PopupMenu/PopupMenuCrash.java create mode 100644 test/jdk/java/awt/PopupMenu/StressTest.java diff --git a/test/jdk/java/awt/PopupMenu/ActivePopupCrashTest.java b/test/jdk/java/awt/PopupMenu/ActivePopupCrashTest.java new file mode 100644 index 0000000000000..51c12964e6295 --- /dev/null +++ b/test/jdk/java/awt/PopupMenu/ActivePopupCrashTest.java @@ -0,0 +1,220 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.Point; +import java.awt.PopupMenu; +import java.awt.Robot; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import java.util.Hashtable; + +/* + * @test + * @bug 4214550 + * @summary Tests that there is no seg fault on repeatedly showing + * PopupMenu by right-clicking Label, Panel or Button + * @key headful + * @run main ActivePopupCrashTest + */ + +public class ActivePopupCrashTest { + private static Frame f; + private static Label l; + private static Button b; + private static Panel p; + + private static volatile Point labelCenter; + private static volatile Point buttonCenter; + private static volatile Point panelCenter; + + public static void main(String[] args) throws Exception { + final int REPEAT_COUNT = 5; + try { + Robot robot = new Robot(); + robot.setAutoDelay(50); + EventQueue.invokeAndWait(ActivePopupCrashTest::createAndShowUI); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + labelCenter = getCenterPoint(l); + buttonCenter = getCenterPoint(b); + panelCenter = getCenterPoint(p); + }); + + for (int i = 0; i < REPEAT_COUNT; i++) { + robot.mouseMove(labelCenter.x, labelCenter.y); + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); + + robot.mouseMove(buttonCenter.x, buttonCenter.y); + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); + + robot.mouseMove(panelCenter.x, panelCenter.y); + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); + } + + // To close the popup, otherwise test fails on windows with timeout error + robot.mouseMove(panelCenter.x - 5, panelCenter.y - 5); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } finally { + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } + + private static Point getCenterPoint(Component component) { + Point p = component.getLocationOnScreen(); + Dimension size = component.getSize(); + return new Point(p.x + size.width / 2, p.y + size.height / 2); + } + + public static void createAndShowUI() { + f = new Frame("ActivePopupCrashTest Test"); + MenuItem item = new MenuItem("file-1"); + item.addActionListener(ActivePopupCrashTest::logActionEvent); + Menu m = new Menu("file"); + m.add(item); + item = new MenuItem("file-2"); + m.add(item); + MenuBar mb = new MenuBar(); + mb.add(m); + + f.setMenuBar(mb); + f.setSize(200, 200); + f.setLayout(new BorderLayout()); + + l = new Label("label"); + addPopup(l, "label"); + f.add(l, BorderLayout.NORTH); + + p = new Panel(); + addPopup(p, "panel"); + f.add(p, BorderLayout.CENTER); + + b = new Button("button"); + addPopup(b, "button"); + f.add(b, BorderLayout.SOUTH); + + f.setSize(400, 300); + f.setLocationRelativeTo(null); + f.setVisible(true); + } + + static void addPopup(Component c, String name) { + PopupMenu pm = new PopupMenu(); + MenuItem mi = new MenuItem(name + "-1"); + mi.addActionListener(ActivePopupCrashTest::logActionEvent); + pm.add(mi); + + mi = new MenuItem(name + "-2"); + pm.add(mi); + + setHash(c, pm); + c.add(pm); + c.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + mouseAction("mouseClicked", e); + } + + @Override + public void mousePressed(MouseEvent e) { + mouseAction("mousePressed", e); + } + + @Override + public void mouseReleased(MouseEvent e) { + mouseAction("mouseReleased", e); + } + }); + } + + static void logActionEvent(ActionEvent e) { + System.out.println("actionPerformed, event=" + e + ", mod=" + getMods(e)); + System.out.println("command=" + e.getActionCommand()); + System.out.println("param=" + e.paramString()); + System.out.println("source=" + e.getSource()); + } + + static String getMods(ActionEvent e) { return getMods(e.getModifiers()); } + + static String getMods(MouseEvent e) { return getMods(e.getModifiers()); } + + static String getMods(int mods) { + String modstr = ""; + if ((mods & ActionEvent.SHIFT_MASK) == ActionEvent.SHIFT_MASK) { + modstr += (" SHIFT"); + } else if ((mods & ActionEvent.ALT_MASK) == ActionEvent.ALT_MASK) { + modstr += (" ALT"); + } else if ((mods & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK) { + modstr += (" CTRL"); + } else if ((mods & ActionEvent.META_MASK) == ActionEvent.META_MASK) { + modstr += (" META"); + } + return modstr; + } + + static void mouseAction(String which, MouseEvent e) { + Component c = e.getComponent(); + System.out.println(which + " e = " + e + " , mods = " + getMods(e) + + " , component = " + c); + if (e.isPopupTrigger()) { + System.out.println("isPopup"); + PopupMenu pm = getHash(c); + pm.show(c, c.getWidth() / 2, c.getHeight() / 2); + } + } + + static Hashtable popupTable = new Hashtable<>(); + + static void setHash(Component c, PopupMenu p) { + popupTable.put(c, p); + } + + static PopupMenu getHash(Component c) { + return popupTable.get(c); + } + +} diff --git a/test/jdk/java/awt/PopupMenu/KeyTraversalCrash.java b/test/jdk/java/awt/PopupMenu/KeyTraversalCrash.java new file mode 100644 index 0000000000000..4d1d4e8f8319b --- /dev/null +++ b/test/jdk/java/awt/PopupMenu/KeyTraversalCrash.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.Point; +import java.awt.PopupMenu; +import java.awt.Robot; + +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 5021183 + * @summary Tests Key Traversal doesn't crash PopupMenu + * @key headful + * @run main KeyTraversalCrash + */ + +public class KeyTraversalCrash { + private static Frame f; + private static Label label; + + private static volatile Point loc; + private static volatile Dimension dim; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoDelay(100); + EventQueue.invokeAndWait(KeyTraversalCrash::createAndShowUI); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + loc = label.getLocationOnScreen(); + dim = label.getSize(); + }); + + robot.mouseMove(loc.x + 20, loc.y + 20); + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); + + robot.mouseMove(loc.x + 25, loc.y + 25); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.keyPress(KeyEvent.VK_LEFT); + robot.keyRelease(KeyEvent.VK_LEFT); + + robot.keyPress(KeyEvent.VK_DOWN); + robot.keyRelease(KeyEvent.VK_DOWN); + + // To close the popup, otherwise test fails on windows with timeout error + robot.mouseMove(loc.x + dim.width - 20, loc.y + dim.height - 20); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } finally { + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } + + public static void createAndShowUI() { + f = new Frame("KeyTraversalCrash Test"); + final PopupMenu popup = new PopupMenu(); + for (int i = 0; i < 10; i++) { + Menu menu = new Menu("Menu " + i); + for(int j = 0; j < 10; j++) { + MenuItem menuItem = new MenuItem("MenuItem " + j); + menu.add(menuItem); + } + popup.add(menu); + } + label = new Label("Label"); + f.add(label); + f.add(popup); + label.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent me) { + if (me.isPopupTrigger()) { + popup.show(me.getComponent(), me.getX(), me.getY()); + } + } + + @Override + public void mouseReleased(MouseEvent me) { + if (me.isPopupTrigger()) { + popup.show(me.getComponent(), me.getX(), me.getY()); + } + } + }); + f.setSize(200, 200); + f.setLocationRelativeTo(null); + f.setVisible(true); + } +} diff --git a/test/jdk/java/awt/PopupMenu/MultiplePopupMenusTest.java b/test/jdk/java/awt/PopupMenu/MultiplePopupMenusTest.java new file mode 100644 index 0000000000000..f939186ca072e --- /dev/null +++ b/test/jdk/java/awt/PopupMenu/MultiplePopupMenusTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTEvent; +import java.awt.Button; +import java.awt.Frame; +import java.awt.MenuItem; +import java.awt.PopupMenu; + +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 4186663 4265525 + * @summary Tests that multiple PopupMenus cannot appear at the same time + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MultiplePopupMenusTest + */ + +public class MultiplePopupMenusTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Click the right mouse button on the button + If multiple popups appear at the same time the + test fails else passes. + """; + + PassFailJFrame.builder() + .title("MultiplePopupMenusTest Instruction") + .instructions(INSTRUCTIONS) + .columns(30) + .testUI(MultiplePopupMenusTest::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + Frame fr = new Frame("MultiplePopupMenusTest Test"); + TestButton button = new TestButton("button"); + fr.add(button); + fr.setSize(200, 200); + return fr; + } + + static class TestButton extends Button { + public TestButton(String title) { + super(title); + enableEvents(AWTEvent.MOUSE_EVENT_MASK); + } + + @Override + public void processMouseEvent(MouseEvent e) { + if (e.isPopupTrigger()) { + for (int i = 0; i < 10; i++) { + PopupMenu pm = new PopupMenu("Popup " + i); + pm.add(new MenuItem("item 1")); + pm.add(new MenuItem("item 2")); + add(pm); + pm.show(this, e.getX() + i * 5, e.getY() + i * 5); + } + } + super.processMouseEvent(e); + } + } +} diff --git a/test/jdk/java/awt/PopupMenu/PopupMenuCrash.java b/test/jdk/java/awt/PopupMenu/PopupMenuCrash.java new file mode 100644 index 0000000000000..7ba738b21d276 --- /dev/null +++ b/test/jdk/java/awt/PopupMenu/PopupMenuCrash.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.MenuItem; +import java.awt.PopupMenu; + +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 4281273 + * @summary PopupMenu crashed in Java. Simplified testcase. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @requires (os.family == "windows") + * @run main/manual PopupMenuCrash + */ + +public class PopupMenuCrash { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + This tests a windows specific problem. + When you see a frame titled "PopupMenuCrash Test", right-click on it + several times for a few seconds. Then wait about 10 seconds before the + PopupMenus start to appear. Then dispose them one by one by clicking on them. + When PopupMenus do not appear anymore, press Pass. + In case of a failure, you'll see a crash. + """; + + PassFailJFrame.builder() + .title("PopupMenuCrash Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(PopupMenuCrash::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + final Frame f = new Frame("PopupMenuCrash Test"); + f.setLayout(new FlowLayout()); + f.add(new Label("Press right mouse button inside this frame.")); + f.add(new Label("A pop-up menu should appear.")); + f.addMouseListener(new MouseAdapter() { + PopupMenu popup; + boolean firstPress = true; + + @Override + public void mousePressed(MouseEvent evt) { + if (firstPress) { + firstPress = false; + try { + Thread.sleep(10000); + } catch (InterruptedException ignored) { + } + } + + if ((evt.getModifiers() & InputEvent.BUTTON3_MASK) != 0) { + popup = new PopupMenu("Popup Menu Title"); + MenuItem mi = new MenuItem("MenuItem"); + popup.add(mi); + f.add(popup); + popup.show(evt.getComponent(), evt.getX(), evt.getY()); + } + } + + @Override + public void mouseReleased(MouseEvent evt) { + if ((evt.getModifiers() & InputEvent.BUTTON3_MASK) != 0) { + if (popup != null) { + f.remove(popup); + popup = null; + } + } + } + }); + + f.setSize(400, 350); + return f; + } +} diff --git a/test/jdk/java/awt/PopupMenu/StressTest.java b/test/jdk/java/awt/PopupMenu/StressTest.java new file mode 100644 index 0000000000000..221aa252aa0b7 --- /dev/null +++ b/test/jdk/java/awt/PopupMenu/StressTest.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.Point; +import java.awt.PopupMenu; +import java.awt.Robot; + +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 4083400 + * @key headful + * @summary Tests that excessive popping up and down does not crash or + * throw an exception. + * @run main StressTest + */ + +public class StressTest { + private static Frame fr; + private static PopupTestPanel panel; + + private static volatile Point panelCenter; + + public static void main(String[] args) throws Exception { + final int REPEAT_COUNT = 5; + try { + Robot robot = new Robot(); + robot.setAutoDelay(50); + EventQueue.invokeAndWait(StressTest::createAndShowUI); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + Point loc = panel.getLocationOnScreen(); + Dimension dim = panel.getSize(); + panelCenter = new Point(loc.x + dim.width / 2, loc.y + dim.height / 2); + }); + + for (int i = 0; i < REPEAT_COUNT; i++) { + robot.mouseMove(panelCenter.x + i * 2, panelCenter.y + i * 2); + + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); + + robot.mouseMove(panelCenter.x - i * 2, panelCenter.y - i * 2); + + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (fr != null) { + fr.dispose(); + } + }); + } + } + + public static void createAndShowUI() { + fr = new Frame("PopupMenu Test"); + panel = new PopupTestPanel(); + fr.add(panel); + fr.setSize(300, 200); + fr.setVisible(true); + } + + static class PopupTestPanel extends Panel { + + static class Item extends MenuItem { + public Item(String text) { + super(text); + } + + public boolean isEnabled() { + try { + Thread.sleep(100); + } catch (InterruptedException ignored) { + } + return super.isEnabled(); + } + } + + final PopupMenu popup; + + public PopupTestPanel() { + popup = new PopupMenu(); + popup.add(new Item("Soap")); + popup.add(new Item("Sponge")); + popup.add(new Item("Flannel")); + popup.add(new Item("Mat")); + popup.add(new Item("Towel")); + add(popup); + addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + if (e.isPopupTrigger()) { + showPopup(e); + } + } + + @Override + public void mouseReleased(MouseEvent e) { + if (e.isPopupTrigger()) { + showPopup(e); + } + } + + private void showPopup(MouseEvent e) { + popup.show((Component) e.getSource(), e.getX(), e.getY()); + } + }); + } + } +} From 36f9ed8a67aaf99ce263ebbde6b8e16e6c0bc2e7 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:27:57 +0000 Subject: [PATCH 072/846] 8337221: CompileFramework: test library to conveniently compile java and jasm sources for fuzzing Reviewed-by: rrich Backport-of: e654a536dcb2b2b3784893d7aa6f5137223d8735 --- .../compile_framework/ClassLoaderBuilder.java | 64 ++++++ .../lib/compile_framework/Compile.java | 202 ++++++++++++++++++ .../compile_framework/CompileFramework.java | 169 +++++++++++++++ .../CompileFrameworkException.java | 37 ++++ .../InternalCompileFrameworkException.java | 37 ++++ .../compiler/lib/compile_framework/README.md | 57 +++++ .../lib/compile_framework/SourceCode.java | 35 +++ .../compiler/lib/compile_framework/Utils.java | 81 +++++++ .../examples/CombinedJavaJasmExample.java | 114 ++++++++++ .../examples/IRFrameworkJavaExample.java | 156 ++++++++++++++ .../examples/MultiFileJasmExample.java | 88 ++++++++ .../examples/MultiFileJavaExample.java | 81 +++++++ .../examples/RunWithFlagsExample.java | 99 +++++++++ .../examples/SimpleJasmExample.java | 79 +++++++ .../examples/SimpleJavaExample.java | 73 +++++++ .../tests/TestBadJasmCompilation.java | 62 ++++++ .../tests/TestBadJavaCompilation.java | 62 ++++++ .../tests/TestConcurrentCompilation.java | 108 ++++++++++ .../jdk/test/lib/process/OutputAnalyzer.java | 7 + 19 files changed, 1611 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/lib/compile_framework/ClassLoaderBuilder.java create mode 100644 test/hotspot/jtreg/compiler/lib/compile_framework/Compile.java create mode 100644 test/hotspot/jtreg/compiler/lib/compile_framework/CompileFramework.java create mode 100644 test/hotspot/jtreg/compiler/lib/compile_framework/CompileFrameworkException.java create mode 100644 test/hotspot/jtreg/compiler/lib/compile_framework/InternalCompileFrameworkException.java create mode 100644 test/hotspot/jtreg/compiler/lib/compile_framework/README.md create mode 100644 test/hotspot/jtreg/compiler/lib/compile_framework/SourceCode.java create mode 100644 test/hotspot/jtreg/compiler/lib/compile_framework/Utils.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/CombinedJavaJasmExample.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/IRFrameworkJavaExample.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/MultiFileJasmExample.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/MultiFileJavaExample.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/RunWithFlagsExample.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/SimpleJasmExample.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/SimpleJavaExample.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestBadJasmCompilation.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestBadJavaCompilation.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestConcurrentCompilation.java diff --git a/test/hotspot/jtreg/compiler/lib/compile_framework/ClassLoaderBuilder.java b/test/hotspot/jtreg/compiler/lib/compile_framework/ClassLoaderBuilder.java new file mode 100644 index 0000000000000..2f14cfb0f0489 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/compile_framework/ClassLoaderBuilder.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 compiler.lib.compile_framework; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +/** + * Build a ClassLoader that loads from classpath and {@code classesDir}. + * Helper class that generates a ClassLoader which allows loading classes + * from the classpath (see {@link Utils#getClassPaths()}) and {@code classesDir}. + *

+ * The CompileFramework compiles all its classes to a specific {@code classesDir}, + * and this generated ClassLoader thus can be used to load those classes. + */ +class ClassLoaderBuilder { + + /** + * Build a ClassLoader that loads from classpath and {@code classesDir}. + */ + public static ClassLoader build(Path classesDir) { + ClassLoader sysLoader = ClassLoader.getSystemClassLoader(); + + try { + // Classpath for all included classes (e.g. IR Framework). + // Get all class paths, convert to URLs. + List urls = new ArrayList<>(); + for (String path : Utils.getClassPaths()) { + urls.add(new File(path).toURI().toURL()); + } + // And add in the compiled classes from this instance of CompileFramework. + urls.add(new File(classesDir.toString()).toURI().toURL()); + return URLClassLoader.newInstance(urls.toArray(URL[]::new), sysLoader); + } catch (IOException e) { + throw new CompileFrameworkException("IOException while creating ClassLoader", e); + } + } +} diff --git a/test/hotspot/jtreg/compiler/lib/compile_framework/Compile.java b/test/hotspot/jtreg/compiler/lib/compile_framework/Compile.java new file mode 100644 index 0000000000000..0f45d982af6d6 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/compile_framework/Compile.java @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 compiler.lib.compile_framework; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.concurrent.TimeUnit; +import java.util.List; +import jdk.test.lib.JDKToolFinder; + +/** + * Helper class for compilation of Java and Jasm {@link SourceCode}. + */ +class Compile { + private static final int COMPILE_TIMEOUT = 60; + + private static final String JAVA_PATH = JDKToolFinder.getJDKTool("java"); + private static final String JAVAC_PATH = JDKToolFinder.getJDKTool("javac"); + + /** + * Compile all sources in {@code javaSources}. First write them to the {@code sourceDir}, + * then compile them to class-files which are stored in {@code classesDir}. + */ + public static void compileJavaSources(List javaSources, Path sourceDir, Path classesDir) { + if (javaSources.isEmpty()) { + Utils.printlnVerbose("No java sources to compile."); + return; + } + Utils.printlnVerbose("Compiling Java sources: " + javaSources.size()); + + List javaFilePaths = writeSourcesToFiles(javaSources, sourceDir); + compileJavaFiles(javaFilePaths, classesDir); + Utils.printlnVerbose("Java sources compiled."); + } + + /** + * Compile a list of files (i.e. {@code paths}) using javac and store + * them in {@code classesDir}. + */ + private static void compileJavaFiles(List paths, Path classesDir) { + List command = new ArrayList<>(); + + command.add(JAVAC_PATH); + command.add("-classpath"); + // Note: the backslashes from windows paths must be escaped! + command.add(Utils.getEscapedClassPathAndClassesDir(classesDir)); + command.add("-d"); + command.add(classesDir.toString()); + for (Path path : paths) { + command.add(path.toAbsolutePath().toString()); + } + + executeCompileCommand(command); + } + + /** + * Compile all sources in {@code jasmSources}. First write them to the {@code sourceDir}, + * then compile them to class-files which are stored in {@code classesDir}. + */ + public static void compileJasmSources(List jasmSources, Path sourceDir, Path classesDir) { + if (jasmSources.isEmpty()) { + Utils.printlnVerbose("No jasm sources to compile."); + return; + } + Utils.printlnVerbose("Compiling jasm sources: " + jasmSources.size()); + + List jasmFilePaths = writeSourcesToFiles(jasmSources, sourceDir); + compileJasmFiles(jasmFilePaths, classesDir); + Utils.printlnVerbose("Jasm sources compiled."); + } + + /** + * Compile a list of files (i.e. {@code paths}) using asmtools jasm and store + * them in {@code classesDir}. + */ + private static void compileJasmFiles(List paths, Path classesDir) { + List command = new ArrayList<>(); + + command.add(JAVA_PATH); + command.add("-classpath"); + command.add(getAsmToolsPath()); + command.add("org.openjdk.asmtools.jasm.Main"); + command.add("-d"); + command.add(classesDir.toString()); + for (Path path : paths) { + command.add(path.toAbsolutePath().toString()); + } + + executeCompileCommand(command); + } + + /** + * Get the path of asmtools, which is shipped with JTREG. + */ + private static String getAsmToolsPath() { + for (String path : Utils.getClassPaths()) { + if (path.endsWith("jtreg.jar")) { + File jtreg = new File(path); + File dir = jtreg.getAbsoluteFile().getParentFile(); + File asmtools = new File(dir, "asmtools.jar"); + if (!asmtools.exists()) { + throw new InternalCompileFrameworkException("Found jtreg.jar in classpath, but could not find asmtools.jar"); + } + return asmtools.getAbsolutePath(); + } + } + throw new InternalCompileFrameworkException("Could not find asmtools because could not find jtreg.jar in classpath"); + } + + private static void writeCodeToFile(String code, Path path) { + Utils.printlnVerbose("File: " + path); + + // Ensure directory of the file exists. + Path dir = path.getParent(); + try { + Files.createDirectories(dir); + } catch (Exception e) { + throw new CompileFrameworkException("Could not create directory: " + dir, e); + } + + // Write to file. + try (BufferedWriter writer = Files.newBufferedWriter(path)) { + writer.write(code); + } catch (Exception e) { + throw new CompileFrameworkException("Could not write file: " + path, e); + } + } + + /** + * Write each source in {@code sources} to a file inside {@code sourceDir}. + */ + private static List writeSourcesToFiles(List sources, Path sourceDir) { + List storedFiles = new ArrayList<>(); + for (SourceCode sourceCode : sources) { + Path path = sourceDir.resolve(sourceCode.filePathName()); + writeCodeToFile(sourceCode.code(), path); + storedFiles.add(path); + } + return storedFiles; + } + + /** + * Execute a given compilation, given as a {@code command}. + */ + private static void executeCompileCommand(List command) { + Utils.printlnVerbose("Compile command: " + String.join(" ", command)); + + ProcessBuilder builder = new ProcessBuilder(command); + builder.redirectErrorStream(true); + + String output; + int exitCode; + try { + Process process = builder.start(); + boolean exited = process.waitFor(COMPILE_TIMEOUT, TimeUnit.SECONDS); + if (!exited) { + process.destroyForcibly(); + System.out.println("Timeout: compile command: " + String.join(" ", command)); + throw new InternalCompileFrameworkException("Process timeout: compilation took too long."); + } + output = new String(process.getInputStream().readAllBytes(), StandardCharsets.UTF_8); + exitCode = process.exitValue(); + } catch (IOException e) { + throw new InternalCompileFrameworkException("IOException during compilation", e); + } catch (InterruptedException e) { + throw new CompileFrameworkException("InterruptedException during compilation", e); + } + + if (exitCode != 0 || !output.isEmpty()) { + System.err.println("Compilation failed."); + System.err.println("Exit code: " + exitCode); + System.err.println("Output: '" + output + "'"); + throw new CompileFrameworkException("Compilation failed."); + } + } +} diff --git a/test/hotspot/jtreg/compiler/lib/compile_framework/CompileFramework.java b/test/hotspot/jtreg/compiler/lib/compile_framework/CompileFramework.java new file mode 100644 index 0000000000000..fe23d596f3c64 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/compile_framework/CompileFramework.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 compiler.lib.compile_framework; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +/** + * This is the entry-point for the Compile Framework. Its purpose it to allow + * compilation and execution of Java and Jasm sources generated at runtime. + * + *

Please reference the README.md for more details and examples. + */ +public class CompileFramework { + private final List javaSources = new ArrayList<>(); + private final List jasmSources = new ArrayList<>(); + private final Path sourceDir = Utils.makeUniqueDir("compile-framework-sources-"); + private final Path classesDir = Utils.makeUniqueDir("compile-framework-classes-"); + private ClassLoader classLoader; + + /** + * Set up a new Compile Framework instance, for a new compilation unit. + */ + public CompileFramework() {} + + /** + * Add a Java source to the compilation. + * + * @param className Class name of the class (e.g. "{@code p.xyz.YXZ}"). + * @param code Java code for the class, in the form of a {@link String}. + */ + public void addJavaSourceCode(String className, String code) { + javaSources.add(new SourceCode(className, "java", code)); + } + + /** + * Add a Jasm source to the compilation. + * + * @param className Class name of the class (e.g. "{@code p.xyz.YXZ}"). + * @param code Jasm code for the class, in the form of a {@link String}. + */ + public void addJasmSourceCode(String className, String code) { + jasmSources.add(new SourceCode(className, "jasm", code)); + } + + /** + * Compile all sources: store the sources to the {@link sourceDir} directory, compile + * Java and Jasm sources and store the generated class-files in the {@link classesDir} + * directory. + */ + public void compile() { + if (classLoader != null) { + throw new CompileFrameworkException("Cannot compile twice!"); + } + + Utils.printlnVerbose("------------------ CompileFramework: SourceCode -------------------"); + Utils.printlnVerbose(sourceCodesAsString(jasmSources)); + Utils.printlnVerbose(sourceCodesAsString(javaSources)); + + System.out.println("------------------ CompileFramework: Compilation ------------------"); + System.out.println("Source directory: " + sourceDir); + System.out.println("Classes directory: " + classesDir); + + Compile.compileJasmSources(jasmSources, sourceDir, classesDir); + Compile.compileJavaSources(javaSources, sourceDir, classesDir); + classLoader = ClassLoaderBuilder.build(classesDir); + } + + private static String sourceCodesAsString(List sourceCodes) { + StringBuilder builder = new StringBuilder(); + for (SourceCode sourceCode : sourceCodes) { + builder.append("SourceCode: ").append(sourceCode.filePathName()).append(System.lineSeparator()); + builder.append(sourceCode.code()).append(System.lineSeparator()); + } + return builder.toString(); + } + + /** + * Access a class from the compiled code. + * + * @param name Name of the class to be retrieved. + * @return The class corresponding to the {@code name}. + */ + public Class getClass(String name) { + try { + return Class.forName(name, true, classLoader); + } catch (ClassNotFoundException e) { + throw new CompileFrameworkException("Class not found:", e); + } + } + + /** + * Invoke a static method from the compiled code. + * + * @param className Class name of a compiled class. + * @param methodName Method name of the class. + * @param args List of arguments for the method invocation. + * @return Return value from the invocation. + */ + public Object invoke(String className, String methodName, Object[] args) { + Method method = findMethod(className, methodName); + + try { + return method.invoke(null, args); + } catch (IllegalAccessException e) { + throw new CompileFrameworkException("Illegal access:", e); + } catch (InvocationTargetException e) { + throw new CompileFrameworkException("Invocation target:", e); + } + } + + private Method findMethod(String className, String methodName) { + Class c = getClass(className); + Method[] methods = c.getDeclaredMethods(); + Method method = null; + + for (Method m : methods) { + if (m.getName().equals(methodName)) { + if (method != null) { + throw new CompileFrameworkException("Method name \"" + methodName + "\" not unique in class \n" + className + "\"."); + } + method = m; + } + } + + if (method == null) { + throw new CompileFrameworkException("Method \"" + methodName + "\" not found in class \n" + className + "\"."); + } + + return method; + } + + /** + * Returns the classpath appended with the {@link classesDir}, where + * the compiled classes are stored. This enables another VM to load + * the compiled classes. Note, the string is already backslash escaped, + * so that Windows paths which use backslashes can be used directly + * as strings. + * + * @return Classpath appended with the path to the compiled classes. + */ + public String getEscapedClassPathOfCompiledClasses() { + return Utils.getEscapedClassPathAndClassesDir(classesDir); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/compile_framework/CompileFrameworkException.java b/test/hotspot/jtreg/compiler/lib/compile_framework/CompileFrameworkException.java new file mode 100644 index 0000000000000..5c71a33a533fd --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/compile_framework/CompileFrameworkException.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 compiler.lib.compile_framework; + +/** + * Exception thrown in the Compilation Framework. Most likely, the user is responsible for the failure. + */ +public class CompileFrameworkException extends RuntimeException { + public CompileFrameworkException(String message) { + super("Exception in Compile Framework:" + System.lineSeparator() + message); + } + + public CompileFrameworkException(String message, Throwable e) { + super("Exception in Compile Framework:" + System.lineSeparator() + message, e); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/compile_framework/InternalCompileFrameworkException.java b/test/hotspot/jtreg/compiler/lib/compile_framework/InternalCompileFrameworkException.java new file mode 100644 index 0000000000000..0cfed80ce1cd6 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/compile_framework/InternalCompileFrameworkException.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 compiler.lib.compile_framework; + +/** + * Internal exception thrown in Compilation Framework. Most likely, this is due to a bug in the CompileFramework. + */ +public class InternalCompileFrameworkException extends RuntimeException { + public InternalCompileFrameworkException(String message) { + super("Internal exception in Compile Framework, please file a bug:" + System.lineSeparator() + message); + } + + public InternalCompileFrameworkException(String message, Throwable e) { + super("Internal exception in Compile Framework, please file a bug:" + System.lineSeparator() + message, e); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/compile_framework/README.md b/test/hotspot/jtreg/compiler/lib/compile_framework/README.md new file mode 100644 index 0000000000000..76ddf677811c7 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/compile_framework/README.md @@ -0,0 +1,57 @@ +# Compile Framework +The Compile Framework allows the compilation and execution of Java and Jasm sources, which are generated at runtime. + +## Motivation +We want to be able to generate Java and Jasm source code in the form of Strings at runtime, then compile them, load the classes and invoke some methods. This allows us to write more elaborate tests. For example small dedicated fuzzers that are targetted at some specific compiler optimization. + +This is more powerful than hand-written tests, as we can generalize tests and cover more examples. It can also be better than a script-generated test: those are static and often the script is not integrated with the generated test. Another limitation of a generator script is that it is only run once, creating fixed static tests. Compilation at runtime allows us to randomly generate tests each time. + +Of course we could compile at runtime without this framework, but it abstracts away the complexity of compilation, and allows the test-writer to focus on the generation of the source code. + +## How to Use the Compile Framework + +Please reference the examples found in [examples](../../../testlibrary_tests/compile_framework/examples/). Some basic tests can be found in [tests](../../../testlibrary_tests/compile_framework/tests/). + +Here a very simple example: + + // Create a new CompileFramework instance. + CompileFramework compileFramework = new CompileFramework(); + + // Add a java source file. + compileFramework.addJavaSourceCode("XYZ", ""); + + // Compile the source file. + compileFramework.compile(); + + // Object returnValue = XYZ.test(5); + Object returnValue = compileFramework.invoke("XYZ", "test", new Object[] {5}); + +### Creating a new Compile Framework Instance + +First, one must create a `new CompileFramework()`, which creates two directories: a sources and a classes directory (see `sourcesDir` and `classesDir` in [CompileFramework](./CompileFramework.java)). The sources directory is where all the sources are placed by the Compile Framework, and the classes directory is where all the compiled classes are placed by the Compile Framework. + +The Compile Framework prints the names of the directories, they are subdirectories of the JTREG scratch directory `JTWork/scratch`. + +### Adding Sources to the Compilation + +Java and Jasm sources can be added to the compilation using `compileFramework.addJavaSourceCode()` and `compileFramework.addJasmSourceCode()`. The source classes can depend on each other, and they can also use the IR Framework ([IRFrameworkJavaExample](../../../testlibrary_tests/compile_framework/examples/IRFrameworkJavaExample.java)). + +When using the IR Framework, or any other library that needs to be compiled, it can be necessary to explicitly let JTREG compile that library. For example with `@compile ../../../compiler/lib/ir_framework/TestFramework.java`. Otherwise, the corresponding class files may not be available, and a corresponding failure will be encounter at class loading. + +### Compiling + +All sources are compiled with `compileFramework.compile()`. First, the sources are stored to the sources directory, then compiled, and then the class-files stored in the classes directory. The respective directory names are printed, so that the user can easily access the generated files for debugging. + +### Interacting with the Compiled Code + +The compiled code is then loaded with a `ClassLoader`. The classes can be accessed directly with `compileFramework.getClass(name)`. Specific methods can also directly be invoked with `compileFramework.invoke()`. + +Should one require the modified classpath that includes the compiled classes, this is available with `compileFramework.getEscapedClassPathOfCompiledClasses()`. This can be necessary if the test launches any other VMs that also access the compiled classes. This is for example necessary when using the IR Framework. + +### Running the Compiled Code in a New VM + +One can also run the compiled code in a new VM. For this, one has to set the classpath with `compileFramework.getEscapedClassPathOfCompiledClasses()` ([RunWithFlagsExample](../../../testlibrary_tests/compile_framework/examples/RunWithFlagsExample.java)) + +### Verbose Printing + +For debugging purposes, one can enable verbose printing, with `-DCompileFrameworkVerbose=true`. diff --git a/test/hotspot/jtreg/compiler/lib/compile_framework/SourceCode.java b/test/hotspot/jtreg/compiler/lib/compile_framework/SourceCode.java new file mode 100644 index 0000000000000..df38e420758e6 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/compile_framework/SourceCode.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 compiler.lib.compile_framework; + +/** + * This class represents the source code of a specific class. + */ +record SourceCode(String className, String extension, String code) { + public String filePathName() { + StringBuilder builder = new StringBuilder(); + builder.append(className.replace('.','/')).append(".").append(extension); + return builder.toString(); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/compile_framework/Utils.java b/test/hotspot/jtreg/compiler/lib/compile_framework/Utils.java new file mode 100644 index 0000000000000..0ac2720f33b19 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/compile_framework/Utils.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 compiler.lib.compile_framework; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.Path; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * Utility class, with many helper methods for the Compile Framework. + */ +class Utils { + private static final boolean VERBOSE = Boolean.getBoolean("CompileFrameworkVerbose"); + + /** + * Verbose printing, enabled with {@code -DCompileFrameworkVerbose=true}. + */ + public static void printlnVerbose(String s) { + if (VERBOSE) { + System.out.println(s); + } + } + + /** + * Create a temporary directory with a unique name to avoid collisions + * with multi-threading. Used to create the sources and classes directories. Since they + * are unique even across threads, the Compile Framework is multi-threading safe, i.e. + * it does not have collisions if two instances generate classes with the same name. + */ + public static Path makeUniqueDir(String prefix) { + try { + return Files.createTempDirectory(Paths.get("."), prefix); + } catch (Exception e) { + throw new InternalCompileFrameworkException("Could not set up temporary directory", e); + } + } + + /** + * Get all paths in the classpath. + */ + public static String[] getClassPaths() { + String separator = File.pathSeparator; + return System.getProperty("java.class.path").split(separator); + } + + /** + * Return the classpath, appended with the {@code classesDir}. + */ + public static String getEscapedClassPathAndClassesDir(Path classesDir) { + String cp = System.getProperty("java.class.path") + + File.pathSeparator + + classesDir.toAbsolutePath(); + // Escape the backslash for Windows paths. We are using the path in the + // command-line and Java code, so we always want it to be escaped. + return cp.replace("\\", "\\\\"); + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/CombinedJavaJasmExample.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/CombinedJavaJasmExample.java new file mode 100644 index 0000000000000..565c92c1b7068 --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/CombinedJavaJasmExample.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @summary Example test to use the Compile Framework. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run driver compile_framework.examples.CombinedJavaJasmExample + */ + +package compile_framework.examples; + +import compiler.lib.compile_framework.*; + +/** + * This test shows a compilation of multiple Java and Jasm source code files. + * In this example, the classes even reference each other. + */ +public class CombinedJavaJasmExample { + + // Generate a source jasm file as String + public static String generateJasm() { + return """ + package p/xyz; + + super public class XYZJasm { + public static Method test:"(I)I" + stack 20 locals 20 + { + iload_0; + iconst_2; + imul; + invokestatic Method p/xyz/XYZJava."mul3":"(I)I"; + ireturn; + } + + public static Method mul5:"(I)I" + stack 20 locals 20 + { + iload_0; + ldc 5; + imul; + ireturn; + } + } + """; + } + + // Generate a source java file as String + public static String generateJava() { + return """ + package p.xyz; + + public class XYZJava { + public static int test(int i) { + return p.xyz.XYZJasm.mul5(i * 7); + } + + public static int mul3(int i) { + return i * 3; + } + } + """; + } + + public static void main(String[] args) { + // Create a new CompileFramework instance. + CompileFramework comp = new CompileFramework(); + + // Generate files. + comp.addJasmSourceCode("p.xyz.XYZJasm", generateJasm()); + comp.addJavaSourceCode("p.xyz.XYZJava", generateJava()); + + // Compile the source files. + comp.compile(); + + test(comp, "p.xyz.XYZJasm", "test", 11, 11 * 2 * 3); + test(comp, "p.xyz.XYZJava", "test", 13, 13 * 7 * 5); + + System.out.println("Success."); + } + + public static void test(CompileFramework comp, String className, String methodName, int input, int expected) { + Object ret = comp.invoke(className, methodName, new Object[] {input}); + + // Extract return value of invocation, verify its value. + int i = (int)ret; + System.out.println("Result of call: " + i + " vs expected: " + expected); + if (i != expected) { + throw new RuntimeException("wrong value: " + i); + } + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/IRFrameworkJavaExample.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/IRFrameworkJavaExample.java new file mode 100644 index 0000000000000..4013a0be20653 --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/IRFrameworkJavaExample.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @summary Example test to use the Compile Framework together with the IR Framework (i.e. TestFramework). + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @compile ../../../compiler/lib/ir_framework/TestFramework.java + * @run driver compile_framework.examples.IRFrameworkJavaExample + */ + +package compile_framework.examples; + +import compiler.lib.compile_framework.*; +import jdk.test.lib.Utils; +import jdk.test.lib.Platform; +import java.lang.reflect.InvocationTargetException; + +/** + * This test shows that the IR verification can be done on code compiled by the Compile Framework. + * The "@compile" command for JTREG is required so that the IRFramework is compiled, other javac + * might not compile it because it is not present in the class, only in the dynamically compiled + * code. + *

+ * Additionally, we must set the classpath for the Test-VM, so that it has access to all compiled + * classes (see {@link CompileFramework#getEscapedClassPathOfCompiledClasses}). + */ +public class IRFrameworkJavaExample { + + public static void main(String[] args) { + testX1(); + testX2(); + } + + // Generate a source java file as String + public static String generateX1(CompileFramework comp) { + return String.format(""" + import compiler.lib.ir_framework.*; + + public class X1 { + public static void main(String args[]) { + TestFramework framework = new TestFramework(X1.class); + framework.addFlags("-classpath", "%s"); + framework.start(); + } + + @Test + //@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0"}, + // applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}) + static float[] test() { + float[] a = new float[1024*8]; + for (int i = 0; i < a.length; i++) { + a[i]++; + } + return a; + } + } + """, comp.getEscapedClassPathOfCompiledClasses()); + } + + static void testX1() { + // Create a new CompileFramework instance. + CompileFramework comp = new CompileFramework(); + + // Add a java source file. + comp.addJavaSourceCode("X1", generateX1(comp)); + + // Compile the source file. + comp.compile(); + + // X1.main(); + comp.invoke("X1", "main", new Object[] {null}); + } + + // Generate a source java file as String + public static String generateX2(CompileFramework comp) { + // Example with conflicting "@IR" rules -> expect a IRViolationException. + return String.format(""" + import compiler.lib.ir_framework.*; + + public class X2 { + public static void main(String args[]) { + TestFramework framework = new TestFramework(X2.class); + framework.addFlags("-classpath", "%s"); + framework.start(); + } + + @Test + @IR(counts = {IRNode.LOAD, "> 0"}) + @IR(failOn = IRNode.LOAD) + static void test() { + } + } + """, comp.getEscapedClassPathOfCompiledClasses()); + } + + static void testX2() { + // Create a new CompileFramework instance. + CompileFramework comp = new CompileFramework(); + + // Add a java source file. + comp.addJavaSourceCode("X2", generateX2(comp)); + + // Compile the source file. + comp.compile(); + + // Load the compiled class. + Class c = comp.getClass("X2"); + + // Invoke the "X2.main" method from the compiled and loaded class. + try { + c.getDeclaredMethod("main", new Class[] { String[].class }).invoke(null, new Object[] { null }); + + // Check if IR framework is expected to execute the IR rules. + if (Utils.getTestJavaOpts().length == 0 && Platform.isDebugBuild() && !Platform.isInt() && !Platform.isComp()) { + throw new RuntimeException("IRViolationException expected."); + } else { + System.out.println("Got no IRViolationException, but was also not expected."); + } + } catch (NoSuchMethodException e) { + throw new RuntimeException("No such method:", e); + } catch (IllegalAccessException e) { + throw new RuntimeException("Illegal access:", e); + } catch (InvocationTargetException e) { + Throwable t = e.getCause(); + if (t == null) { + throw new RuntimeException("IRViolationException expected:", e); + } + if (!t.getClass().getSimpleName().equals("IRViolationException")) { + throw new RuntimeException("IRViolationException expected:", e); + } + System.out.println("Success, we got a IRViolationException."); + } + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/MultiFileJasmExample.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/MultiFileJasmExample.java new file mode 100644 index 0000000000000..33fe07a53970b --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/MultiFileJasmExample.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @summary Example test to use the Compile Framework. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run driver comile_framework.examples.MultiFileJasmExample + */ + +package comile_framework.examples; + +import compiler.lib.compile_framework.*; +import java.io.StringWriter; +import java.io.PrintWriter; + +/** + * This test shows a compilation of multiple jasm source code files. + */ +public class MultiFileJasmExample { + + // Generate a source jasm file as String + public static String generate(int i) { + StringWriter writer = new StringWriter(); + PrintWriter out = new PrintWriter(writer); + out.println("package p/xyz;"); + out.println(""); + out.println("super public class XYZ" + i + " {"); + out.println(" public static Method test:\"(I)I\""); + out.println(" stack 20 locals 20"); + out.println(" {"); + out.println(" iload_0;"); + out.println(" iconst_2;"); // every call multiplies by 2, in total 2^10 = 1024 + out.println(" imul;"); + if (i != 0) { + out.println(" invokestatic Method p/xyz/XYZ" + (i-1) + ".\"test\":\"(I)I\";"); + } + out.println(" ireturn;"); + out.println(" }"); + out.println("}"); + return writer.toString(); + } + + public static void main(String[] args) { + // Create a new CompileFramework instance. + CompileFramework comp = new CompileFramework(); + + // Generate 10 files. + for (int i = 0; i < 10; i++) { + comp.addJasmSourceCode("p.xyz.XYZ" + i, generate(i)); + } + + // Compile the source files. + comp.compile(); + + // Object ret = XYZ9.test(5); + Object ret = comp.invoke("p.xyz.XYZ9", "test", new Object[] { 5 }); + + // Extract return value of invocation, verify its value. + int i = (int)ret; + System.out.println("Result of call: " + i); + if (i != 5 * 1024) { + throw new RuntimeException("wrong value: " + i); + } + System.out.println("Success."); + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/MultiFileJavaExample.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/MultiFileJavaExample.java new file mode 100644 index 0000000000000..e493ebab4e8c8 --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/MultiFileJavaExample.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @summary Example test to use the Compile Framework. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run driver compile_framework.examples.MultiFileJavaExample + */ + +package compile_framework.examples; + +import compiler.lib.compile_framework.*; +import java.io.StringWriter; +import java.io.PrintWriter; + +/** + * This test shows a compilation of multiple java source code files. + */ +public class MultiFileJavaExample { + + // Generate a source java file as String + public static String generate(int i) { + StringWriter writer = new StringWriter(); + PrintWriter out = new PrintWriter(writer); + out.println("package p.xyz;"); + out.println(""); + out.println("public class XYZ" + i + " {"); + if (i > 0) { + out.println(" public XYZ" + (i - 1) + " xyz = new XYZ" + (i - 1) + "();"); + } + out.println(""); + out.println(" public static Object test() {"); + out.println(" return new XYZ" + i + "();"); + out.println(" }"); + out.println("}"); + return writer.toString(); + } + + public static void main(String[] args) { + // Create a new CompileFramework instance. + CompileFramework comp = new CompileFramework(); + + // Generate 10 files. + for (int i = 0; i < 10; i++) { + comp.addJavaSourceCode("p.xyz.XYZ" + i, generate(i)); + } + + // Compile the source files. + comp.compile(); + + // Object ret = XYZ9.test(); + Object ret = comp.invoke("p.xyz.XYZ9", "test", new Object[] {}); + + if (!ret.getClass().getSimpleName().equals("XYZ9")) { + throw new RuntimeException("wrong result:" + ret); + } + System.out.println("Success."); + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/RunWithFlagsExample.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/RunWithFlagsExample.java new file mode 100644 index 0000000000000..a67e6e0eb4937 --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/RunWithFlagsExample.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @summary Example test to use the Compile Framework and run the compiled code with additional flags + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run driver compile_framework.examples.RunWithFlagsExample + */ + +package compile_framework.examples; + +import compiler.lib.compile_framework.*; + +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +/** + * This test shows how the generated code can be compiled and invoked in a new VM. This allows + * the execution of the code with additional VM flags and options. + *

+ * The new VM must be able to locate the class files of the newly compiled code. For this we + * set the class path using {@link CompileFramework#getEscapedClassPathOfCompiledClasses}. + */ +public class RunWithFlagsExample { + + private static String generate() { + return """ + package p.xyz; + + public class X { + public static void main(String args[]) { + System.out.println("Hello world!"); + System.out.println(System.getProperty("MyMessage", "fail")); + System.err.println(args[0]); + } + } + """; + } + + public static void main(String[] args) throws Exception { + // Create a new CompileFramework instance. + CompileFramework comp = new CompileFramework(); + + // Add a Java source file. + comp.addJavaSourceCode("p.xyz.X", generate()); + + // Compile the source file. + comp.compile(); + + // Build command line. + String[] command = { + // Set the classpath to include our newly compiled class. + "-classpath", + comp.getEscapedClassPathOfCompiledClasses(), + // Pass additional flags here. + // "-Xbatch" is a harmless VM flag, so this example runs everywhere without issues. + "-Xbatch", + // We can also pass properties like "MyMessage". + "-DMyMessage=hello_world", + "p.xyz.X", + "hello_arg" + }; + + // Execute the command, and capture the output. + // The JTREG Java and VM options are automatically passed to the test VM. + OutputAnalyzer analyzer = ProcessTools.executeTestJava(command); + + // Verify output. + analyzer.shouldHaveExitValue(0); + analyzer.stdoutContains("Hello world!"); + analyzer.stdoutContains("hello_world"); + analyzer.stdoutContains("hello_arg"); + + // Print output to stderr. + analyzer.reportDiagnosticSummary(); + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/SimpleJasmExample.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/SimpleJasmExample.java new file mode 100644 index 0000000000000..e01b45e744175 --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/SimpleJasmExample.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @summary Example test to use the Compile Framework. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run driver compile_framework.examples.SimpleJasmExample + */ + +package compile_framework.examples; + +import compiler.lib.compile_framework.*; + +/** + * This test shows a simple compilation of java source code, and its invocation. + */ +public class SimpleJasmExample { + + // Generate a source jasm file as String + public static String generate() { + return """ + super public class XYZ { + public static Method test:"(I)I" + stack 20 locals 20 + { + iload_0; + iconst_2; + imul; + ireturn; + } + } + """; + } + + public static void main(String[] args) { + // Create a new CompileFramework instance. + CompileFramework comp = new CompileFramework(); + + // Add a java source file. + String src = generate(); + comp.addJasmSourceCode("XYZ", src); + + // Compile the source file. + comp.compile(); + + // Object ret = XYZ.test(5); + Object ret = comp.invoke("XYZ", "test", new Object[] {5}); + + // Extract return value of invocation, verify its value. + int i = (int)ret; + System.out.println("Result of call: " + i); + if (i != 10) { + throw new RuntimeException("wrong value: " + i); + } + System.out.println("Success."); + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/SimpleJavaExample.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/SimpleJavaExample.java new file mode 100644 index 0000000000000..5e54a6e8a08a6 --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/examples/SimpleJavaExample.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @summary Example test to use the Compile Framework. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run driver compile_framework.examples.SimpleJavaExample + */ + +package compile_framework.examples; + +import compiler.lib.compile_framework.*; + +/** + * This test shows a simple compilation of java source code, and its invocation. + */ +public class SimpleJavaExample { + + // Generate a source java file as String + public static String generate() { + return """ + public class XYZ { + public static int test(int i) { + System.out.println("Hello from XYZ.test: " + i); + return i * 2; + } + } + """; + } + + public static void main(String[] args) { + // Create a new CompileFramework instance. + CompileFramework comp = new CompileFramework(); + + // Add a java source file. + comp.addJavaSourceCode("XYZ", generate()); + + // Compile the source file. + comp.compile(); + + // Object ret = XYZ.test(5); + Object ret = comp.invoke("XYZ", "test", new Object[] {5}); + + // Extract return value of invocation, verify its value. + int i = (int)ret; + System.out.println("Result of call: " + i); + if (i != 10) { + throw new RuntimeException("wrong value: " + i); + } + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestBadJasmCompilation.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestBadJasmCompilation.java new file mode 100644 index 0000000000000..b5b6f3e104095 --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestBadJasmCompilation.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @summary Example test with failing jasm compilation. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run driver compile_framework.tests.TestBadJasmCompilation + */ + +package compile_framework.tests; + +import compiler.lib.compile_framework.*; + +public class TestBadJasmCompilation { + + // Generate a source jasm file as String + public static String generate() { + return """ + super public class XYZ { + some bad code + } + """; + } + + public static void main(String[] args) { + // Create a new CompileFramework instance. + CompileFramework comp = new CompileFramework(); + + // Add a java source file. + comp.addJasmSourceCode("XYZ", generate()); + + try { + // Compile the source file. + comp.compile(); + throw new RuntimeException("Expected compilation to fail."); + } catch (CompileFrameworkException e) { + System.out.println("Success, expected compilation to fail."); + } + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestBadJavaCompilation.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestBadJavaCompilation.java new file mode 100644 index 0000000000000..1cb1d79afbcca --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestBadJavaCompilation.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @summary Example test with failing java compilation. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run driver compile_framework.tests.TestBadJavaCompilation + */ + +package compile_framework.tests; + +import compiler.lib.compile_framework.*; + +public class TestBadJavaCompilation { + + // Generate a source java file as String + public static String generate() { + return """ + public class XYZ { + some bad code + } + """; + } + + public static void main(String[] args) { + // Create a new CompileFramework instance. + CompileFramework comp = new CompileFramework(); + + // Add a java source file. + comp.addJavaSourceCode("XYZ", generate()); + + try { + // Compile the source file. + comp.compile(); + throw new RuntimeException("Expected compilation to fail."); + } catch (CompileFrameworkException e) { + System.out.println("Success, expected compilation to fail."); + } + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestConcurrentCompilation.java b/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestConcurrentCompilation.java new file mode 100644 index 0000000000000..1cb902d34e4aa --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/compile_framework/tests/TestConcurrentCompilation.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @summary Example test with multi-threaded use of the CompileFramework. + * Tests that the source and class directories are set up correctly. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run driver compile_framework.tests.TestConcurrentCompilation + */ + +package compile_framework.tests; + +import compiler.lib.compile_framework.*; + +import java.util.ArrayList; +import java.util.List; + +public class TestConcurrentCompilation { + + // Generate a source java file as String + public static String generate(int i) { + return String.format(""" + public class XYZ { + public static int test() { + return %d; + } + } + """, i); + } + + public static void test(int i) { + System.out.println("Generate and compile XYZ for " + i); + CompileFramework comp = new CompileFramework(); + comp.addJavaSourceCode("XYZ", generate(i)); + comp.compile(); + + // Now, sleep to give the other threads time to compile and store their class-files. + System.out.println("Sleep for " + i); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + System.out.println("Sleep interrupted for " + i); + } + + // Now, hopefully all threads have compiled and stored their class-files. + // We can check if we get the expected result, i.e. the class-file from the current thread. + System.out.println("Run XYZ.test for " + i); + int j = (int)comp.invoke("XYZ", "test", new Object[] {}); + if (i != j) { + System.out.println("Wrong value: " + i + " vs " + j); + throw new RuntimeException("Wrong value: " + i + " vs " + j); + } + System.out.println("Success for " + i); + } + + public static class MyRunnable implements Runnable { + private int i; + + public MyRunnable(int i) { + this.i = i; + } + + public void run() { + TestConcurrentCompilation.test(i); + } + } + + public static void main(String[] args) { + System.out.println("Generating threads:"); + List threads = new ArrayList(); + for (int i = 0; i < 3; i++) { + Thread thread = new Thread(new MyRunnable(i)); + thread.start(); + threads.add(thread); + } + System.out.println("Waiting to join threads:"); + try { + for (Thread thread : threads) { + thread.join(); + } + } catch (InterruptedException e) { + throw new RuntimeException("interrupted", e); + } + System.out.println("Success."); + } +} diff --git a/test/lib/jdk/test/lib/process/OutputAnalyzer.java b/test/lib/jdk/test/lib/process/OutputAnalyzer.java index f554b969f4eee..e0d27e2374bbc 100644 --- a/test/lib/jdk/test/lib/process/OutputAnalyzer.java +++ b/test/lib/jdk/test/lib/process/OutputAnalyzer.java @@ -207,6 +207,13 @@ public OutputAnalyzer stderrShouldNotBeEmpty() { return this; } + /** + * Returns true if stdout contains the given string + */ + public boolean stdoutContains(String expectedString) { + return getStdout().contains(expectedString); + } + /** * Verify that the stdout and stderr contents of output buffer contains the string * From d0a02d008f7068aa99756fecdba66ec3f4fcbf02 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:29:10 +0000 Subject: [PATCH 073/846] 8343103: Enable debug logging for vmTestbase/nsk/jvmti/scenarios/sampling/SP05/sp05t003/TestDescription.java Backport-of: 1b177ce5b7e25b3a563066ba92dbf8cacfd29126 --- .../scenarios/sampling/SP05/sp05t003/TestDescription.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP05/sp05t003/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP05/sp05t003/TestDescription.java index ecb2cfc59e59d..1c8ca451c8e82 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP05/sp05t003/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP05/sp05t003/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ * @library /vmTestbase * /test/lib * @run main/othervm/native - * -agentlib:sp05t003=-waittime=5 + * -agentlib:sp05t003=-waittime=5,-verbose * nsk.jvmti.scenarios.sampling.SP05.sp05t003 */ From 5fdaafb42c681a919da291d3a029853557c4fbf4 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:30:32 +0000 Subject: [PATCH 074/846] 8343936: Adjust timeout in test javax/management/monitor/DerivedGaugeMonitorTest.java Reviewed-by: rrich Backport-of: 4fa760a1ed24ad2e6fba6dca51c5cf7dc7436719 --- test/jdk/ProblemList.txt | 2 -- .../management/monitor/DerivedGaugeMonitorTest.java | 9 +++++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index b75d0260efd6c..0b5c56aabea0f 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -526,8 +526,6 @@ java/lang/instrument/RetransformBigClass.sh 8065756 generic- java/lang/management/MemoryMXBean/Pending.java 8158837 generic-all java/lang/management/MemoryMXBean/PendingAllGC.sh 8158837 generic-all -javax/management/monitor/DerivedGaugeMonitorTest.java 8042211 generic-all - ############################################################################ # jdk_io diff --git a/test/jdk/javax/management/monitor/DerivedGaugeMonitorTest.java b/test/jdk/javax/management/monitor/DerivedGaugeMonitorTest.java index 36b9dd40b502c..1452de5c3ce19 100644 --- a/test/jdk/javax/management/monitor/DerivedGaugeMonitorTest.java +++ b/test/jdk/javax/management/monitor/DerivedGaugeMonitorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ * @summary Test that the initial derived gauge is (Integer)0 * @author Daniel Fuchs * + * @library /test/lib + * * @run clean DerivedGaugeMonitorTest * @run build DerivedGaugeMonitorTest * @run main DerivedGaugeMonitorTest @@ -40,9 +42,12 @@ import javax.management.ObjectName; import javax.management.monitor.CounterMonitor; import javax.management.monitor.GaugeMonitor; +import jdk.test.lib.Utils; public class DerivedGaugeMonitorTest { + public static final int WAIT_TIME = 1000; + public static interface Things { public long getALong(); public int getAnInt(); @@ -239,7 +244,7 @@ public static void test(String attr) throws Exception { mon1.setGranularityPeriod(5); mon2.setGranularityPeriod(5); - my.cdl.await(1000, TimeUnit.MILLISECONDS); + my.cdl.await(Utils.adjustTimeout(WAIT_TIME), TimeUnit.MILLISECONDS); if (my.cdl.getCount() > 0) throw new Exception(attr+": Count down not reached!"); From 011a970151eb5bc0650567b1722967188d02a054 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:32:02 +0000 Subject: [PATCH 075/846] 8342524: Use latch in AbstractButton/bug6298940.java instead of delay Backport-of: 2bd8f026dbd449e810dc6ce96cd9235e5cb51a9b --- .../swing/AbstractButton/bug6298940.java | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 test/jdk/javax/swing/AbstractButton/bug6298940.java diff --git a/test/jdk/javax/swing/AbstractButton/bug6298940.java b/test/jdk/javax/swing/AbstractButton/bug6298940.java new file mode 100644 index 0000000000000..c2857c68ae305 --- /dev/null +++ b/test/jdk/javax/swing/AbstractButton/bug6298940.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2005, 2025, 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 6298940 + * @key headful + * @summary Tests that mnemonic keystroke fires an action + * @library /javax/swing/regtesthelpers + * @build Util + * @run main bug6298940 + */ + +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.util.concurrent.CountDownLatch; + +import javax.swing.ButtonModel; +import javax.swing.DefaultButtonModel; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +import static java.util.concurrent.TimeUnit.SECONDS; + +public final class bug6298940 { + private static JFrame frame; + + private static final CountDownLatch actionEvent = new CountDownLatch(1); + + private static void createAndShowGUI() { + ButtonModel model = new DefaultButtonModel(); + model.addActionListener(event -> { + System.out.println("ActionEvent"); + actionEvent.countDown(); + }); + model.setMnemonic('T'); + + JButton button = new JButton("Test"); + button.setModel(model); + + frame = new JFrame("bug6298940"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.add(button); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.toFront(); + } + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + + SwingUtilities.invokeAndWait(bug6298940::createAndShowGUI); + + robot.waitForIdle(); + robot.delay(500); + + Util.hitMnemonics(robot, KeyEvent.VK_T); + + try { + if (!actionEvent.await(1, SECONDS)) { + throw new RuntimeException("Mnemonic didn't fire an action"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} From 3d76ae00131d40b95aec4080d39a107ac6be0e40 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:33:23 +0000 Subject: [PATCH 076/846] 8294155: Exception thrown before awaitAndCheck hangs PassFailJFrame Backport-of: 906358d3a14ce755fec771f0a6bb856b3a8f3297 --- .../java/awt/regtesthelpers/PassFailJFrame.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java index 95d925d7b3db0..5f559ea47c314 100644 --- a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java +++ b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java @@ -1787,8 +1787,20 @@ public Builder position(Position position) { public PassFailJFrame build() throws InterruptedException, InvocationTargetException { - validate(); - return new PassFailJFrame(this); + try { + validate(); + return new PassFailJFrame(this); + } catch (final Throwable t) { + // Dispose of all the windows, including those that may not + // be registered with PassFailJFrame to allow AWT to shut down + try { + invokeOnEDT(() -> Arrays.stream(Window.getWindows()) + .forEach(Window::dispose)); + } catch (Throwable edt) { + t.addSuppressed(edt); + } + throw t; + } } /** From 3a0e19b209b03a06e3afc44986b0692a153f72a9 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:34:41 +0000 Subject: [PATCH 077/846] 8350260: Improve HTML instruction formatting in PassFailJFrame Backport-of: 014701a09b23d21f57edb5b085820532804475bd --- test/jdk/java/awt/regtesthelpers/PassFailJFrame.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java index 5f559ea47c314..5b825bb4c37ce 100644 --- a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java +++ b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java @@ -633,6 +633,8 @@ private static JComponent createInstructionUIPanel(String instructions, ? configureHTML(instructions, rows, columns) : configurePlainText(instructions, rows, columns); text.setEditable(false); + text.setBorder(createTextBorder()); + text.setCaretPosition(0); JPanel textPanel = new JPanel(new BorderLayout()); textPanel.setBorder(createEmptyBorder(GAP, 0, GAP, 0)); @@ -687,7 +689,6 @@ private static JTextComponent configurePlainText(String instructions, JTextArea text = new JTextArea(instructions, rows, columns); text.setLineWrap(true); text.setWrapStyleWord(true); - text.setBorder(createTextBorder()); return text; } @@ -701,10 +702,10 @@ private static JTextComponent configureHTML(String instructions, HTMLEditorKit kit = (HTMLEditorKit) text.getEditorKit(); StyleSheet styles = kit.getStyleSheet(); - // Reduce the default margins - styles.addRule("ol, ul { margin-left-ltr: 20; margin-left-rtl: 20 }"); - // Make the size of code blocks the same as other text - styles.addRule("code { font-size: inherit }"); + // Reduce the list default margins + styles.addRule("ol, ul { margin-left-ltr: 30; margin-left-rtl: 30 }"); + // Make the size of code (and other elements) the same as other text + styles.addRule("code, kbd, samp, pre { font-size: inherit }"); return text; } From e31723b199db9df6781dbb771b32b0db1bb1dba7 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:36:01 +0000 Subject: [PATCH 078/846] 8345598: Upgrade NSS binaries for interop tests Backport-of: 0f82268134df65bbc65ecda158d25f708f18d150 --- test/jdk/sun/security/pkcs11/PKCS11Test.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/sun/security/pkcs11/PKCS11Test.java b/test/jdk/sun/security/pkcs11/PKCS11Test.java index c969e566e1210..52294ae26eb5a 100644 --- a/test/jdk/sun/security/pkcs11/PKCS11Test.java +++ b/test/jdk/sun/security/pkcs11/PKCS11Test.java @@ -79,7 +79,7 @@ public abstract class PKCS11Test { // Version of the NSS artifact. This coincides with the version of // the NSS version - private static final String NSS_BUNDLE_VERSION = "3.101"; + private static final String NSS_BUNDLE_VERSION = "3.107"; private static final String NSSLIB = "jpg.tests.jdk.nsslib"; static double nss_version = -1; From dda39ec6d4ab80366147fc103f40ddff321ff561 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:37:11 +0000 Subject: [PATCH 079/846] 8280991: [XWayland] No displayChanged event after setDisplayMode call Backport-of: 29de20dbc22e0b68698a1b9cb1241ae5861a6b9a --- .../classes/sun/awt/X11GraphicsDevice.java | 38 ++++++++++++++- test/jdk/ProblemList.txt | 1 - .../FullscreenWindowProps.java | 6 ++- .../NoResizeEventOnDMChangeTest.java | 46 ++++++++++++++++++- 4 files changed, 87 insertions(+), 4 deletions(-) diff --git a/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java b/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java index 4b05b387a891f..93f54cd180797 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java +++ b/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -73,6 +73,15 @@ public final class X11GraphicsDevice extends GraphicsDevice private boolean shutdownHookRegistered; private int scale; + // Wayland clients are by design not allowed to change the resolution in Wayland. + // XRandR in Xwayland is just an emulation, it doesn't actually change the resolution. + // This emulation is per window/x11 client, so different clients can have + // different emulated resolutions at the same time. + // So any request to get the current display mode will always return + // the original screen resolution, even if we are in emulated resolution. + // To handle this situation, we store the last set display mode in this variable. + private volatile DisplayMode xwlCurrentDisplayMode; + public X11GraphicsDevice(int screennum) { this.screen = screennum; this.scale = initScaleFactor(); @@ -125,6 +134,20 @@ public int scaleDown(int x) { private Rectangle getBoundsImpl() { Rectangle rect = pGetBounds(getScreen()); + + if (XToolkit.isOnWayland() && xwlCurrentDisplayMode != null) { + // XRandR resolution change in Xwayland is an emulation, + // and implemented in such a way that multiple display modes + // for a device are only available in a single screen scenario, + // if we have multiple screens they will each have a single display mode + // (no emulated resolution change is available). + // So we don't have to worry about x and y for a screen here. + rect.setSize( + xwlCurrentDisplayMode.getWidth(), + xwlCurrentDisplayMode.getHeight() + ); + } + if (getScaleFactor() != 1) { rect.x = scaleDown(rect.x); rect.y = scaleDown(rect.y); @@ -424,10 +447,19 @@ private DisplayMode getDefaultDisplayMode() { @Override public synchronized DisplayMode getDisplayMode() { if (isFullScreenSupported()) { + if (XToolkit.isOnWayland() && xwlCurrentDisplayMode != null) { + return xwlCurrentDisplayMode; + } + DisplayMode mode = getCurrentDisplayMode(screen); if (mode == null) { mode = getDefaultDisplayMode(); } + + if (XToolkit.isOnWayland()) { + xwlCurrentDisplayMode = mode; + } + return mode; } else { if (origDisplayMode == null) { @@ -503,6 +535,10 @@ public synchronized void setDisplayMode(DisplayMode dm) { dm.getWidth(), dm.getHeight(), dm.getRefreshRate()); + if (XToolkit.isOnWayland()) { + xwlCurrentDisplayMode = dm; + } + // update bounds of the fullscreen window w.setBounds(0, 0, dm.getWidth(), dm.getHeight()); diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 0b5c56aabea0f..f2d42e4ef9634 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -489,7 +489,6 @@ java/awt/Dialog/ChoiceModalDialogTest.java 8161475 macosx-all # Wayland related -java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java 8280991 linux-x64 ############################################################################ diff --git a/test/jdk/java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java b/test/jdk/java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java index f5f77d47319d7..66f358d64ce41 100644 --- a/test/jdk/java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java +++ b/test/jdk/java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, 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 @@ -52,6 +52,10 @@ public void paint(Graphics g) { super.paint(g); g.setColor(Color.GREEN); g.fillRect(0, 0, getWidth(), getHeight()); + g.setColor(Color.RED); + DisplayMode displayMode = + getGraphicsConfiguration().getDevice().getDisplayMode(); + g.drawString(displayMode.toString(), 100, 100); } }; try { diff --git a/test/jdk/java/awt/FullScreen/NoResizeEventOnDMChangeTest/NoResizeEventOnDMChangeTest.java b/test/jdk/java/awt/FullScreen/NoResizeEventOnDMChangeTest/NoResizeEventOnDMChangeTest.java index 455ad2f2b0a3e..c7277e8b96caa 100644 --- a/test/jdk/java/awt/FullScreen/NoResizeEventOnDMChangeTest/NoResizeEventOnDMChangeTest.java +++ b/test/jdk/java/awt/FullScreen/NoResizeEventOnDMChangeTest/NoResizeEventOnDMChangeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, 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 @@ -26,6 +26,8 @@ * @bug 6646411 * @summary Tests that full screen window and its children receive resize event when display mode changes + * @library /test/lib + * @build jdk.test.lib.Platform jtreg.SkippedException * @run main/othervm NoResizeEventOnDMChangeTest * @run main/othervm -Dsun.java2d.d3d=false NoResizeEventOnDMChangeTest */ @@ -44,9 +46,21 @@ import java.awt.event.ComponentEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.io.BufferedReader; +import java.io.IOException; + +import static java.util.concurrent.TimeUnit.SECONDS; +import jdk.test.lib.Platform; +import jtreg.SkippedException; public class NoResizeEventOnDMChangeTest { + public static void main(String[] args) { + if (Platform.isOnWayland() && !isFixDelivered()) { + throw new SkippedException("Test skipped because fix was not" + + "delivered in current GnomeShell version"); + } + final GraphicsDevice gd = GraphicsEnvironment. getLocalGraphicsEnvironment().getDefaultScreenDevice(); @@ -231,4 +245,34 @@ public synchronized int getDmChanges() { return dmChanges; } } + + private static boolean isFixDelivered() { + try { + Process process = + new ProcessBuilder("/usr/bin/gnome-shell", "--version") + .start(); + + try (BufferedReader reader = process.inputReader()) { + if (process.waitFor(2, SECONDS) && process.exitValue() == 0) { + String line = reader.readLine(); + if (line != null) { + System.out.println("Gnome shell version: " + line); + String[] versionComponents = line + .replaceAll("[^\\d.]", "") + .split("\\."); + + if (versionComponents.length >= 1) { + return Integer.parseInt(versionComponents[0]) > 42; + } + } + } + } + } catch (IOException + | InterruptedException + | IllegalThreadStateException + | NumberFormatException ignored) { + } + + return false; + } } From 763ee0a7e5bb6e9bdbf739e886d7c47bb28ea2b0 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Mar 2025 19:38:20 +0000 Subject: [PATCH 080/846] 8348110: Update LCMS to 2.17 Reviewed-by: andrew Backport-of: a23fb0af65f491ef655ba114fcc8032a09a55213 --- src/java.desktop/share/legal/lcms.md | 12 +- .../share/native/liblcms/cmsalpha.c | 10 +- .../share/native/liblcms/cmscam02.c | 11 +- .../share/native/liblcms/cmscgats.c | 147 +++++++++----- .../share/native/liblcms/cmscnvrt.c | 3 +- .../share/native/liblcms/cmserr.c | 2 +- .../share/native/liblcms/cmsgamma.c | 2 +- .../share/native/liblcms/cmsgmt.c | 11 +- .../share/native/liblcms/cmshalf.c | 2 +- .../share/native/liblcms/cmsintrp.c | 4 +- .../share/native/liblcms/cmsio0.c | 7 +- .../share/native/liblcms/cmsio1.c | 2 +- .../share/native/liblcms/cmslut.c | 4 +- .../share/native/liblcms/cmsmd5.c | 10 +- .../share/native/liblcms/cmsmtrx.c | 2 +- .../share/native/liblcms/cmsnamed.c | 4 +- .../share/native/liblcms/cmsopt.c | 2 +- .../share/native/liblcms/cmspack.c | 28 ++- .../share/native/liblcms/cmspcs.c | 2 +- .../share/native/liblcms/cmsplugin.c | 7 +- .../share/native/liblcms/cmsps2.c | 62 ++++-- .../share/native/liblcms/cmssamp.c | 2 +- src/java.desktop/share/native/liblcms/cmssm.c | 2 +- .../share/native/liblcms/cmstypes.c | 188 +++++++++++++++++- .../share/native/liblcms/cmsvirt.c | 10 +- .../share/native/liblcms/cmswtpnt.c | 2 +- .../share/native/liblcms/cmsxform.c | 68 ++++--- src/java.desktop/share/native/liblcms/lcms2.h | 12 +- .../share/native/liblcms/lcms2_internal.h | 7 +- .../share/native/liblcms/lcms2_plugin.h | 2 +- 30 files changed, 451 insertions(+), 176 deletions(-) diff --git a/src/java.desktop/share/legal/lcms.md b/src/java.desktop/share/legal/lcms.md index 02af4fff0005e..83c47d3acdb47 100644 --- a/src/java.desktop/share/legal/lcms.md +++ b/src/java.desktop/share/legal/lcms.md @@ -1,11 +1,11 @@ -## Little Color Management System (LCMS) v2.16 +## Little Color Management System (LCMS) v2.17 ### LCMS License

 
 MIT License
 
-Copyright (C) 1998-2023 Marti Maria Saguer
+Copyright (C) 1998-2025 Marti Maria Saguer
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the "Software"),
@@ -26,10 +26,10 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 ---------------------------------
-The below license applies to the following files:
+The below applies to the following file(s):
 liblcms/cmssm.c
 
-Copyright 2001, softSurfer (www.softsurfer.com)
+Copyright (C) 2001, softSurfer (www.softsurfer.com)
 
 This code may be freely used and modified for any purpose
 providing that this copyright notice is included with it.
@@ -99,5 +99,5 @@ Christian Albrecht
 Dimitrios Anastassakis
 Lemke Software
 Tim Zaman
-
-```
+Amir Montazery and Open Source Technology Improvement Fund (ostif.org), Google, for fuzzer fundings.
+```
\ No newline at end of file
diff --git a/src/java.desktop/share/native/liblcms/cmsalpha.c b/src/java.desktop/share/native/liblcms/cmsalpha.c
index 78d3ca6b67151..2e50b65be24cb 100644
--- a/src/java.desktop/share/native/liblcms/cmsalpha.c
+++ b/src/java.desktop/share/native/liblcms/cmsalpha.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -612,8 +612,8 @@ void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
         cmsUInt8Number* SourcePtr;
         cmsUInt8Number* DestPtr;
 
-        cmsUInt32Number SourceStrideIncrement = 0;
-        cmsUInt32Number DestStrideIncrement = 0;
+        size_t SourceStrideIncrement = 0;
+        size_t DestStrideIncrement = 0;
 
         // The loop itself
         for (i = 0; i < LineCount; i++) {
@@ -640,8 +640,8 @@ void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
         cmsUInt8Number* SourcePtr[cmsMAXCHANNELS];
         cmsUInt8Number* DestPtr[cmsMAXCHANNELS];
 
-        cmsUInt32Number SourceStrideIncrements[cmsMAXCHANNELS];
-        cmsUInt32Number DestStrideIncrements[cmsMAXCHANNELS];
+        size_t SourceStrideIncrements[cmsMAXCHANNELS];
+        size_t DestStrideIncrements[cmsMAXCHANNELS];
 
         memset(SourceStrideIncrements, 0, sizeof(SourceStrideIncrements));
         memset(DestStrideIncrements, 0, sizeof(DestStrideIncrements));
diff --git a/src/java.desktop/share/native/liblcms/cmscam02.c b/src/java.desktop/share/native/liblcms/cmscam02.c
index 71a48d43de4ad..45ef4eef970ca 100644
--- a/src/java.desktop/share/native/liblcms/cmscam02.c
+++ b/src/java.desktop/share/native/liblcms/cmscam02.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -117,17 +117,16 @@ cmsFloat64Number computeFL(cmsCIECAM02* pMod)
     return FL;
 }
 
-static
-cmsFloat64Number computeD(cmsCIECAM02* pMod)
+static cmsFloat64Number computeD(cmsCIECAM02* pMod)
 {
-    cmsFloat64Number D;
+    cmsFloat64Number D, temp;
 
-    D = pMod->F - (1.0/3.6)*(exp(((-pMod ->LA-42) / 92.0)));
+    temp = 1.0 - ((1.0 / 3.6) * exp((-pMod->LA - 42) / 92.0));
 
+    D = pMod->F * temp;
     return D;
 }
 
-
 static
 CAM02COLOR XYZtoCAT02(CAM02COLOR clr)
 {
diff --git a/src/java.desktop/share/native/liblcms/cmscgats.c b/src/java.desktop/share/native/liblcms/cmscgats.c
index 57725ae4731a2..3e62d064c3f6a 100644
--- a/src/java.desktop/share/native/liblcms/cmscgats.c
+++ b/src/java.desktop/share/native/liblcms/cmscgats.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -444,10 +444,11 @@ static
 void StringClear(string* s)
 {
     s->len = 0;
+    s->begin[0] = 0;
 }
 
 static
-void StringAppend(string* s, char c)
+cmsBool StringAppend(string* s, char c)
 {
     if (s->len + 1 >= s->max)
     {
@@ -455,6 +456,8 @@ void StringAppend(string* s, char c)
 
         s->max *= 10;
         new_ptr = (char*) AllocChunk(s->it8, s->max);
+        if (new_ptr == NULL) return FALSE;
+
         if (new_ptr != NULL && s->begin != NULL)
             memcpy(new_ptr, s->begin, s->len);
 
@@ -466,6 +469,8 @@ void StringAppend(string* s, char c)
         s->begin[s->len++] = c;
         s->begin[s->len] = 0;
     }
+
+    return TRUE;
 }
 
 static
@@ -475,13 +480,15 @@ char* StringPtr(string* s)
 }
 
 static
-void StringCat(string* s, const char* c)
+cmsBool StringCat(string* s, const char* c)
 {
     while (*c)
     {
-        StringAppend(s, *c);
+        if (!StringAppend(s, *c)) return FALSE;
         c++;
     }
+
+    return TRUE;
 }
 
 
@@ -830,7 +837,12 @@ void InStringSymbol(cmsIT8* it8)
 
             if (it8->ch == '\n' || it8->ch == '\r' || it8->ch == 0) break;
             else {
-                StringAppend(it8->str, (char)it8->ch);
+                if (!StringAppend(it8->str, (char)it8->ch)) {
+
+                    SynError(it8, "Out of memory");
+                    return;
+                }
+
                 NextCh(it8);
             }
         }
@@ -860,7 +872,11 @@ void InSymbol(cmsIT8* it8)
 
             do {
 
-                StringAppend(it8->id, (char) it8->ch);
+                if (!StringAppend(it8->id, (char)it8->ch)) {
+
+                    SynError(it8, "Out of memory");
+                    return;
+                }
 
                 NextCh(it8);
 
@@ -904,7 +920,6 @@ void InSymbol(cmsIT8* it8)
                             if ((cmsFloat64Number) it8->inum * 16.0 + (cmsFloat64Number) j > (cmsFloat64Number)+2147483647.0)
                             {
                                 SynError(it8, "Invalid hexadecimal number");
-                                it8->sy = SEOF;
                                 return;
                             }
 
@@ -926,7 +941,6 @@ void InSymbol(cmsIT8* it8)
                             if ((cmsFloat64Number) it8->inum * 2.0 + j > (cmsFloat64Number)+2147483647.0)
                             {
                                 SynError(it8, "Invalid binary number");
-                                it8->sy = SEOF;
                                 return;
                             }
 
@@ -979,11 +993,19 @@ void InSymbol(cmsIT8* it8)
                     }
 
                     StringClear(it8->id);
-                    StringCat(it8->id, buffer);
+                    if (!StringCat(it8->id, buffer)) {
+
+                        SynError(it8, "Out of memory");
+                        return;
+                    }
 
                     do {
 
-                        StringAppend(it8->id, (char) it8->ch);
+                        if (!StringAppend(it8->id, (char)it8->ch)) {
+
+                            SynError(it8, "Out of memory");
+                            return;
+                        }
 
                         NextCh(it8);
 
@@ -1038,7 +1060,6 @@ void InSymbol(cmsIT8* it8)
 
         default:
             SynError(it8, "Unrecognized character: 0x%x", it8 ->ch);
-            it8->sy = SEOF;
             return;
             }
 
@@ -1053,24 +1074,21 @@ void InSymbol(cmsIT8* it8)
                 if(it8 -> IncludeSP >= (MAXINCLUDE-1)) {
 
                     SynError(it8, "Too many recursion levels");
-                    it8->sy = SEOF;
                     return;
                 }
 
                 InStringSymbol(it8);
                 if (!Check(it8, SSTRING, "Filename expected"))
-                {
-                    it8->sy = SEOF;
                     return;
-                }
+
 
                 FileNest = it8 -> FileStack[it8 -> IncludeSP + 1];
                 if(FileNest == NULL) {
 
                     FileNest = it8 ->FileStack[it8 -> IncludeSP + 1] = (FILECTX*)AllocChunk(it8, sizeof(FILECTX));
                     if (FileNest == NULL) {
+
                         SynError(it8, "Out of memory");
-                        it8->sy = SEOF;
                         return;
                     }
                 }
@@ -1078,8 +1096,8 @@ void InSymbol(cmsIT8* it8)
                 if (BuildAbsolutePath(StringPtr(it8->str),
                                       it8->FileStack[it8->IncludeSP]->FileName,
                                       FileNest->FileName, cmsMAX_PATH-1) == FALSE) {
+
                     SynError(it8, "File path too long");
-                    it8->sy = SEOF;
                     return;
                 }
 
@@ -1087,7 +1105,6 @@ void InSymbol(cmsIT8* it8)
                 if (FileNest->Stream == NULL) {
 
                         SynError(it8, "File %s not found", FileNest->FileName);
-                        it8->sy = SEOF;
                         return;
                 }
                 it8->IncludeSP++;
@@ -1102,10 +1119,10 @@ void InSymbol(cmsIT8* it8)
 static
 cmsBool CheckEOLN(cmsIT8* it8)
 {
-        if (!Check(it8, SEOLN, "Expected separator")) return FALSE;
-        while (it8 -> sy == SEOLN)
-                        InSymbol(it8);
-        return TRUE;
+    if (!Check(it8, SEOLN, "Expected separator")) return FALSE;
+    while (it8->sy == SEOLN)
+        InSymbol(it8);
+    return TRUE;
 
 }
 
@@ -1114,8 +1131,8 @@ cmsBool CheckEOLN(cmsIT8* it8)
 static
 void Skip(cmsIT8* it8, SYMBOL sy)
 {
-        if (it8->sy == sy && it8->sy != SEOF)
-                        InSymbol(it8);
+    if (it8->sy == sy && it8->sy != SEOF && it8->sy != SSYNERROR)
+        InSymbol(it8);
 }
 
 
@@ -1124,7 +1141,7 @@ static
 void SkipEOLN(cmsIT8* it8)
 {
     while (it8->sy == SEOLN) {
-             InSymbol(it8);
+        InSymbol(it8);
     }
 }
 
@@ -1235,9 +1252,12 @@ void* AllocChunk(cmsIT8* it8, cmsUInt32Number size)
     cmsUInt8Number* ptr;
 
     size = _cmsALIGNMEM(size);
+    if (size == 0) return NULL;
 
     if (size > Free) {
 
+        cmsUInt8Number* new_block;
+
         if (it8 -> Allocator.BlockSize == 0)
 
                 it8 -> Allocator.BlockSize = 20*1024;
@@ -1248,7 +1268,11 @@ void* AllocChunk(cmsIT8* it8, cmsUInt32Number size)
                 it8 ->Allocator.BlockSize = size;
 
         it8 ->Allocator.Used = 0;
-        it8 ->Allocator.Block = (cmsUInt8Number*) AllocBigBlock(it8, it8 ->Allocator.BlockSize);
+        new_block = (cmsUInt8Number*)AllocBigBlock(it8, it8->Allocator.BlockSize);
+        if (new_block == NULL)
+            return NULL;
+
+        it8->Allocator.Block = new_block;
     }
 
     if (it8->Allocator.Block == NULL)
@@ -1258,7 +1282,6 @@ void* AllocChunk(cmsIT8* it8, cmsUInt32Number size)
     it8 ->Allocator.Used += size;
 
     return (void*) ptr;
-
 }
 
 
@@ -1266,9 +1289,12 @@ void* AllocChunk(cmsIT8* it8, cmsUInt32Number size)
 static
 char *AllocString(cmsIT8* it8, const char* str)
 {
-    cmsUInt32Number Size = (cmsUInt32Number) strlen(str)+1;
+    cmsUInt32Number Size;
     char *ptr;
 
+    if (str == NULL) return NULL;
+
+    Size = (cmsUInt32Number)strlen(str) + 1;
 
     ptr = (char *) AllocChunk(it8, Size);
     if (ptr) memcpy(ptr, str, Size-1);
@@ -1404,10 +1430,13 @@ KEYVALUE* AddAvailableSampleID(cmsIT8* it8, const char* Key)
 
 
 static
-void AllocTable(cmsIT8* it8)
+cmsBool AllocTable(cmsIT8* it8)
 {
     TABLE* t;
 
+    if (it8->TablesCount >= (MAXTABLES-1))
+        return FALSE;
+
     t = it8 ->Tab + it8 ->TablesCount;
 
     t->HeaderList = NULL;
@@ -1415,6 +1444,7 @@ void AllocTable(cmsIT8* it8)
     t->Data       = NULL;
 
     it8 ->TablesCount++;
+    return TRUE;
 }
 
 
@@ -1426,7 +1456,10 @@ cmsInt32Number CMSEXPORT cmsIT8SetTable(cmsHANDLE  IT8, cmsUInt32Number nTable)
 
          if (nTable == it8 ->TablesCount) {
 
-             AllocTable(it8);
+             if (!AllocTable(it8)) {
+                 SynError(it8, "Too many tables");
+                 return -1;
+             }
          }
          else {
              SynError(it8, "Table %d is out of sequence", nTable);
@@ -1610,8 +1643,8 @@ cmsInt32Number satoi(const char* b)
     if (b == NULL) return 0;
 
     n = atoi(b);
-    if (n > 0x7fffffffL) return 0x7fffffffL;
-    if (n < -0x7ffffffeL) return -0x7ffffffeL;
+    if (n > 0x7ffffff0L) return 0x7ffffff0L;
+    if (n < -0x7ffffff0L) return -0x7ffffff0L;
 
     return (cmsInt32Number)n;
 }
@@ -1620,22 +1653,26 @@ cmsInt32Number satoi(const char* b)
 static
 cmsBool AllocateDataFormat(cmsIT8* it8)
 {
+    cmsUInt32Number size;
+
     TABLE* t = GetTable(it8);
 
-    if (t -> DataFormat) return TRUE;    // Already allocated
+    if (t->DataFormat) return TRUE;    // Already allocated
 
-    t -> nSamples  = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
+    t->nSamples = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
 
-    if (t -> nSamples <= 0) {
+    if (t->nSamples <= 0 || t->nSamples > 0x7ffe) {
 
-        SynError(it8, "AllocateDataFormat: Unknown NUMBER_OF_FIELDS");
+        SynError(it8, "Wrong NUMBER_OF_FIELDS");
         return FALSE;
-        }
+    }
+
+    size = ((cmsUInt32Number)t->nSamples + 1) * sizeof(char*);
 
-    t -> DataFormat = (char**) AllocChunk (it8, ((cmsUInt32Number) t->nSamples + 1) * sizeof(char *));
+    t->DataFormat = (char**)AllocChunk(it8, size);
     if (t->DataFormat == NULL) {
 
-        SynError(it8, "AllocateDataFormat: Unable to allocate dataFormat array");
+        SynError(it8, "Unable to allocate dataFormat array");
         return FALSE;
     }
 
@@ -1664,7 +1701,7 @@ cmsBool SetDataFormat(cmsIT8* it8, int n, const char *label)
             return FALSE;
     }
 
-    if (n > t -> nSamples) {
+    if (n >= t -> nSamples) {
         SynError(it8, "More than NUMBER_OF_FIELDS fields.");
         return FALSE;
     }
@@ -1713,13 +1750,14 @@ cmsBool AllocateDataSet(cmsIT8* it8)
     t-> nSamples   = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
     t-> nPatches   = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
 
-    if (t -> nSamples < 0 || t->nSamples > 0x7ffe || t->nPatches < 0 || t->nPatches > 0x7ffe)
+    if (t -> nSamples < 0 || t->nSamples > 0x7ffe || t->nPatches < 0 || t->nPatches > 0x7ffe ||
+        (t->nPatches * t->nSamples) > 200000)
     {
         SynError(it8, "AllocateDataSet: too much data");
         return FALSE;
     }
     else {
-        // Some dumb analizers warns of possible overflow here, just take a look couple of lines above.
+        // Some dumb analyzers warns of possible overflow here, just take a look couple of lines above.
         t->Data = (char**)AllocChunk(it8, ((cmsUInt32Number)t->nSamples + 1) * ((cmsUInt32Number)t->nPatches + 1) * sizeof(char*));
         if (t->Data == NULL) {
 
@@ -1748,8 +1786,11 @@ char* GetData(cmsIT8* it8, int nSet, int nField)
 static
 cmsBool SetData(cmsIT8* it8, int nSet, int nField, const char *Val)
 {
+    char* ptr;
+
     TABLE* t = GetTable(it8);
 
+
     if (!t->Data) {
         if (!AllocateDataSet(it8)) return FALSE;
     }
@@ -1766,7 +1807,11 @@ cmsBool SetData(cmsIT8* it8, int nSet, int nField, const char *Val)
 
     }
 
-    t->Data [nSet * t -> nSamples + nField] = AllocString(it8, Val);
+    ptr = AllocString(it8, Val);
+    if (ptr == NULL)
+        return FALSE;
+
+    t->Data [nSet * t -> nSamples + nField] = ptr;
     return TRUE;
 }
 
@@ -2121,7 +2166,7 @@ cmsBool DataSection (cmsIT8* it8)
         if (!AllocateDataSet(it8)) return FALSE;
     }
 
-    while (it8->sy != SEND_DATA && it8->sy != SEOF)
+    while (it8->sy != SEND_DATA && it8->sy != SEOF && it8->sy != SSYNERROR)
     {
         if (iField >= t -> nSamples) {
             iField = 0;
@@ -2129,7 +2174,7 @@ cmsBool DataSection (cmsIT8* it8)
 
         }
 
-        if (it8->sy != SEND_DATA && it8->sy != SEOF) {
+        if (it8->sy != SEND_DATA && it8->sy != SEOF && it8->sy != SSYNERROR) {
 
             switch (it8->sy)
             {
@@ -2225,8 +2270,8 @@ cmsBool HeaderSection(cmsIT8* it8)
             if (!GetVal(it8, Buffer, MAXSTR - 1, "Property data expected")) return FALSE;
 
             if (Key->WriteAs != WRITE_PAIR) {
-                AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer,
-                    (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED);
+                if (AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer,
+                    (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED) == NULL) return FALSE;
             }
             else {
                 const char *Subkey;
@@ -2332,9 +2377,10 @@ cmsBool ParseIT8(cmsIT8* it8, cmsBool nosheet)
 
                     if (!DataSection(it8)) return FALSE;
 
-                    if (it8 -> sy != SEOF) {
+                    if (it8 -> sy != SEOF && it8->sy != SSYNERROR) {
+
+                            if (!AllocTable(it8)) return FALSE;
 
-                            AllocTable(it8);
                             it8 ->nTable = it8 ->TablesCount - 1;
 
                             // Read sheet type if present. We only support identifier and string.
@@ -3064,7 +3110,8 @@ cmsBool ParseCube(cmsIT8* cube, cmsStage** Shaper, cmsStage** CLUT, char title[]
 
     InSymbol(cube);
 
-    while (cube->sy != SEOF) {
+    while (cube->sy != SEOF && cube->sy != SSYNERROR) {
+
         switch (cube->sy)
         {
         // Set profile description
diff --git a/src/java.desktop/share/native/liblcms/cmscnvrt.c b/src/java.desktop/share/native/liblcms/cmscnvrt.c
index d18865b15b9a3..9f8619cb9dac1 100644
--- a/src/java.desktop/share/native/liblcms/cmscnvrt.c
+++ b/src/java.desktop/share/native/liblcms/cmscnvrt.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -750,7 +750,6 @@ static
 cmsBool is_cmyk_devicelink(cmsHPROFILE hProfile)
 {
     return cmsGetDeviceClass(hProfile) == cmsSigLinkClass &&
-            cmsGetColorSpace(hProfile) == cmsSigCmykData &&
             cmsGetColorSpace(hProfile) == cmsSigCmykData;
 }
 
diff --git a/src/java.desktop/share/native/liblcms/cmserr.c b/src/java.desktop/share/native/liblcms/cmserr.c
index 9fb7db89c9a6c..d421c550d32d7 100644
--- a/src/java.desktop/share/native/liblcms/cmserr.c
+++ b/src/java.desktop/share/native/liblcms/cmserr.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
diff --git a/src/java.desktop/share/native/liblcms/cmsgamma.c b/src/java.desktop/share/native/liblcms/cmsgamma.c
index 8e489a43c5533..773858b0c1f02 100644
--- a/src/java.desktop/share/native/liblcms/cmsgamma.c
+++ b/src/java.desktop/share/native/liblcms/cmsgamma.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
diff --git a/src/java.desktop/share/native/liblcms/cmsgmt.c b/src/java.desktop/share/native/liblcms/cmsgmt.c
index e9ee73b52cd0d..03ac70202a50a 100644
--- a/src/java.desktop/share/native/liblcms/cmsgmt.c
+++ b/src/java.desktop/share/native/liblcms/cmsgmt.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2021 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -327,8 +327,9 @@ cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
     cmsUInt32Number dwFormat;
     GAMUTCHAIN Chain;
     cmsUInt32Number nGridpoints;
-    cmsInt32Number nChannels;
+    cmsInt32Number nChannels, nInputChannels;
     cmsColorSpaceSignature ColorSpace;
+    cmsColorSpaceSignature InputColorSpace;
     cmsUInt32Number i;
     cmsHPROFILE ProfileList[256];
     cmsBool     BPCList[256];
@@ -374,11 +375,13 @@ cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
     AdaptationList[nGamutPCSposition] = 1.0;
     IntentList[nGamutPCSposition] = INTENT_RELATIVE_COLORIMETRIC;
 
-
     ColorSpace  = cmsGetColorSpace(hGamut);
     nChannels   = cmsChannelsOfColorSpace(ColorSpace);
     nGridpoints = _cmsReasonableGridpointsByColorspace(ColorSpace, cmsFLAGS_HIGHRESPRECALC);
-    dwFormat    = (CHANNELS_SH(nChannels)|BYTES_SH(2));
+
+    InputColorSpace = cmsGetColorSpace(ProfileList[0]);
+    nInputChannels  = cmsChannelsOfColorSpace(InputColorSpace);
+    dwFormat        = (CHANNELS_SH(nInputChannels)|BYTES_SH(2));
 
     // 16 bits to Lab double
     Chain.hInput = cmsCreateExtendedTransform(ContextID,
diff --git a/src/java.desktop/share/native/liblcms/cmshalf.c b/src/java.desktop/share/native/liblcms/cmshalf.c
index 5babb063eb000..7e5f7a3c7e03a 100644
--- a/src/java.desktop/share/native/liblcms/cmshalf.c
+++ b/src/java.desktop/share/native/liblcms/cmshalf.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
diff --git a/src/java.desktop/share/native/liblcms/cmsintrp.c b/src/java.desktop/share/native/liblcms/cmsintrp.c
index 9837454df0bb6..43c47429c3cda 100644
--- a/src/java.desktop/share/native/liblcms/cmsintrp.c
+++ b/src/java.desktop/share/native/liblcms/cmsintrp.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -524,7 +524,7 @@ void TrilinearInterpFloat(const cmsFloat32Number Input[],
     py = fclamp(Input[1]) * p->Domain[1];
     pz = fclamp(Input[2]) * p->Domain[2];
 
-    x0 = (int) floor(px); fx = px - (cmsFloat32Number) x0;  // We need full floor funcionality here
+    x0 = (int) floor(px); fx = px - (cmsFloat32Number) x0;  // We need full floor functionality here
     y0 = (int) floor(py); fy = py - (cmsFloat32Number) y0;
     z0 = (int) floor(pz); fz = pz - (cmsFloat32Number) z0;
 
diff --git a/src/java.desktop/share/native/liblcms/cmsio0.c b/src/java.desktop/share/native/liblcms/cmsio0.c
index 05baa9392e21a..5258b7939d2bf 100644
--- a/src/java.desktop/share/native/liblcms/cmsio0.c
+++ b/src/java.desktop/share/native/liblcms/cmsio0.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -306,6 +306,11 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromMem(cmsContext ContextID, void *Buff
         fm = (FILEMEM*) _cmsMallocZero(ContextID, sizeof(FILEMEM));
         if (fm == NULL) goto Error;
 
+        if (Buffer == NULL) {
+            cmsSignalError(ContextID, cmsERROR_WRITE, "Couldn't write profile to NULL pointer");
+            goto Error;
+        }
+
         fm ->Block = (cmsUInt8Number*) Buffer;
         fm ->FreeBlockOnClose = FALSE;
         fm ->Size    = size;
diff --git a/src/java.desktop/share/native/liblcms/cmsio1.c b/src/java.desktop/share/native/liblcms/cmsio1.c
index e42d4d3898730..48772c7cbde9d 100644
--- a/src/java.desktop/share/native/liblcms/cmsio1.c
+++ b/src/java.desktop/share/native/liblcms/cmsio1.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
diff --git a/src/java.desktop/share/native/liblcms/cmslut.c b/src/java.desktop/share/native/liblcms/cmslut.c
index b544c94862592..3cf4e8cac5a6b 100644
--- a/src/java.desktop/share/native/liblcms/cmslut.c
+++ b/src/java.desktop/share/native/liblcms/cmslut.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -1109,7 +1109,7 @@ cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID)
     return mpe;
 }
 
-// Fom XYZ to floating point PCS
+// From XYZ to floating point PCS
 cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID)
 {
 #define n (32768.0/65535.0)
diff --git a/src/java.desktop/share/native/liblcms/cmsmd5.c b/src/java.desktop/share/native/liblcms/cmsmd5.c
index 01aa44de85a09..d9b9a4e526080 100644
--- a/src/java.desktop/share/native/liblcms/cmsmd5.c
+++ b/src/java.desktop/share/native/liblcms/cmsmd5.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -280,8 +280,8 @@ void CMSEXPORT cmsMD5finish(cmsProfileID* ProfileID,  cmsHANDLE Handle)
 
 
 // Assuming io points to an ICC profile, compute and store MD5 checksum
-// In the header, rendering intentent, attributes and ID should be set to zero
-// before computing MD5 checksum (per 6.1.13 in ICC spec)
+// In the header, rendering intentent, flags and ID should be set to zero
+// before computing MD5 checksum (per 7.2.18 of ICC spec 4.4)
 
 cmsBool CMSEXPORT cmsMD5computeID(cmsHPROFILE hProfile)
 {
@@ -299,8 +299,8 @@ cmsBool CMSEXPORT cmsMD5computeID(cmsHPROFILE hProfile)
     // Save a copy of the profile header
     memmove(&Keep, Icc, sizeof(_cmsICCPROFILE));
 
-    // Set RI, attributes and ID
-    memset(&Icc ->attributes, 0, sizeof(Icc ->attributes));
+    // Set RI, flags and ID
+    Icc ->flags = 0;
     Icc ->RenderingIntent = 0;
     memset(&Icc ->ProfileID, 0, sizeof(Icc ->ProfileID));
 
diff --git a/src/java.desktop/share/native/liblcms/cmsmtrx.c b/src/java.desktop/share/native/liblcms/cmsmtrx.c
index 599c290bd7051..841da662a1079 100644
--- a/src/java.desktop/share/native/liblcms/cmsmtrx.c
+++ b/src/java.desktop/share/native/liblcms/cmsmtrx.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
diff --git a/src/java.desktop/share/native/liblcms/cmsnamed.c b/src/java.desktop/share/native/liblcms/cmsnamed.c
index d3cd97d4aea5f..451bfe9f34d57 100644
--- a/src/java.desktop/share/native/liblcms/cmsnamed.c
+++ b/src/java.desktop/share/native/liblcms/cmsnamed.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -598,7 +598,7 @@ cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
     if (BufferSize < ASCIIlen + 1)
         ASCIIlen = BufferSize - 1;
 
-    // Precess each character
+    // Process each character
     for (i=0; i < ASCIIlen; i++) {
 
         wchar_t wc = Wide[i];
diff --git a/src/java.desktop/share/native/liblcms/cmsopt.c b/src/java.desktop/share/native/liblcms/cmsopt.c
index 421a4f4a70193..767008e68c58c 100644
--- a/src/java.desktop/share/native/liblcms/cmsopt.c
+++ b/src/java.desktop/share/native/liblcms/cmsopt.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
diff --git a/src/java.desktop/share/native/liblcms/cmspack.c b/src/java.desktop/share/native/liblcms/cmspack.c
index fc875995a80c2..d430e73051ded 100644
--- a/src/java.desktop/share/native/liblcms/cmspack.c
+++ b/src/java.desktop/share/native/liblcms/cmspack.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -217,7 +217,7 @@ cmsUInt8Number* UnrollPlanarBytes(CMSREGISTER _cmsTRANSFORM* info,
     else
     {
         if (Premul && Extra)
-            alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(accum[(nChan) * Stride]));
+            alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(accum[nChan * Stride]));
     }
 
     for (i=0; i < nChan; i++) {
@@ -606,8 +606,8 @@ cmsUInt8Number* UnrollAnyWordsPremul(CMSREGISTER _cmsTRANSFORM* info,
    cmsUInt32Number ExtraFirst  = DoSwap ^ SwapFirst;
    cmsUInt32Number i;
 
-   cmsUInt16Number alpha = (ExtraFirst ? accum[0] : accum[nChan - 1]);
-   cmsUInt32Number alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(alpha));
+   cmsUInt16Number alpha = (ExtraFirst ? ((cmsUInt16Number*)accum)[0] : ((cmsUInt16Number*)accum)[nChan]);
+   cmsUInt32Number alpha_factor = _cmsToFixedDomain(alpha);
 
     if (ExtraFirst) {
         accum += sizeof(cmsUInt16Number);
@@ -691,8 +691,8 @@ cmsUInt8Number* UnrollPlanarWordsPremul(CMSREGISTER _cmsTRANSFORM* info,
     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
     cmsUInt8Number* Init = accum;
 
-    cmsUInt16Number  alpha = (ExtraFirst ? accum[0] : accum[(nChan - 1) * Stride]);
-    cmsUInt32Number alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(alpha));
+    cmsUInt16Number alpha = (ExtraFirst ? ((cmsUInt16Number*)accum)[0] : ((cmsUInt16Number*)accum)[nChan * Stride / 2]);
+    cmsUInt32Number alpha_factor = _cmsToFixedDomain(alpha);
 
     if (ExtraFirst) {
         accum += Stride;
@@ -1107,8 +1107,7 @@ cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type)
 }
 
 // Return the size in bytes of a given formatter
-static
-cmsUInt32Number PixelSize(cmsUInt32Number Format)
+cmsINLINE cmsUInt32Number PixelSize(cmsUInt32Number Format)
 {
     cmsUInt32Number fmt_bytes = T_BYTES(Format);
 
@@ -1454,7 +1453,7 @@ cmsUInt8Number* UnrollDoublesToFloat(_cmsTRANSFORM* info,
     if (Premul && Extra)
     {
         if (Planar)
-            alpha_factor = (ExtraFirst ? ptr[0] : ptr[(nChan) * Stride]) / maximum;
+            alpha_factor = (ExtraFirst ? ptr[0] : ptr[nChan * Stride]) / maximum;
         else
             alpha_factor = (ExtraFirst ? ptr[0] : ptr[nChan]) / maximum;
     }
@@ -3052,6 +3051,7 @@ cmsUInt8Number* PackWordsFromFloat(_cmsTRANSFORM* info,
     if (ExtraFirst)
         start = Extra;
 
+    Stride /= 2;
     for (i = 0; i < nChan; i++) {
 
         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
@@ -3115,7 +3115,7 @@ cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info,
                      v = maximum - v;
 
               if (Planar)
-                     ((cmsFloat32Number*)output)[(i + start)* Stride] = (cmsFloat32Number)v;
+                     ((cmsFloat32Number*)output)[(i + start) * Stride] = (cmsFloat32Number)v;
               else
                      ((cmsFloat32Number*)output)[i + start] = (cmsFloat32Number)v;
        }
@@ -3455,7 +3455,7 @@ cmsUInt8Number* UnrollHalfToFloat(_cmsTRANSFORM* info,
     cmsUInt32Number i, start = 0;
     cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
 
-    Stride /= PixelSize(info->OutputFormat);
+    Stride /= PixelSize(info->InputFormat);
 
     if (ExtraFirst)
             start = Extra;
@@ -4062,6 +4062,9 @@ cmsUInt32Number CMSEXPORT cmsFormatterForColorspaceOfProfile(cmsHPROFILE hProfil
     // Unsupported color space?
     if (nOutputChans < 0) return 0;
 
+    // Fix float spaces
+    nBytes &= 7;
+
     // Create a fake formatter for result
     return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
 }
@@ -4079,6 +4082,9 @@ cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsU
     // Unsupported color space?
     if (nOutputChans < 0) return 0;
 
+    // Fix float spaces
+    nBytes &= 7;
+
     // Create a fake formatter for result
     return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
 }
diff --git a/src/java.desktop/share/native/liblcms/cmspcs.c b/src/java.desktop/share/native/liblcms/cmspcs.c
index c4739840053b3..5f1b1f0d8e6db 100644
--- a/src/java.desktop/share/native/liblcms/cmspcs.c
+++ b/src/java.desktop/share/native/liblcms/cmspcs.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
diff --git a/src/java.desktop/share/native/liblcms/cmsplugin.c b/src/java.desktop/share/native/liblcms/cmsplugin.c
index f84e0172c813d..aaad39f52b04c 100644
--- a/src/java.desktop/share/native/liblcms/cmsplugin.c
+++ b/src/java.desktop/share/native/liblcms/cmsplugin.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -935,7 +935,10 @@ cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData)
     if (!InitContextMutex()) return NULL;
 
     // Setup default memory allocators
-    memcpy(&ctx->DefaultMemoryManager, &src->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));
+    if (ContextID == NULL)
+        _cmsInstallAllocFunctions(NULL, &ctx->DefaultMemoryManager);
+    else
+        memcpy(&ctx->DefaultMemoryManager, &src->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));
 
     // Maintain the linked list
     _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
diff --git a/src/java.desktop/share/native/liblcms/cmsps2.c b/src/java.desktop/share/native/liblcms/cmsps2.c
index 9a2ab464f315a..476817e9c1a2d 100644
--- a/src/java.desktop/share/native/liblcms/cmsps2.c
+++ b/src/java.desktop/share/native/liblcms/cmsps2.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -494,7 +494,7 @@ void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table)
     // Bounds check
     EmitRangeCheck(m);
 
-    // Emit intepolation code
+    // Emit interpolation code
 
     // PostScript code                      Stack
     // ===============                      ========================
@@ -618,7 +618,7 @@ int OutputValueSampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUI
     }
 
 
-    // Hadle the parenthesis on rows
+    // Handle the parenthesis on rows
 
     if (In[0] != sc ->FirstComponent) {
 
@@ -694,8 +694,10 @@ void WriteCLUT(cmsIOHANDLER* m, cmsStage* mpe, const char* PreMaj,
 
         _cmsIOPrintf(m, "[");
 
-        for (i = 0; i < sc.Pipeline->Params->nInputs; i++)
-            _cmsIOPrintf(m, " %d ", sc.Pipeline->Params->nSamples[i]);
+        for (i = 0; i < sc.Pipeline->Params->nInputs; i++) {
+            if (i < MAX_INPUT_DIMENSIONS)
+                _cmsIOPrintf(m, " %d ", sc.Pipeline->Params->nSamples[i]);
+        }
 
         _cmsIOPrintf(m, " [\n");
 
@@ -869,13 +871,13 @@ cmsToneCurve* ExtractGray2Y(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt3
 // a more perceptually uniform space... I do choose Lab.
 
 static
-int WriteInputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
+cmsBool WriteInputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
 {
     cmsHPROFILE hLab;
     cmsHTRANSFORM xform;
     cmsUInt32Number nChannels;
     cmsUInt32Number InputFormat;
-    int rc;
+
     cmsHPROFILE Profiles[2];
     cmsCIEXYZ BlackPointAdaptedToD50;
 
@@ -900,7 +902,7 @@ int WriteInputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent,
     if (xform == NULL) {
 
         cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Cannot create transform Profile -> Lab");
-        return 0;
+        return FALSE;
     }
 
     // Only 1, 3 and 4 channels are allowed
@@ -919,29 +921,35 @@ int WriteInputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent,
             cmsUInt32Number OutFrm = TYPE_Lab_16;
             cmsPipeline* DeviceLink;
             _cmsTRANSFORM* v = (_cmsTRANSFORM*) xform;
+            cmsBool rc;
 
             DeviceLink = cmsPipelineDup(v ->Lut);
-            if (DeviceLink == NULL) return 0;
+            if (DeviceLink == NULL) {
+                cmsDeleteTransform(xform);
+                return FALSE;
+            }
 
             dwFlags |= cmsFLAGS_FORCE_CLUT;
             _cmsOptimizePipeline(m->ContextID, &DeviceLink, Intent, &InputFormat, &OutFrm, &dwFlags);
 
             rc = EmitCIEBasedDEF(m, DeviceLink, Intent, &BlackPointAdaptedToD50);
             cmsPipelineFree(DeviceLink);
-            if (rc == 0) return 0;
+            if (!rc) {
+                cmsDeleteTransform(xform);
+                return FALSE;
+            }
             }
             break;
 
     default:
 
+        cmsDeleteTransform(xform);
         cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Only 3, 4 channels are supported for CSA. This profile has %d channels.", nChannels);
-        return 0;
+        return FALSE;
     }
 
-
     cmsDeleteTransform(xform);
-
-    return 1;
+    return TRUE;
 }
 
 static
@@ -1284,7 +1292,7 @@ void EmitXYZ2Lab(cmsIOHANDLER* m)
 // 8 bits.
 
 static
-int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
+cmsBool WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
 {
     cmsHPROFILE hLab;
     cmsHTRANSFORM xform;
@@ -1302,7 +1310,7 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
     cmsStage* first;
 
     hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
-    if (hLab == NULL) return 0;
+    if (hLab == NULL) return FALSE;
 
     OutputFormat = cmsFormatterForColorspaceOfProfile(hProfile, 2, FALSE);
     nChannels    = T_CHANNELS(OutputFormat);
@@ -1327,7 +1335,7 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
 
     if (xform == NULL) {
         cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Cannot create transform Lab -> Profile in CRD creation");
-        return 0;
+        return FALSE;
     }
 
     // Get a copy of the internal devicelink
@@ -1335,17 +1343,22 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
     DeviceLink = cmsPipelineDup(v ->Lut);
     if (DeviceLink == NULL) {
         cmsDeleteTransform(xform);
-        return 0;
+        cmsSignalError(m->ContextID, cmsERROR_CORRUPTION_DETECTED, "Cannot access link for CRD");
+        return FALSE;
     }
 
      // We need a CLUT
     dwFlags |= cmsFLAGS_FORCE_CLUT;
-    _cmsOptimizePipeline(m->ContextID, &DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags);
+    if (!_cmsOptimizePipeline(m->ContextID, &DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags)) {
+        cmsPipelineFree(DeviceLink);
+        cmsDeleteTransform(xform);
+        cmsSignalError(m->ContextID, cmsERROR_CORRUPTION_DETECTED, "Cannot create CLUT table for CRD");
+        return FALSE;
+    }
 
     _cmsIOPrintf(m, "<<\n");
     _cmsIOPrintf(m, "/ColorRenderingType 1\n");
 
-
     cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, Intent, 0);
 
     // Emit headers, etc.
@@ -1367,6 +1380,13 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
 
     first = cmsPipelineGetPtrToFirstStage(DeviceLink);
     if (first != NULL) {
+        if (first->Type != cmsSigCLutElemType) {
+            cmsPipelineFree(DeviceLink);
+            cmsDeleteTransform(xform);
+            cmsSignalError(m->ContextID, cmsERROR_CORRUPTION_DETECTED, "Cannot create CLUT, revise your flags!");
+            return FALSE;
+        }
+
         WriteCLUT(m, first, "<", ">\n", "", "", lFixWhite, ColorSpace);
     }
 
@@ -1389,7 +1409,7 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
     cmsPipelineFree(DeviceLink);
     cmsDeleteTransform(xform);
 
-    return 1;
+    return TRUE;
 }
 
 
diff --git a/src/java.desktop/share/native/liblcms/cmssamp.c b/src/java.desktop/share/native/liblcms/cmssamp.c
index 74f5f4bff29b5..ca5c4a9d69318 100644
--- a/src/java.desktop/share/native/liblcms/cmssamp.c
+++ b/src/java.desktop/share/native/liblcms/cmssamp.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
diff --git a/src/java.desktop/share/native/liblcms/cmssm.c b/src/java.desktop/share/native/liblcms/cmssm.c
index 3e1486ae3ae1b..e2a810a266954 100644
--- a/src/java.desktop/share/native/liblcms/cmssm.c
+++ b/src/java.desktop/share/native/liblcms/cmssm.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
diff --git a/src/java.desktop/share/native/liblcms/cmstypes.c b/src/java.desktop/share/native/liblcms/cmstypes.c
index 862f393497aa4..22514f8822682 100644
--- a/src/java.desktop/share/native/liblcms/cmstypes.c
+++ b/src/java.desktop/share/native/liblcms/cmstypes.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -599,6 +599,178 @@ void Type_ColorantOrderType_Free(struct _cms_typehandler_struct* self, void* Ptr
     _cmsFree(self ->ContextID, Ptr);
 }
 
+// ********************************************************************************
+// Type cmsSigUInt8ArrayType
+// ********************************************************************************
+// This type represents an array of generic 1-byte/8-bit quantity.
+
+static
+void* Type_UInt8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
+{
+    cmsUInt8Number* array;
+    cmsUInt32Number i, n;
+
+    *nItems = 0;
+    n = SizeOfTag / sizeof(cmsUInt8Number);
+    array = (cmsUInt8Number*)_cmsCalloc(self->ContextID, n, sizeof(cmsUInt8Number));
+    if (array == NULL) return NULL;
+
+    for (i = 0; i < n; i++) {
+
+        if (!_cmsReadUInt8Number(io, &array[i])) {
+
+            _cmsFree(self->ContextID, array);
+            return NULL;
+        }
+    }
+
+    *nItems = n;
+    return (void*)array;
+}
+
+static
+cmsBool Type_UInt8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
+{
+    cmsUInt8Number* Value = (cmsUInt8Number*)Ptr;
+    cmsUInt32Number i;
+
+    for (i = 0; i < nItems; i++) {
+
+        if (!_cmsWriteUInt8Number(io, Value[i])) return FALSE;
+    }
+
+    return TRUE;
+
+    cmsUNUSED_PARAMETER(self);
+}
+
+static
+void* Type_UInt8_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n)
+{
+    return _cmsDupMem(self->ContextID, Ptr, n * sizeof(cmsUInt8Number));
+}
+
+
+static
+void Type_UInt8_Free(struct _cms_typehandler_struct* self, void* Ptr)
+{
+    _cmsFree(self->ContextID, Ptr);
+}
+
+// ********************************************************************************
+// Type cmsSigUInt32ArrayType
+// ********************************************************************************
+// This type represents an array of generic 4-byte/32-bit quantity.
+static
+void* Type_UInt32_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
+{
+    cmsUInt32Number* array;
+    cmsUInt32Number i, n;
+
+    *nItems = 0;
+    n = SizeOfTag / sizeof(cmsUInt32Number);
+    array = (cmsUInt32Number*)_cmsCalloc(self->ContextID, n, sizeof(cmsUInt32Number));
+    if (array == NULL) return NULL;
+
+    for (i = 0; i < n; i++) {
+
+        if (!_cmsReadUInt32Number(io, &array[i])) {
+
+            _cmsFree(self->ContextID, array);
+            return NULL;
+        }
+    }
+
+    *nItems = n;
+    return (void*)array;
+}
+
+static
+cmsBool Type_UInt32_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
+{
+    cmsUInt32Number* Value = (cmsUInt32Number*)Ptr;
+    cmsUInt32Number i;
+
+    for (i = 0; i < nItems; i++) {
+
+        if (!_cmsWriteUInt32Number(io, Value[i])) return FALSE;
+    }
+
+    return TRUE;
+
+    cmsUNUSED_PARAMETER(self);
+}
+
+static
+void* Type_UInt32_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n)
+{
+    return _cmsDupMem(self->ContextID, Ptr, n * sizeof(cmsUInt32Number));
+}
+
+
+static
+void Type_UInt32_Free(struct _cms_typehandler_struct* self, void* Ptr)
+{
+    _cmsFree(self->ContextID, Ptr);
+}
+
+// ********************************************************************************
+// Type cmsSigUInt64ArrayType
+// ********************************************************************************
+// This type represents an array of generic 8-byte/64-bit quantity.
+static
+void* Type_UInt64_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
+{
+    cmsUInt64Number* array;
+    cmsUInt32Number i, n;
+
+    *nItems = 0;
+    n = SizeOfTag / sizeof(cmsUInt64Number);
+    array = (cmsUInt64Number*)_cmsCalloc(self->ContextID, n, sizeof(cmsUInt64Number));
+    if (array == NULL) return NULL;
+
+    for (i = 0; i < n; i++) {
+
+        if (!_cmsReadUInt64Number(io, &array[i])) {
+
+            _cmsFree(self->ContextID, array);
+            return NULL;
+        }
+    }
+
+    *nItems = n;
+    return (void*)array;
+}
+
+static
+cmsBool Type_UInt64_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
+{
+    cmsUInt64Number* Value = (cmsUInt64Number*)Ptr;
+    cmsUInt32Number i;
+
+    for (i = 0; i < nItems; i++) {
+
+        if (!_cmsWriteUInt64Number(io, &Value[i])) return FALSE;
+    }
+
+    return TRUE;
+
+    cmsUNUSED_PARAMETER(self);
+}
+
+static
+void* Type_UInt64_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n)
+{
+    return _cmsDupMem(self->ContextID, Ptr, n * sizeof(cmsUInt64Number));
+}
+
+
+static
+void Type_UInt64_Free(struct _cms_typehandler_struct* self, void* Ptr)
+{
+    _cmsFree(self->ContextID, Ptr);
+}
+
 // ********************************************************************************
 // Type cmsSigS15Fixed16ArrayType
 // ********************************************************************************
@@ -968,6 +1140,8 @@ void *Type_Text_Description_Read(struct _cms_typehandler_struct* self, cmsIOHAND
 
     // Read len of ASCII
     if (!_cmsReadUInt32Number(io, &AsciiCount)) return NULL;
+    if (AsciiCount > 0x7ffff) return NULL;
+
     SizeOfTag -= sizeof(cmsUInt32Number);
 
     // Check for size
@@ -999,7 +1173,8 @@ void *Type_Text_Description_Read(struct _cms_typehandler_struct* self, cmsIOHAND
     if (!_cmsReadUInt32Number(io, &UnicodeCount)) goto Done;
     SizeOfTag -= 2* sizeof(cmsUInt32Number);
 
-    if (UnicodeCount == 0 || SizeOfTag < UnicodeCount*sizeof(cmsUInt16Number)) goto Done;
+    if (UnicodeCount == 0 || UnicodeCount > 0x7ffff ||
+        SizeOfTag < UnicodeCount*sizeof(cmsUInt16Number)) goto Done;
 
     UnicodeString = (wchar_t*)_cmsMallocZero(self->ContextID, (UnicodeCount + 1) * sizeof(wchar_t));
     if (UnicodeString == NULL) goto Done;
@@ -1129,7 +1304,7 @@ cmsBool  Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
     if (!io ->Write(io, 67, Filler)) goto Error;
 
     // possibly add pad at the end of tag
-    if(len_aligned - len_tag_requirement > 0)
+    if (len_aligned > len_tag_requirement)
       if (!io ->Write(io, len_aligned - len_tag_requirement, Filler)) goto Error;
 
     rc = TRUE;
@@ -5191,7 +5366,7 @@ cmsBool ReadOneWChar(cmsIOHANDLER* io,  _cmsDICelem* e, cmsUInt32Number i, wchar
       if (!io -> Seek(io, e -> Offsets[i])) return FALSE;
 
       nChars = e ->Sizes[i] / sizeof(cmsUInt16Number);
-
+      if (nChars > 0x7ffff) return FALSE;
 
       *wcstr = (wchar_t*) _cmsMallocZero(e ->ContextID, (nChars + 1) * sizeof(wchar_t));
       if (*wcstr == NULL) return FALSE;
@@ -5772,7 +5947,10 @@ static const _cmsTagTypeLinkedList SupportedTagTypes[] = {
 {TYPE_HANDLER(cmsSigDictType,                  Dictionary),         (_cmsTagTypeLinkedList*) &SupportedTagTypes[30] },
 {TYPE_HANDLER(cmsSigcicpType,                  VideoSignal),        (_cmsTagTypeLinkedList*) &SupportedTagTypes[31] },
 {TYPE_HANDLER(cmsSigVcgtType,                  vcgt),               (_cmsTagTypeLinkedList*) &SupportedTagTypes[32] },
-{TYPE_HANDLER(cmsSigMHC2Type,                  MHC2),                NULL }
+{TYPE_HANDLER(cmsSigMHC2Type,                  MHC2),               (_cmsTagTypeLinkedList*) &SupportedTagTypes[33] },
+{TYPE_HANDLER(cmsSigUInt8ArrayType,            UInt8),              (_cmsTagTypeLinkedList*) &SupportedTagTypes[34] },
+{TYPE_HANDLER(cmsSigUInt32ArrayType,           UInt32),             (_cmsTagTypeLinkedList*) &SupportedTagTypes[35] },
+{TYPE_HANDLER(cmsSigUInt64ArrayType,           UInt64),             NULL }
 };
 
 
diff --git a/src/java.desktop/share/native/liblcms/cmsvirt.c b/src/java.desktop/share/native/liblcms/cmsvirt.c
index e8d18d4ca9f95..1ef86dae05447 100644
--- a/src/java.desktop/share/native/liblcms/cmsvirt.c
+++ b/src/java.desktop/share/native/liblcms/cmsvirt.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -412,7 +412,7 @@ int InkLimitingSampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUI
     Out[1] = _cmsQuickSaturateWord(In[1] * Ratio);     // M
     Out[2] = _cmsQuickSaturateWord(In[2] * Ratio);     // Y
 
-    Out[3] = In[3];                                 // K (untouched)
+    Out[3] = In[3];                                    // K (untouched)
 
     return TRUE;
 }
@@ -433,7 +433,7 @@ cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID,
         return NULL;
     }
 
-    if (Limit < 0.0 || Limit > 400) {
+    if (Limit < 1.0 || Limit > 400) {
 
         cmsSignalError(ContextID, cmsERROR_RANGE, "InkLimiting: Limit should be between 1..400");
         if (Limit < 1) Limit = 1;
@@ -705,7 +705,7 @@ cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfile(void)
 *
 * This virtual profile cannot be saved as an ICC file
 */
-cmsHPROFILE cmsCreate_OkLabProfile(cmsContext ctx)
+cmsHPROFILE CMSEXPORT cmsCreate_OkLabProfile(cmsContext ctx)
 {
     cmsStage* XYZPCS = _cmsStageNormalizeFromXyzFloat(ctx);
     cmsStage* PCSXYZ = _cmsStageNormalizeToXyzFloat(ctx);
@@ -774,6 +774,8 @@ cmsHPROFILE cmsCreate_OkLabProfile(cmsContext ctx)
     cmsPipeline* BToA = cmsPipelineAlloc(ctx, 3, 3);
 
     cmsHPROFILE hProfile = cmsCreateProfilePlaceholder(ctx);
+    if (!hProfile)            // can't allocate
+        goto error;
 
     cmsSetProfileVersion(hProfile, 4.4);
 
diff --git a/src/java.desktop/share/native/liblcms/cmswtpnt.c b/src/java.desktop/share/native/liblcms/cmswtpnt.c
index 27d7180353189..ebba2cd6a9788 100644
--- a/src/java.desktop/share/native/liblcms/cmswtpnt.c
+++ b/src/java.desktop/share/native/liblcms/cmswtpnt.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
diff --git a/src/java.desktop/share/native/liblcms/cmsxform.c b/src/java.desktop/share/native/liblcms/cmsxform.c
index 86afd7202fdbf..1eb3eecbf1823 100644
--- a/src/java.desktop/share/native/liblcms/cmsxform.c
+++ b/src/java.desktop/share/native/liblcms/cmsxform.c
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -295,7 +295,7 @@ void FloatXFORM(_cmsTRANSFORM* p,
     cmsUInt8Number* output;
     cmsFloat32Number fIn[cmsMAXCHANNELS], fOut[cmsMAXCHANNELS];
     cmsFloat32Number OutOfGamut;
-    cmsUInt32Number i, j, c, strideIn, strideOut;
+    size_t i, j, c, strideIn, strideOut;
 
     _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
 
@@ -322,9 +322,11 @@ void FloatXFORM(_cmsTRANSFORM* p,
                 // Is current color out of gamut?
                 if (OutOfGamut > 0.0) {
 
+                    _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*)_cmsContextGetClientChunk(p->ContextID, AlarmCodesContext);
+
                     // Certainly, out of gamut
                     for (c = 0; c < cmsMAXCHANNELS; c++)
-                        fOut[c] = -1.0;
+                        fOut[c] = ContextAlarmCodes->AlarmCodes[c] / 65535.0F;
 
                 }
                 else {
@@ -361,7 +363,7 @@ void NullFloatXFORM(_cmsTRANSFORM* p,
     cmsUInt8Number* accum;
     cmsUInt8Number* output;
     cmsFloat32Number fIn[cmsMAXCHANNELS];
-    cmsUInt32Number i, j, strideIn, strideOut;
+    size_t i, j, strideIn, strideOut;
 
     _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
 
@@ -399,7 +401,7 @@ void NullXFORM(_cmsTRANSFORM* p,
     cmsUInt8Number* accum;
     cmsUInt8Number* output;
     cmsUInt16Number wIn[cmsMAXCHANNELS];
-    cmsUInt32Number i, j, strideIn, strideOut;
+    size_t i, j, strideIn, strideOut;
 
     _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
 
@@ -409,17 +411,17 @@ void NullXFORM(_cmsTRANSFORM* p,
 
     for (i = 0; i < LineCount; i++) {
 
-           accum = (cmsUInt8Number*)in + strideIn;
-           output = (cmsUInt8Number*)out + strideOut;
+        accum = (cmsUInt8Number*)in + strideIn;
+        output = (cmsUInt8Number*)out + strideOut;
 
-           for (j = 0; j < PixelsPerLine; j++) {
+        for (j = 0; j < PixelsPerLine; j++) {
 
-                  accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
-                  output = p->ToOutput(p, wIn, output, Stride->BytesPerPlaneOut);
-    }
+            accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
+            output = p->ToOutput(p, wIn, output, Stride->BytesPerPlaneOut);
+        }
 
-           strideIn += Stride->BytesPerLineIn;
-           strideOut += Stride->BytesPerLineOut;
+        strideIn += Stride->BytesPerLineIn;
+        strideOut += Stride->BytesPerLineOut;
     }
 
 }
@@ -437,7 +439,7 @@ void PrecalculatedXFORM(_cmsTRANSFORM* p,
     CMSREGISTER cmsUInt8Number* accum;
     CMSREGISTER cmsUInt8Number* output;
     cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
-    cmsUInt32Number i, j, strideIn, strideOut;
+    size_t i, j, strideIn, strideOut;
 
     _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
 
@@ -500,7 +502,7 @@ void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
     cmsUInt8Number* accum;
     cmsUInt8Number* output;
     cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
-    cmsUInt32Number i, j, strideIn, strideOut;
+    size_t i, j, strideIn, strideOut;
 
     _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
 
@@ -511,18 +513,18 @@ void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
 
     for (i = 0; i < LineCount; i++) {
 
-           accum = (cmsUInt8Number*)in + strideIn;
-           output = (cmsUInt8Number*)out + strideOut;
+        accum = (cmsUInt8Number*)in + strideIn;
+        output = (cmsUInt8Number*)out + strideOut;
 
-           for (j = 0; j < PixelsPerLine; j++) {
+        for (j = 0; j < PixelsPerLine; j++) {
 
-                  accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
-                  TransformOnePixelWithGamutCheck(p, wIn, wOut);
-                  output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut);
-           }
+            accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
+            TransformOnePixelWithGamutCheck(p, wIn, wOut);
+            output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut);
+        }
 
-           strideIn += Stride->BytesPerLineIn;
-           strideOut += Stride->BytesPerLineOut;
+        strideIn += Stride->BytesPerLineIn;
+        strideOut += Stride->BytesPerLineOut;
     }
 }
 
@@ -540,7 +542,7 @@ void CachedXFORM(_cmsTRANSFORM* p,
     cmsUInt8Number* output;
     cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
     _cmsCACHE Cache;
-    cmsUInt32Number i, j, strideIn, strideOut;
+    size_t i, j, strideIn, strideOut;
 
     _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
 
@@ -595,7 +597,7 @@ void CachedXFORMGamutCheck(_cmsTRANSFORM* p,
     cmsUInt8Number* output;
     cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
     _cmsCACHE Cache;
-    cmsUInt32Number i, j, strideIn, strideOut;
+    size_t i, j, strideIn, strideOut;
 
     _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
 
@@ -712,7 +714,7 @@ void _cmsTransform2toTransformAdaptor(struct _cmstransform_struct *CMMcargo,
                                       const cmsStride* Stride)
 {
 
-       cmsUInt32Number i, strideIn, strideOut;
+       size_t i, strideIn, strideOut;
 
        _cmsHandleExtraChannels(CMMcargo, InputBuffer, OutputBuffer, PixelsPerLine, LineCount, Stride);
 
@@ -1099,7 +1101,7 @@ cmsBool  IsProperColorSpace(cmsColorSpaceSignature Check, cmsUInt32Number dwForm
     int Space1 = (int) T_COLORSPACE(dwFormat);
     int Space2 = _cmsLCMScolorSpace(Check);
 
-    if (Space1 == PT_ANY) return TRUE;
+    if (Space1 == PT_ANY) return (T_CHANNELS(dwFormat) == cmsChannelsOf(Check));
     if (Space1 == Space2) return TRUE;
 
     if (Space1 == PT_LabV2 && Space2 == PT_Lab) return TRUE;
@@ -1160,7 +1162,15 @@ cmsHTRANSFORM CMSEXPORT cmsCreateExtendedTransform(cmsContext ContextID,
     cmsColorSpaceSignature EntryColorSpace;
     cmsColorSpaceSignature ExitColorSpace;
     cmsPipeline* Lut;
-    cmsUInt32Number LastIntent = Intents[nProfiles-1];
+    cmsUInt32Number LastIntent;
+
+    // Safeguard
+    if (nProfiles <= 0 || nProfiles > 255) {
+        cmsSignalError(ContextID, cmsERROR_RANGE, "Wrong number of profiles. 1..255 expected, %d found.", nProfiles);
+        return NULL;
+    }
+
+    LastIntent = Intents[nProfiles - 1];
 
     // If it is a fake transform
     if (dwFlags & cmsFLAGS_NULLTRANSFORM)
diff --git a/src/java.desktop/share/native/liblcms/lcms2.h b/src/java.desktop/share/native/liblcms/lcms2.h
index 2d9a8b1248f93..5ba0966130887 100644
--- a/src/java.desktop/share/native/liblcms/lcms2.h
+++ b/src/java.desktop/share/native/liblcms/lcms2.h
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2025 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -52,7 +52,7 @@
 //
 //---------------------------------------------------------------------------------
 //
-// Version 2.16
+// Version 2.17
 //
 
 #ifndef _lcms2_H
@@ -93,6 +93,9 @@
 // Uncomment this to remove the "register" storage class
 // #define CMS_NO_REGISTER_KEYWORD 1
 
+// Uncomment this to remove visibility attribute when building shared objects
+// #define CMS_NO_VISIBILITY 1
+
 // ********** End of configuration toggles ******************************
 
 // Needed for streams
@@ -113,7 +116,7 @@ extern "C" {
 #endif
 
 // Version/release
-#define LCMS_VERSION        2160
+#define LCMS_VERSION        2170
 
 // I will give the chance of redefining basic types for compilers that are not fully C99 compliant
 #ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
@@ -277,7 +280,7 @@ typedef int                  cmsBool;
 #     define CMSAPI
 #  endif
 #else  // not Windows
-#  ifdef HAVE_FUNC_ATTRIBUTE_VISIBILITY
+#  if defined(HAVE_FUNC_ATTRIBUTE_VISIBILITY) && !defined(CMS_NO_VISIBILITY)
 #     define CMSEXPORT
 #     define CMSAPI    __attribute__((visibility("default")))
 #  else
@@ -987,7 +990,6 @@ typedef void* cmsHTRANSFORM;
 // IEEE 754-2008 "half"
 #define TYPE_GRAY_HALF_FLT    (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(2))
 #define TYPE_RGB_HALF_FLT     (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2))
-#define TYPE_RGBA_HALF_FLT    (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2))
 #define TYPE_CMYK_HALF_FLT    (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2))
 
 #define TYPE_RGBA_HALF_FLT    (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2))
diff --git a/src/java.desktop/share/native/liblcms/lcms2_internal.h b/src/java.desktop/share/native/liblcms/lcms2_internal.h
index 75973edad0d2c..d14c0dd823ea0 100644
--- a/src/java.desktop/share/native/liblcms/lcms2_internal.h
+++ b/src/java.desktop/share/native/liblcms/lcms2_internal.h
@@ -27,9 +27,10 @@
 // However, the following notice accompanied the original version of this
 // file:
 //
+
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -467,7 +468,7 @@ cmsBool  _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin
 // Mutex
 cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 
-// Paralellization
+// Parallelization
 cmsBool _cmsRegisterParallelizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 
 // ---------------------------------------------------------------------------------------------------------
@@ -1000,7 +1001,7 @@ cmsBool           _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile);
 
 // Link several profiles to obtain a single LUT modelling the whole color transform. Intents, Black point
 // compensation and Adaptation parameters may vary across profiles. BPC and Adaptation refers to the PCS
-// after the profile. I.e, BPC[0] refers to connexion between profile(0) and profile(1)
+// after the profile. I.e, BPC[0] refers to connetion between profile(0) and profile(1)
 cmsPipeline* _cmsLinkProfiles(cmsContext         ContextID,
                               cmsUInt32Number    nProfiles,
                               cmsUInt32Number    TheIntents[],
diff --git a/src/java.desktop/share/native/liblcms/lcms2_plugin.h b/src/java.desktop/share/native/liblcms/lcms2_plugin.h
index e7e7bd1f0ce1b..bdfc76f6bf5d5 100644
--- a/src/java.desktop/share/native/liblcms/lcms2_plugin.h
+++ b/src/java.desktop/share/native/liblcms/lcms2_plugin.h
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2023 Marti Maria Saguer
+//  Copyright (c) 1998-2024 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),

From 4e67796c3fcbffa706be8fabb56d00f9128edac1 Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Thu, 20 Mar 2025 19:39:25 +0000
Subject: [PATCH 081/846] 8303770: Remove Baltimore root certificate expiring
 in May 2025

Reviewed-by: sgehwolf, rschmelter
Backport-of: 2371696781edc040d8fa8133c78b284a2e3de1ed
---
 make/data/cacerts/baltimorecybertrustca       | 28 -------------------
 .../security/lib/cacerts/VerifyCACerts.java   | 10 +++----
 2 files changed, 4 insertions(+), 34 deletions(-)
 delete mode 100644 make/data/cacerts/baltimorecybertrustca

diff --git a/make/data/cacerts/baltimorecybertrustca b/make/data/cacerts/baltimorecybertrustca
deleted file mode 100644
index b3cf6547c1661..0000000000000
--- a/make/data/cacerts/baltimorecybertrustca
+++ /dev/null
@@ -1,28 +0,0 @@
-Owner: CN=Baltimore CyberTrust Root, OU=CyberTrust, O=Baltimore, C=IE
-Issuer: CN=Baltimore CyberTrust Root, OU=CyberTrust, O=Baltimore, C=IE
-Serial number: 20000b9
-Valid from: Fri May 12 18:46:00 GMT 2000 until: Mon May 12 23:59:00 GMT 2025
-Signature algorithm name: SHA1withRSA
-Subject Public Key Algorithm: 2048-bit RSA key
-Version: 3
------BEGIN CERTIFICATE-----
-MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
-RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
-VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
-DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
-ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
-VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
-mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
-IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
-mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
-XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
-dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
-jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
-BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
-DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
-9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
-jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
-Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
-ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
-R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
------END CERTIFICATE-----
diff --git a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java
index 1c99897f53bc5..0ebb8248b0308 100644
--- a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java
+++ b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2025, 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
@@ -28,7 +28,7 @@
  *      8223499 8225392 8232019 8234245 8233223 8225068 8225069 8243321 8243320
  *      8243559 8225072 8258630 8259312 8256421 8225081 8225082 8225083 8245654
  *      8305975 8304760 8307134 8295894 8314960 8317373 8317374 8318759 8319187
- *      8321408 8316138 8341057
+ *      8321408 8316138 8341057 8303770
  * @summary Check root CA entries in cacerts file
  */
 import java.io.ByteArrayInputStream;
@@ -47,12 +47,12 @@ public class VerifyCACerts {
             + File.separator + "security" + File.separator + "cacerts";
 
     // The numbers of certs now.
-    private static final int COUNT = 112;
+    private static final int COUNT = 111;
 
     // SHA-256 of cacerts, can be generated with
     // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95
     private static final String CHECKSUM
-            = "8F:E0:6F:7F:21:59:33:A6:43:F3:48:FD:A3:4A:8E:28:35:AA:DD:6E:A5:43:56:F1:28:34:48:DF:5C:D2:7C:72";
+            = "B7:60:5A:7A:01:0A:9F:47:E3:46:B9:30:E1:FC:A2:71:69:58:76:CB:8C:85:2B:FF:1A:D5:92:71:AF:F5:60:8F";
 
     // Hex formatter to upper case with ":" delimiter
     private static final HexFormat HEX = HexFormat.ofDelimiter(":").withUpperCase();
@@ -95,8 +95,6 @@ public class VerifyCACerts {
                     "68:7F:A4:51:38:22:78:FF:F0:C8:B1:1F:8D:43:D5:76:67:1C:6E:B2:BC:EA:B4:13:FB:83:D9:65:D0:6D:2F:F2");
             put("addtrustqualifiedca [jdk]",
                     "80:95:21:08:05:DB:4B:BC:35:5E:44:28:D8:FD:6E:C2:CD:E3:AB:5F:B9:7A:99:42:98:8E:B8:F4:DC:D0:60:16");
-            put("baltimorecybertrustca [jdk]",
-                    "16:AF:57:A9:F6:76:B0:AB:12:60:95:AA:5E:BA:DE:F2:2A:B3:11:19:D6:44:AC:95:CD:4B:93:DB:F3:F2:6A:EB");
             put("digicertglobalrootca [jdk]",
                     "43:48:A0:E9:44:4C:78:CB:26:5E:05:8D:5E:89:44:B4:D8:4F:96:62:BD:26:DB:25:7F:89:34:A4:43:C7:01:61");
             put("digicertglobalrootg2 [jdk]",

From b2255b98f5122c3d26b822dac4597a54257ffcaf Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Thu, 20 Mar 2025 19:40:38 +0000
Subject: [PATCH 082/846] 8352302: Test
 sun/security/tools/jarsigner/TimestampCheck.java is failing

Backport-of: 577ede73d8e916bac9050d3bee80d2f18cc833a7
---
 test/jdk/sun/security/tools/jarsigner/TimestampCheck.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java b/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java
index 5596ca3a7c7d9..0c7d634da3aef 100644
--- a/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java
+++ b/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java
@@ -888,7 +888,7 @@ static void prepare() throws Exception {
         }
 
         gencert("tsold", "-ext eku:critical=ts -startdate -40d -validity 500");
-        gencert("tsbefore2019", "-ext eku:critical=ts -startdate 2018/01/01 -validity 3000");
+        gencert("tsbefore2019", "-ext eku:critical=ts -startdate 2018/01/01 -validity 5000");
 
         gencert("tsweak", "-ext eku:critical=ts");
         gencert("tsdisabled", "-ext eku:critical=ts");

From b31ac46bcb149c4dc6ef4a28a431e61789d16751 Mon Sep 17 00:00:00 2001
From: Dmitry Chuyko 
Date: Mon, 24 Mar 2025 15:18:22 +0000
Subject: [PATCH 083/846] 8335662: [AArch64] C1: guarantee(val < (1ULL <<
 nbits)) failed: Field too big for insn

Backport-of: 401d0d6b09ea422eacecda2900793a416097dc9b
---
 .../cpu/aarch64/c1_LIRAssembler_aarch64.cpp   |   6 +-
 .../compiler/c1/TestOSRLotsOfLocals.java      | 102 ++++++++++++++++++
 2 files changed, 105 insertions(+), 3 deletions(-)
 create mode 100644 test/hotspot/jtreg/compiler/c1/TestOSRLotsOfLocals.java

diff --git a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
index ae5ee625b8c60..450bd28fbcebf 100644
--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
@@ -276,14 +276,14 @@ void LIR_Assembler::osr_entry() {
       // verify the interpreter's monitor has a non-null object
       {
         Label L;
-        __ ldr(rscratch1, Address(OSR_buf, slot_offset + 1*BytesPerWord));
+        __ ldr(rscratch1, __ form_address(rscratch1, OSR_buf, slot_offset + 1*BytesPerWord, 0));
         __ cbnz(rscratch1, L);
         __ stop("locked object is NULL");
         __ bind(L);
       }
 #endif
-      __ ldr(r19, Address(OSR_buf, slot_offset));
-      __ ldr(r20, Address(OSR_buf, slot_offset + BytesPerWord));
+      __ ldr(r19, __ form_address(rscratch1, OSR_buf, slot_offset, 0));
+      __ ldr(r20, __ form_address(rscratch1, OSR_buf, slot_offset + BytesPerWord, 0));
       __ str(r19, frame_map()->address_for_monitor_lock(i));
       __ str(r20, frame_map()->address_for_monitor_object(i));
     }
diff --git a/test/hotspot/jtreg/compiler/c1/TestOSRLotsOfLocals.java b/test/hotspot/jtreg/compiler/c1/TestOSRLotsOfLocals.java
new file mode 100644
index 0000000000000..c6e111fabad55
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/c1/TestOSRLotsOfLocals.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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
+ * @summary Test that OSR correctly handles method with large number of locals
+ * @bug 8335662
+ * @library /test/lib /
+ * @modules java.base/jdk.internal.misc
+ *
+ * @build jdk.test.whitebox.WhiteBox
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   compiler.c1.TestOSRLotsOfLocals
+ */
+package compiler.c1;
+
+import java.lang.reflect.Method;
+
+import jdk.test.whitebox.WhiteBox;
+
+import static compiler.whitebox.CompilerWhiteBoxTest.COMP_LEVEL_SIMPLE;
+
+public class TestOSRLotsOfLocals {
+
+    private static WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static void main(String... args) throws Exception {
+        Method method = TestOSRLotsOfLocals.class.getDeclaredMethod("lotsOfLocals");
+
+        wb.enqueueMethodForCompilation(method, COMP_LEVEL_SIMPLE, 0);
+        while (wb.isMethodQueuedForCompilation(method)) {
+            Thread.onSpinWait();
+        }
+    }
+
+    private static synchronized void lotsOfLocals() {
+        boolean b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33, b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49, b50, b51, b52, b53, b54, b55, b56, b57, b58, b59, b60, b61, b62, b63, b64, b65, b66, b67, b68, b69, b70, b71, b72, b73, b74, b75, b76, b77, b78, b79, b80, b81, b82, b83, b84, b85, b86, b87, b88, b89, b90, b91, b92, b93, b94, b95, b96, b97, b98, b99,
+                b100, b101, b102, b103, b104, b105, b106, b107, b108, b109, b110, b111, b112, b113, b114, b115, b116, b117, b118, b119, b120, b121, b122, b123, b124, b125, b126, b127, b128, b129, b130, b131, b132, b133, b134, b135, b136, b137, b138, b139, b140, b141, b142, b143, b144, b145, b146, b147, b148, b149, b150, b151, b152, b153, b154, b155, b156, b157, b158, b159, b160, b161, b162, b163, b164, b165, b166, b167, b168, b169, b170, b171, b172, b173, b174, b175, b176, b177, b178, b179, b180, b181, b182, b183, b184, b185, b186, b187, b188, b189, b190, b191, b192, b193, b194, b195, b196, b197, b198, b199,
+                b200, b201, b202, b203, b204, b205, b206, b207, b208, b209, b210, b211, b212, b213, b214, b215, b216, b217, b218, b219, b220, b221, b222, b223, b224, b225, b226, b227, b228, b229, b230, b231, b232, b233, b234, b235, b236, b237, b238, b239, b240, b241, b242, b243, b244, b245, b246, b247, b248, b249, b250, b251, b252, b253, b254, b255, b256, b257, b258, b259, b260, b261, b262, b263, b264, b265, b266, b267, b268, b269, b270, b271, b272, b273, b274, b275, b276, b277, b278, b279, b280, b281, b282, b283, b284, b285, b286, b287, b288, b289, b290, b291, b292, b293, b294, b295, b296, b297, b298, b299,
+                b300, b301, b302, b303, b304, b305, b306, b307, b308, b309, b310, b311, b312, b313, b314, b315, b316, b317, b318, b319, b320, b321, b322, b323, b324, b325, b326, b327, b328, b329, b330, b331, b332, b333, b334, b335, b336, b337, b338, b339, b340, b341, b342, b343, b344, b345, b346, b347, b348, b349, b350, b351, b352, b353, b354, b355, b356, b357, b358, b359, b360, b361, b362, b363, b364, b365, b366, b367, b368, b369, b370, b371, b372, b373, b374, b375, b376, b377, b378, b379, b380, b381, b382, b383, b384, b385, b386, b387, b388, b389, b390, b391, b392, b393, b394, b395, b396, b397, b398, b399,
+                b400, b401, b402, b403, b404, b405, b406, b407, b408, b409, b410, b411, b412, b413, b414, b415, b416, b417, b418, b419, b420, b421, b422, b423, b424, b425, b426, b427, b428, b429, b430, b431, b432, b433, b434, b435, b436, b437, b438, b439, b440, b441, b442, b443, b444, b445, b446, b447, b448, b449, b450, b451, b452, b453, b454, b455, b456, b457, b458, b459, b460, b461, b462, b463, b464, b465, b466, b467, b468, b469, b470, b471, b472, b473, b474, b475, b476, b477, b478, b479, b480, b481, b482, b483, b484, b485, b486, b487, b488, b489, b490, b491, b492, b493, b494, b495, b496, b497, b498, b499,
+                b500, b501, b502, b503, b504, b505, b506, b507, b508, b509, b510, b511, b512, b513, b514, b515, b516, b517, b518, b519, b520, b521, b522, b523, b524, b525, b526, b527, b528, b529, b530, b531, b532, b533, b534, b535, b536, b537, b538, b539, b540, b541, b542, b543, b544, b545, b546, b547, b548, b549, b550, b551, b552, b553, b554, b555, b556, b557, b558, b559, b560, b561, b562, b563, b564, b565, b566, b567, b568, b569, b570, b571, b572, b573, b574, b575, b576, b577, b578, b579, b580, b581, b582, b583, b584, b585, b586, b587, b588, b589, b590, b591, b592, b593, b594, b595, b596, b597, b598, b599,
+                b600, b601, b602, b603, b604, b605, b606, b607, b608, b609, b610, b611, b612, b613, b614, b615, b616, b617, b618, b619, b620, b621, b622, b623, b624, b625, b626, b627, b628, b629, b630, b631, b632, b633, b634, b635, b636, b637, b638, b639, b640, b641, b642, b643, b644, b645, b646, b647, b648, b649, b650, b651, b652, b653, b654, b655, b656, b657, b658, b659, b660, b661, b662, b663, b664, b665, b666, b667, b668, b669, b670, b671, b672, b673, b674, b675, b676, b677, b678, b679, b680, b681, b682, b683, b684, b685, b686, b687, b688, b689, b690, b691, b692, b693, b694, b695, b696, b697, b698, b699,
+                b700, b701, b702, b703, b704, b705, b706, b707, b708, b709, b710, b711, b712, b713, b714, b715, b716, b717, b718, b719, b720, b721, b722, b723, b724, b725, b726, b727, b728, b729, b730, b731, b732, b733, b734, b735, b736, b737, b738, b739, b740, b741, b742, b743, b744, b745, b746, b747, b748, b749, b750, b751, b752, b753, b754, b755, b756, b757, b758, b759, b760, b761, b762, b763, b764, b765, b766, b767, b768, b769, b770, b771, b772, b773, b774, b775, b776, b777, b778, b779, b780, b781, b782, b783, b784, b785, b786, b787, b788, b789, b790, b791, b792, b793, b794, b795, b796, b797, b798, b799,
+                b800, b801, b802, b803, b804, b805, b806, b807, b808, b809, b810, b811, b812, b813, b814, b815, b816, b817, b818, b819, b820, b821, b822, b823, b824, b825, b826, b827, b828, b829, b830, b831, b832, b833, b834, b835, b836, b837, b838, b839, b840, b841, b842, b843, b844, b845, b846, b847, b848, b849, b850, b851, b852, b853, b854, b855, b856, b857, b858, b859, b860, b861, b862, b863, b864, b865, b866, b867, b868, b869, b870, b871, b872, b873, b874, b875, b876, b877, b878, b879, b880, b881, b882, b883, b884, b885, b886, b887, b888, b889, b890, b891, b892, b893, b894, b895, b896, b897, b898, b899,
+                b900, b901, b902, b903, b904, b905, b906, b907, b908, b909, b910, b911, b912, b913, b914, b915, b916, b917, b918, b919, b920, b921, b922, b923, b924, b925, b926, b927, b928, b929, b930, b931, b932, b933, b934, b935, b936, b937, b938, b939, b940, b941, b942, b943, b944, b945, b946, b947, b948, b949, b950, b951, b952, b953, b954, b955, b956, b957, b958, b959, b960, b961, b962, b963, b964, b965, b966, b967, b968, b969, b970, b971, b972, b973, b974, b975, b976, b977, b978, b979, b980, b981, b982, b983, b984, b985, b986, b987, b988, b989, b990, b991, b992, b993, b994, b995, b996, b997, b998, b999,
+                b1000, b1001, b1002, b1003, b1004, b1005, b1006, b1007, b1008, b1009, b1010, b1011, b1012, b1013, b1014, b1015, b1016, b1017, b1018, b1019, b1020, b1021, b1022, b1023, b1024, b1025, b1026, b1027, b1028, b1029, b1030, b1031, b1032, b1033, b1034, b1035, b1036, b1037, b1038, b1039, b1040, b1041, b1042, b1043, b1044, b1045, b1046, b1047, b1048, b1049, b1050, b1051, b1052, b1053, b1054, b1055, b1056, b1057, b1058, b1059, b1060, b1061, b1062, b1063, b1064, b1065, b1066, b1067, b1068, b1069, b1070, b1071, b1072, b1073, b1074, b1075, b1076, b1077, b1078, b1079, b1080, b1081, b1082, b1083, b1084, b1085, b1086, b1087, b1088, b1089, b1090, b1091, b1092, b1093, b1094, b1095, b1096, b1097, b1098, b1099,
+                b1100, b1101, b1102, b1103, b1104, b1105, b1106, b1107, b1108, b1109, b1110, b1111, b1112, b1113, b1114, b1115, b1116, b1117, b1118, b1119, b1120, b1121, b1122, b1123, b1124, b1125, b1126, b1127, b1128, b1129, b1130, b1131, b1132, b1133, b1134, b1135, b1136, b1137, b1138, b1139, b1140, b1141, b1142, b1143, b1144, b1145, b1146, b1147, b1148, b1149, b1150, b1151, b1152, b1153, b1154, b1155, b1156, b1157, b1158, b1159, b1160, b1161, b1162, b1163, b1164, b1165, b1166, b1167, b1168, b1169, b1170, b1171, b1172, b1173, b1174, b1175, b1176, b1177, b1178, b1179, b1180, b1181, b1182, b1183, b1184, b1185, b1186, b1187, b1188, b1189, b1190, b1191, b1192, b1193, b1194, b1195, b1196, b1197, b1198, b1199,
+                b1200, b1201, b1202, b1203, b1204, b1205, b1206, b1207, b1208, b1209, b1210, b1211, b1212, b1213, b1214, b1215, b1216, b1217, b1218, b1219, b1220, b1221, b1222, b1223, b1224, b1225, b1226, b1227, b1228, b1229, b1230, b1231, b1232, b1233, b1234, b1235, b1236, b1237, b1238, b1239, b1240, b1241, b1242, b1243, b1244, b1245, b1246, b1247, b1248, b1249, b1250, b1251, b1252, b1253, b1254, b1255, b1256, b1257, b1258, b1259, b1260, b1261, b1262, b1263, b1264, b1265, b1266, b1267, b1268, b1269, b1270, b1271, b1272, b1273, b1274, b1275, b1276, b1277, b1278, b1279, b1280, b1281, b1282, b1283, b1284, b1285, b1286, b1287, b1288, b1289, b1290, b1291, b1292, b1293, b1294, b1295, b1296, b1297, b1298, b1299,
+                b1300, b1301, b1302, b1303, b1304, b1305, b1306, b1307, b1308, b1309, b1310, b1311, b1312, b1313, b1314, b1315, b1316, b1317, b1318, b1319, b1320, b1321, b1322, b1323, b1324, b1325, b1326, b1327, b1328, b1329, b1330, b1331, b1332, b1333, b1334, b1335, b1336, b1337, b1338, b1339, b1340, b1341, b1342, b1343, b1344, b1345, b1346, b1347, b1348, b1349, b1350, b1351, b1352, b1353, b1354, b1355, b1356, b1357, b1358, b1359, b1360, b1361, b1362, b1363, b1364, b1365, b1366, b1367, b1368, b1369, b1370, b1371, b1372, b1373, b1374, b1375, b1376, b1377, b1378, b1379, b1380, b1381, b1382, b1383, b1384, b1385, b1386, b1387, b1388, b1389, b1390, b1391, b1392, b1393, b1394, b1395, b1396, b1397, b1398, b1399,
+                b1400, b1401, b1402, b1403, b1404, b1405, b1406, b1407, b1408, b1409, b1410, b1411, b1412, b1413, b1414, b1415, b1416, b1417, b1418, b1419, b1420, b1421, b1422, b1423, b1424, b1425, b1426, b1427, b1428, b1429, b1430, b1431, b1432, b1433, b1434, b1435, b1436, b1437, b1438, b1439, b1440, b1441, b1442, b1443, b1444, b1445, b1446, b1447, b1448, b1449, b1450, b1451, b1452, b1453, b1454, b1455, b1456, b1457, b1458, b1459, b1460, b1461, b1462, b1463, b1464, b1465, b1466, b1467, b1468, b1469, b1470, b1471, b1472, b1473, b1474, b1475, b1476, b1477, b1478, b1479, b1480, b1481, b1482, b1483, b1484, b1485, b1486, b1487, b1488, b1489, b1490, b1491, b1492, b1493, b1494, b1495, b1496, b1497, b1498, b1499,
+                b1500, b1501, b1502, b1503, b1504, b1505, b1506, b1507, b1508, b1509, b1510, b1511, b1512, b1513, b1514, b1515, b1516, b1517, b1518, b1519, b1520, b1521, b1522, b1523, b1524, b1525, b1526, b1527, b1528, b1529, b1530, b1531, b1532, b1533, b1534, b1535, b1536, b1537, b1538, b1539, b1540, b1541, b1542, b1543, b1544, b1545, b1546, b1547, b1548, b1549, b1550, b1551, b1552, b1553, b1554, b1555, b1556, b1557, b1558, b1559, b1560, b1561, b1562, b1563, b1564, b1565, b1566, b1567, b1568, b1569, b1570, b1571, b1572, b1573, b1574, b1575, b1576, b1577, b1578, b1579, b1580, b1581, b1582, b1583, b1584, b1585, b1586, b1587, b1588, b1589, b1590, b1591, b1592, b1593, b1594, b1595, b1596, b1597, b1598, b1599,
+                b1600, b1601, b1602, b1603, b1604, b1605, b1606, b1607, b1608, b1609, b1610, b1611, b1612, b1613, b1614, b1615, b1616, b1617, b1618, b1619, b1620, b1621, b1622, b1623, b1624, b1625, b1626, b1627, b1628, b1629, b1630, b1631, b1632, b1633, b1634, b1635, b1636, b1637, b1638, b1639, b1640, b1641, b1642, b1643, b1644, b1645, b1646, b1647, b1648, b1649, b1650, b1651, b1652, b1653, b1654, b1655, b1656, b1657, b1658, b1659, b1660, b1661, b1662, b1663, b1664, b1665, b1666, b1667, b1668, b1669, b1670, b1671, b1672, b1673, b1674, b1675, b1676, b1677, b1678, b1679, b1680, b1681, b1682, b1683, b1684, b1685, b1686, b1687, b1688, b1689, b1690, b1691, b1692, b1693, b1694, b1695, b1696, b1697, b1698, b1699,
+                b1700, b1701, b1702, b1703, b1704, b1705, b1706, b1707, b1708, b1709, b1710, b1711, b1712, b1713, b1714, b1715, b1716, b1717, b1718, b1719, b1720, b1721, b1722, b1723, b1724, b1725, b1726, b1727, b1728, b1729, b1730, b1731, b1732, b1733, b1734, b1735, b1736, b1737, b1738, b1739, b1740, b1741, b1742, b1743, b1744, b1745, b1746, b1747, b1748, b1749, b1750, b1751, b1752, b1753, b1754, b1755, b1756, b1757, b1758, b1759, b1760, b1761, b1762, b1763, b1764, b1765, b1766, b1767, b1768, b1769, b1770, b1771, b1772, b1773, b1774, b1775, b1776, b1777, b1778, b1779, b1780, b1781, b1782, b1783, b1784, b1785, b1786, b1787, b1788, b1789, b1790, b1791, b1792, b1793, b1794, b1795, b1796, b1797, b1798, b1799,
+                b1800, b1801, b1802, b1803, b1804, b1805, b1806, b1807, b1808, b1809, b1810, b1811, b1812, b1813, b1814, b1815, b1816, b1817, b1818, b1819, b1820, b1821, b1822, b1823, b1824, b1825, b1826, b1827, b1828, b1829, b1830, b1831, b1832, b1833, b1834, b1835, b1836, b1837, b1838, b1839, b1840, b1841, b1842, b1843, b1844, b1845, b1846, b1847, b1848, b1849, b1850, b1851, b1852, b1853, b1854, b1855, b1856, b1857, b1858, b1859, b1860, b1861, b1862, b1863, b1864, b1865, b1866, b1867, b1868, b1869, b1870, b1871, b1872, b1873, b1874, b1875, b1876, b1877, b1878, b1879, b1880, b1881, b1882, b1883, b1884, b1885, b1886, b1887, b1888, b1889, b1890, b1891, b1892, b1893, b1894, b1895, b1896, b1897, b1898, b1899,
+                b1900, b1901, b1902, b1903, b1904, b1905, b1906, b1907, b1908, b1909, b1910, b1911, b1912, b1913, b1914, b1915, b1916, b1917, b1918, b1919, b1920, b1921, b1922, b1923, b1924, b1925, b1926, b1927, b1928, b1929, b1930, b1931, b1932, b1933, b1934, b1935, b1936, b1937, b1938, b1939, b1940, b1941, b1942, b1943, b1944, b1945, b1946, b1947, b1948, b1949, b1950, b1951, b1952, b1953, b1954, b1955, b1956, b1957, b1958, b1959, b1960, b1961, b1962, b1963, b1964, b1965, b1966, b1967, b1968, b1969, b1970, b1971, b1972, b1973, b1974, b1975, b1976, b1977, b1978, b1979, b1980, b1981, b1982, b1983, b1984, b1985, b1986, b1987, b1988, b1989, b1990, b1991, b1992, b1993, b1994, b1995, b1996, b1997, b1998, b1999,
+                b2000, b2001, b2002, b2003, b2004, b2005, b2006, b2007, b2008, b2009, b2010, b2011, b2012, b2013, b2014, b2015, b2016, b2017, b2018, b2019, b2020, b2021, b2022, b2023, b2024, b2025, b2026, b2027, b2028, b2029, b2030, b2031, b2032, b2033, b2034, b2035, b2036, b2037, b2038, b2039, b2040, b2041, b2042, b2043, b2044, b2045, b2046, b2047, b2048, b2049, b2050, b2051, b2052, b2053, b2054, b2055, b2056, b2057, b2058, b2059, b2060, b2061, b2062, b2063, b2064, b2065, b2066, b2067, b2068, b2069, b2070, b2071, b2072, b2073, b2074, b2075, b2076, b2077, b2078, b2079, b2080, b2081, b2082, b2083, b2084, b2085, b2086, b2087, b2088, b2089, b2090, b2091, b2092, b2093, b2094, b2095, b2096, b2097, b2098, b2099,
+                b2100, b2101, b2102, b2103, b2104, b2105, b2106, b2107, b2108, b2109, b2110, b2111, b2112, b2113, b2114, b2115, b2116, b2117, b2118, b2119, b2120, b2121, b2122, b2123, b2124, b2125, b2126, b2127, b2128, b2129, b2130, b2131, b2132, b2133, b2134, b2135, b2136, b2137, b2138, b2139, b2140, b2141, b2142, b2143, b2144, b2145, b2146, b2147, b2148, b2149, b2150, b2151, b2152, b2153, b2154, b2155, b2156, b2157, b2158, b2159, b2160, b2161, b2162, b2163, b2164, b2165, b2166, b2167, b2168, b2169, b2170, b2171, b2172, b2173, b2174, b2175, b2176, b2177, b2178, b2179, b2180, b2181, b2182, b2183, b2184, b2185, b2186, b2187, b2188, b2189, b2190, b2191, b2192, b2193, b2194, b2195, b2196, b2197, b2198, b2199,
+                b2200, b2201, b2202, b2203, b2204, b2205, b2206, b2207, b2208, b2209, b2210, b2211, b2212, b2213, b2214, b2215, b2216, b2217, b2218, b2219, b2220, b2221, b2222, b2223, b2224, b2225, b2226, b2227, b2228, b2229, b2230, b2231, b2232, b2233, b2234, b2235, b2236, b2237, b2238, b2239, b2240, b2241, b2242, b2243, b2244, b2245, b2246, b2247, b2248, b2249, b2250, b2251, b2252, b2253, b2254, b2255, b2256, b2257, b2258, b2259, b2260, b2261, b2262, b2263, b2264, b2265, b2266, b2267, b2268, b2269, b2270, b2271, b2272, b2273, b2274, b2275, b2276, b2277, b2278, b2279, b2280, b2281, b2282, b2283, b2284, b2285, b2286, b2287, b2288, b2289, b2290, b2291, b2292, b2293, b2294, b2295, b2296, b2297, b2298, b2299,
+                b2300, b2301, b2302, b2303, b2304, b2305, b2306, b2307, b2308, b2309, b2310, b2311, b2312, b2313, b2314, b2315, b2316, b2317, b2318, b2319, b2320, b2321, b2322, b2323, b2324, b2325, b2326, b2327, b2328, b2329, b2330, b2331, b2332, b2333, b2334, b2335, b2336, b2337, b2338, b2339, b2340, b2341, b2342, b2343, b2344, b2345, b2346, b2347, b2348, b2349, b2350, b2351, b2352, b2353, b2354, b2355, b2356, b2357, b2358, b2359, b2360, b2361, b2362, b2363, b2364, b2365, b2366, b2367, b2368, b2369, b2370, b2371, b2372, b2373, b2374, b2375, b2376, b2377, b2378, b2379, b2380, b2381, b2382, b2383, b2384, b2385, b2386, b2387, b2388, b2389, b2390, b2391, b2392, b2393, b2394, b2395, b2396, b2397, b2398, b2399,
+                b2400, b2401, b2402, b2403, b2404, b2405, b2406, b2407, b2408, b2409, b2410, b2411, b2412, b2413, b2414, b2415, b2416, b2417, b2418, b2419, b2420, b2421, b2422, b2423, b2424, b2425, b2426, b2427, b2428, b2429, b2430, b2431, b2432, b2433, b2434, b2435, b2436, b2437, b2438, b2439, b2440, b2441, b2442, b2443, b2444, b2445, b2446, b2447, b2448, b2449, b2450, b2451, b2452, b2453, b2454, b2455, b2456, b2457, b2458, b2459, b2460, b2461, b2462, b2463, b2464, b2465, b2466, b2467, b2468, b2469, b2470, b2471, b2472, b2473, b2474, b2475, b2476, b2477, b2478, b2479, b2480, b2481, b2482, b2483, b2484, b2485, b2486, b2487, b2488, b2489, b2490, b2491, b2492, b2493, b2494, b2495, b2496, b2497, b2498, b2499,
+                b2500, b2501, b2502, b2503, b2504, b2505, b2506, b2507, b2508, b2509, b2510, b2511, b2512, b2513, b2514, b2515, b2516, b2517, b2518, b2519, b2520, b2521, b2522, b2523, b2524, b2525, b2526, b2527, b2528, b2529, b2530, b2531, b2532, b2533, b2534, b2535, b2536, b2537, b2538, b2539, b2540, b2541, b2542, b2543, b2544, b2545, b2546, b2547, b2548, b2549, b2550, b2551, b2552, b2553, b2554, b2555, b2556, b2557, b2558, b2559, b2560, b2561, b2562, b2563, b2564, b2565, b2566, b2567, b2568, b2569, b2570, b2571, b2572, b2573, b2574, b2575, b2576, b2577, b2578, b2579, b2580, b2581, b2582, b2583, b2584, b2585, b2586, b2587, b2588, b2589, b2590, b2591, b2592, b2593, b2594, b2595, b2596, b2597, b2598, b2599,
+                b2600, b2601, b2602, b2603, b2604, b2605, b2606, b2607, b2608, b2609, b2610, b2611, b2612, b2613, b2614, b2615, b2616, b2617, b2618, b2619, b2620, b2621, b2622, b2623, b2624, b2625, b2626, b2627, b2628, b2629, b2630, b2631, b2632, b2633, b2634, b2635, b2636, b2637, b2638, b2639, b2640, b2641, b2642, b2643, b2644, b2645, b2646, b2647, b2648, b2649, b2650, b2651, b2652, b2653, b2654, b2655, b2656, b2657, b2658, b2659, b2660, b2661, b2662, b2663, b2664, b2665, b2666, b2667, b2668, b2669, b2670, b2671, b2672, b2673, b2674, b2675, b2676, b2677, b2678, b2679, b2680, b2681, b2682, b2683, b2684, b2685, b2686, b2687, b2688, b2689, b2690, b2691, b2692, b2693, b2694, b2695, b2696, b2697, b2698, b2699,
+                b2700, b2701, b2702, b2703, b2704, b2705, b2706, b2707, b2708, b2709, b2710, b2711, b2712, b2713, b2714, b2715, b2716, b2717, b2718, b2719, b2720, b2721, b2722, b2723, b2724, b2725, b2726, b2727, b2728, b2729, b2730, b2731, b2732, b2733, b2734, b2735, b2736, b2737, b2738, b2739, b2740, b2741, b2742, b2743, b2744, b2745, b2746, b2747, b2748, b2749, b2750, b2751, b2752, b2753, b2754, b2755, b2756, b2757, b2758, b2759, b2760, b2761, b2762, b2763, b2764, b2765, b2766, b2767, b2768, b2769, b2770, b2771, b2772, b2773, b2774, b2775, b2776, b2777, b2778, b2779, b2780, b2781, b2782, b2783, b2784, b2785, b2786, b2787, b2788, b2789, b2790, b2791, b2792, b2793, b2794, b2795, b2796, b2797, b2798, b2799,
+                b2800, b2801, b2802, b2803, b2804, b2805, b2806, b2807, b2808, b2809, b2810, b2811, b2812, b2813, b2814, b2815, b2816, b2817, b2818, b2819, b2820, b2821, b2822, b2823, b2824, b2825, b2826, b2827, b2828, b2829, b2830, b2831, b2832, b2833, b2834, b2835, b2836, b2837, b2838, b2839, b2840, b2841, b2842, b2843, b2844, b2845, b2846, b2847, b2848, b2849, b2850, b2851, b2852, b2853, b2854, b2855, b2856, b2857, b2858, b2859, b2860, b2861, b2862, b2863, b2864, b2865, b2866, b2867, b2868, b2869, b2870, b2871, b2872, b2873, b2874, b2875, b2876, b2877, b2878, b2879, b2880, b2881, b2882, b2883, b2884, b2885, b2886, b2887, b2888, b2889, b2890, b2891, b2892, b2893, b2894, b2895, b2896, b2897, b2898, b2899,
+                b2900, b2901, b2902, b2903, b2904, b2905, b2906, b2907, b2908, b2909, b2910, b2911, b2912, b2913, b2914, b2915, b2916, b2917, b2918, b2919, b2920, b2921, b2922, b2923, b2924, b2925, b2926, b2927, b2928, b2929, b2930, b2931, b2932, b2933, b2934, b2935, b2936, b2937, b2938, b2939, b2940, b2941, b2942, b2943, b2944, b2945, b2946, b2947, b2948, b2949, b2950, b2951, b2952, b2953, b2954, b2955, b2956, b2957, b2958, b2959, b2960, b2961, b2962, b2963, b2964, b2965, b2966, b2967, b2968, b2969, b2970, b2971, b2972, b2973, b2974, b2975, b2976, b2977, b2978, b2979, b2980, b2981, b2982, b2983, b2984, b2985, b2986, b2987, b2988, b2989, b2990, b2991, b2992, b2993, b2994, b2995, b2996, b2997, b2998, b2999,
+                b3000, b3001, b3002, b3003, b3004, b3005, b3006, b3007, b3008, b3009, b3010, b3011, b3012, b3013, b3014, b3015, b3016, b3017, b3018, b3019, b3020, b3021, b3022, b3023, b3024, b3025, b3026, b3027, b3028, b3029, b3030, b3031, b3032, b3033, b3034, b3035, b3036, b3037, b3038, b3039, b3040, b3041, b3042, b3043, b3044, b3045, b3046, b3047, b3048, b3049, b3050, b3051, b3052, b3053, b3054, b3055, b3056, b3057, b3058, b3059, b3060, b3061, b3062, b3063, b3064, b3065, b3066, b3067, b3068, b3069, b3070, b3071, b3072, b3073, b3074, b3075, b3076, b3077, b3078, b3079, b3080, b3081, b3082, b3083, b3084, b3085, b3086, b3087, b3088, b3089, b3090, b3091, b3092, b3093, b3094, b3095, b3096, b3097, b3098, b3099,
+                b3100, b3101, b3102, b3103, b3104, b3105, b3106, b3107, b3108, b3109, b3110, b3111, b3112, b3113, b3114, b3115, b3116, b3117, b3118, b3119, b3120, b3121, b3122, b3123, b3124, b3125, b3126, b3127, b3128, b3129, b3130, b3131, b3132, b3133, b3134, b3135, b3136, b3137, b3138, b3139, b3140, b3141, b3142, b3143, b3144, b3145, b3146, b3147, b3148, b3149, b3150, b3151, b3152, b3153, b3154, b3155, b3156, b3157, b3158, b3159, b3160, b3161, b3162, b3163, b3164, b3165, b3166, b3167, b3168, b3169, b3170, b3171, b3172, b3173, b3174, b3175, b3176, b3177, b3178, b3179, b3180, b3181, b3182, b3183, b3184, b3185, b3186, b3187, b3188, b3189, b3190, b3191, b3192, b3193, b3194, b3195, b3196, b3197, b3198, b3199,
+                b3200, b3201, b3202, b3203, b3204, b3205, b3206, b3207, b3208, b3209, b3210, b3211, b3212, b3213, b3214, b3215, b3216, b3217, b3218, b3219, b3220, b3221, b3222, b3223, b3224, b3225, b3226, b3227, b3228, b3229, b3230, b3231, b3232, b3233, b3234, b3235, b3236, b3237, b3238, b3239, b3240, b3241, b3242, b3243, b3244, b3245, b3246, b3247, b3248, b3249, b3250, b3251, b3252, b3253, b3254, b3255, b3256, b3257, b3258, b3259, b3260, b3261, b3262, b3263, b3264, b3265, b3266, b3267, b3268, b3269, b3270, b3271, b3272, b3273, b3274, b3275, b3276, b3277, b3278, b3279, b3280, b3281, b3282, b3283, b3284, b3285, b3286, b3287, b3288, b3289, b3290, b3291, b3292, b3293, b3294, b3295, b3296, b3297, b3298, b3299,
+                b3300, b3301, b3302, b3303, b3304, b3305, b3306, b3307, b3308, b3309, b3310, b3311, b3312, b3313, b3314, b3315, b3316, b3317, b3318, b3319, b3320, b3321, b3322, b3323, b3324, b3325, b3326, b3327, b3328, b3329, b3330, b3331, b3332, b3333, b3334, b3335, b3336, b3337, b3338, b3339, b3340, b3341, b3342, b3343, b3344, b3345, b3346, b3347, b3348, b3349, b3350, b3351, b3352, b3353, b3354, b3355, b3356, b3357, b3358, b3359, b3360, b3361, b3362, b3363, b3364, b3365, b3366, b3367, b3368, b3369, b3370, b3371, b3372, b3373, b3374, b3375, b3376, b3377, b3378, b3379, b3380, b3381, b3382, b3383, b3384, b3385, b3386, b3387, b3388, b3389, b3390, b3391, b3392, b3393, b3394, b3395, b3396, b3397, b3398, b3399,
+                b3400, b3401, b3402, b3403, b3404, b3405, b3406, b3407, b3408, b3409, b3410, b3411, b3412, b3413, b3414, b3415, b3416, b3417, b3418, b3419, b3420, b3421, b3422, b3423, b3424, b3425, b3426, b3427, b3428, b3429, b3430, b3431, b3432, b3433, b3434, b3435, b3436, b3437, b3438, b3439, b3440, b3441, b3442, b3443, b3444, b3445, b3446, b3447, b3448, b3449, b3450, b3451, b3452, b3453, b3454, b3455, b3456, b3457, b3458, b3459, b3460, b3461, b3462, b3463, b3464, b3465, b3466, b3467, b3468, b3469, b3470, b3471, b3472, b3473, b3474, b3475, b3476, b3477, b3478, b3479, b3480, b3481, b3482, b3483, b3484, b3485, b3486, b3487, b3488, b3489, b3490, b3491, b3492, b3493, b3494, b3495, b3496, b3497, b3498, b3499,
+                b3500, b3501, b3502, b3503, b3504, b3505, b3506, b3507, b3508, b3509, b3510, b3511, b3512, b3513, b3514, b3515, b3516, b3517, b3518, b3519, b3520, b3521, b3522, b3523, b3524, b3525, b3526, b3527, b3528, b3529, b3530, b3531, b3532, b3533, b3534, b3535, b3536, b3537, b3538, b3539, b3540, b3541, b3542, b3543, b3544, b3545, b3546, b3547, b3548, b3549, b3550, b3551, b3552, b3553, b3554, b3555, b3556, b3557, b3558, b3559, b3560, b3561, b3562, b3563, b3564, b3565, b3566, b3567, b3568, b3569, b3570, b3571, b3572, b3573, b3574, b3575, b3576, b3577, b3578, b3579, b3580, b3581, b3582, b3583, b3584, b3585, b3586, b3587, b3588, b3589, b3590, b3591, b3592, b3593, b3594, b3595, b3596, b3597, b3598, b3599,
+                b3600, b3601, b3602, b3603, b3604, b3605, b3606, b3607, b3608, b3609, b3610, b3611, b3612, b3613, b3614, b3615, b3616, b3617, b3618, b3619, b3620, b3621, b3622, b3623, b3624, b3625, b3626, b3627, b3628, b3629, b3630, b3631, b3632, b3633, b3634, b3635, b3636, b3637, b3638, b3639, b3640, b3641, b3642, b3643, b3644, b3645, b3646, b3647, b3648, b3649, b3650, b3651, b3652, b3653, b3654, b3655, b3656, b3657, b3658, b3659, b3660, b3661, b3662, b3663, b3664, b3665, b3666, b3667, b3668, b3669, b3670, b3671, b3672, b3673, b3674, b3675, b3676, b3677, b3678, b3679, b3680, b3681, b3682, b3683, b3684, b3685, b3686, b3687, b3688, b3689, b3690, b3691, b3692, b3693, b3694, b3695, b3696, b3697, b3698, b3699,
+                b3700, b3701, b3702, b3703, b3704, b3705, b3706, b3707, b3708, b3709, b3710, b3711, b3712, b3713, b3714, b3715, b3716, b3717, b3718, b3719, b3720, b3721, b3722, b3723, b3724, b3725, b3726, b3727, b3728, b3729, b3730, b3731, b3732, b3733, b3734, b3735, b3736, b3737, b3738, b3739, b3740, b3741, b3742, b3743, b3744, b3745, b3746, b3747, b3748, b3749, b3750, b3751, b3752, b3753, b3754, b3755, b3756, b3757, b3758, b3759, b3760, b3761, b3762, b3763, b3764, b3765, b3766, b3767, b3768, b3769, b3770, b3771, b3772, b3773, b3774, b3775, b3776, b3777, b3778, b3779, b3780, b3781, b3782, b3783, b3784, b3785, b3786, b3787, b3788, b3789, b3790, b3791, b3792, b3793, b3794, b3795, b3796, b3797, b3798, b3799,
+                b3800, b3801, b3802, b3803, b3804, b3805, b3806, b3807, b3808, b3809, b3810, b3811, b3812, b3813, b3814, b3815, b3816, b3817, b3818, b3819, b3820, b3821, b3822, b3823, b3824, b3825, b3826, b3827, b3828, b3829, b3830, b3831, b3832, b3833, b3834, b3835, b3836, b3837, b3838, b3839, b3840, b3841, b3842, b3843, b3844, b3845, b3846, b3847, b3848, b3849, b3850, b3851, b3852, b3853, b3854, b3855, b3856, b3857, b3858, b3859, b3860, b3861, b3862, b3863, b3864, b3865, b3866, b3867, b3868, b3869, b3870, b3871, b3872, b3873, b3874, b3875, b3876, b3877, b3878, b3879, b3880, b3881, b3882, b3883, b3884, b3885, b3886, b3887, b3888, b3889, b3890, b3891, b3892, b3893, b3894, b3895, b3896, b3897, b3898, b3899,
+                b3900, b3901, b3902, b3903, b3904, b3905, b3906, b3907, b3908, b3909, b3910, b3911, b3912, b3913, b3914, b3915, b3916, b3917, b3918, b3919, b3920, b3921, b3922, b3923, b3924, b3925, b3926, b3927, b3928, b3929, b3930, b3931, b3932, b3933, b3934, b3935, b3936, b3937, b3938, b3939, b3940, b3941, b3942, b3943, b3944, b3945, b3946, b3947, b3948, b3949, b3950, b3951, b3952, b3953, b3954, b3955, b3956, b3957, b3958, b3959, b3960, b3961, b3962, b3963, b3964, b3965, b3966, b3967, b3968, b3969, b3970, b3971, b3972, b3973, b3974, b3975, b3976, b3977, b3978, b3979, b3980, b3981, b3982, b3983, b3984, b3985, b3986, b3987, b3988, b3989, b3990, b3991, b3992, b3993, b3994, b3995, b3996, b3997, b3998, b3999,
+                b4000, b4001, b4002, b4003, b4004, b4005, b4006, b4007, b4008, b4009, b4010, b4011, b4012, b4013, b4014, b4015, b4016, b4017, b4018, b4019, b4020, b4021, b4022, b4023, b4024, b4025, b4026, b4027, b4028, b4029, b4030, b4031, b4032, b4033, b4034, b4035, b4036, b4037, b4038, b4039, b4040, b4041, b4042, b4043, b4044, b4045, b4046, b4047, b4048, b4049, b4050, b4051, b4052, b4053, b4054, b4055, b4056, b4057, b4058, b4059, b4060, b4061, b4062, b4063, b4064, b4065, b4066, b4067, b4068, b4069, b4070, b4071, b4072, b4073, b4074, b4075, b4076, b4077, b4078, b4079, b4080, b4081, b4082, b4083, b4084, b4085, b4086, b4087, b4088, b4089, b4090, b4091, b4092, b4093, b4094, b4095, b4096, b4097, b4098, b4099;
+    }
+
+}

From 4eeec6ca8573d5e586195f46b41c97ccd658d4b7 Mon Sep 17 00:00:00 2001
From: Martin Balao 
Date: Mon, 24 Mar 2025 18:36:42 +0000
Subject: [PATCH 084/846] 8339810: Clean up the code in sun.tools.jar.Main to
 properly close resources and use ZipFile during extract

Reviewed-by: mbaesken
Backport-of: 8fce5275fc94ebc404a6a37f5ea0407140de63c1
---
 .../share/classes/sun/tools/jar/Main.java     | 275 ++++++++----------
 1 file changed, 127 insertions(+), 148 deletions(-)

diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java
index 7a60317a5f5b3..77cb74dfce76c 100644
--- a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java
+++ b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -252,7 +252,7 @@ private static File createTempFileInSameDirectoryAs(File file)
      * Starts main program with the specified arguments.
      */
     @SuppressWarnings({"removal"})
-    public synchronized boolean run(String args[]) {
+    public synchronized boolean run(String[] args) {
         ok = true;
         if (!parseArgs(args)) {
             return false;
@@ -367,11 +367,9 @@ public synchronized boolean run(String args[]) {
                 if (fname != null) {
                     list(fname, files);
                 } else {
-                    InputStream in = new FileInputStream(FileDescriptor.in);
-                    try {
-                        list(new BufferedInputStream(in), files);
-                    } finally {
-                        in.close();
+                    try (InputStream in = new FileInputStream(FileDescriptor.in);
+                         BufferedInputStream bis = new BufferedInputStream(in)) {
+                        list(bis, files);
                     }
                 }
             } else if (xflag) {
@@ -387,18 +385,12 @@ public synchronized boolean run(String args[]) {
                 // latter can handle it.
 
                 String[] files = filesMapToFiles(filesMap);
-                if (fname != null && files != null) {
+                if (fname != null) {
                     extract(fname, files);
                 } else {
-                    InputStream in = (fname == null)
-                        ? new FileInputStream(FileDescriptor.in)
-                        : new FileInputStream(fname);
-                    try {
-                        if (!extract(new BufferedInputStream(in), files) && fname != null) {
-                            extract(fname, files);
-                        }
-                    } finally {
-                        in.close();
+                    try (InputStream in = new FileInputStream(FileDescriptor.in);
+                         BufferedInputStream bis = new BufferedInputStream(in)) {
+                        extract(bis, files);
                     }
                 }
             } else if (iflag) {
@@ -495,7 +487,7 @@ Stream filesToEntryNames(Map.Entry fileEntries) {
     /**
      * Parses command line arguments.
      */
-    boolean parseArgs(String args[]) {
+    boolean parseArgs(String[] args) {
         /* Preprocess and expand @file arguments */
         try {
             args = CommandLine.parse(args);
@@ -929,118 +921,116 @@ boolean update(InputStream in, OutputStream out,
                    Map moduleInfos,
                    JarIndex jarIndex) throws IOException
     {
-        ZipInputStream zis = new ZipInputStream(in);
-        ZipOutputStream zos = new JarOutputStream(out);
-        ZipEntry e = null;
-        boolean foundManifest = false;
         boolean updateOk = true;
+        try (ZipInputStream zis = new ZipInputStream(in);
+            ZipOutputStream zos = new JarOutputStream(out)) {
 
-        // All actual entries added/updated/existing, in the jar file (excl manifest
-        // and module-info.class ).
-        Set jentries = new HashSet<>();
-
-        if (jarIndex != null) {
-            addIndex(jarIndex, zos);
-        }
+            if (jarIndex != null) {
+                addIndex(jarIndex, zos);
+            }
+            ZipEntry e = null;
+            boolean foundManifest = false;
+            // All actual entries added/updated/existing, in the jar file (excl manifest
+            // and module-info.class ).
+            Set jentries = new HashSet<>();
 
-        // put the old entries first, replace if necessary
-        while ((e = zis.getNextEntry()) != null) {
-            String name = e.getName();
+            // put the old entries first, replace if necessary
+            while ((e = zis.getNextEntry()) != null) {
+                String name = e.getName();
 
-            boolean isManifestEntry = equalsIgnoreCase(name, MANIFEST_NAME);
-            boolean isModuleInfoEntry = isModuleInfoEntry(name);
+                boolean isManifestEntry = equalsIgnoreCase(name, MANIFEST_NAME);
+                boolean isModuleInfoEntry = isModuleInfoEntry(name);
 
-            if ((jarIndex != null && equalsIgnoreCase(name, INDEX_NAME))
-                || (Mflag && isManifestEntry)) {
-                continue;
-            } else if (isManifestEntry && ((newManifest != null) ||
+                if ((jarIndex != null && equalsIgnoreCase(name, INDEX_NAME))
+                        || (Mflag && isManifestEntry)) {
+                    continue;
+                } else if (isManifestEntry && ((newManifest != null) ||
                         (ename != null) || isMultiRelease)) {
-                foundManifest = true;
-                if (newManifest != null) {
-                    // Don't read from the newManifest InputStream, as we
-                    // might need it below, and we can't re-read the same data
-                    // twice.
-                    try (FileInputStream fis = new FileInputStream(mname)) {
-                        if (isAmbiguousMainClass(new Manifest(fis))) {
-                            return false;
+                    foundManifest = true;
+                    if (newManifest != null) {
+                        // Don't read from the newManifest InputStream, as we
+                        // might need it below, and we can't re-read the same data
+                        // twice.
+                        try (FileInputStream fis = new FileInputStream(mname)) {
+                            if (isAmbiguousMainClass(new Manifest(fis))) {
+                                return false;
+                            }
                         }
                     }
-                }
-                // Update the manifest.
-                Manifest old = new Manifest(zis);
-                if (newManifest != null) {
-                    old.read(newManifest);
-                }
-                if (!updateManifest(old, zos)) {
-                    return false;
-                }
-            } else if (moduleInfos != null && isModuleInfoEntry) {
-                moduleInfos.putIfAbsent(name, zis.readAllBytes());
-            } else {
-                boolean isDir = e.isDirectory();
-                if (!entryMap.containsKey(name)) { // copy the old stuff
-                    // do our own compression
-                    ZipEntry e2 = new ZipEntry(name);
-                    e2.setMethod(e.getMethod());
-                    setZipEntryTime(e2, e.getTime());
-                    e2.setComment(e.getComment());
-                    e2.setExtra(e.getExtra());
-                    if (e.getMethod() == ZipEntry.STORED) {
-                        e2.setSize(e.getSize());
-                        e2.setCrc(e.getCrc());
+                    // Update the manifest.
+                    Manifest old = new Manifest(zis);
+                    if (newManifest != null) {
+                        old.read(newManifest);
+                    }
+                    if (!updateManifest(old, zos)) {
+                        return false;
+                    }
+                } else if (moduleInfos != null && isModuleInfoEntry) {
+                    moduleInfos.putIfAbsent(name, zis.readAllBytes());
+                } else {
+                    boolean isDir = e.isDirectory();
+                    if (!entryMap.containsKey(name)) { // copy the old stuff
+                        // do our own compression
+                        ZipEntry e2 = new ZipEntry(name);
+                        e2.setMethod(e.getMethod());
+                        setZipEntryTime(e2, e.getTime());
+                        e2.setComment(e.getComment());
+                        e2.setExtra(e.getExtra());
+                        if (e.getMethod() == ZipEntry.STORED) {
+                            e2.setSize(e.getSize());
+                            e2.setCrc(e.getCrc());
+                        }
+                        zos.putNextEntry(e2);
+                        copy(zis, zos);
+                    } else { // replace with the new files
+                        Entry ent = entryMap.get(name);
+                        addFile(zos, ent);
+                        entryMap.remove(name);
+                        entries.remove(ent);
+                        isDir = ent.isDir;
+                    }
+                    if (!isDir) {
+                        jentries.add(name);
                     }
-                    zos.putNextEntry(e2);
-                    copy(zis, zos);
-                } else { // replace with the new files
-                    Entry ent = entryMap.get(name);
-                    addFile(zos, ent);
-                    entryMap.remove(name);
-                    entries.remove(ent);
-                    isDir = ent.isDir;
-                }
-                if (!isDir) {
-                    jentries.add(name);
                 }
             }
-        }
 
-        // add the remaining new files
-        for (Entry entry : entries) {
-            addFile(zos, entry);
-            if (!entry.isDir) {
-                jentries.add(entry.name);
+            // add the remaining new files
+            for (Entry entry : entries) {
+                addFile(zos, entry);
+                if (!entry.isDir) {
+                    jentries.add(entry.name);
+                }
             }
-        }
-        if (!foundManifest) {
-            if (newManifest != null) {
-                Manifest m = new Manifest(newManifest);
-                updateOk = !isAmbiguousMainClass(m);
-                if (updateOk) {
-                    if (!updateManifest(m, zos)) {
+            if (!foundManifest) {
+                if (newManifest != null) {
+                    Manifest m = new Manifest(newManifest);
+                    updateOk = !isAmbiguousMainClass(m);
+                    if (updateOk) {
+                        if (!updateManifest(m, zos)) {
+                            updateOk = false;
+                        }
+                    }
+                } else if (ename != null) {
+                    if (!updateManifest(new Manifest(), zos)) {
                         updateOk = false;
                     }
                 }
-            } else if (ename != null) {
-                if (!updateManifest(new Manifest(), zos)) {
+            }
+            if (updateOk) {
+                if (moduleInfos != null && !moduleInfos.isEmpty()) {
+                    Set pkgs = new HashSet<>();
+                    jentries.forEach(je -> addPackageIfNamed(pkgs, je));
+                    addExtendedModuleAttributes(moduleInfos, pkgs);
+                    updateOk = checkModuleInfo(moduleInfos.get(MODULE_INFO), jentries);
+                    updateModuleInfo(moduleInfos, zos);
+                    // TODO: check manifest main classes, etc
+                } else if (moduleVersion != null || modulesToHash != null) {
+                    error(getMsg("error.module.options.without.info"));
                     updateOk = false;
                 }
             }
         }
-        if (updateOk) {
-            if (moduleInfos != null && !moduleInfos.isEmpty()) {
-                Set pkgs = new HashSet<>();
-                jentries.forEach( je -> addPackageIfNamed(pkgs, je));
-                addExtendedModuleAttributes(moduleInfos, pkgs);
-                updateOk = checkModuleInfo(moduleInfos.get(MODULE_INFO), jentries);
-                updateModuleInfo(moduleInfos, zos);
-                // TODO: check manifest main classes, etc
-            } else if (moduleVersion != null || modulesToHash != null) {
-                error(getMsg("error.module.options.without.info"));
-                updateOk = false;
-            }
-        }
-        zis.close();
-        zos.close();
         return updateOk;
     }
 
@@ -1362,19 +1352,12 @@ void updateLastModifiedTime(Set zes) throws IOException {
 
     /**
      * Extracts specified entries from JAR file.
-     *
-     * @return whether entries were found and successfully extracted
-     * (indicating this was a zip file without "leading garbage")
      */
-    boolean extract(InputStream in, String files[]) throws IOException {
+    void extract(InputStream in, String[] files) throws IOException {
         ZipInputStream zis = new ZipInputStream(in);
         ZipEntry e;
-        // Set of all directory entries specified in archive.  Disallows
-        // null entries.  Disallows all entries if using pre-6.0 behavior.
-        boolean entriesFound = false;
         Set dirs = newDirSet();
         while ((e = zis.getNextEntry()) != null) {
-            entriesFound = true;
             if (files == null) {
                 dirs.add(extractFile(zis, e));
             } else {
@@ -1393,32 +1376,31 @@ boolean extract(InputStream in, String files[]) throws IOException {
         // instead of during, because creating a file in a directory changes
         // that directory's timestamp.
         updateLastModifiedTime(dirs);
-
-        return entriesFound;
     }
 
     /**
      * Extracts specified entries from JAR file, via ZipFile.
      */
-    void extract(String fname, String files[]) throws IOException {
-        ZipFile zf = new ZipFile(fname);
-        Set dirs = newDirSet();
-        Enumeration zes = zf.entries();
-        while (zes.hasMoreElements()) {
-            ZipEntry e = zes.nextElement();
-            if (files == null) {
-                dirs.add(extractFile(zf.getInputStream(e), e));
-            } else {
-                String name = e.getName();
-                for (String file : files) {
-                    if (name.startsWith(file)) {
-                        dirs.add(extractFile(zf.getInputStream(e), e));
-                        break;
+    void extract(String fname, String[] files) throws IOException {
+        final Set dirs;
+        try (ZipFile zf = new ZipFile(fname)) {
+            dirs = newDirSet();
+            Enumeration zes = zf.entries();
+            while (zes.hasMoreElements()) {
+                ZipEntry e = zes.nextElement();
+                if (files == null) {
+                    dirs.add(extractFile(zf.getInputStream(e), e));
+                } else {
+                    String name = e.getName();
+                    for (String file : files) {
+                        if (name.startsWith(file)) {
+                            dirs.add(extractFile(zf.getInputStream(e), e));
+                            break;
+                        }
                     }
                 }
             }
         }
-        zf.close();
         updateLastModifiedTime(dirs);
     }
 
@@ -1499,7 +1481,7 @@ ZipEntry extractFile(InputStream is, ZipEntry e) throws IOException {
     /**
      * Lists contents of JAR file.
      */
-    void list(InputStream in, String files[]) throws IOException {
+    void list(InputStream in, String[] files) throws IOException {
         ZipInputStream zis = new ZipInputStream(in);
         ZipEntry e;
         while ((e = zis.getNextEntry()) != null) {
@@ -1517,13 +1499,13 @@ void list(InputStream in, String files[]) throws IOException {
     /**
      * Lists contents of JAR file, via ZipFile.
      */
-    void list(String fname, String files[]) throws IOException {
-        ZipFile zf = new ZipFile(fname);
-        Enumeration zes = zf.entries();
-        while (zes.hasMoreElements()) {
-            printEntry(zes.nextElement(), files);
+    void list(String fname, String[] files) throws IOException {
+        try (ZipFile zf = new ZipFile(fname)) {
+            Enumeration zes = zf.entries();
+            while (zes.hasMoreElements()) {
+                printEntry(zes.nextElement(), files);
+            }
         }
-        zf.close();
     }
 
     /**
@@ -1566,10 +1548,8 @@ List getJarPath(String jar) throws IOException {
         // class path attribute will give us jar file name with
         // '/' as separators, so we need to change them to the
         // appropriate one before we open the jar file.
-        JarFile rf = new JarFile(jar.replace('/', File.separatorChar));
-
-        if (rf != null) {
-            Manifest man = rf.getManifest();
+        try (JarFile jarFile = new JarFile(jar.replace('/', File.separatorChar))) {
+            Manifest man = jarFile.getManifest();
             if (man != null) {
                 Attributes attr = man.getMainAttributes();
                 if (attr != null) {
@@ -1590,7 +1570,6 @@ List getJarPath(String jar) throws IOException {
                 }
             }
         }
-        rf.close();
         return files;
     }
 
@@ -1697,7 +1676,7 @@ void warn(String s) {
     /**
      * Main routine to start program.
      */
-    public static void main(String args[]) {
+    public static void main(String[] args) {
         Main jartool = new Main(System.out, System.err, "jar");
         System.exit(jartool.run(args) ? 0 : 1);
     }

From 5b28aa600bb1729cdb9e19d9fffe84f078939e1b Mon Sep 17 00:00:00 2001
From: Satyen Subramaniam 
Date: Tue, 25 Mar 2025 00:04:31 +0000
Subject: [PATCH 085/846] 8334895: OpenJDK fails to configure on linux aarch64
 when CDS is disabled after JDK-8331942

Backport-of: 3b1ca986427d3a69c9e167b9b4c07d1b83bc264d
---
 make/autoconf/jdk-options.m4 | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/make/autoconf/jdk-options.m4 b/make/autoconf/jdk-options.m4
index e8d8565ff6491..c20e8c7e29127 100644
--- a/make/autoconf/jdk-options.m4
+++ b/make/autoconf/jdk-options.m4
@@ -211,9 +211,8 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_OPTIONS],
   # three different page sizes: 4K, 64K, and if run on Mac m1 hardware, 16K.
   COMPATIBLE_CDS_ALIGNMENT_DEFAULT=false
   if test "x$OPENJDK_TARGET_OS" = "xlinux" && test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then
-    COMPATIBLE_CDS_ALIGNMENT_DEFAULT=true
+    COMPATIBLE_CDS_ALIGNMENT_DEFAULT=auto
   fi
-  AC_SUBST(COMPATIBLE_CDS_ALIGNMENT_DEFAULT)
 
   # Compress jars
   COMPRESS_JARS=false
@@ -596,7 +595,7 @@ AC_DEFUN([JDKOPT_ENABLE_DISABLE_COMPATIBLE_CDS_ALIGNMENT],
   UTIL_ARG_ENABLE(NAME: compatible-cds-alignment, DEFAULT: $COMPATIBLE_CDS_ALIGNMENT_DEFAULT,
       RESULT: ENABLE_COMPATIBLE_CDS_ALIGNMENT,
       DESC: [enable use alternative compatible cds core region alignment],
-      DEFAULT_DESC: [disabled],
+      DEFAULT_DESC: [disabled except on linux-aarch64],
       CHECKING_MSG: [if compatible cds region alignment enabled],
       CHECK_AVAILABLE: [
         AC_MSG_CHECKING([if CDS archive is available])

From 48c8aac638c66ef68e23984e75804779b8d4a440 Mon Sep 17 00:00:00 2001
From: Satyen Subramaniam 
Date: Tue, 25 Mar 2025 00:04:56 +0000
Subject: [PATCH 086/846] 8334780: Crash: assert(h_array_list.not_null())
 failed: invariant

Backport-of: e7a0b5b09bcfcd8b09667e51ec588e206f0652ff
---
 src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp b/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp
index c591fcef13057..ed62a59c7d4cf 100644
--- a/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp
+++ b/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp
@@ -132,7 +132,9 @@ jobject JdkJfrEvent::get_all_klasses(TRAPS) {
   transform_klasses_to_local_jni_handles(event_subklasses, THREAD);
 
   Handle h_array_list(THREAD, new_java_util_arraylist(THREAD));
-  assert(h_array_list.not_null(), "invariant");
+  if (h_array_list.is_null()) {
+    return empty_java_util_arraylist;
+  }
 
   static const char add_method_name[] = "add";
   static const char add_method_signature[] = "(Ljava/lang/Object;)Z";

From b338d1083927bdd17ee94142c01a6ff61de5758a Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Thu, 27 Mar 2025 15:53:47 +0000
Subject: [PATCH 087/846] 8298248: Limit sscanf output width in cgroup file
 parsers

Backport-of: 3e041eb9093275bc658c02ae74cd39b4a74684ee
---
 src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp
index 2fd9a9c0beafd..705a3a410c134 100644
--- a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp
+++ b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp
@@ -97,7 +97,7 @@ char * CgroupV2Subsystem::cpu_cpuset_cpus() {
 
 char* CgroupV2Subsystem::cpu_quota_val() {
   GET_CONTAINER_INFO_CPTR(cptr, _unified, "/cpu.max",
-                     "Raw value for CPU quota is: %s", "%s %*d", quota, 1024);
+                     "Raw value for CPU quota is: %s", "%1023s %*d", quota, 1024);
   return os::strdup(quota);
 }
 
@@ -141,7 +141,7 @@ jlong CgroupV2Subsystem::memory_max_usage_in_bytes() {
 
 char* CgroupV2Subsystem::mem_soft_limit_val() {
   GET_CONTAINER_INFO_CPTR(cptr, _unified, "/memory.low",
-                         "Memory Soft Limit is: %s", "%s", mem_soft_limit_str, 1024);
+                         "Memory Soft Limit is: %s", "%1023s", mem_soft_limit_str, 1024);
   return os::strdup(mem_soft_limit_str);
 }
 
@@ -164,14 +164,14 @@ jlong CgroupV2Subsystem::memory_and_swap_limit_in_bytes() {
 
 char* CgroupV2Subsystem::mem_swp_limit_val() {
   GET_CONTAINER_INFO_CPTR(cptr, _unified, "/memory.swap.max",
-                         "Memory and Swap Limit is: %s", "%s", mem_swp_limit_str, 1024);
+                         "Memory and Swap Limit is: %s", "%1023s", mem_swp_limit_str, 1024);
   return os::strdup(mem_swp_limit_str);
 }
 
 // memory.swap.current : total amount of swap currently used by the cgroup and its descendants
 char* CgroupV2Subsystem::mem_swp_current_val() {
   GET_CONTAINER_INFO_CPTR(cptr, _unified, "/memory.swap.current",
-                         "Swap currently used is: %s", "%s", mem_swp_current_str, 1024);
+                         "Swap currently used is: %s", "%1023s", mem_swp_current_str, 1024);
   return os::strdup(mem_swp_current_str);
 }
 
@@ -198,7 +198,7 @@ jlong CgroupV2Subsystem::read_memory_limit_in_bytes() {
 
 char* CgroupV2Subsystem::mem_limit_val() {
   GET_CONTAINER_INFO_CPTR(cptr, _unified, "/memory.max",
-                         "Raw value for memory limit is: %s", "%s", mem_limit_str, 1024);
+                         "Raw value for memory limit is: %s", "%1023s", mem_limit_str, 1024);
   return os::strdup(mem_limit_str);
 }
 
@@ -224,7 +224,7 @@ char* CgroupV2Controller::construct_path(char* mount_path, char *cgroup_path) {
 
 char* CgroupV2Subsystem::pids_max_val() {
   GET_CONTAINER_INFO_CPTR(cptr, _unified, "/pids.max",
-                     "Maximum number of tasks is: %s", "%s %*d", pidsmax, 1024);
+                     "Maximum number of tasks is: %s", "%1023s %*d", pidsmax, 1024);
   return os::strdup(pidsmax);
 }
 

From e4cbb3b420f97c32df9889789dc3d9a1fd1b01df Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Thu, 27 Mar 2025 15:55:18 +0000
Subject: [PATCH 088/846] 8315981: Opensource five more random Swing tests

Backport-of: c43ebd34afeab9ece9dee05f0da184a20e487a12
---
 .../4180943/bug4180943.java                   |  40 +++++++
 .../DefaultListModel/4466250/bug4466250.java  |  47 ++++++++
 .../4140619/bug4140619.java                   |  50 ++++++++
 .../4177723/bug4177723.java                   |  51 ++++++++
 .../swing/ImageIcon/4827074/bug4827074.java   | 109 ++++++++++++++++++
 5 files changed, 297 insertions(+)
 create mode 100644 test/jdk/javax/swing/DefaultListCellRenderer/4180943/bug4180943.java
 create mode 100644 test/jdk/javax/swing/DefaultListModel/4466250/bug4466250.java
 create mode 100644 test/jdk/javax/swing/DefaultListSelectionModel/4140619/bug4140619.java
 create mode 100644 test/jdk/javax/swing/DefaultListSelectionModel/4177723/bug4177723.java
 create mode 100644 test/jdk/javax/swing/ImageIcon/4827074/bug4827074.java

diff --git a/test/jdk/javax/swing/DefaultListCellRenderer/4180943/bug4180943.java b/test/jdk/javax/swing/DefaultListCellRenderer/4180943/bug4180943.java
new file mode 100644
index 0000000000000..24a6257c155b6
--- /dev/null
+++ b/test/jdk/javax/swing/DefaultListCellRenderer/4180943/bug4180943.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2000, 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.
+ */
+
+/* @test
+ * @bug 4180943
+ * @summary Extra borders created by DefaultListCellRenderer
+ * @run main bug4180943
+ */
+
+import javax.swing.DefaultListCellRenderer;
+
+public class bug4180943 {
+    public static void main(String[] argv) {
+        DefaultListCellRenderer lcr1 = new DefaultListCellRenderer();
+        DefaultListCellRenderer lcr2 = new DefaultListCellRenderer();
+        if (lcr1.getBorder() != lcr2.getBorder()) {
+            throw new RuntimeException("Extra borders created by DefaultListCellRenderer");
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/DefaultListModel/4466250/bug4466250.java b/test/jdk/javax/swing/DefaultListModel/4466250/bug4466250.java
new file mode 100644
index 0000000000000..16c3899ea6d35
--- /dev/null
+++ b/test/jdk/javax/swing/DefaultListModel/4466250/bug4466250.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+/* @test
+ * @bug 4466250
+ * @summary DefaultListModel.removeRange does not throw IllegalArgumentException
+ * @run main bug4466250
+*/
+
+import javax.swing.DefaultListModel;
+import javax.swing.JLabel;
+
+public class bug4466250 {
+    public static void main(String[] args) {
+        DefaultListModel model = new DefaultListModel();
+        int size = 16;
+        for (int i = 0; i < size; i++ ) {
+            model.addElement(new JLabel("wow"));
+        }
+
+        try {
+            model.removeRange(3, 1);
+            throw new RuntimeException("IllegalArgumentException has not been thrown");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/DefaultListSelectionModel/4140619/bug4140619.java b/test/jdk/javax/swing/DefaultListSelectionModel/4140619/bug4140619.java
new file mode 100644
index 0000000000000..3ea55270b7a0e
--- /dev/null
+++ b/test/jdk/javax/swing/DefaultListSelectionModel/4140619/bug4140619.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2001, 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.
+ */
+
+/*
+ * @test
+ * @bug 4140619
+ * @summary Breaks SINGLE_SELECTION in DefaultListSelectionModel.setLeadSelectionIndex()
+ * @run main bug4140619
+ */
+
+import javax.swing.DefaultListSelectionModel;
+import javax.swing.ListSelectionModel;
+
+public class bug4140619 {
+    public static void main(String[] args) {
+        DefaultListSelectionModel selection = new DefaultListSelectionModel();
+        selection.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        selection.setSelectionInterval(10, 10);
+        selection.removeSelectionInterval(10, 10);
+        selection.setLeadSelectionIndex(2);
+        selection.setLeadSelectionIndex(30);
+        selection.setLeadSelectionIndex(5);
+
+        if (selection.getMinSelectionIndex()!=5
+                || selection.getMaxSelectionIndex()!=5) {
+            throw new RuntimeException("DefaultListSelectionModel: breaks SINGLE_SELECTION "
+                    + "in setLeadSelectionIndex()");
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/DefaultListSelectionModel/4177723/bug4177723.java b/test/jdk/javax/swing/DefaultListSelectionModel/4177723/bug4177723.java
new file mode 100644
index 0000000000000..c247429dc198d
--- /dev/null
+++ b/test/jdk/javax/swing/DefaultListSelectionModel/4177723/bug4177723.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 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.
+ */
+
+/* @test
+ * @bug 4177723
+ * @summary ListSelectionEvents fired on model changes affecting JList selection
+ * @run main bug4177723
+ */
+
+import javax.swing.DefaultListModel;
+import javax.swing.JList;
+
+public class bug4177723 {
+    static int count = 0;
+
+    public static void main (String[] args) {
+        DefaultListModel model = new DefaultListModel();
+        for (int i = 0; i < 10; i++) {
+            model.addElement("item " + i);
+        }
+
+        JList list = new JList(model);
+        list.addListSelectionListener(e -> count++);
+
+        list.getSelectionModel().setSelectionInterval(3, 8);
+        model.removeRange(4, 7);
+        if (count != 2) {
+            throw new RuntimeException("ListSelectionEvent wasn't generated");
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/ImageIcon/4827074/bug4827074.java b/test/jdk/javax/swing/ImageIcon/4827074/bug4827074.java
new file mode 100644
index 0000000000000..44a80b520804a
--- /dev/null
+++ b/test/jdk/javax/swing/ImageIcon/4827074/bug4827074.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+/* @test
+ * @bug 4827074
+ * @summary ImageIcon serialization does not preload restored images
+ * @run main bug4827074
+ */
+
+import javax.swing.ImageIcon;
+import java.awt.Image;
+import java.awt.Panel;
+import java.awt.image.MemoryImageSource;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+public class bug4827074 extends Panel {
+
+    static ImageIcon testIcon = null;
+    private volatile static boolean passed = false;
+
+    public void init() {
+        testIcon = new TestImageIcon();
+        ImageIcon icon = saveAndLoad(testIcon);
+
+        if (!passed) {
+            throw new RuntimeException("Image was not loaded properly");
+        }
+    }
+
+    synchronized static void setPassed(boolean p) {
+        passed = p;
+    }
+
+    static ImageIcon saveAndLoad(ImageIcon ii) {
+        ImageIcon _ii = null;
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream out = new ObjectOutputStream(baos);
+            out.writeObject(ii);
+            out.flush();
+            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+            ObjectInputStream in = new ObjectInputStream(bais);
+            _ii = (ImageIcon)in.readObject();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+        return _ii;
+    }
+
+    class TestImageIcon extends ImageIcon {
+        public TestImageIcon() {
+            super();
+            setImage(buildImage());
+        }
+
+        private Image buildImage() {
+            int w = 32, h = 32;
+            float halfW = w / 2 , halfH = h / 2;
+            int col = 0xff0000;
+            int[] pixels = new int[w * h];
+            for(int y = 0; y < h; y++) {
+                for(int x = 0; x < w; x++) {
+                    float cx = 1f - (float)x / halfW;
+                    float cy = 1f - (float)y / halfH;
+                    double ray = Math.sqrt(cx * cx + cy * cy);
+                    pixels[y * w + x] = ray < 1 ? col | (255 - (int)(ray * 255)) << 24:0;
+                }
+            }
+            MemoryImageSource mis = new MemoryImageSource(w, h, pixels, 0, w);
+            Image image = createImage(mis);
+            return image;
+        }
+
+        protected void loadImage(Image image) {
+            super.loadImage(image);
+            if (testIcon != null && image != testIcon.getImage()) {
+                setPassed(true);
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        bug4827074 bug = new bug4827074();
+        bug.init();
+    }
+}

From 8d513cfbe885ad679dd5926b3a833837bc767a97 Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Thu, 27 Mar 2025 15:58:21 +0000
Subject: [PATCH 089/846] 8316388: Opensource five Swing component related
 regression tests

Backport-of: c05f8c72239ed3f16ff0d13f4dba795731f9559f
---
 .../javax/swing/JDesktopPane/bug4132993.java  |  51 ++++++++
 .../javax/swing/JDesktopPane/bug4773378.java  | 120 +++++++++++++++++
 .../javax/swing/JEditorPane/bug4325606.java   | 123 ++++++++++++++++++
 .../javax/swing/JEditorPane/bug4330998.java   |  37 ++++++
 .../javax/swing/JEditorPane/bug4694598.java   | 119 +++++++++++++++++
 5 files changed, 450 insertions(+)
 create mode 100644 test/jdk/javax/swing/JDesktopPane/bug4132993.java
 create mode 100644 test/jdk/javax/swing/JDesktopPane/bug4773378.java
 create mode 100644 test/jdk/javax/swing/JEditorPane/bug4325606.java
 create mode 100644 test/jdk/javax/swing/JEditorPane/bug4330998.java
 create mode 100644 test/jdk/javax/swing/JEditorPane/bug4694598.java

diff --git a/test/jdk/javax/swing/JDesktopPane/bug4132993.java b/test/jdk/javax/swing/JDesktopPane/bug4132993.java
new file mode 100644
index 0000000000000..58530ae91e605
--- /dev/null
+++ b/test/jdk/javax/swing/JDesktopPane/bug4132993.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 4132993
+ * @summary JDesktopPane.getAllFramesInLayer(..) return iconified frame
+ * @run main bug4132993
+ */
+
+import javax.swing.JDesktopPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JLayeredPane;
+
+
+public class bug4132993 {
+    public static void main(String[] args) throws Exception {
+        JDesktopPane mDesktop = new JDesktopPane();
+        JInternalFrame jif = new JInternalFrame("My Frame");
+        jif.setIconifiable(true);
+        mDesktop.add(jif);
+        jif.setIcon(true);
+        JInternalFrame[] ji =
+                mDesktop.getAllFramesInLayer(JLayeredPane.DEFAULT_LAYER);
+        for (int i = 0; i < ji.length; i++) {
+            if (jif == ji[i]) {
+                return;
+            }
+        }
+        throw new RuntimeException("JDesktopPane.getAllFramesInLayer() failed...");
+    }
+}
diff --git a/test/jdk/javax/swing/JDesktopPane/bug4773378.java b/test/jdk/javax/swing/JDesktopPane/bug4773378.java
new file mode 100644
index 0000000000000..b961c77d40456
--- /dev/null
+++ b/test/jdk/javax/swing/JDesktopPane/bug4773378.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 4773378
+ * @summary BasicDesktopPaneUI.desktopManager nulled after JDesktopPane.updateUI()
+ * @key headful
+ * @run main bug4773378
+ */
+
+import java.awt.AWTException;
+import java.awt.BorderLayout;
+import java.awt.Robot;
+import java.awt.event.KeyEvent;
+import java.beans.PropertyVetoException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.CountDownLatch;
+import javax.swing.DefaultDesktopManager;
+import javax.swing.JDesktopPane;
+import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
+import javax.swing.SwingUtilities;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
+
+public class bug4773378 {
+    JFrame frame;
+
+    JDesktopPane desktop;
+    DefaultDesktopManager desktopManager;
+    JInternalFrame jif;
+
+    Robot robot;
+    private final CountDownLatch frameActivated = new CountDownLatch(1);
+    public void setupGUI() {
+        frame = new JFrame("bug4773378");
+        frame.setLayout(new BorderLayout());
+        desktop = new JDesktopPane();
+        frame.add(desktop, BorderLayout.CENTER);
+
+        jif = new JInternalFrame("jif", true, false, true, true);
+        jif.setSize(150, 100);
+        jif.setVisible(true);
+        desktop.add(jif);
+
+        jif.addInternalFrameListener(new InternalFrameAdapter() {
+                public void internalFrameActivated(InternalFrameEvent e) {
+                    frameActivated.countDown();
+                }
+            });
+
+        desktopManager = new MyDesktopManager();
+        desktop.setDesktopManager(desktopManager);
+        desktop.updateUI();
+
+        frame.setSize(200, 200);
+        frame.setLocationRelativeTo(null);
+        frame.setVisible(true);
+        jif.requestFocus();
+    }
+
+    public void performTest() throws InterruptedException,
+            InvocationTargetException, AWTException {
+        SwingUtilities.invokeAndWait(() -> {
+            try {
+                jif.setSelected(true);
+            } catch (PropertyVetoException e) {
+                throw new RuntimeException(e);
+            }
+        });
+
+        frameActivated.await();
+
+        robot = new Robot();
+        robot.keyPress(KeyEvent.VK_CONTROL);
+        robot.keyPress(KeyEvent.VK_F6);
+        robot.keyRelease(KeyEvent.VK_F6);
+        robot.keyRelease(KeyEvent.VK_CONTROL);
+
+        robot.waitForIdle();
+    }
+
+    public void cleanupGUI() {
+        if (frame != null) {
+            frame.setVisible(false);
+            frame.dispose();
+        }
+    }
+
+    private static class MyDesktopManager extends DefaultDesktopManager {
+    }
+
+    public static void main(String[] args) throws InterruptedException,
+            InvocationTargetException, AWTException {
+        bug4773378 b = new bug4773378();
+        SwingUtilities.invokeAndWait(b::setupGUI);
+        b.performTest();
+        SwingUtilities.invokeAndWait(b::cleanupGUI);
+    }
+}
diff --git a/test/jdk/javax/swing/JEditorPane/bug4325606.java b/test/jdk/javax/swing/JEditorPane/bug4325606.java
new file mode 100644
index 0000000000000..fa82e3f9e0acb
--- /dev/null
+++ b/test/jdk/javax/swing/JEditorPane/bug4325606.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 4325606
+ * @summary Tests getting row start
+ * @key headful
+ * @run main bug4325606
+ */
+
+import java.awt.AWTException;
+import java.awt.BorderLayout;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.lang.reflect.InvocationTargetException;
+import javax.swing.JEditorPane;
+import javax.swing.JFrame;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Utilities;
+
+public class bug4325606 {
+
+    public volatile boolean passed = true;
+    private JFrame frame;
+    private JEditorPane pane;
+
+    public void setupGUI() {
+        frame = new JFrame("Click Bug");
+        frame.setLayout(new BorderLayout());
+
+        pane = new JEditorPane();
+        pane.addMouseListener(new ClickListener());
+        pane.setContentType("text/html");
+        pane.setText("" +
+                "

Here is line one

" + + "

Here is line two

" + + ""); + + frame.add(new JScrollPane(pane), BorderLayout.CENTER); + + frame.addWindowListener(new TestStateListener()); + frame.setLocation(50, 50); + frame.setSize(400, 300); + frame.setVisible(true); + } + + class TestStateListener extends WindowAdapter { + public void windowOpened(WindowEvent ev) { + Robot robo; + try { + robo = new Robot(); + } catch (AWTException e) { + throw new RuntimeException("Robot could not be created", e); + } + robo.setAutoDelay(100); + robo.delay(1000); + Point p = frame.getLocationOnScreen(); + robo.mouseMove(p.x + 50, p.y + 50); + robo.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robo.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robo.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robo.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robo.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robo.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + } + + class ClickListener extends MouseAdapter { + public void mouseClicked(MouseEvent event) { + try { + Utilities.getRowStart(pane, pane.getCaretPosition()); + } catch (BadLocationException blex) { + throw new RuntimeException("Test failed.", blex); + } + } + } + + public void cleanupGUI() { + if (frame != null) { + frame.setVisible(false); + frame.dispose(); + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + bug4325606 b = new bug4325606(); + try { + Robot robot = new Robot(); + SwingUtilities.invokeAndWait(b::setupGUI); + robot.waitForIdle(); + } finally { + SwingUtilities.invokeAndWait(b::cleanupGUI); + } + } +} diff --git a/test/jdk/javax/swing/JEditorPane/bug4330998.java b/test/jdk/javax/swing/JEditorPane/bug4330998.java new file mode 100644 index 0000000000000..cb8a348b591b3 --- /dev/null +++ b/test/jdk/javax/swing/JEditorPane/bug4330998.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4330998 + * @summary JEditorPane.setText(null) throws NullPointerException. + * @run main bug4330998 + */ + +import javax.swing.JEditorPane; + +public class bug4330998 { + public static void main(String[] args) { + JEditorPane jep = new JEditorPane(); + jep.setText(null); + } +} diff --git a/test/jdk/javax/swing/JEditorPane/bug4694598.java b/test/jdk/javax/swing/JEditorPane/bug4694598.java new file mode 100644 index 0000000000000..c0dcc34b62b90 --- /dev/null +++ b/test/jdk/javax/swing/JEditorPane/bug4694598.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4694598 + * @key headful + * @summary JEditor pane throws NullPointerException on mouse movement. + * @run main bug4694598 + */ + +import java.awt.AWTException; +import java.awt.Robot; +import java.io.IOException; +import java.io.Writer; +import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class bug4694598 { + JFrame frame; + volatile int bottom; + final Path frameContentFile = Path.of("FrameContent.html"); + + public void setupGUI() { + frame = new JFrame("Test 4694598"); + JEditorPane jep = new JEditorPane(); + jep.setEditable(false); + frame.getContentPane().add(jep); + frame.setLocation(50, 50); + frame.setSize(400, 400); + + String frameContentString = "\n" + + " Frame content.\n" + + ""; + try (Writer writer = Files.newBufferedWriter(frameContentFile)) { + writer.write(frameContentString); + } catch (IOException ioe){ + throw new RuntimeException("Could not create html file to embed", ioe); + } + URL frameContentUrl; + try { + frameContentUrl = frameContentFile.toUri().toURL(); + } catch (MalformedURLException mue) { + throw new RuntimeException("Can not convert path to URL", mue); + } + jep.setContentType("text/html"); + String html = " " + + "" + + "" + + "" + + // ! Without bug is not reproducable + "<NOFRAMES>" + + "" + + " "; + jep.setText(html); + + frame.setVisible(true); + } + + public void performTest() throws InterruptedException, + InvocationTargetException, AWTException { + Robot robo = new Robot(); + robo.waitForIdle(); + + final int range = 20; + SwingUtilities.invokeAndWait(() -> { + bottom = frame.getLocationOnScreen().y + + frame.getSize().height - range; + }); + for (int i = 0; i < range; i++) { + robo.mouseMove(300, bottom + i); + robo.waitForIdle(); + robo.delay(50); + } + } + + public void cleanupGUI() { + if (frame != null) { + frame.setVisible(false); + frame.dispose(); + } + try { + Files.deleteIfExists(frameContentFile); + } catch (IOException ignore) {} + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + bug4694598 app = new bug4694598(); + SwingUtilities.invokeAndWait(app::setupGUI); + app.performTest(); + SwingUtilities.invokeAndWait(app::cleanupGUI); + } +} From 0bba48671ef0a0874ed2ed97a158bb0f067dc296 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 27 Mar 2025 16:00:13 +0000 Subject: [PATCH 090/846] 8337299: vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002.java failure goes undetected Backport-of: e2c07d5044587476fc0fff14260e2b73816d2062 --- .../jdb/stop_at/stop_at002/stop_at002.java | 64 ++++++++++++++----- .../jdb/stop_at/stop_at002/stop_at002a.java | 8 ++- 2 files changed, 52 insertions(+), 20 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002.java index 620c50fa2ae22..9dae8c17cfc36 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,17 +82,10 @@ public static int run(String argv[], PrintStream out) { static final String DEBUGGEE_CLASS = TEST_CLASS + "a"; static final String FIRST_BREAK = DEBUGGEE_CLASS + ".main"; static final String LAST_BREAK = DEBUGGEE_CLASS + ".lastBreak"; - static final String DEBUGGEE_LOCATION1 = DEBUGGEE_CLASS + "$Nested$DeeperNested$DeepestNested:43"; - static final String DEBUGGEE_LOCATION2 = DEBUGGEE_CLASS + "$Inner$MoreInner:57"; - static final String FAILURE_PATTERN = "Unable to set"; + static final String DEBUGGEE_LOCATION1 = DEBUGGEE_CLASS + "$Nested$DeeperNested$DeepestNested:64"; + static final String DEBUGGEE_LOCATION2 = DEBUGGEE_CLASS + "$Inner$MoreInner:78"; protected void runCases() { - String[] reply; - Paragrep grep; - int count; - Vector v; - String found; - if (!checkStop(DEBUGGEE_LOCATION1)) { success = false; } @@ -101,25 +94,62 @@ protected void runCases() { success = false; } - jdb.contToExit(3); + if (!checkBreakpointHit(DEBUGGEE_LOCATION1)) { + success = false; + } + + if (!checkBreakpointHit(DEBUGGEE_LOCATION2)) { + success = false; + } + + jdb.contToExit(1); } - private boolean checkStop (String location) { + private boolean checkStop(String location) { Paragrep grep; String[] reply; String found; - boolean result = true; log.display("Trying to set breakpoint at line: " + location); reply = jdb.receiveReplyFor(JdbCommand.stop_at + location); grep = new Paragrep(reply); - found = grep.findFirst(FAILURE_PATTERN); + found = grep.findFirst("Deferring breakpoint " + location); + if (found.length() == 0) { + log.complain("jdb failed to setup deferred breakpoint at line: " + location); + return false; + } + + return true; + } + + private boolean checkBreakpointHit(String location) { + Paragrep grep; + String[] reply; + String found; + + log.display("continuing to breakpoint at line: " + location); + reply = jdb.receiveReplyFor(JdbCommand.cont); + grep = new Paragrep(reply); + + found = grep.findFirst("Unable to set deferred breakpoint"); if (found.length() > 0) { - log.complain("jdb failed to set line breakpoint at line: " + found); - result = false; + log.complain("jdb failed to set deferred breakpoint at line: " + location); + return false; + } + + found = grep.findFirst("Set deferred breakpoint " + location); + if (found.length() == 0) { + log.complain("jdb failed to set deferred breakpoint at line: " + location); + return false; + } + + found = grep.findFirst("Breakpoint hit: \"thread=main\", "); + if (found.length() == 0) { + log.complain("jdb failed to hit breakpoint at line: " + location); + return false; } - return result; + return true; } } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002a.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002a.java index 9195dd2698612..d4a40689372d4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002a.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002a.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,6 +21,8 @@ * questions. */ +// THIS TEST IS LINE NUMBER SENSITIVE + package nsk.jdb.stop_at.stop_at002; import nsk.share.*; @@ -59,7 +61,7 @@ class Nested { class DeeperNested { class DeepestNested { public void foo(boolean input) { - flag = input; /* <-------- This is line number 43 */ + flag = input; /* <-------- This is line number 64 */ } } } @@ -73,7 +75,7 @@ public MoreInner() { content = ""; } public void foo(String input) { - content += input; /* <-------- This is line number 57 */ + content += input; /* <-------- This is line number 78 */ } } } From df6cdbe513ebfd59b776fd45cfbd4ed29702d50c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 27 Mar 2025 16:02:13 +0000 Subject: [PATCH 091/846] 8339794: Open source closed choice tests #1 Backport-of: 5e5942a282e14846404b68c65d43594d6b9226d9 --- .../jdk/java/awt/Choice/ChoiceInsertTest.java | 89 ++++++++++ .../java/awt/Choice/ChoiceMouseDragTest.java | 138 ++++++++++++++++ .../java/awt/Choice/WheelEventsConsumed.java | 156 ++++++++++++++++++ 3 files changed, 383 insertions(+) create mode 100644 test/jdk/java/awt/Choice/ChoiceInsertTest.java create mode 100644 test/jdk/java/awt/Choice/ChoiceMouseDragTest.java create mode 100644 test/jdk/java/awt/Choice/WheelEventsConsumed.java diff --git a/test/jdk/java/awt/Choice/ChoiceInsertTest.java b/test/jdk/java/awt/Choice/ChoiceInsertTest.java new file mode 100644 index 0000000000000..5eafa83a13991 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceInsertTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Choice; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Label; +import java.awt.Robot; + +/* + * @test + * @bug 4082078 + * @summary Test for bug(s): 4082078, Multiple calls to Choice.insert cause core dump + * @key headful + * @run main ChoiceInsertTest + */ + +public class ChoiceInsertTest extends Frame { + Choice c; + Label l; + + private static ChoiceInsertTest choiceInsertTest; + + public ChoiceInsertTest() { + c = new Choice(); + l = new Label("If you see this, the choice insert bug is fixed!"); + c.add("Initial choice"); + add(c); + } + + public void testInsertion() { + // inserting 30 or so items aborts Solaris VM + // in JDK's before 1.1.5 + for (int nchoice = 0; nchoice < 30; nchoice++) { + c.insert("new choice", 0); + } + // if you made it to here the bug is not there anymore... + remove(l); + add(l); + validate(); + } + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + try { + EventQueue.invokeAndWait(() ->{ + choiceInsertTest = new ChoiceInsertTest(); + choiceInsertTest.setTitle("ChoiceInsertTest"); + choiceInsertTest.setLocationRelativeTo(null); + choiceInsertTest.setSize(500, 300); + choiceInsertTest.setLayout(new GridLayout()); + choiceInsertTest.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(500); + EventQueue.invokeAndWait(choiceInsertTest::testInsertion); + robot.delay(1000); + } finally { + EventQueue.invokeAndWait(() -> { + if (choiceInsertTest != null) { + choiceInsertTest.dispose(); + } + }); + } + + System.err.println("ChoiceInsertTest: Didn't abort VM inserting 30 items, so we passed!"); + } +} diff --git a/test/jdk/java/awt/Choice/ChoiceMouseDragTest.java b/test/jdk/java/awt/Choice/ChoiceMouseDragTest.java new file mode 100644 index 0000000000000..0c0c059032dda --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceMouseDragTest.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.awt.BorderLayout; +import java.awt.Choice; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 4328557 + * @summary Tests that MouseDragged and MouseReleased are triggered on choice + * @library /lib/client + * @build ExtendedRobot + * @key headful + * @run main ChoiceMouseDragTest + */ + + +public class ChoiceMouseDragTest extends Frame { + private static final Choice choice = new Choice(); + + private static ExtendedRobot robot; + private volatile boolean isDragged; + private volatile boolean isReleased; + + private static volatile ChoiceMouseDragTest choiceMouseDragTest; + + public ChoiceMouseDragTest() { + super("ChoiceMouseDragTest"); + this.setLayout(new BorderLayout()); + choice.add("item-1"); + choice.add("item-2"); + choice.add("item-3"); + choice.add("item-4"); + add("Center", choice); + choice.addMouseListener(new MouseEventHandler()); + choice.addMouseMotionListener(new MouseMotionEventHandler()); + setSize(400, 200); + setLocationRelativeTo(null); + setVisible(true); + } + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> + choiceMouseDragTest = new ChoiceMouseDragTest()); + + robot = new ExtendedRobot(); + robot.waitForIdle(); + robot.delay(500); + + Point pointToDrag = choice.getLocationOnScreen(); + pointToDrag.x += choice.getWidth() - 10; + pointToDrag.y += choice.getHeight() / 2 ; + + choiceMouseDragTest.test(InputEvent.BUTTON3_DOWN_MASK, pointToDrag); + choiceMouseDragTest.test(InputEvent.BUTTON1_DOWN_MASK, pointToDrag); + } finally { + EventQueue.invokeAndWait(() -> { + if (choiceMouseDragTest != null) { + choiceMouseDragTest.dispose(); + } + }); + } + } + + void test(int buttonToTest, Point pointToDrag) { + isDragged = false; + isReleased = false; + + robot.mouseMove(pointToDrag.x, pointToDrag.y); + robot.waitForIdle(); + + robot.mousePress(buttonToTest); + + robot.glide(pointToDrag.x + 100, pointToDrag.y); + robot.waitForIdle(); + + robot.mouseRelease(buttonToTest); + robot.waitForIdle(); + + if (!isReleased || !isDragged) { + throw new RuntimeException(("Test failed: button %d dragged(received %b) or " + + "released(received %b)") + .formatted(buttonToTest, isDragged, isReleased)); + } + + robot.delay(500); + } + + class MouseEventHandler extends MouseAdapter { + public void mousePressed(MouseEvent me) { + System.out.println(me.paramString()); + } + + public void mouseReleased(MouseEvent me) { + System.out.println(me.paramString()); + isReleased = true; + } + + public void mouseClicked(MouseEvent me) { + System.out.println(me.paramString()); + } + } + + class MouseMotionEventHandler extends MouseAdapter { + public void mouseDragged(MouseEvent me) { + System.out.println(me.paramString()); + isDragged = true; + } + } +} diff --git a/test/jdk/java/awt/Choice/WheelEventsConsumed.java b/test/jdk/java/awt/Choice/WheelEventsConsumed.java new file mode 100644 index 0000000000000..37200214734bb --- /dev/null +++ b/test/jdk/java/awt/Choice/WheelEventsConsumed.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Choice; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; + +/* + * @test + * @bug 6253211 + * @summary PIT: MouseWheel events not triggered for Choice drop down in XAWT + * @requires (os.family == "linux") + * @key headful + * @run main WheelEventsConsumed + */ + +public class WheelEventsConsumed extends Frame implements MouseWheelListener +{ + Robot robot; + Choice choice1 = new Choice(); + Point pt; + final static int delay = 100; + boolean mouseWheeled = false; + final static int OUTSIDE_CHOICE = 1; + final static int INSIDE_LIST_OF_CHOICE = 2; + final static int INSIDE_CHOICE_COMPONENT = 3; + static String toolkit; + + private static volatile WheelEventsConsumed frame = null; + + public static void main(String[] args) throws Exception { + toolkit = Toolkit.getDefaultToolkit().getClass().getName(); + try { + EventQueue.invokeAndWait(() -> { + frame = new WheelEventsConsumed(); + frame.initAndShow(); + }); + frame.test(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public void mouseWheelMoved(MouseWheelEvent me) { + mouseWheeled = true; + System.out.println(me); + } + + public void initAndShow() { + setTitle("WheelEventsConsumed test"); + for (int i = 1; i < 10; i++) { + choice1.add("item-0" + i); + } + + choice1.addMouseWheelListener(this); + add(choice1); + setLayout(new FlowLayout()); + setSize(200, 200); + setLocationRelativeTo(null); + setVisible(true); + validate(); + } + + public void test() { + try { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.waitForIdle(); + robot.delay(delay * 5); + testMouseWheel(1, OUTSIDE_CHOICE); + robot.delay(delay); + testMouseWheel(-1, INSIDE_LIST_OF_CHOICE); + robot.delay(delay); + testMouseWheel(1, INSIDE_CHOICE_COMPONENT); + robot.delay(delay); + } catch (Throwable e) { + throw new RuntimeException("Test failed. Exception thrown: " + e); + } + } + + public void testMouseWheel(int amt, int mousePosition) { + pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth() / 2, pt.y + choice1.getHeight() / 2); + + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(50); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(50); + + switch (mousePosition) { + case OUTSIDE_CHOICE: + robot.mouseMove(pt.x + choice1.getWidth() * 3 / 2, pt.y + choice1.getHeight() / 2); + break; + case INSIDE_LIST_OF_CHOICE: + robot.mouseMove(pt.x + choice1.getWidth() / 2, pt.y + choice1.getHeight() * 4); + break; + case INSIDE_CHOICE_COMPONENT: + robot.mouseMove(pt.x + choice1.getWidth() / 2, pt.y + choice1.getHeight() / 2); + break; + } + + robot.delay(delay); + for (int i = 0; i < 10; i++) { + robot.mouseWheel(amt); + robot.delay(delay); + } + + if (!mouseWheeled) { + if (toolkit.equals("sun.awt.windows.WToolkit") && mousePosition == OUTSIDE_CHOICE) { + System.out.println("Passed. Separate case on Win32. Choice generated MouseWheel events" + mousePosition); + } else { + throw new RuntimeException("Test failed. Choice should generate MOUSE_WHEEL events." + mousePosition); + } + } else { + System.out.println("Passed. Choice generated MouseWheel events" + mousePosition); + } + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.delay(10); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + mouseWheeled = false; + } +} From 65ff52750b8178e21e2ef5adb16d73c2b1bde1f0 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 27 Mar 2025 16:04:06 +0000 Subject: [PATCH 092/846] 8339906: Open source several AWT focus tests - series 4 Backport-of: 46b02f49bcc730d94e37cf17fa996fdd12bdb990 --- test/jdk/java/awt/Focus/AltTabEventsTest.java | 151 +++++++++++++++++ .../awt/Focus/ComponentLostFocusTest.java | 154 ++++++++++++++++++ test/jdk/java/awt/Focus/FocusKeepTest.java | 103 ++++++++++++ test/jdk/java/awt/Focus/KeyStrokeTest.java | 118 ++++++++++++++ 4 files changed, 526 insertions(+) create mode 100644 test/jdk/java/awt/Focus/AltTabEventsTest.java create mode 100644 test/jdk/java/awt/Focus/ComponentLostFocusTest.java create mode 100644 test/jdk/java/awt/Focus/FocusKeepTest.java create mode 100644 test/jdk/java/awt/Focus/KeyStrokeTest.java diff --git a/test/jdk/java/awt/Focus/AltTabEventsTest.java b/test/jdk/java/awt/Focus/AltTabEventsTest.java new file mode 100644 index 0000000000000..15d679ce7295a --- /dev/null +++ b/test/jdk/java/awt/Focus/AltTabEventsTest.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4524015 + * @summary Tests that when user switches between windows using Alt-tab then the appropriate events are generated + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual AltTabEventsTest + */ + +import java.awt.Button; +import java.awt.Choice; +import java.awt.Component; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class AltTabEventsTest { + + private static final String INSTRUCTIONS = """ + This test verifies that when user switches between windows using Alt-tab + key combination then appropriate window events are generated. Also, when + user interacts with Menu bar, Popup menu, Choice then no excessive window + event is generated. + + After test started you will see Frame('Test for 4524015')-F1 with some + components and Frame('Another frame')-F2 with no components. + 1. Make F1 active by clicking on it. + 2. Press Alt-tab. + In the messqge dialog area you should see that + WINDOW_DEACTIVATED, WINDOW_LOST_FOCUS event were generated. + If you switched to F2 then also WINDOW_ACTIVATED, WINDOW_GAINED_FOCUS + were generated. + If no events were generated the test FAILED. + Repeat the 2) with different circumstances. + + 3. Make F1 active by clicking on it. + 4. Click on Menu bar/Button 'popup'/Choice and select some item from + the list shown. If any of the window events appeared in the output then + the test FAILED. + + else the test PASSED."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("AltTabEventsTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 5) + .columns(35) + .testUI(Test::new) + .logArea() + .build() + .awaitAndCheck(); + } + +} + + +class Test extends Frame { + PopupMenu pop; + Frame f; + + void println(String messageIn) { + PassFailJFrame.log(messageIn); + } + + public Test() { + super("Test for 4524015"); + WindowAdapter wa = new WindowAdapter() { + public void windowActivated(WindowEvent e) { + println(e.toString()); + } + public void windowDeactivated(WindowEvent e) { + println(e.toString()); + } + public void windowGainedFocus(WindowEvent e) { + println(e.toString()); + } + public void windowLostFocus(WindowEvent e) { + println(e.toString()); + } + }; + addWindowListener(wa); + addWindowFocusListener(wa); + + f = new Frame("Another frame"); + f.addWindowListener(wa); + f.addWindowFocusListener(wa); + f.setBounds(800, 300, 300, 100); + f.setVisible(true); + + setLayout(new FlowLayout()); + Button b = new Button("popup"); + add(b); + b.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + pop.show((Component)e.getSource(), 10, 10); + } + }); + Choice cho = new Choice(); + add(cho); + cho.addItem("1"); + cho.addItem("2"); + cho.addItem("3"); + + MenuBar bar = new MenuBar(); + Menu menu = new Menu("menu"); + MenuItem item = new MenuItem("first"); + menu.add(item); + item = new MenuItem("second"); + menu.add(item); + bar.add(menu); + setMenuBar(bar); + + pop = new PopupMenu(); + pop.add("1"); + pop.add("@"); + add(pop); + setSize(300, 100); + } +} + diff --git a/test/jdk/java/awt/Focus/ComponentLostFocusTest.java b/test/jdk/java/awt/Focus/ComponentLostFocusTest.java new file mode 100644 index 0000000000000..6af8322b2cd82 --- /dev/null +++ b/test/jdk/java/awt/Focus/ComponentLostFocusTest.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4982943 + * @key headful + * @summary focus lost in text fields or text areas, unable to enter characters from keyboard + * @run main ComponentLostFocusTest + */ + +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.KeyboardFocusManager; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextField; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class ComponentLostFocusTest { + + static Frame frame; + static TextField tf; + static Robot r; + static Dialog dialog = null; + static volatile boolean passed; + static volatile Point loc; + static volatile int width; + static volatile int top; + + private static void createTestUI() { + + dialog = new Dialog(frame, "Dialog", true); + + frame = new Frame("ComponentLostFocusTest Frame"); + frame.setLayout(new FlowLayout()); + frame.addWindowFocusListener(new WindowAdapter() { + public void windowGainedFocus(WindowEvent e) { + System.out.println("Frame gained focus: "+e); + } + }); + tf = new TextField("Text Field"); + frame.add(tf); + frame.setSize(400,300); + frame.setVisible(true); + frame.setLocationRelativeTo(null); + frame.validate(); + } + + public static void doTest() { + System.out.println("dialog.setVisible.... "); + new Thread(new Runnable() { + public void run() { + dialog.setVisible(true); + } + }).start(); + + // The bug is that this construction leads to the redundant xRequestFocus + // By the way, the requestFocusInWindow() works fine before the fix + System.out.println("requesting.... "); + frame.requestFocus(); + + r.delay(1000); + + // Returning the focus to the initial frame will work correctly after the fix + System.out.println("disposing.... "); + dialog.dispose(); + + r.delay(1000); + + // We want to track the GAIN_FOCUS from this time + tf.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + System.out.println("TextField gained focus: " + e); + passed = true; + } + }); + + } + + private static void doRequestFocusToTextField() { + // do activation using press title + r.mouseMove(loc.x + width / 2, loc.y + top / 2); + r.waitForIdle(); + r.mousePress(InputEvent.BUTTON1_DOWN_MASK); + r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + r.waitForIdle(); + + // request focus to the text field + tf.requestFocus(); + } + + public static final void main(String args[]) throws Exception { + r = new Robot(); + r.setAutoDelay(100); + + EventQueue.invokeAndWait(() -> createTestUI()); + r.waitForIdle(); + r.delay(1000); + try { + EventQueue.invokeAndWait(() -> { + doTest(); + loc = frame.getLocationOnScreen(); + width = frame.getWidth(); + top = frame.getInsets().top; + }); + doRequestFocusToTextField(); + + System.out.println("Focused window: " + + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + getFocusedWindow()); + System.out.println("Focus owner: " + + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + getFocusOwner()); + + if (!passed) { + throw new RuntimeException("TextField got no focus! Test failed."); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} + diff --git a/test/jdk/java/awt/Focus/FocusKeepTest.java b/test/jdk/java/awt/Focus/FocusKeepTest.java new file mode 100644 index 0000000000000..0adc463f5d9ae --- /dev/null +++ b/test/jdk/java/awt/Focus/FocusKeepTest.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4128659 + * @summary Tests whether a focus request will work on a focus lost event. + * @key headful + * @run main FocusKeepTest + */ + +import java.awt.BorderLayout; +import java.awt.KeyboardFocusManager; +import java.awt.Robot; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; +import javax.swing.JFrame; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; + +public class FocusKeepTest { + + static JFrame frame; + static JTextField tf; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + try { + SwingUtilities.invokeAndWait(() -> createTestUI()); + robot.waitForIdle(); + robot.delay(1000); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() instanceof JTextField tf1) { + if (!tf1.getText().equals("TextField 1")) { + throw new RuntimeException("Focus on wrong textfield"); + } + } else { + throw new RuntimeException("Focus not on correct component"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createTestUI() { + frame = new JFrame("FocusKeepTest"); + tf = new JTextField("TextField 1"); + tf.addFocusListener(new MyFocusAdapter("TextField 1")); + frame.add(tf, BorderLayout.NORTH); + + tf = new JTextField("TextField 2"); + tf.addFocusListener(new MyFocusAdapter("TextField 2")); + frame.add(tf, BorderLayout.SOUTH); + + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + static class MyFocusAdapter extends FocusAdapter { + private String myName; + + public MyFocusAdapter (String name) { + myName = name; + } + + public void focusLost (FocusEvent e) { + if (myName.equals ("TextField 1")) { + e.getComponent().requestFocus (); + } + } + + public void focusGained (FocusEvent e) { + } + } +} diff --git a/test/jdk/java/awt/Focus/KeyStrokeTest.java b/test/jdk/java/awt/Focus/KeyStrokeTest.java new file mode 100644 index 0000000000000..7c462ce8f22d6 --- /dev/null +++ b/test/jdk/java/awt/Focus/KeyStrokeTest.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4845868 + * @summary REGRESSION: First keystroke after JDialog is closed is lost + * @key headful + * @run main KeyStrokeTest + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +public class KeyStrokeTest { + static boolean keyTyped; + static Frame frame; + + public static void main(String[] args) throws Exception { + try { + KeyStrokeTest test = new KeyStrokeTest(); + test.doTest(); + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + + private static void doTest() throws Exception { + final Object monitor = new Object(); + frame = new Frame(); + TextField textField = new TextField() { + public void transferFocus() { + System.err.println("transferFocus()"); + final Dialog dialog = new Dialog(frame, true); + Button btn = new Button("Close It"); + btn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + System.err.println("action performed"); + dialog.setVisible(false); + } + }); + dialog.add(btn); + dialog.setSize(200, 200); + dialog.setVisible(true); + } + }; + + textField.addKeyListener(new KeyAdapter() { + public void keyTyped(KeyEvent e) { + System.err.println(e); + if (e.getKeyChar() == 'a') { + keyTyped = true; + } + + synchronized (monitor) { + monitor.notifyAll(); + } + } + }); + frame.add(textField); + frame.setSize(400, 400); + frame.setVisible(true); + + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + + robot.delay(1000); + robot.keyPress(KeyEvent.VK_SPACE); + robot.keyRelease(KeyEvent.VK_SPACE); + + robot.delay(1000); + synchronized (monitor) { + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + monitor.wait(3000); + } + + if (!keyTyped) { + throw new RuntimeException("TEST FAILED"); + } + + System.out.println("Test passed"); + } + +} From 90b1bdd127d7956ee1677d3de72625b122083593 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 27 Mar 2025 16:06:16 +0000 Subject: [PATCH 093/846] 8340228: Open source couple more miscellaneous AWT tests Backport-of: f7bc9ba552cf913eef2131b964c48f1b4b55131c --- .../EditAndPrintTest/EditAndPrintTest.java | 152 ++++++++++++++++++ .../TextField/GetTextTest/GetTextTest.java | 104 ++++++++++++ .../SetEchoCharTest3/SetEchoCharTest3.java | 65 ++++++++ 3 files changed, 321 insertions(+) create mode 100644 test/jdk/java/awt/Desktop/EditAndPrintTest/EditAndPrintTest.java create mode 100644 test/jdk/java/awt/TextField/GetTextTest/GetTextTest.java create mode 100644 test/jdk/java/awt/TextField/SetEchoCharTest3/SetEchoCharTest3.java diff --git a/test/jdk/java/awt/Desktop/EditAndPrintTest/EditAndPrintTest.java b/test/jdk/java/awt/Desktop/EditAndPrintTest/EditAndPrintTest.java new file mode 100644 index 0000000000000..3f161f7fcaf90 --- /dev/null +++ b/test/jdk/java/awt/Desktop/EditAndPrintTest/EditAndPrintTest.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @key printer + * @bug 6255196 + * @summary Verifies the function of methods edit(java.io.File file) and + * print(java.io.File file) + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual EditAndPrintTest + */ + +import java.awt.Desktop; +import java.awt.Desktop.Action; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import javax.swing.JPanel; + +public class EditAndPrintTest extends JPanel { + + static final String INSTRUCTIONS = """ + This test tries to edit and print a directory, which will expectedly raise IOException. + Then this test would edit and print a .txt file, which should be successful. + After test execution close the editor if it was launched by test. + If you see any EXCEPTION messages in the output press FAIL. + """; + + public EditAndPrintTest() { + if (!Desktop.isDesktopSupported()) { + PassFailJFrame.log("Class java.awt.Desktop is not supported on " + + "current platform. Further testing will not be performed"); + PassFailJFrame.forcePass(); + } + + Desktop desktop = Desktop.getDesktop(); + + if (!desktop.isSupported(Action.PRINT) && !desktop.isSupported(Action.EDIT)) { + PassFailJFrame.log("Neither EDIT nor PRINT actions are supported. Nothing to test."); + PassFailJFrame.forcePass(); + } + + /* + * Part 1: print or edit a directory, which should throw an IOException. + */ + File userHome = new File(System.getProperty("user.home")); + try { + if (desktop.isSupported(Action.EDIT)) { + PassFailJFrame.log("Trying to edit " + userHome); + desktop.edit(userHome); + PassFailJFrame.log("No exception has been thrown for editing " + + "directory " + userHome.getPath()); + PassFailJFrame.log("Test failed."); + } else { + PassFailJFrame.log("Action EDIT is unsupported."); + } + } catch (IOException e) { + PassFailJFrame.log("Expected IOException is caught."); + } + + try { + if (desktop.isSupported(Action.PRINT)) { + PassFailJFrame.log("Trying to print " + userHome); + desktop.print(userHome); + PassFailJFrame.log("No exception has been thrown for printing " + + "directory " + userHome.getPath()); + PassFailJFrame.log("Test failed."); + } else { + PassFailJFrame.log("Action PRINT is unsupported.\n"); + } + } catch (IOException e) { + PassFailJFrame.log("Expected IOException is caught."); + } + + /* + * Part 2: print or edit a normal .txt file, which may succeed if there + * is associated application to print or edit the given file. It fails + * otherwise. + */ + // Create a temp .txt file for test. + String testFilePath = System.getProperty("java.io.tmpdir") + File.separator + "JDIC-test.txt"; + File testFile = null; + try { + PassFailJFrame.log("Creating temporary file."); + testFile = File.createTempFile("JDIC-test", ".txt", new File(System.getProperty("java.io.tmpdir"))); + testFile.deleteOnExit(); + FileWriter writer = new FileWriter(testFile); + writer.write("This is a temp file used to test print() method of Desktop."); + writer.flush(); + writer.close(); + } catch (java.io.IOException ioe){ + PassFailJFrame.log("EXCEPTION: " + ioe.getMessage()); + PassFailJFrame.forceFail("Failed to create temp file for testing."); + } + + try { + if (desktop.isSupported(Action.EDIT)) { + PassFailJFrame.log("Try to edit " + testFile); + desktop.edit(testFile); + PassFailJFrame.log("Succeed."); + } + } catch (IOException e) { + PassFailJFrame.log("EXCEPTION: " + e.getMessage()); + } + + try { + if (desktop.isSupported(Action.PRINT)) { + PassFailJFrame.log("Trying to print " + testFile); + desktop.print(testFile); + PassFailJFrame.log("Succeed."); + } + } catch (IOException e) { + PassFailJFrame.log("EXCEPTION: " + e.getMessage()); + } + } + + public static void main(String args[]) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Edit and Print test") + .splitUI(EditAndPrintTest::new) + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 1) + .columns(60) + .logArea() + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/java/awt/TextField/GetTextTest/GetTextTest.java b/test/jdk/java/awt/TextField/GetTextTest/GetTextTest.java new file mode 100644 index 0000000000000..ab5aebc11d47a --- /dev/null +++ b/test/jdk/java/awt/TextField/GetTextTest/GetTextTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4100188 + * @key headful + * @summary Make sure that TextFields contain all of, + * and exactly, the text that was entered into them. + * @run main GetTextTest + */ + +import java.awt.AWTException; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.lang.reflect.InvocationTargetException; + +public class GetTextTest extends Frame implements ActionListener { + private final String s = "test string"; + private volatile String ac; + private TextField t; + private Point location; + private Dimension size; + + public void setupGUI() { + setLayout(new FlowLayout(FlowLayout.LEFT)); + + t = new TextField(s, 32); + add(new Label("Hit after text")); + add(t); + t.addActionListener(this); + setLocationRelativeTo(null); + pack(); + setVisible(true); + } + + public void actionPerformed(ActionEvent evt) { + ac = evt.getActionCommand(); + } + + public void performTest() throws AWTException, InterruptedException, + InvocationTargetException { + EventQueue.invokeAndWait(() -> { + location = t.getLocationOnScreen(); + size = t.getSize(); + }); + Robot robot = new Robot(); + robot.setAutoDelay(50); + robot.delay(1000); + robot.waitForIdle(); + robot.mouseMove(location.x + size.width - 3, location.y + (size.height / 2)); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(1000); + robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + robot.delay(1000); + if (!s.equals(ac)) { + throw new RuntimeException("Action command should be the same as text field content"); + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + GetTextTest test = new GetTextTest(); + EventQueue.invokeAndWait(test::setupGUI); + try { + test.performTest(); + } finally { + EventQueue.invokeAndWait(test::dispose); + } + } +} diff --git a/test/jdk/java/awt/TextField/SetEchoCharTest3/SetEchoCharTest3.java b/test/jdk/java/awt/TextField/SetEchoCharTest3/SetEchoCharTest3.java new file mode 100644 index 0000000000000..10779365defc4 --- /dev/null +++ b/test/jdk/java/awt/TextField/SetEchoCharTest3/SetEchoCharTest3.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4222122 + * @summary TextField.setEchoCharacter() seems to be broken + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual SetEchoCharTest3 + */ + +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.TextField; +import java.lang.reflect.InvocationTargetException; + +public class SetEchoCharTest3 extends Frame { + static String INSTRUCTIONS = """ + Type in the text field and "*" characters should echo. + If only one "*" echoes and then the system beeps after + the second character is typed, then press Fail, otherwise press Pass. + """; + public SetEchoCharTest3() { + setLayout(new FlowLayout()); + add(new Label("Enter text:")); + TextField tf = new TextField(15); + tf.setEchoChar('*'); + add(tf); + pack(); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Set Echo Char Test 3") + .testUI(SetEchoCharTest3::new) + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 1) + .columns(40) + .build() + .awaitAndCheck(); + } +} From 5d028732f76971f4768c7c9ab11d5bb3386cb197 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 27 Mar 2025 16:07:55 +0000 Subject: [PATCH 094/846] 8341000: Open source some of the AWT Window tests Backport-of: d3139b4c3682defab2a8bfa0a24890232c3f00a3 --- .../awt/Window/BadConfigure/BadConfigure.java | 71 ++++++++++++ .../InvalidFocusLostEventTest.java | 101 ++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 test/jdk/java/awt/Window/BadConfigure/BadConfigure.java create mode 100644 test/jdk/java/awt/Window/InvalidFocusLostEventTest/InvalidFocusLostEventTest.java diff --git a/test/jdk/java/awt/Window/BadConfigure/BadConfigure.java b/test/jdk/java/awt/Window/BadConfigure/BadConfigure.java new file mode 100644 index 0000000000000..a25ab9b91b9a5 --- /dev/null +++ b/test/jdk/java/awt/Window/BadConfigure/BadConfigure.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6261336 + * @summary Tests that Choice inside ScrollPane opens at the right location + * after resize + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual BadConfigure +*/ + +import java.awt.BorderLayout; +import java.awt.Choice; +import java.awt.Frame; + +public class BadConfigure +{ + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Please resize the BadConfigure window using the left border. + Now click on choice. Its popup will be opened. + Please verify that the popup is opened right under the choice. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(initialize()) + .build() + .awaitAndCheck(); + } + + private static Frame initialize() { + Frame f = new Frame("BadConfigure"); + f.setLayout(new BorderLayout()); + Choice ch = new Choice(); + f.add(ch, BorderLayout.NORTH); + ch.add("One"); + ch.add("One"); + ch.add("One"); + ch.add("One"); + ch.add("One"); + ch.add("One"); + f.setSize(200, 200); + f.validate(); + return f; + } +} diff --git a/test/jdk/java/awt/Window/InvalidFocusLostEventTest/InvalidFocusLostEventTest.java b/test/jdk/java/awt/Window/InvalidFocusLostEventTest/InvalidFocusLostEventTest.java new file mode 100644 index 0000000000000..569d59f146d38 --- /dev/null +++ b/test/jdk/java/awt/Window/InvalidFocusLostEventTest/InvalidFocusLostEventTest.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4397883 + * @summary Tests that non-focusable Window doesn't grab focus + * @key headful + * @run main InvalidFocusLostEventTest + */ + +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.KeyboardFocusManager; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; + +public class InvalidFocusLostEventTest implements ActionListener { + private static Frame f; + private static Button b; + private static KeyboardFocusManager fm; + private static volatile Point bp; + private static volatile int width, height; + private static Robot robot; + + public static void main(String[] args) throws Exception { + try { + InvalidFocusLostEventTest test = new InvalidFocusLostEventTest(); + EventQueue.invokeAndWait(() -> test.createUI()); + runTest(); + // we should check focus after all events are processed, + // since focus transfers are asynchronous + robot.waitForIdle(); + if (fm.getFocusOwner() != b) { + throw new RuntimeException("Failed: focus was lost"); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } + + private void createUI() { + f = new Frame("InvalidFocusLostEventTest"); + b = new Button("Press me"); + fm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); + b.addActionListener(this); + f.add(b); + f.pack(); + f.setLocationRelativeTo(null); + f.setVisible(true); + } + + private static void runTest() throws Exception { + robot = new Robot(); + robot.setAutoDelay(100); + robot.setAutoWaitForIdle(true); + EventQueue.invokeAndWait(() -> { + bp = b.getLocationOnScreen(); + width = b.getWidth(); + height = b.getHeight(); + }); + robot.mouseMove(bp.x + width / 2, bp.y + height / 2 ); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + + public void actionPerformed(ActionEvent ev) { + // pop up a non-focusable window + Window win = new Window(f); + win.setFocusableWindowState(false); + } +} From 9a5b72fb771f9cb1db589d490c0aafd8f5318626 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 27 Mar 2025 16:09:30 +0000 Subject: [PATCH 095/846] 8341373: Open source closed frame tests # 4 Backport-of: d0c5e4bc50cc2cbb65efe827ae8cf3e077f45e07 --- .../awt/Frame/AddRemoveMenuBarTest_5.java | 120 ++++++++++++++++++ .../java/awt/Frame/FrameResizableTest.java | 97 ++++++++++++++ test/jdk/java/awt/Frame/I18NTitle.java | 65 ++++++++++ .../jdk/java/awt/Frame/MenuBarOffsetTest.java | 81 ++++++++++++ test/jdk/java/awt/Frame/MinimumSizeTest.java | 114 +++++++++++++++++ 5 files changed, 477 insertions(+) create mode 100644 test/jdk/java/awt/Frame/AddRemoveMenuBarTest_5.java create mode 100644 test/jdk/java/awt/Frame/FrameResizableTest.java create mode 100644 test/jdk/java/awt/Frame/I18NTitle.java create mode 100644 test/jdk/java/awt/Frame/MenuBarOffsetTest.java create mode 100644 test/jdk/java/awt/Frame/MinimumSizeTest.java diff --git a/test/jdk/java/awt/Frame/AddRemoveMenuBarTest_5.java b/test/jdk/java/awt/Frame/AddRemoveMenuBarTest_5.java new file mode 100644 index 0000000000000..f5f1018c26282 --- /dev/null +++ b/test/jdk/java/awt/Frame/AddRemoveMenuBarTest_5.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.Robot; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +/* + * @test + * @key headful + * @bug 4159883 + * @summary Adding/Removing a menu causes frame to unexpected small size + * @requires (os.family == "linux" | os.family == "windows") + */ + +public class AddRemoveMenuBarTest_5 { + + static Frame frame; + static MenuBar menu; + static Button btnAdd, btnRemove; + static Dimension oldSize; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + try { + EventQueue.invokeAndWait(AddRemoveMenuBarTest_5::initAndShowGui); + robot.waitForIdle(); + robot.delay(500); + + EventQueue.invokeAndWait(() -> { + oldSize = frame.getSize(); + changeMenubar(true); + }); + robot.waitForIdle(); + robot.delay(500); + + EventQueue.invokeAndWait(() -> { + checkSize(); + changeMenubar(false); + }); + robot.waitForIdle(); + robot.delay(500); + + EventQueue.invokeAndWait(AddRemoveMenuBarTest_5::checkSize); + } finally { + EventQueue.invokeAndWait(frame::dispose); + } + } + + public static void initAndShowGui() { + frame = new Frame(); + frame.setLocationRelativeTo(null); + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowOpened(WindowEvent e) { + System.out.println("Frame size:" + frame.getSize().toString()); + System.out.println("Button size:" + btnAdd.getSize().toString()); + } + }); + frame.add("West", btnAdd = new Button("TRY:ADD")); + frame.add("East", btnRemove = new Button("TRY:REMOVE")); + + + btnAdd.addActionListener((e) -> changeMenubar(true)); + btnRemove.addActionListener((e) -> changeMenubar(false)); + frame.setSize(500, 100); + frame.setVisible(true); + } + + private static void changeMenubar(boolean enable) { + if (enable) { + menu = new MenuBar(); + menu.add(new Menu("BAAAAAAAAAAAAAAA")); + menu.add(new Menu("BZZZZZZZZZZZZZZZ")); + menu.add(new Menu("BXXXXXXXXXXXXXXX")); + } else { + menu = null; + } + frame.setMenuBar(menu); + frame.invalidate(); + frame.validate(); + + System.out.println("Frame size:" + frame.getSize().toString()); + System.out.println("Button size:" + btnAdd.getSize().toString()); + } + + private static void checkSize() { + Dimension newSize = frame.getSize(); + if (!oldSize.equals(newSize)) { + throw new RuntimeException("Frame size changed: old %s new %s" + .formatted(oldSize, newSize)); + } + } +} diff --git a/test/jdk/java/awt/Frame/FrameResizableTest.java b/test/jdk/java/awt/Frame/FrameResizableTest.java new file mode 100644 index 0000000000000..4734ce71670aa --- /dev/null +++ b/test/jdk/java/awt/Frame/FrameResizableTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Panel; +import java.awt.event.ActionListener; + +/* + * @test + * @bug 1231233 + * @summary Tests whether the resizable property of a Frame is + * respected after it is set. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual FrameResizableTest + */ + +public class FrameResizableTest { + private static final String INSTRUCTIONS = """ + There is a frame with two buttons and a label. The label + reads 'true' or 'false' to indicate whether the frame can be + resized or not. + + When the first button, 'Set Resizable', is + clicked, you should be able to resize the frame. + When the second button, 'UnSet Resizable', is clicked, you should + not be able to resize the frame. + + A frame is resized in a way which depends upon the window manager (WM) running. + You may resize the frame by dragging the corner resize handles or the borders, + or you may use the title bar's resize menu items and buttons. + + Upon test completion, click Pass or Fail appropriately. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("FrameResizableTest Instructions") + .instructions(INSTRUCTIONS) + .columns(50) + .testUI(FrameResizable::new) + .build() + .awaitAndCheck(); + } + + private static class FrameResizable extends Frame { + Label label; + Button buttonResizable; + Button buttonNotResizable; + + public FrameResizable() { + super("FrameResizable"); + setResizable(false); + Panel panel = new Panel(); + + add("North", panel); + ActionListener actionListener = (e) -> { + if (e.getSource() == buttonResizable) { + setResizable(true); + } else if (e.getSource() == buttonNotResizable) { + setResizable(false); + } + label.setText("Resizable: " + isResizable()); + }; + + panel.add(buttonResizable = new Button("Set Resizable")); + panel.add(buttonNotResizable = new Button("UnSet Resizable")); + panel.add(label = new Label("Resizable: " + isResizable())); + buttonResizable.addActionListener(actionListener); + buttonNotResizable.addActionListener(actionListener); + + setSize(400, 200); + } + } +} diff --git a/test/jdk/java/awt/Frame/I18NTitle.java b/test/jdk/java/awt/Frame/I18NTitle.java new file mode 100644 index 0000000000000..7127fc3dfbf6b --- /dev/null +++ b/test/jdk/java/awt/Frame/I18NTitle.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Window; + +/* + * @test + * @bug 6269884 4929291 + * @summary Tests that title which contains mix of non-English characters is displayed correctly + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual I18NTitle + */ + +public class I18NTitle { + private static final String INSTRUCTIONS = """ + You will see a frame with some title (S. Chinese, Cyrillic and German). + Please check if non-English characters are visible and compare + the visible title with the same string shown in the label + (it should not look worse than the label). + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("I18NTitle Instructions") + .instructions(INSTRUCTIONS) + .columns(50) + .testUI(I18NTitle::createAndShowGUI) + .build() + .awaitAndCheck(); + } + + private static Window createAndShowGUI() { + String s = "\u4e2d\u6587\u6d4b\u8bd5 \u0420\u0443\u0441\u0441\u043a\u0438\u0439 Zur\u00FCck"; + Frame frame = new Frame(s); + frame.setLayout(new BorderLayout()); + Label l = new Label(s); + frame.add(l); + frame.setSize(400, 100); + return frame; + } +} diff --git a/test/jdk/java/awt/Frame/MenuBarOffsetTest.java b/test/jdk/java/awt/Frame/MenuBarOffsetTest.java new file mode 100644 index 0000000000000..65a4a8ef4bd59 --- /dev/null +++ b/test/jdk/java/awt/Frame/MenuBarOffsetTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Menu; +import java.awt.MenuBar; + +/* + * @test + * @bug 4180577 + * @summary offset problems with menus in frames: (2 * 1) should be (2 * menuBarBorderSize) + * @requires (os.family == "linux" | os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MenuBarOffsetTest +*/ + +public class MenuBarOffsetTest { + private static final String INSTRUCTIONS = """ + If a menubar containing a menubar item labeled Test appears. + in a frame, and fits within the frame, press Pass, else press Fail. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("MenuBarOffsetTest Instructions") + .instructions(INSTRUCTIONS) + .columns(45) + .testUI(FrameTest::new) + .build() + .awaitAndCheck(); + } + + private static class FrameTest extends Frame { + public FrameTest() { + super("MenuBarOffsetTest FrameTest"); + MenuBar m = new MenuBar(); + setMenuBar(m); + Menu test = m.add(new Menu("Test")); + test.add("1"); + test.add("2"); + setSize(100, 100); + } + + public void paint(Graphics g) { + setForeground(Color.red); + Insets i = getInsets(); + Dimension d = getSize(); + System.err.println(getBounds()); + System.err.println("" + i); + + g.drawRect(i.left, i.top, + d.width - i.left - i.right - 1, + d.height - i.top - i.bottom - 1); + } + } +} diff --git a/test/jdk/java/awt/Frame/MinimumSizeTest.java b/test/jdk/java/awt/Frame/MinimumSizeTest.java new file mode 100644 index 0000000000000..cfff77be5f93c --- /dev/null +++ b/test/jdk/java/awt/Frame/MinimumSizeTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.imageio.ImageIO; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +/* + * @test + * @key headful + * @bug 1256759 + * @summary Checks that Frames with a very small size don't cause Motif + * to generate VendorShells which consume the entire desktop. + */ + +public class MinimumSizeTest { + + private static final Color BG_COLOR = Color.RED; + private static Frame backgroundFrame; + private static Frame testedFrame; + + private static Robot robot; + private static final Point location = new Point(200, 200); + private static final Point[] testPointLocations = { + new Point(100, 200), + new Point(200, 100), + new Point(450, 210), + new Point(210, 350), + }; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + + try { + EventQueue.invokeAndWait(MinimumSizeTest::initAndShowGui); + robot.waitForIdle(); + robot.delay(500); + test(); + System.out.println("Test passed."); + } finally { + EventQueue.invokeAndWait(() -> { + backgroundFrame.dispose(); + testedFrame.dispose(); + }); + } + } + + private static void test() { + for (Point testLocation : testPointLocations) { + Color pixelColor = robot.getPixelColor(testLocation.x, testLocation.y); + + if (!pixelColor.equals(BG_COLOR)) { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + BufferedImage screenCapture = robot.createScreenCapture(new Rectangle(screenSize)); + try { + ImageIO.write(screenCapture, "png", new File("failure.png")); + } catch (IOException ignored) {} + throw new RuntimeException("Pixel color does not match expected color %s at %s" + .formatted(pixelColor, testLocation)); + } + } + } + + private static void initAndShowGui() { + backgroundFrame = new Frame("MinimumSizeTest background"); + backgroundFrame.setUndecorated(true); + backgroundFrame.setBackground(BG_COLOR); + backgroundFrame.setBounds(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())); + backgroundFrame.setVisible(true); + + testedFrame = new MinimumSizeTestFrame(); + testedFrame.setVisible(true); + } + + private static class MinimumSizeTestFrame extends Frame { + public MinimumSizeTestFrame() { + super("MinimumSizeTest"); + setVisible(true); + setBackground(Color.BLUE); + setSize(0, 0); + setLocation(location); + } + } +} + From a064c2f8600d8d6d00e3500166b23907653f3048 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 27 Mar 2025 16:11:12 +0000 Subject: [PATCH 096/846] 8343529: serviceability/sa/ClhsdbWhere.java fails AssertionFailure: Corrupted constant pool 8307318: Test serviceability/sa/ClhsdbCDSJstackPrintAll.java failed: ArrayIndexOutOfBoundsException Backport-of: e985f85d990e6d38f16608e5eb8c94400638d13b --- .../sa/ClhsdbCDSJstackPrintAll.java | 6 +++++- .../serviceability/sa/ClhsdbLauncher.java | 20 +++++++++++++------ .../jtreg/serviceability/sa/ClhsdbWhere.java | 6 +++++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbCDSJstackPrintAll.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbCDSJstackPrintAll.java index 3fe60de23646e..4d01f9a26c86f 100644 --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbCDSJstackPrintAll.java +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbCDSJstackPrintAll.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,6 +51,10 @@ public static void main(String[] args) throws Exception { CDSTestUtils.createArchiveAndCheck(opts); ClhsdbLauncher test = new ClhsdbLauncher(); + // This test could possibly cause some unexpected SA exceptions because one + // or more threads are active during the stack trace. Ignore them. The threads + // we care about should still be present in the output. + test.ignoreExceptions(); theApp = LingeredApp.startApp( "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=" + sharedArchiveName, diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java index 961311f5d5b09..ffb95fd9f7048 100644 --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,9 +41,15 @@ public class ClhsdbLauncher { private Process toolProcess; + private boolean ignoreExceptions; public ClhsdbLauncher() { toolProcess = null; + ignoreExceptions = false; + } + + public void ignoreExceptions() { + ignoreExceptions = true; } /** @@ -147,11 +153,13 @@ private String runCmd(List commands, // -Xcheck:jni might be set via TEST_VM_OPTS. Make sure there are no warnings. oa.shouldNotMatch("^WARNING: JNI local refs:.*$"); oa.shouldNotMatch("^WARNING in native method:.*$"); - // This will detect most SA failures, including during the attach. - oa.shouldNotMatch("^sun.jvm.hotspot.debugger.DebuggerException:.*$"); - // This will detect unexpected exceptions, like NPEs and asserts, that are caught - // by sun.jvm.hotspot.CommandProcessor. - oa.shouldNotMatch("^Error: .*$"); + if (!ignoreExceptions) { + // This will detect most SA failures, including during the attach. + oa.shouldNotMatch("^sun.jvm.hotspot.debugger.DebuggerException:.*$"); + // This will detect unexpected exceptions, like NPEs and asserts, that are caught + // by sun.jvm.hotspot.CommandProcessor. + oa.shouldNotMatch("^Error: .*$"); + } String[] parts = output.split("hsdb>"); for (String cmd : commands) { diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbWhere.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbWhere.java index 4b665ac002df6..8295a479fa082 100644 --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbWhere.java +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbWhere.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,10 @@ public static void main(String[] args) throws Exception { LingeredApp theApp = null; try { ClhsdbLauncher test = new ClhsdbLauncher(); + // This test could possibly cause some unexpected SA exceptions because one + // or more threads are active during the stack trace. Ignore them. The threads + // we care about should still be present in the output. + test.ignoreExceptions(); theApp = LingeredApp.startApp(); System.out.println("Started LingeredApp with pid " + theApp.getPid()); From 8cf46226a5f85e55fe76067da2266f22ec35aed0 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 27 Mar 2025 16:15:43 +0000 Subject: [PATCH 097/846] 8345134: Test sun/security/tools/jarsigner/ConciseJarsigner.java failed: unable to find valid certification path to requested target Backport-of: a0f7982e44deec2cd59379c62b215c3f526fc2c4 --- .../security/tools/jarsigner/ConciseJarsigner.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java b/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java index 69b45ea22930d..e81a25712a6b2 100644 --- a/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java +++ b/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2025, 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 @@ -43,8 +43,15 @@ public class ConciseJarsigner { static OutputAnalyzer kt(String cmd) throws Exception { // Choose 2048-bit RSA to make sure it runs fine and fast. In // fact, every keyalg/keysize combination is OK for this test. - return SecurityTools.keytool("-storepass changeit -keypass changeit " - + "-keystore ks -keyalg rsa -keysize 2048 " + cmd); + // The start date is set to -1M to prevent the certificate not yet valid during fast enough execution. + // If -startdate is specified in cmd, cmd version will be used. + if (cmd.contains("-startdate")) { + return SecurityTools.keytool("-storepass changeit -keypass changeit " + + "-keystore ks -keyalg rsa -keysize 2048 " + cmd); + } else { + return SecurityTools.keytool("-storepass changeit -keypass changeit " + + "-keystore ks -keyalg rsa -keysize 2048 -startdate -1M " + cmd); + } } static void gencert(String owner, String cmd) throws Exception { From 260f1c03ed9e605dd0e16edb27d2a55879a8f28b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 27 Mar 2025 16:20:14 +0000 Subject: [PATCH 098/846] 8348107: test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java fails intermittently Reviewed-by: rschmelter Backport-of: 5c4a387b7e5643815542dd6938e8e1dbb817ad90 --- .../net/httpclient/HttpsTunnelAuthTest.java | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java b/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java index f83118adea3f6..9548b0e215654 100644 --- a/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java +++ b/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, 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 @@ -108,6 +108,7 @@ public class HttpsTunnelAuthTest implements HttpServerAdapters, AutoCloseable { } void setUp() throws IOException { + HttpServerAdapters.enableServerLogging(); // Creates an HTTP/1.1 Server that will authenticate for // arthur with password dent http1Server = DigestEchoServer.createServer(Version.HTTP_1_1, @@ -143,10 +144,8 @@ void setUp() throws IOException { // Creates a proxy selector that unconditionally select the // above proxy. - var ps = proxySelector = ProxySelector.of(proxy.getProxyAddress()); + proxySelector = ProxySelector.of(proxy.getProxyAddress()); - // Creates a client that uses the above proxy selector - client = newHttpClient(ps); } @Override @@ -177,23 +176,28 @@ public static void main(String[] args) throws Exception { try (HttpsTunnelAuthTest test = new HttpsTunnelAuthTest()) { test.setUp(); - // tests proxy and server authentication through: - // - plain proxy connection to plain HTTP/1.1 server, - test.test(Version.HTTP_1_1, "http", "/foo/http1"); + { + HttpClient client = test.newHttpClient(test.proxySelector); + // tests proxy and server authentication through: + // - plain proxy connection to plain HTTP/1.1 server, + test.test(client, Version.HTTP_1_1, "http", "/foo/http1"); + } // can't really test plain proxy connection to plain HTTP/2 server: // this is not supported: we downgrade to HTTP/1.1 in that case // so that is actually somewhat equivalent to the first case: // therefore we will use a new client to force re-authentication // of the proxy connection. - test.client = test.newHttpClient(test.proxySelector); - test.test(Version.HTTP_2, "http", "/foo/http2"); + { + HttpClient client = test.newHttpClient(test.proxySelector); + test.test(client, Version.HTTP_2, "http", "/foo/http2"); - // - proxy tunnel SSL connection to HTTP/1.1 server - test.test(Version.HTTP_1_1, "https", "/foo/https1"); + // - proxy tunnel SSL connection to HTTP/1.1 server + test.test(client, Version.HTTP_1_1, "https", "/foo/https1"); - // - proxy tunnel SSl connection to HTTP/2 server - test.test(Version.HTTP_2, "https", "/foo/https2"); + // - proxy tunnel SSl connection to HTTP/2 server + test.test(client, Version.HTTP_2, "https", "/foo/https2"); + } } } @@ -227,14 +231,14 @@ Version expectedVersion(String scheme, Version version) { return "http".equals(scheme) ? Version.HTTP_1_1 : version; } - public void test(Version version, String scheme, String path) throws Exception { + public void test(HttpClient client, Version version, String scheme, String path) throws Exception { System.out.printf("%nTesting %s, %s, %s%n", version, scheme, path); DigestEchoServer server = server(scheme, version); try { URI uri = jdk.test.lib.net.URIBuilder.newBuilder() .scheme(scheme) - .host("localhost") + .loopback() .port(server.getServerAddress().getPort()) .path(path).build(); From 96e8c5652053e4ee424d73834dc55d97838c6eea Mon Sep 17 00:00:00 2001 From: Daniel Hu Date: Thu, 27 Mar 2025 16:31:52 +0000 Subject: [PATCH 099/846] 8277983: Remove unused fields from sun.net.www.protocol.jar.JarURLConnection Backport-of: f34f8d4d6a9b3e24a93a322b985c1413c27311cc --- .../www/protocol/jar/JarURLConnection.java | 42 +++++-------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java index 4ccf781991440..234827fb76f2e 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java @@ -25,21 +25,17 @@ package sun.net.www.protocol.jar; -import java.io.InputStream; -import java.io.IOException; -import java.io.FileNotFoundException; import java.io.BufferedInputStream; -import java.net.URL; -import java.net.URLConnection; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; import java.net.MalformedURLException; -import java.net.UnknownServiceException; -import java.util.Enumeration; -import java.util.Map; +import java.net.URL; +import java.security.Permission; import java.util.List; +import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import java.util.jar.Manifest; -import java.security.Permission; /** * @author Benjamin Renaud @@ -47,26 +43,10 @@ */ public class JarURLConnection extends java.net.JarURLConnection { - private static final boolean debug = false; - /* the Jar file factory. It handles both retrieval and caching. */ private static final JarFileFactory factory = JarFileFactory.getInstance(); - /* the url for the Jar file */ - private URL jarFileURL; - - /* the permission to get this JAR file. This is the actual, ultimate, - * permission, returned by the jar file factory. - */ - private Permission permission; - - /* the url connection for the JAR file */ - private URLConnection jarFileURLConnection; - - /* the entry name, if any */ - private String entryName; - /* the JarEntry */ private JarEntry jarEntry; @@ -80,12 +60,10 @@ public JarURLConnection(URL url, Handler handler) throws MalformedURLException, IOException { super(url); - jarFileURL = getJarFileURL(); - jarFileURLConnection = jarFileURL.openConnection(); + jarFileURLConnection = getJarFileURL().openConnection(); // whether, or not, the embedded URL should use the cache will depend // on this instance's cache value jarFileURLConnection.setUseCaches(useCaches); - entryName = getEntryName(); } public JarFile getJarFile() throws IOException { @@ -120,7 +98,7 @@ public void close () throws IOException { public void connect() throws IOException { if (!connected) { boolean useCaches = getUseCaches(); - String entryName = this.entryName; + String entryName = getEntryName(); /* the factory call will do the security checks */ URL url = getJarFileURL(); @@ -176,6 +154,7 @@ public InputStream getInputStream() throws IOException { InputStream result = null; + String entryName = getEntryName(); if (entryName == null) { throw new IOException("no entry name specified"); } else { @@ -216,7 +195,7 @@ public Object getContent() throws IOException { Object result = null; connect(); - if (entryName == null) { + if (getEntryName() == null) { result = jarFile; } else { result = super.getContent(); @@ -226,6 +205,7 @@ public Object getContent() throws IOException { public String getContentType() { if (contentType == null) { + String entryName = getEntryName(); if (entryName == null) { contentType = "x-java/jar"; } else { From 9631398cd936a947bc71af82b10b1a7ece8f68b3 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Fri, 28 Mar 2025 08:49:25 +0000 Subject: [PATCH 100/846] 8347576: Error output in libjsound has non matching format strings Backport-of: 950e655064a75e20540955ad91430c8bea7ae73b --- .../share/native/libjsound/MidiInDevice.c | 4 ++-- .../share/native/libjsound/MidiOutDevice.c | 4 ++-- .../native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp | 12 +++++++----- .../native/libjsound/PLATFORM_API_WinOS_Ports.c | 4 ++-- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/java.desktop/share/native/libjsound/MidiInDevice.c b/src/java.desktop/share/native/libjsound/MidiInDevice.c index fe320a59a874f..fb27602f39915 100644 --- a/src/java.desktop/share/native/libjsound/MidiInDevice.c +++ b/src/java.desktop/share/native/libjsound/MidiInDevice.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -137,7 +137,7 @@ Java_com_sun_media_sound_MidiInDevice_nGetTimeStamp(JNIEnv* e, jobject thisObj, /* Handle error codes. */ if (ret < -1) { - ERROR1("Java_com_sun_media_sound_MidiInDevice_nGetTimeStamp: MIDI_IN_GetTimeStamp returned %lld\n", ret); + ERROR1("Java_com_sun_media_sound_MidiInDevice_nGetTimeStamp: MIDI_IN_GetTimeStamp returned %lld\n", (long long int) ret); ret = -1; } return ret; diff --git a/src/java.desktop/share/native/libjsound/MidiOutDevice.c b/src/java.desktop/share/native/libjsound/MidiOutDevice.c index 29ef140b89d91..2f351bb1720f9 100644 --- a/src/java.desktop/share/native/libjsound/MidiOutDevice.c +++ b/src/java.desktop/share/native/libjsound/MidiOutDevice.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -94,7 +94,7 @@ Java_com_sun_media_sound_MidiOutDevice_nGetTimeStamp(JNIEnv* e, jobject thisObj, /* Handle error codes. */ if (ret < -1) { - ERROR1("Java_com_sun_media_sound_MidiOutDevice_nGetTimeStamp: MIDI_IN_GetTimeStamp returned %lld\n", ret); + ERROR1("Java_com_sun_media_sound_MidiOutDevice_nGetTimeStamp: MIDI_IN_GetTimeStamp returned %lld\n", (long long int) ret); ret = -1; } return ret; diff --git a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp index 4d1f4fee19e9e..1b4fcb6608642 100644 --- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -47,6 +47,8 @@ extern "C" { #define MIDIIN_CHECK_ERROR #endif +#include + /* * Callback from the MIDI device for all messages. */ @@ -55,8 +57,8 @@ void CALLBACK MIDI_IN_PutMessage( HMIDIIN hMidiIn, UINT wMsg, UINT_PTR dwInstanc MidiDeviceHandle* handle = (MidiDeviceHandle*) dwInstance; - TRACE3("> MIDI_IN_PutMessage, hMidiIn: %x, wMsg: %x, dwInstance: %x\n", hMidiIn, wMsg, dwInstance); - TRACE2(" dwParam1: %x, dwParam2: %x\n", dwParam1, dwParam2); + TRACE3("> MIDI_IN_PutMessage, hMidiIn: 0x%" PRIxPTR ", wMsg: %x, dwInstance: 0x%" PRIxPTR "\n", (uintptr_t)hMidiIn, wMsg, (uintptr_t)dwInstance); + TRACE2(" dwParam1: 0x%" PRIxPTR ", dwParam2: 0x%" PRIxPTR "\n", (uintptr_t)dwParam1, (uintptr_t)dwParam2); switch(wMsg) { @@ -70,8 +72,8 @@ void CALLBACK MIDI_IN_PutMessage( HMIDIIN hMidiIn, UINT wMsg, UINT_PTR dwInstanc case MIM_MOREDATA: case MIM_DATA: - TRACE3(" MIDI_IN_PutMessage: MIM_MOREDATA or MIM_DATA. status=%x data1=%x data2=%x\n", - dwParam1 & 0xFF, (dwParam1 & 0xFF00)>>8, (dwParam1 & 0xFF0000)>>16); + TRACE3(" MIDI_IN_PutMessage: MIM_MOREDATA or MIM_DATA. status=%x data1=%x data2=%x\n", + (int)(dwParam1 & 0xFF), (int)((dwParam1 & 0xFF00)>>8), (int)((dwParam1 & 0xFF0000)>>16)); if (handle!=NULL && handle->queue!=NULL && handle->platformData) { MIDI_QueueAddShort(handle->queue, // queue stores packedMsg in big endian diff --git a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c index 55dcb6e28827a..237aa89c12502 100644 --- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, 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 @@ -251,7 +251,7 @@ void printInfo(PortInfo* info) { TRACE5(" PortInfo %p: handle=%p, mixerIndex=%d, dstLineCount=%d, dstLines=%p, ", info, (void*) info->handle, info->mixerIndex, info->dstLineCount, info->dstLines); TRACE5("srcLineCount=%d, srcLines=%p, targetPortCount=%d, sourcePortCount=%d, ports=%p, ", info->srcLineCount, info->srcLines, info->targetPortCount, info->sourcePortCount, info->ports); TRACE3("maxControlCount=%d, usedControlIDs=%d, controlIDs=%p \n", info->maxControlCount, info->usedControlIDs, info->controlIDs); - TRACE2("usedMuxData=%d, muxData=%p, controlIDs=%p \n", info->usedMuxData, info->muxData); + TRACE3("usedMuxData=%d, muxData=%p, controlIDs=%p \n", info->usedMuxData, info->muxData, info->controlIDs); } #endif // USE_TRACE From 00c53b70b6281a969af7389e4da297bd64fb86bf Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Sun, 30 Mar 2025 15:48:59 +0000 Subject: [PATCH 101/846] 8347267: [macOS]: UnixOperatingSystem.c:67:40: runtime error: division by zero Backport-of: 5e92a4ceafd0626e3600e44a3370ca2f5d9347c8 --- .../macosx/native/libmanagement_ext/UnixOperatingSystem.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/jdk.management/macosx/native/libmanagement_ext/UnixOperatingSystem.c b/src/jdk.management/macosx/native/libmanagement_ext/UnixOperatingSystem.c index 2c11cd9ca9d8d..269c4d4535909 100644 --- a/src/jdk.management/macosx/native/libmanagement_ext/UnixOperatingSystem.c +++ b/src/jdk.management/macosx/native/libmanagement_ext/UnixOperatingSystem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, 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 @@ -63,6 +63,9 @@ Java_com_sun_management_internal_OperatingSystemImpl_getCpuLoad0 jlong used_delta = used - last_used; jlong total_delta = total - last_total; + if (total_delta == 0) { + return 0; + } jdouble cpu = (jdouble) used_delta / total_delta; From 59468baadb4c0fbaf9377c39242cc4da81151370 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Sun, 30 Mar 2025 15:50:58 +0000 Subject: [PATCH 102/846] 8349039: Adjust exception No type named in database Backport-of: 669f8c0c07b57fa00ac84b8a90c4a1a1459443e3 --- .../sun/jvm/hotspot/types/basic/BasicTypeDataBase.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java index 0944d59fc7154..7dceae1f0306a 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -83,7 +83,7 @@ public Type lookupType(String cTypeName) { public Type lookupType(String cTypeName, boolean throwException) { Type type = (Type) nameToTypeMap.get(cTypeName); if (type == null && throwException) { - throw new RuntimeException("No type named \"" + cTypeName + "\" in database"); + throw new RuntimeException("No type named \"" + cTypeName + "\" present in type database"); } return type; } From 41b35416615c6078e6c31ef76120a86fe56fe84d Mon Sep 17 00:00:00 2001 From: Dmitry Chuyko Date: Mon, 31 Mar 2025 15:35:37 +0000 Subject: [PATCH 103/846] 8298061: vmTestbase/nsk/sysdict/vm/stress/btree/btree012/btree012.java failed with "fatal error: refcount has gone to zero" Reviewed-by: coleenp Backport-of: 03d992728e27bd3dcd00d1af8a7b7179281e626f --- src/hotspot/share/classfile/placeholders.cpp | 7 ++++++- src/hotspot/share/classfile/placeholders.hpp | 8 ++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/classfile/placeholders.cpp b/src/hotspot/share/classfile/placeholders.cpp index 88b8d0fcc208d..18707c04b4605 100644 --- a/src/hotspot/share/classfile/placeholders.cpp +++ b/src/hotspot/share/classfile/placeholders.cpp @@ -326,7 +326,12 @@ void PlaceholderTable::find_and_remove(unsigned int hash, PlaceholderEntry *probe = get_entry(hash, name, loader_data); if (probe != NULL) { log(probe, "find_and_remove", action); - probe->remove_seen_thread(thread, action); + + bool empty = probe->remove_seen_thread(thread, action); + if (empty && action == LOAD_SUPER) { + probe->set_supername(NULL); + } + // If no other threads using this entry, and this thread is not using this entry for other states if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL) && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) { diff --git a/src/hotspot/share/classfile/placeholders.hpp b/src/hotspot/share/classfile/placeholders.hpp index d85ac9adfdc84..0474632e69070 100644 --- a/src/hotspot/share/classfile/placeholders.hpp +++ b/src/hotspot/share/classfile/placeholders.hpp @@ -142,8 +142,12 @@ class PlaceholderEntry : public HashtableEntry { Symbol* supername() const { return _supername; } void set_supername(Symbol* supername) { - _supername = supername; - if (_supername != NULL) _supername->increment_refcount(); + if (supername != _supername) { + _supername = supername; + if (_supername != NULL) { + _supername->increment_refcount(); + } + } } Thread* definer() const {return _definer; } From 01425e40cd545b0183d792fc6d3a82bbfb70c468 Mon Sep 17 00:00:00 2001 From: Daniel Hu Date: Mon, 31 Mar 2025 18:35:47 +0000 Subject: [PATCH 104/846] 6956385: URLConnection.getLastModified() leaks file handles for jar:file and file: URLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define FileURLConnection.closeInputStream for use by JarURLInputStream.close. JarURLConnection properly tracks any InputStream it itself opened, and correspondingly closes the JarFile if necessary (when caches are disabled). But if its underlying FileURLConnection was used to retrieve a header field, that would have caused a FileInputStream to be opened which never gets closed until it is garbage collected. This means that an application which calls certain methods on jar:file:/…something.jar!/… URLs will leak file handles, even if URLConnection caches are supposed to be turned off. This can delay release of system resources, and on Windows can prevent the JAR file from being deleted even after it is no longer in use (for example after URLClassLoader.close). Backport-of: 9f98136c3a00ca24d59ffefd58308603b58110c7 --- .../www/protocol/file/FileURLConnection.java | 6 ++ .../www/protocol/jar/JarURLConnection.java | 11 ++- .../protocol/jar/FileURLConnectionLeak.java | 71 +++++++++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 test/jdk/sun/net/www/protocol/jar/FileURLConnectionLeak.java diff --git a/src/java.base/share/classes/sun/net/www/protocol/file/FileURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/file/FileURLConnection.java index c6878a6369945..dd34c339ebc48 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/file/FileURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/file/FileURLConnection.java @@ -99,6 +99,12 @@ public void connect() throws IOException { } } + public synchronized void closeInputStream() throws IOException { + if (is != null) { + is.close(); + } + } + private boolean initializedHeaders = false; private void initializeHeaders() { diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java index 234827fb76f2e..725b4cb95a084 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java @@ -25,6 +25,7 @@ package sun.net.www.protocol.jar; +import sun.net.www.protocol.file.FileURLConnection; import java.io.BufferedInputStream; import java.io.FileNotFoundException; import java.io.IOException; @@ -88,8 +89,14 @@ public void close () throws IOException { try { super.close(); } finally { - if (!getUseCaches()) { - jarFile.close(); + try { + if (!getUseCaches()) { + jarFile.close(); + } + } finally { + if (jarFileURLConnection instanceof FileURLConnection fileURLConnection) { + fileURLConnection.closeInputStream(); + } } } } diff --git a/test/jdk/sun/net/www/protocol/jar/FileURLConnectionLeak.java b/test/jdk/sun/net/www/protocol/jar/FileURLConnectionLeak.java new file mode 100644 index 0000000000000..5ff687ca42df8 --- /dev/null +++ b/test/jdk/sun/net/www/protocol/jar/FileURLConnectionLeak.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 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. + */ + +/* + * @test + * @bug 6956385 + * @summary JarURLConnection may fail to close its underlying FileURLConnection + * @run main/othervm FileURLConnectionLeak + */ + +import java.net.URI; +import java.net.URLConnection; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.jar.Attributes; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +public class FileURLConnectionLeak { + public static void main(String[] args) throws Exception { + URLConnection.setDefaultUseCaches("file", false); + URLConnection.setDefaultUseCaches("jar", false); + var jar = Path.of("x.jar").toAbsolutePath(); + var mani = new Manifest(); + mani.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); + try (var os = Files.newOutputStream(jar); var jos = new JarOutputStream(os, mani)) {} + var u = URI.create("jar:" + jar.toUri() + "!/META-INF/MANIFEST.MF").toURL(); + // FileURLConnection.is not used, so was always fine: + try (var is = u.openStream()) { + is.transferTo(System.out); + } + // FileURLConnection.is opened implicitly: + var conn = u.openConnection(); + conn.getLastModified(); + // Idiom to close URLConnection (cf. JDK-8224095), which must also close the other stream: + conn.getInputStream().close(); + var fds = Path.of("/proc/" + ProcessHandle.current().pid() + "/fd"); + if (Files.isDirectory(fds)) { + // Linux: verify that x.jar is not open + for (var fd : (Iterable) Files.list(fds)::iterator) { + if (Files.isSymbolicLink(fd)) { + var file = Files.readSymbolicLink(fd); + if (file.equals(jar)) { + throw new IllegalStateException("Still held open " + jar + " from " + fd); + } + } + } + } + // Windows: verify that mandatory file locks do not prevent deletion + Files.delete(jar); + } +} From 692f275d7af1db381ec9cf22eeb566f8e7a07667 Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Mon, 31 Mar 2025 18:43:15 +0000 Subject: [PATCH 105/846] 8350211: CTW: Attempt to preload all classes in constant pool Backport-of: d13fd5738f8a3d4b4009c2e15cfd967332d97bbd --- .../ctw/src/sun/hotspot/tools/ctw/Compiler.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java index 961090c1d4035..ae8850ce6b646 100644 --- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java +++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java @@ -87,17 +87,16 @@ public static void compileClass(Class aClass, long id, Executor executor) { private static void preloadClasses(String className, long id, ConstantPool constantPool) { - try { - for (int i = 0, n = constantPool.getSize(); i < n; ++i) { - try { + for (int i = 0, n = constantPool.getSize(); i < n; ++i) { + try { + if (constantPool.getTagAt(i) == ConstantPool.Tag.CLASS) { constantPool.getClassAt(i); - } catch (IllegalArgumentException ignore) { } + } catch (Throwable t) { + CompileTheWorld.OUT.println(String.format("[%d]\t%s\tWARNING preloading failed : %s", + id, className, t)); + t.printStackTrace(CompileTheWorld.ERR); } - } catch (Throwable t) { - CompileTheWorld.OUT.println(String.format("[%d]\t%s\tWARNING preloading failed : %s", - id, className, t)); - t.printStackTrace(CompileTheWorld.ERR); } } From 845a11ef68ccc37933b256e423aa42b6226e2ee5 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Wed, 2 Apr 2025 06:03:57 +0000 Subject: [PATCH 106/846] 8287801: Fix test-bugs related to stress flags Reviewed-by: phh Backport-of: 302a6c068dcbb176381b1535baf25547079c9b06 --- .../jtreg/compiler/arraycopy/TestArrayCopyNoInitDeopt.java | 1 + test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java | 2 ++ test/hotspot/jtreg/compiler/c2/cr7200264/TestSSE2IntVect.java | 3 ++- test/hotspot/jtreg/compiler/c2/cr7200264/TestSSE4IntVect.java | 3 ++- .../c2/irTests/blackhole/BlackholeStoreStoreEATest.java | 1 + test/hotspot/jtreg/compiler/cha/AbstractRootMethod.java | 2 ++ test/hotspot/jtreg/compiler/cha/DefaultRootMethod.java | 2 ++ .../compiler/intrinsics/klass/CastNullCheckDroppingsTest.java | 4 +++- .../compiler/jvmci/compilerToVM/IsMatureVsReprofileTest.java | 1 + .../jtreg/compiler/jvmci/compilerToVM/ReprofileTest.java | 1 + test/hotspot/jtreg/compiler/profiling/TestTypeProfiling.java | 2 ++ .../jtreg/compiler/rangechecks/TestExplicitRangeChecks.java | 1 + .../jtreg/compiler/rangechecks/TestRangeCheckSmearing.java | 1 + .../jtreg/compiler/uncommontrap/TestUnstableIfTrap.java | 4 ++++ 14 files changed, 25 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyNoInitDeopt.java b/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyNoInitDeopt.java index 9e6c7f47cc413..b0fa21b4f9553 100644 --- a/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyNoInitDeopt.java +++ b/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyNoInitDeopt.java @@ -34,6 +34,7 @@ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -Xmixed -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:TypeProfileLevel=020 + * -XX:+UnlockExperimentalVMOptions -XX:PerMethodSpecTrapLimit=5000 -XX:PerMethodTrapLimit=100 * compiler.arraycopy.TestArrayCopyNoInitDeopt */ diff --git a/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java b/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java index 3f9ddcd168f5d..8fc1fa0580ddd 100644 --- a/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java +++ b/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java @@ -49,6 +49,8 @@ private List executeApplication() throws Throwable { "-XX:-TieredCompilation", "-XX:+PrintCompilation", "-XX:+TraceNewVectors", + "-XX:+IgnoreUnrecognizedVMOptions", + "-XX:StressLongCountedLoop=0", // make sure int loops do not get converted to long TestIntVect.class.getName()); outputAnalyzer.shouldHaveExitValue(0); return outputAnalyzer.asLines(); diff --git a/test/hotspot/jtreg/compiler/c2/cr7200264/TestSSE2IntVect.java b/test/hotspot/jtreg/compiler/c2/cr7200264/TestSSE2IntVect.java index 857eb34a5fbed..c78e2cd398bfc 100644 --- a/test/hotspot/jtreg/compiler/c2/cr7200264/TestSSE2IntVect.java +++ b/test/hotspot/jtreg/compiler/c2/cr7200264/TestSSE2IntVect.java @@ -28,7 +28,8 @@ * @requires vm.cpu.features ~= ".*sse2.*" & vm.debug & vm.flavor == "server" * @requires !vm.emulatedClient & !vm.graal.enabled * @library /test/lib / - * @run driver compiler.c2.cr7200264.TestSSE2IntVect + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:StressLongCountedLoop=0 + * compiler.c2.cr7200264.TestSSE2IntVect */ package compiler.c2.cr7200264; diff --git a/test/hotspot/jtreg/compiler/c2/cr7200264/TestSSE4IntVect.java b/test/hotspot/jtreg/compiler/c2/cr7200264/TestSSE4IntVect.java index dee9b81f1fdc1..a7dbbceef912a 100644 --- a/test/hotspot/jtreg/compiler/c2/cr7200264/TestSSE4IntVect.java +++ b/test/hotspot/jtreg/compiler/c2/cr7200264/TestSSE4IntVect.java @@ -28,7 +28,8 @@ * @requires vm.cpu.features ~= ".*sse4\\.1.*" & vm.debug & vm.flavor == "server" * @requires !vm.emulatedClient & !vm.graal.enabled * @library /test/lib / - * @run driver compiler.c2.cr7200264.TestSSE4IntVect + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:StressLongCountedLoop=0 + * compiler.c2.cr7200264.TestSSE4IntVect */ package compiler.c2.cr7200264; diff --git a/test/hotspot/jtreg/compiler/c2/irTests/blackhole/BlackholeStoreStoreEATest.java b/test/hotspot/jtreg/compiler/c2/irTests/blackhole/BlackholeStoreStoreEATest.java index bfdab82d2f937..d84534baed31f 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/blackhole/BlackholeStoreStoreEATest.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/blackhole/BlackholeStoreStoreEATest.java @@ -39,6 +39,7 @@ public class BlackholeStoreStoreEATest { public static void main(String[] args) { TestFramework.runWithFlags( + "-XX:+UseTLAB", "-XX:+UnlockExperimentalVMOptions", "-XX:CompileCommand=blackhole,compiler.c2.irTests.blackhole.BlackholeStoreStoreEATest::blackhole" ); diff --git a/test/hotspot/jtreg/compiler/cha/AbstractRootMethod.java b/test/hotspot/jtreg/compiler/cha/AbstractRootMethod.java index e1a22c816a656..5ddfb7459f171 100644 --- a/test/hotspot/jtreg/compiler/cha/AbstractRootMethod.java +++ b/test/hotspot/jtreg/compiler/cha/AbstractRootMethod.java @@ -38,6 +38,7 @@ * -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=dontinline,*::test * -Xbatch -Xmixed -XX:+WhiteBoxAPI * -XX:-TieredCompilation + * -XX:-StressMethodHandleLinkerInlining * compiler.cha.AbstractRootMethod * * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions @@ -46,6 +47,7 @@ * -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=dontinline,*::test * -Xbatch -Xmixed -XX:+WhiteBoxAPI * -XX:+TieredCompilation -XX:TieredStopAtLevel=1 + * -XX:-StressMethodHandleLinkerInlining * compiler.cha.AbstractRootMethod */ package compiler.cha; diff --git a/test/hotspot/jtreg/compiler/cha/DefaultRootMethod.java b/test/hotspot/jtreg/compiler/cha/DefaultRootMethod.java index 06b622f6d3b8f..d3bdb1ede0dda 100644 --- a/test/hotspot/jtreg/compiler/cha/DefaultRootMethod.java +++ b/test/hotspot/jtreg/compiler/cha/DefaultRootMethod.java @@ -38,6 +38,7 @@ * -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=dontinline,*::test * -Xbatch -Xmixed -XX:+WhiteBoxAPI * -XX:-TieredCompilation + * -XX:-StressMethodHandleLinkerInlining * compiler.cha.DefaultRootMethod * * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions @@ -46,6 +47,7 @@ * -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=dontinline,*::test * -Xbatch -Xmixed -XX:+WhiteBoxAPI * -XX:+TieredCompilation -XX:TieredStopAtLevel=1 + * -XX:-StressMethodHandleLinkerInlining * compiler.cha.DefaultRootMethod */ package compiler.cha; diff --git a/test/hotspot/jtreg/compiler/intrinsics/klass/CastNullCheckDroppingsTest.java b/test/hotspot/jtreg/compiler/intrinsics/klass/CastNullCheckDroppingsTest.java index 28a7ab664abc4..8ee5397b3435a 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/klass/CastNullCheckDroppingsTest.java +++ b/test/hotspot/jtreg/compiler/intrinsics/klass/CastNullCheckDroppingsTest.java @@ -35,6 +35,8 @@ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -Xmixed -XX:-BackgroundCompilation -XX:-TieredCompilation -XX:CompileThreshold=1000 + * -XX:+UnlockExperimentalVMOptions -XX:PerMethodTrapLimit=100 -XX:-StressReflectiveCode + * -XX:+UncommonNullCast -XX:-StressMethodHandleLinkerInlining -XX:TypeProfileLevel=0 * -XX:CompileCommand=exclude,compiler.intrinsics.klass.CastNullCheckDroppingsTest::runTest * compiler.intrinsics.klass.CastNullCheckDroppingsTest */ @@ -356,7 +358,7 @@ static void checkDeoptimization(List events, int compilerId, bool if (exist != mustExist) { System.err.println("events:"); System.err.println(events); - throw new AssertionError("compilation must " + (mustExist ? "" : " not ") + " got deoptimized"); + throw new AssertionError("compilation must " + (mustExist ? "" : " not ") + " get deoptimized"); } if (mustExist && events.stream() diff --git a/test/hotspot/jtreg/compiler/jvmci/compilerToVM/IsMatureVsReprofileTest.java b/test/hotspot/jtreg/compiler/jvmci/compilerToVM/IsMatureVsReprofileTest.java index 692f55ccd9b7e..e76b968de2aeb 100644 --- a/test/hotspot/jtreg/compiler/jvmci/compilerToVM/IsMatureVsReprofileTest.java +++ b/test/hotspot/jtreg/compiler/jvmci/compilerToVM/IsMatureVsReprofileTest.java @@ -40,6 +40,7 @@ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Xbatch -XX:CompileThresholdScaling=1.0 + * -XX:CompileCommand=dontinline,compiler.jvmci.common.testcases.SimpleClass::testMethod * compiler.jvmci.compilerToVM.IsMatureVsReprofileTest */ diff --git a/test/hotspot/jtreg/compiler/jvmci/compilerToVM/ReprofileTest.java b/test/hotspot/jtreg/compiler/jvmci/compilerToVM/ReprofileTest.java index 09aec239356c3..e7be6ef262b4c 100644 --- a/test/hotspot/jtreg/compiler/jvmci/compilerToVM/ReprofileTest.java +++ b/test/hotspot/jtreg/compiler/jvmci/compilerToVM/ReprofileTest.java @@ -40,6 +40,7 @@ * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI * -Xmixed -Xbatch + * -XX:TypeProfileLevel=0 * compiler.jvmci.compilerToVM.ReprofileTest */ diff --git a/test/hotspot/jtreg/compiler/profiling/TestTypeProfiling.java b/test/hotspot/jtreg/compiler/profiling/TestTypeProfiling.java index cc11462d02e1b..af054f21d01de 100644 --- a/test/hotspot/jtreg/compiler/profiling/TestTypeProfiling.java +++ b/test/hotspot/jtreg/compiler/profiling/TestTypeProfiling.java @@ -39,11 +39,13 @@ * -XX:-BackgroundCompilation -XX:-UseOnStackReplacement * -XX:CompileThreshold=10000 * -server -XX:-TieredCompilation -XX:TypeProfileLevel=020 + * -XX:+UnlockExperimentalVMOptions -XX:PerMethodSpecTrapLimit=5000 -XX:PerMethodTrapLimit=100 * compiler.profiling.TestTypeProfiling * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:-BackgroundCompilation -XX:-UseOnStackReplacement * -XX:CompileThreshold=10000 * -server -XX:-TieredCompilation -XX:TypeProfileLevel=200 + * -XX:+UnlockExperimentalVMOptions -XX:PerMethodSpecTrapLimit=5000 -XX:PerMethodTrapLimit=100 * compiler.profiling.TestTypeProfiling */ diff --git a/test/hotspot/jtreg/compiler/rangechecks/TestExplicitRangeChecks.java b/test/hotspot/jtreg/compiler/rangechecks/TestExplicitRangeChecks.java index 8e8e8974bad95..ba045814fc2dd 100644 --- a/test/hotspot/jtreg/compiler/rangechecks/TestExplicitRangeChecks.java +++ b/test/hotspot/jtreg/compiler/rangechecks/TestExplicitRangeChecks.java @@ -31,6 +31,7 @@ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -ea -Xmixed -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:-BackgroundCompilation -XX:-UseOnStackReplacement + * -XX:+UnlockExperimentalVMOptions -XX:PerMethodSpecTrapLimit=5000 -XX:PerMethodTrapLimit=100 * -XX:CompileCommand=compileonly,compiler.rangechecks.TestExplicitRangeChecks::test* * compiler.rangechecks.TestExplicitRangeChecks * diff --git a/test/hotspot/jtreg/compiler/rangechecks/TestRangeCheckSmearing.java b/test/hotspot/jtreg/compiler/rangechecks/TestRangeCheckSmearing.java index 676b1f0118173..6f9d05899dd4c 100644 --- a/test/hotspot/jtreg/compiler/rangechecks/TestRangeCheckSmearing.java +++ b/test/hotspot/jtreg/compiler/rangechecks/TestRangeCheckSmearing.java @@ -29,6 +29,7 @@ * @modules java.base/jdk.internal.misc * java.management * @build jdk.test.whitebox.WhiteBox + * @requires vm.flavor == "server" & (vm.opt.TieredStopAtLevel == null | vm.opt.TieredStopAtLevel == 4) * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -ea -Xmixed -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:-BackgroundCompilation -XX:-UseOnStackReplacement diff --git a/test/hotspot/jtreg/compiler/uncommontrap/TestUnstableIfTrap.java b/test/hotspot/jtreg/compiler/uncommontrap/TestUnstableIfTrap.java index eef9fc6c19dc7..5fee59c751079 100644 --- a/test/hotspot/jtreg/compiler/uncommontrap/TestUnstableIfTrap.java +++ b/test/hotspot/jtreg/compiler/uncommontrap/TestUnstableIfTrap.java @@ -35,21 +35,25 @@ * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -Xbatch -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+UnlockExperimentalVMOptions -XX:PerMethodTrapLimit=100 * -XX:+WhiteBoxAPI -XX:+LogCompilation * -XX:CompileCommand=compileonly,UnstableIfExecutable.test * -XX:LogFile=always_taken_not_fired.xml * compiler.uncommontrap.TestUnstableIfTrap ALWAYS_TAKEN false * @run main/othervm -Xbatch -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+UnlockExperimentalVMOptions -XX:PerMethodTrapLimit=100 * -XX:+WhiteBoxAPI -XX:+LogCompilation * -XX:CompileCommand=compileonly,UnstableIfExecutable.test * -XX:LogFile=always_taken_fired.xml * compiler.uncommontrap.TestUnstableIfTrap ALWAYS_TAKEN true * @run main/othervm -Xbatch -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+UnlockExperimentalVMOptions -XX:PerMethodTrapLimit=100 * -XX:+WhiteBoxAPI -XX:+LogCompilation * -XX:CompileCommand=compileonly,UnstableIfExecutable.test * -XX:LogFile=never_taken_not_fired.xml * compiler.uncommontrap.TestUnstableIfTrap NEVER_TAKEN false * @run main/othervm -Xbatch -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+UnlockExperimentalVMOptions -XX:PerMethodTrapLimit=100 * -XX:+WhiteBoxAPI -XX:+LogCompilation * -XX:CompileCommand=compileonly,UnstableIfExecutable.test * -XX:LogFile=never_taken_fired.xml From 450b290a10c1647f41cd8fb06d9fa78826e71538 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 2 Apr 2025 09:50:22 +0000 Subject: [PATCH 107/846] 8315951: Open source several Swing HTMLEditorKit related tests Backport-of: d19e017d3fd87a6b7613f44a3757d574a6560680 --- .../awt/event/PaintEvent/RepaintTest.java | 133 ++++++++++++++++++ .../text/html/HTMLEditorKit/bug4214848.java | 49 +++++++ .../text/html/HTMLEditorKit/bug4230197.java | 58 ++++++++ .../text/html/HTMLEditorKit/bug4238223.java | 125 ++++++++++++++++ 4 files changed, 365 insertions(+) create mode 100644 test/jdk/java/awt/event/PaintEvent/RepaintTest.java create mode 100644 test/jdk/javax/swing/text/html/HTMLEditorKit/bug4214848.java create mode 100644 test/jdk/javax/swing/text/html/HTMLEditorKit/bug4230197.java create mode 100644 test/jdk/javax/swing/text/html/HTMLEditorKit/bug4238223.java diff --git a/test/jdk/java/awt/event/PaintEvent/RepaintTest.java b/test/jdk/java/awt/event/PaintEvent/RepaintTest.java new file mode 100644 index 0000000000000..caeeaf7d5a8e8 --- /dev/null +++ b/test/jdk/java/awt/event/PaintEvent/RepaintTest.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2001, 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. + */ + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.Robot; +import java.util.concurrent.atomic.AtomicInteger; + +/* + * @test + * @bug 4394287 + * @key headful + * @summary Paint pending on heavyweight component move + */ + +public class RepaintTest { + private static Frame frame; + private static Panel panel; + private static volatile IncrementComponent counter; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + EventQueue.invokeAndWait(RepaintTest::createAndShowUI); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> panel.setLocation(panel.getX() + 10, + panel.getY() + 10)); + robot.waitForIdle(); + robot.delay(500); + + int count = counter.getCount().get(); + + EventQueue.invokeAndWait(panel::repaint); + robot.waitForIdle(); + robot.delay(1000); + + if (counter.getCount().get() == count) { + throw new RuntimeException("Failed"); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + frame = new MyFrame("Repaint Test"); + frame.setLayout(null); + + counter = new IncrementComponent(); + panel = new Panel(); + panel.add(counter); + frame.add(panel); + panel.setBounds(0, 0, 100, 100); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + private static class MyFrame extends Frame { + + public MyFrame(String title) { + super(title); + } + + public void update(Graphics g) { + System.out.println("UPDATE: " + g.getClipBounds()); + super.update(g); + } + + public void paint(Graphics g) { + System.out.println("PAINT: " + g.getClipBounds()); + super.paint(g); + } + } + + // Subclass of Component, everytime paint is invoked a counter + // is incremented, this counter is displayed in the component. + private static class IncrementComponent extends Component { + private static final AtomicInteger paintCount = new AtomicInteger(0); + + public Dimension getPreferredSize() { + return new Dimension(100, 100); + } + + public AtomicInteger getCount() { + return paintCount; + } + + public void paint(Graphics g) { + g.setColor(Color.red); + g.fillRect(0, 0, getWidth(), getHeight()); + g.setColor(Color.white); + + String string = Integer.toString(paintCount.getAndIncrement()); + FontMetrics metrics = g.getFontMetrics(); + int x = (getWidth() - metrics.stringWidth(string)) / 2; + int y = (getHeight() + metrics.getHeight()) / 2; + g.drawString(string, x, y); + } + } +} diff --git a/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4214848.java b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4214848.java new file mode 100644 index 0000000000000..9a5353598660c --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4214848.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 1999, 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. + */ + +import java.io.StringReader; +import java.io.StringWriter; +import javax.swing.text.Document; +import javax.swing.text.html.HTMLEditorKit; + +/* + * @test + * @bug 4214848 + * @summary Tests whether HTMLEditorKit.read(...) + * creates Document for html with empty BODY + */ + +public class bug4214848 { + public static void main (String[] args) throws Exception { + StringWriter sw = new StringWriter(); + String test = ""; + HTMLEditorKit kit = new HTMLEditorKit(); + Document doc = kit.createDefaultDocument(); + kit.read(new StringReader(test), doc, 0); // prepare test document + kit.write(sw, doc, 0, 10); + String out = sw.toString().toLowerCase(); + if (out.indexOf("") != out.lastIndexOf("")) { + throw new RuntimeException("Test failed: extra section generated"); + } + } +} diff --git a/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4230197.java b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4230197.java new file mode 100644 index 0000000000000..59d4952c3230d --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4230197.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1999, 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. + */ + +import java.io.StringWriter; +import javax.swing.text.html.HTML; +import javax.swing.text.html.HTMLDocument; +import javax.swing.text.html.HTMLEditorKit; + +/* + * @test + * @bug 4230197 + * @summary Tests if HTMLEditorKit.insertHTML() works for font/phrase tags + */ + +public class bug4230197 { + + public static void main(String[] args) throws Exception { + HTMLEditorKit kit = new HTMLEditorKit(); + StringWriter sw = new StringWriter(); + HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument(); + kit.insertHTML(doc, doc.getLength(), "0", 0, 0, HTML.Tag.SUB); + kit.insertHTML(doc, doc.getLength(), "0", 0, 0, HTML.Tag.SUP); + kit.insertHTML(doc, doc.getLength(), "0", 0, 0, HTML.Tag.B); + kit.insertHTML(doc, doc.getLength(), "0", 0, 0, HTML.Tag.I); + kit.insertHTML(doc, doc.getLength(), "0", 0, 0, HTML.Tag.CODE); + kit.write(sw, doc, 0, doc.getLength()); + + String out = sw.toString().toLowerCase(); + if ((!out.contains("0")) + || (!out.contains("0")) + || (!out.contains("0")) + || (!out.contains("0")) + || (!out.contains("0"))) { + throw new RuntimeException("Test failed: HTMLEditorKit.insertHTML()" + + " doesn't work for font/phrase tags"); + } + } +} diff --git a/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4238223.java b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4238223.java new file mode 100644 index 0000000000000..86479ea55709c --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4238223.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1999, 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. + */ + +import java.io.Reader; +import java.io.StringReader; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.html.HTML; +import javax.swing.text.html.HTMLEditorKit; +import javax.swing.text.html.parser.ParserDelegator; + +/* + * @test + * @bug 4238223 + * @summary Tests that HTMLEditorKit.ParserCallback methods receive + * correct 'pos' argument. + */ + +public class bug4238223 { + + public static void main(String[] argv) throws Exception { + TestParser parser = new TestParser(); + String testHTML = "Text" + + "Simple text"; + parser.parse(testHTML); + } + + static class TestCallback extends HTMLEditorKit.ParserCallback { + String commentData = "comment"; + int commentIndex = 65; + + public void handleComment(char[] data, int pos) { + if (!(new String(data)).equals(commentData) + || pos != commentIndex) { + + throw new RuntimeException("handleComment failed"); + } + } + + HTML.Tag[] endTags = {HTML.Tag.TITLE, HTML.Tag.HEAD, + HTML.Tag.BODY, HTML.Tag.HTML}; + int[] endTagPositions = {23, 31, 79, 86}; + int endTagIndex = 0; + public void handleEndTag(HTML.Tag tag, int pos) { + if (!tag.equals(endTags[endTagIndex]) + || pos != endTagPositions[endTagIndex]) { + + throw new RuntimeException("handleEndTag failed"); + } else { + endTagIndex++; + } + } + + int errorIndex = 54; + public void handleError(String errorMsg, int pos) { + if (pos != errorIndex) { + throw new RuntimeException("handleError failed"); + } + } + + int[] simpleTagPositions = {44, 93}; + int simpleTagIndex = 0; + public void handleSimpleTag(HTML.Tag tag, MutableAttributeSet attr, + int pos) { + if (pos != simpleTagPositions[simpleTagIndex++]) { + throw new RuntimeException("handleSimpleTag failed"); + } + } + + HTML.Tag[] startTags = {HTML.Tag.HTML, HTML.Tag.HEAD, + HTML.Tag.TITLE, HTML.Tag.BODY}; + int[] startTagPositions = {0, 6, 12, 38}; + int startTagIndex = 0; + public void handleStartTag(HTML.Tag tag, MutableAttributeSet attr, + int pos) { + if (!tag.equals(startTags[startTagIndex]) + || pos != startTagPositions[startTagIndex]) { + + throw new RuntimeException("handleStartTag failed"); + } else { + startTagIndex++; + } + } + + String[] textData = {"Text", "Simple text"}; + int[] textPositions = {19, 54}; + int textIndex = 0; + public void handleText(char[] data, int pos) { + if (!textData[textIndex].equals(new String(data)) + || pos != textPositions[textIndex]) { + + throw new RuntimeException("handleText failed"); + } else { + textIndex++; + } + } + } + + static class TestParser extends ParserDelegator { + public void parse(String html) throws Exception { + Reader r = new StringReader(html); + super.parse(r, new TestCallback(), false); + r.close(); + } + } +} From 7c4fdd2b116ac0786bbe5274e76009f6471edbe6 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 2 Apr 2025 09:51:44 +0000 Subject: [PATCH 108/846] 8328484: Convert and Opensource few JFileChooser applet test to main Backport-of: 528efe206d5ee3775b01f3b90600ca3cab6c96f0 --- .../JFileChooser/EnterEmptyDirectory.java | 88 ++++++++ .../JFileChooser/FileSelectionTests.java | 145 ++++++++++++ .../swing/JFileChooser/ShowHiddenFiles.java | 209 ++++++++++++++++++ 3 files changed, 442 insertions(+) create mode 100644 test/jdk/javax/swing/JFileChooser/EnterEmptyDirectory.java create mode 100644 test/jdk/javax/swing/JFileChooser/FileSelectionTests.java create mode 100644 test/jdk/javax/swing/JFileChooser/ShowHiddenFiles.java diff --git a/test/jdk/javax/swing/JFileChooser/EnterEmptyDirectory.java b/test/jdk/javax/swing/JFileChooser/EnterEmptyDirectory.java new file mode 100644 index 0000000000000..5a9a7945f601a --- /dev/null +++ b/test/jdk/javax/swing/JFileChooser/EnterEmptyDirectory.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JPanel; +import javax.swing.UIManager; + +/* + * @test + * @bug 4913368 + * @requires (os.family == "linux") + * @summary Test repainting when entering an empty directory w/ GTK LAF + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual EnterEmptyDirectory + */ + +public class EnterEmptyDirectory { + + private static final String INSTRUCTIONS = """ + This test is only for the GTK Look & Feel. + + Step 1: + Find or create an empty directory. This directory should + be in a directory with other files and directories, such that + there are items in both the Folders and Files lists of the + JFileChooser. + + Step 2: + Click the "Show JFileChooser" button and enter the empty directory. + If both lists are correctly repainted such that they are both empty + (except for the ./ and ../) then the test passes. + + If the contents of the Folders or Files lists are unchanged, test FAILS. """; + + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); + PassFailJFrame.builder() + .title("JFileChooser Instructions") + .instructions(INSTRUCTIONS) + .rows(15) + .columns(40) + .splitUI(EnterEmptyDirectory::createAndShowUI) + .build() + .awaitAndCheck(); + } + + public static JPanel createAndShowUI() { + JButton button = new JButton("Show JFileChooser"); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser jfc = new JFileChooser(); + jfc.setMultiSelectionEnabled(true); + jfc.showOpenDialog(null); + } + }); + JPanel p = new JPanel(); + p.setLayout(new BorderLayout()); + p.setSize(200, 200); + p.add(button); + return p; + } +} diff --git a/test/jdk/javax/swing/JFileChooser/FileSelectionTests.java b/test/jdk/javax/swing/JFileChooser/FileSelectionTests.java new file mode 100644 index 0000000000000..728f7dc2b22e1 --- /dev/null +++ b/test/jdk/javax/swing/JFileChooser/FileSelectionTests.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JPanel; +import javax.swing.UIManager; + +/* + * @test + * @bug 4835633 + * @requires (os.family == "windows") + * @summary Test various file selection scenarios + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual FileSelectionTests + */ + +public class FileSelectionTests { + private static final String INSTRUCTIONS = """ + This test is only for the Windows Look & Feel. + This is a test of file selection/deselection using the mouse. + There are quite a few steps. If any step doesn't behave as + expected, press Fail else press Pass. + + Make sure that you are in a directory with at least a few files. + Note that if you don't wait long enough between mouse buttons presses + that the action will be interpreted as a double-click and will dismiss + the dialog. Just re-show the dialog in this case. + + Press "Show Windows JFileChooser" button to show the JFileChooser. + + TEST 1: + Click on a filename. The file should become selected. + TEST 2: + Clear any selection. Click to right of a filename, + in the space between the filename and the file's icon in the next column. + The file should NOT be selected. If it becomes selected, press Fail. + TEST 3: + Select a filename. As in TEST 2, click in the empty space to the right of + the filename. The file should be deselected. + TEST 4: + Clear any selection. If necessary, resize the file dialog and/or change to + a directory with only a couple files, so that there is some space between + the list of files and the bottom of the file pane. + Click below the file list, in the empty space between the last file and + bottom of the file pane. The last file in the column above the cursor + should NOT become selected. If any file becomes selected, press Fail. + TEST 5: + Select a file. As in TEST 4, click in the empty space below the file list. + The selected file should become deselected. + TEST 6: + Clear any selection. As in TEST 4, click below the file list. + Then click on the last filename in the list. It should NOT go into edit mode. + TEST 7: + Clear any selection. Double-click below file list. The dialog should not be + dismissed, and no exception should be thrown. + TEST 8: + Clear any selection. As in TEST 2, press the mouse button in the empty space + to the right of a filename, but this time drag the mouse onto the filename. + The file should NOT become selected. + TEST 9: + Clear any selection. As in TEST 4, press the mouse button in the empty space + below the file list, but this time drag onto the last filename in the column. + The file should NOT become selected. + TEST 10: + Click on a filename, and then click again to go into rename mode. + Modify the filename, and then click to the right of the edit box. + The filename should be the new filename. + TEST 11: + As in TEST 10, rename a file, but this time end the editing by clicking below + the file list. Again, the file should retain the new name. + TEST 12: + Use shift-click to select several files. Hold "shift down" and click in + (1) the empty space to the right of a file name and + (2) in the empty space below the list of files. + The files should remain selected. If the selection is cleared press Fail. + TEST 13: + Switch to Details view. Repeat TESTS 1-11. + TEST 14: + Details view. Clear any selection. Click in the Size column. + No file should become selected. + TEST 15: + Details view. Select a file. Click in the Size column. + The file should be deselected. + TEST 16: + Details view. Shift-click to select several files. Shift-click in + (1) the empty space to the right of a filename + (2) in the Size column and + (3) below the list of files. + The files should remain selected. If the selection is cleared, press Fail. """; + + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + PassFailJFrame.builder() + .title("JFileChooser Instructions") + .instructions(INSTRUCTIONS) + .rows(25) + .columns(50) + .testTimeOut(10) + .splitUI(FileSelectionTests::createAndShowUI) + .build() + .awaitAndCheck(); + } + + public static JPanel createAndShowUI() { + JButton button = new JButton("Show Windows JFileChooser"); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser jfc = new JFileChooser(); + jfc.setMultiSelectionEnabled(true); + jfc.showOpenDialog(null); + } + }); + JPanel p = new JPanel(); + p.setLayout(new BorderLayout()); + p.setSize(200, 200); + p.add(button); + return p; + } +} diff --git a/test/jdk/javax/swing/JFileChooser/ShowHiddenFiles.java b/test/jdk/javax/swing/JFileChooser/ShowHiddenFiles.java new file mode 100644 index 0000000000000..ddca136755591 --- /dev/null +++ b/test/jdk/javax/swing/JFileChooser/ShowHiddenFiles.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeEvent; +import javax.swing.JComponent; +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; + +/* + * @test + * @bug 4835479 + * @requires (os.family == "windows") + * @summary JFileChooser should respect native setting for showing hidden files + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ShowHiddenFiles + */ + +public class ShowHiddenFiles +{ + private static final String INSTRUCTIONS = """ + This tests JFileChooser's ability to track the native setting for + displaying of hidden files. + This test has four parts. If any portion of any of the tests don't + behave as specified, press FAIL else press PASS. + Before beginning the tests, you'll want to find the Folder Options + dialog on your Windows platform. Open an Explorer window for c:/ + and select Tools->Folder Options. Under the View tab, locate + the option to show hidden files. You will need this for the tests. + + TEST 1: + This tests that JFileChooser tracks the native platform setting. + Configure windows to Show Hidden Files, and in an Explorer window + locate a hidden file that is now shown (there are usually hidden + files in c:/). + Click on the TEST 1 button to display a JFileChooser. + Confirm that the hidden files are shown in the JFileChooser. + On Windows 98, TEST 1 is now complete. + On Windows 2000 and later, configure Folder Options to hide hidden + files. Confirm that + (1) the files are hidden in the JFileChooser and + (2) "PropertyChangeEvent for FILE_HIDING_CHANGED_PROPERTY" + appears in the accessory text field. + Re-enable showing of hidden files and confirm that + (1) the hidden files are again shown and + (2) you get another PropertyChangeEvent. + Press "Cancel" button to close JFileChooser window. + + TEST 2: + This tests that JFileChooser.setFileHidingEnabled(true) overrides the + native platform setting. + Make sure Windows is configured to Show Hidden Files. + Click on the TEST 2 button. + Confirm that hidden files are NOT displayed in the JFileChooser. + Press "Cancel" button to close JFileChooser window. + + TEST 3: + This tests that JFileChooser.setFileHidingEnabled(false) overrides the + Make sure Windows is configured to NOT show hidden files. + Click on the TEST 3 button. + Confirm that hidden files ARE displayed in the JFileChooser. + Press "Cancel" button to close JFileChooser window. + + TEST 4: + This tests that calling setFileHidingEnabled() on a showing + JFileChooser will cause it to ignore further changes in the + native platform setting. + Click on the TEST 4 button. As in TEST 1, confirm that the + JFileChooser tracks the native setting. + Click on the "Show Hidden Files" button. + Confirm that hidden files remain visible, even when you change + the native setting. + Repeat the test for the "Hide Hidden Files" button. + Press "Cancel" button to close JFileChooser window. + """; + private static JButton test1, test2, test3, test4; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("JFileChooser Instructions") + .instructions(INSTRUCTIONS) + .rows(25) + .columns(50) + .splitUI(ShowHiddenFiles::createAndShowUI) + .build() + .awaitAndCheck(); + } + + public static JPanel createAndShowUI() { + test1 = new JButton("TEST 1: Track native setting"); + test2 = new JButton("TEST 2: setFileHidingEnabled(true)"); + test3 = new JButton("TEST 3: setFileHidingEnabled(false)"); + test4 = new JButton("TEST 4: setFileHidingEnabled() on showing JFC"); + + ButtonListener bl = new ButtonListener(); + test1.addActionListener(bl); + test2.addActionListener(bl); + test3.addActionListener(bl); + test4.addActionListener(bl); + + JPanel p = new JPanel(); + p.setLayout(new GridLayout(4,1)); + p.setSize(200, 200); + p.add(test1); + p.add(test2); + p.add(test3); + p.add(test4); + return p; + } + + private static class ButtonListener implements ActionListener { + public void actionPerformed(ActionEvent e) { + JFileChooser jfc = new JFileChooser("c:/"); + if (e.getSource() == test1) { + jfc.setAccessory(createTest1Acc(jfc)); + } + else if (e.getSource() == test2) { + jfc.setAccessory(null); + jfc.setFileHidingEnabled(true); + } + else if (e.getSource() == test3) { + jfc.setAccessory(null); + jfc.setFileHidingEnabled(false); + } + else if (e.getSource() == test4) { + jfc.setAccessory(createTest4Acc(jfc)); + } + else { + return; + } + jfc.showOpenDialog(new JFrame()); + } + } + + private static class JFCHideButton extends JButton implements ActionListener { + JFileChooser jfc; + boolean setVal; + + public JFCHideButton(String label, JFileChooser jfc, boolean setVal) { + super(label); + this.jfc = jfc; + this.setVal = setVal; + addActionListener(this); + } + public void actionPerformed(ActionEvent e) { + jfc.setFileHidingEnabled(setVal); + } + } + + private static JPanel createTest1Acc(JFileChooser jfc) { + JPanel jpl = new JPanel(); + jpl.add(createTAListener(jfc)); + return jpl; + } + + private static JPanel createTest4Acc(JFileChooser jfc) { + JPanel jpl = new JPanel(); + jpl.setLayout(new BorderLayout()); + + JPanel north = new JPanel(); + north.setLayout(new GridLayout(2,1)); + north.add(new JFCHideButton("Show Hidden Files", jfc, false)); + north.add(new JFCHideButton("Hide Hidden Files", jfc, true)); + jpl.add(BorderLayout.NORTH, north); + jpl.add(BorderLayout.CENTER, createTAListener(jfc)); + return jpl; + } + + private static JComponent createTAListener(JFileChooser jfc) { + final JTextArea jta = new JTextArea(10,20); + PropertyChangeListener pcl = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent e) { + jta.append("PropertyChangeEvent for FILE_HIDING_CHANGED_PROPERTY\n"); + } + }; + jfc.addPropertyChangeListener(JFileChooser.FILE_HIDING_CHANGED_PROPERTY, pcl); + JScrollPane jsp = new JScrollPane(jta); + return jsp; + } +} From 8505d6a80dec1c22d5f132f275de6317a42ee0f1 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 2 Apr 2025 09:55:38 +0000 Subject: [PATCH 109/846] 8339639: Opensource few AWT PopupMenu tests Backport-of: a0794e0a054c5e7ed051efa6362726cdd7598255 --- test/jdk/ProblemList.txt | 1 + .../jdk/java/awt/PopupMenu/PopupHangTest.java | 258 ++++++++++++++++++ .../java/awt/PopupMenu/PopupMenuVisuals.java | 101 +++++++ 3 files changed, 360 insertions(+) create mode 100644 test/jdk/java/awt/PopupMenu/PopupHangTest.java create mode 100644 test/jdk/java/awt/PopupMenu/PopupMenuVisuals.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index f2d42e4ef9634..296244fa13fd9 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -829,6 +829,7 @@ java/awt/Focus/AppletInitialFocusTest/AppletInitialFocusTest1.java 8256289 windo java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java 8258103 linux-all java/awt/Focus/FrameMinimizeTest/FrameMinimizeTest.java 8016266 linux-x64 java/awt/Frame/SizeMinimizedTest.java 8305915 linux-x64 +java/awt/PopupMenu/PopupHangTest.java 8340022 windows-all java/awt/dnd/WinMoveFileToShellTest.java 8341665 windows-all diff --git a/test/jdk/java/awt/PopupMenu/PopupHangTest.java b/test/jdk/java/awt/PopupMenu/PopupHangTest.java new file mode 100644 index 0000000000000..bfdf6bf2abe38 --- /dev/null +++ b/test/jdk/java/awt/PopupMenu/PopupHangTest.java @@ -0,0 +1,258 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4145193 + * @summary Mouse event activates multiple pull-down menus when testing Oracle app + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual PopupHangTest +*/ + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Label; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyListener; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + +public class PopupHangTest { + private static final String INSTRUCTIONS = """ + 2 areas yellow and red should be seen. + + Clicking in these areas should cause a menu to popup. See if you can + get the menu to stay up and grab all input. One way to do this is to + click and hold the mouse to popup the menu, move away/outside of the + menu and release the mouse. At that point, the input is grabbed and + the *only* way out is to hit the escape key. Try this on both areas. + + To make things worse, when the popup menu is up, click repeatedly on + the LightWeight component area. Hit escape. Do you see multiple menus appearing ? + + If you do not see either of the two problems above, the problem is fixed. + Press pass, else press Fail"""; + + static Frame frame; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("PopupHangTest") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(45) + .testUI(PopupHangTest::createUI) + .logArea() + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + TestMenuButton m1; + TestHeavyButton m2; + frame = new Frame(); + + frame.setLayout (new BorderLayout ()); + + m1 = new TestMenuButton("LightWeight component"); + m1.setBackground(Color.yellow); + + m2 = new TestHeavyButton("HeavyWeight component"); + m2.setBackground(Color.red); + + frame.add("North", m1); + frame.add("South", m2); + + m1.requestFocus(); + frame.setSize(200, 110); + return frame; + } + +} + +class TestMenuButton extends Component implements MouseListener, + MouseMotionListener, + KeyListener, + FocusListener { + + PopupMenu popupMenu = null; + String name; + + TestMenuButton(String name) { + PopupMenu menu = popupMenu = new PopupMenu("Popup"); + menu.add(new MenuItem("item 1")); + menu.add(new MenuItem("item 2")); + menu.add(new MenuItem("item 3")); + this.add(menu); + this.name = name; + addMouseListener(this); + addMouseMotionListener(this); + addKeyListener(this); + addFocusListener(this); + } + + void println(String messageIn) { + PassFailJFrame.log(messageIn); + } + + public void mouseClicked(MouseEvent event) { + /* + popupMenu.show(this, event.getX(), event.getY()); + */ + } + public void mousePressed(MouseEvent event) { + println("TestMenuButton.mousePressed() called !!"); + popupMenu.show(this, event.getX(), event.getY()); + } + public void mouseReleased(MouseEvent event) { + println("TestMenuButton.mouseReleased() called !!"); + } + public void mouseEntered(MouseEvent event) { + println("TestMenuButton.mouseEntered() called !!"); + requestFocus(); + } + public void mouseExited(MouseEvent event) { + } + + public void mouseDragged(MouseEvent event) { + println("TestMenuButton.mouseDragged() called !!"); + } + public void mouseMoved(MouseEvent event) { + println("TestMenuButton.mouseMoved() called !!"); + } + + public void keyPressed(KeyEvent event) { + println("TestMenuButton.keyPressed() called !!"); + } + public void keyReleased(KeyEvent event) { + println("TestMenuButton.keyReleased() called !!"); + } + public void keyTyped(KeyEvent event) { + println("TestMenuButton.keyTyped() called !!"); + } + + + public void focusGained(FocusEvent e){ + println("TestMenuButton.focusGained():" + e); + } + public void focusLost(FocusEvent e){ + println("TestMenuButton.focusLost():" + e); + } + + + public void paint(Graphics g) { + Dimension d = getSize(); + + g.setColor(getBackground()); + g.fillRect(0, 0, d.width-1, d.height-1); + + g.setColor(Color.black); + g.drawString(name, 15, 15); + } + + public Dimension getPreferredSize() { + return (new Dimension(200, 50)); + } + +} + +class TestHeavyButton extends Label implements MouseListener, + MouseMotionListener, + KeyListener, + FocusListener { + + PopupMenu popupMenu = null; + String name; + + TestHeavyButton(String name) { + super(name); + PopupMenu menu = popupMenu = new PopupMenu("Popup"); + menu.add(new MenuItem("item 1")); + menu.add(new MenuItem("item 2")); + menu.add(new MenuItem("item 3")); + this.add(menu); + this.name = name; + addMouseListener(this); + addMouseMotionListener(this); + addKeyListener(this); + addFocusListener(this); + } + + void println(String messageIn) { + PassFailJFrame.log(messageIn); + } + + public void mouseClicked(MouseEvent event) { + /* + popupMenu.show(this, event.getX(), event.getY()); + */ + } + public void mousePressed(MouseEvent event) { + println("TestHeavyButton.mousePressed() called !!"); + popupMenu.show(this, event.getX(), event.getY()); + } + public void mouseReleased(MouseEvent event) { + println("TestHeavyButton.mouseReleased() called !!"); + } + public void mouseEntered(MouseEvent event) { + println("TestHeavyButton.mouseEntered() called !!"); + requestFocus(); + } + public void mouseExited(MouseEvent event) { + } + + public void mouseDragged(MouseEvent event) { + println("TestHeavyButton.mouseDragged() called !!"); + } + public void mouseMoved(MouseEvent event) { + println("TestHeavyButton.mouseMoved() called !!"); + } + + public void keyPressed(KeyEvent event) { + println("TestHeavyButton.keyPressed() called !!"); + } + public void keyReleased(KeyEvent event) { + println("TestHeavyButton.keyReleased() called !!"); + } + public void keyTyped(KeyEvent event) { + println("TestHeavyButton.keyTyped() called !!"); + } + + public void focusGained(FocusEvent e){ + println("TestHeavyButton.focusGained():" + e); + } + public void focusLost(FocusEvent e){ + println("TestHeavyButton.focusLost():" + e); + } + +} + diff --git a/test/jdk/java/awt/PopupMenu/PopupMenuVisuals.java b/test/jdk/java/awt/PopupMenu/PopupMenuVisuals.java new file mode 100644 index 0000000000000..3aa437e484540 --- /dev/null +++ b/test/jdk/java/awt/PopupMenu/PopupMenuVisuals.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6180413 6184485 6267144 + * @summary test for popup menu visual bugs in XAWT + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual PopupMenuVisuals +*/ + +import java.awt.Button; +import java.awt.CheckboxMenuItem; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.MenuShortcut; +import java.awt.PopupMenu; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; + +public class PopupMenuVisuals { + private static final String INSTRUCTIONS = """ + This test should show a button 'Popup'. + Click on the button. A popup menu should be shown. + If following conditions are met: + - Menu is disabled + - Menu has caption 'Popup menu' (only applicable for linux) + - Menu items don't show shortcuts + + Click Pass else click Fail."""; + + static PopupMenu pm; + static Frame frame; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("PopupMenu Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(PopupMenuVisuals::createTestUI) + .build() + .awaitAndCheck(); + } + + static class Listener implements ActionListener { + public void actionPerformed(ActionEvent e) { + pm.show(frame, 0, 0); + } + } + + private static Frame createTestUI() { + Button b = new Button("Popup"); + pm = new PopupMenu("Popup menu"); + MenuItem mi1 = new MenuItem("Item 1"); + CheckboxMenuItem mi2 = new CheckboxMenuItem("Item 2"); + CheckboxMenuItem mi3 = new CheckboxMenuItem("Item 3"); + Menu sm = new Menu("Submenu"); + + //Get things going. Request focus, set size, et cetera + frame = new Frame("PopupMenuVisuals"); + frame.setSize (200,200); + frame.validate(); + + frame.add(b); + b.addActionListener(new Listener()); + mi1.setShortcut(new MenuShortcut(KeyEvent.VK_A)); + pm.add(mi1); + pm.add(mi2); + pm.add(mi3); + pm.add(sm); + sm.add(new MenuItem("Item")); + pm.setEnabled(false); + mi3.setState(true); + frame.add(pm); + return frame; + } + +} From 50fef47007f763ef6a8bf1f1e23322c10ecc28e4 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 2 Apr 2025 09:58:11 +0000 Subject: [PATCH 110/846] 8339895: Open source several AWT focus tests - series 3 Backport-of: 94c33179b6a1205100d7c125f3a7c11e29621db9 --- test/jdk/ProblemList.txt | 1 + .../jdk/java/awt/Focus/ActivateFocusTest.java | 148 ++++++++++++ .../Focus/CanvasPanelFocusOnClickTest.java | 212 ++++++++++++++++++ test/jdk/java/awt/Focus/FocusPolicyTest.java | 177 +++++++++++++++ .../awt/Focus/RequestInInactiveFrame.java | 106 +++++++++ 5 files changed, 644 insertions(+) create mode 100644 test/jdk/java/awt/Focus/ActivateFocusTest.java create mode 100644 test/jdk/java/awt/Focus/CanvasPanelFocusOnClickTest.java create mode 100644 test/jdk/java/awt/Focus/FocusPolicyTest.java create mode 100644 test/jdk/java/awt/Focus/RequestInInactiveFrame.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 296244fa13fd9..fe34cc1935cf5 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -140,6 +140,7 @@ java/awt/Focus/WrongKeyTypedConsumedTest/WrongKeyTypedConsumedTest.java 8169096 java/awt/Focus/TestDisabledAutoTransfer.java 8159871 macosx-all,windows-all java/awt/Focus/TestDisabledAutoTransferSwing.java 6962362 windows-all java/awt/Focus/ActivateOnProperAppContextTest.java 8136516 macosx-all +java/awt/Focus/FocusPolicyTest.java 7160904 linux-all java/awt/event/KeyEvent/CorrectTime/CorrectTime.java 6626492 generic-all java/awt/EventQueue/6980209/bug6980209.java 8198615 macosx-all java/awt/EventQueue/PushPopDeadlock/PushPopDeadlock.java 8024034 generic-all diff --git a/test/jdk/java/awt/Focus/ActivateFocusTest.java b/test/jdk/java/awt/Focus/ActivateFocusTest.java new file mode 100644 index 0000000000000..09f5bbb172ca8 --- /dev/null +++ b/test/jdk/java/awt/Focus/ActivateFocusTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4369903 + * @summary Focus on window activation does not work correctly + * @key headful + * @run main ActivateFocusTest + */ + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Toolkit; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class ActivateFocusTest { + + public static void main(final String[] args) { + ActivateFocusTest app = new ActivateFocusTest(); + app.doTest(); + } + + public void doTest() { + ActivateFocus[] af = new ActivateFocus[2]; + boolean testFailed = false; + Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize(); + for (int i = 0; i < 2; i++) { + af[i] = new ActivateFocus(i); + af[i].setLocation(i * 160 + scrSize.width / 2, scrSize.height / 2); + af[i].setVisible(true); + } + try { + Thread.sleep(5000); + } catch (InterruptedException ie) { + throw new RuntimeException("TEST FAILED - thread was interrupted"); + } + for (int i = 0; i < 2; i++) { + testFailed = (af[i].lw.focusCounter > 1); + } + if (testFailed) { + throw new RuntimeException("TEST FAILED - focus is gained more than one time"); + } else { + System.out.println("TEST PASSED"); + } + } + + } + +class ActivateFocus extends Frame { + + public LightWeight lw = null; + int num; + + public String toString() { + return ("Window " + num); + } + + public ActivateFocus(int i) { + setTitle("Window " + i); + lw = new LightWeight(i); + num=i; + addWindowListener(new WindowAdapter() { + public void windowActivated(WindowEvent e) { + if(lw != null) { + lw.requestFocus(); + } + } + }); + add(lw); + pack(); + } + + // A very simple lightweight component + class LightWeight extends Component implements FocusListener { + + boolean focused = false; + int num; + public int focusCounter = 0; + + public LightWeight(int num) { + this.num = num; + addFocusListener(this); + } + + public void paint(Graphics g) { + Dimension size = getSize(); + int w = size.width; + int h = size.height; + g.setColor(getBackground()); + g.fillRect(0, 0, w, h); + g.setColor(Color.black); + g.drawOval(0, 0, w-1, h-1); + if (focused) { + g.drawLine(w/2, 0, w/2, h); + g.drawLine(0, h/2, w, h/2); + } + + } + + public Dimension getPreferredSize() { + return new Dimension(150, 150); + } + + public void focusGained(FocusEvent e) { + focused = true; + focusCounter++; + System.out.println("focusGained on " + e.getComponent()); + repaint(); + } + + public void focusLost(FocusEvent e) { + focused = false; + System.out.println("focusLost on " + e.getComponent()); + repaint(); + } + + public String toString() { + return ("Component " + num); + } + } +} diff --git a/test/jdk/java/awt/Focus/CanvasPanelFocusOnClickTest.java b/test/jdk/java/awt/Focus/CanvasPanelFocusOnClickTest.java new file mode 100644 index 0000000000000..8df21ba0f0a67 --- /dev/null +++ b/test/jdk/java/awt/Focus/CanvasPanelFocusOnClickTest.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4041703 4096228 4032657 4066152 4149866 4025223 + * @summary Ensures that an Panel/Canvas without heavyweight children + receives focus on mouse click + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual CanvasPanelFocusOnClickTest + */ + +import java.awt.Button; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Component; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +public class CanvasPanelFocusOnClickTest { + + private static final String INSTRUCTIONS = """ + + Click on the red Canvas. Verify that it has focus by key pressing. + Click on the yellow Panel. Verify that it has focus by key pressing. + Click on the blue heavyweight Panel (NOT ON THE BUTTON!). + Verify that it doesn't have focus by key pressing. + If two empty containers are able to the get focus by a mouse click + and the container with heavyweight children are unable to get + the focus by a mouse click which can be verified through messages in message dialog + the test passes."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("CanvasPanelFocusOnClickTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(40) + .testUI(CanvasPanelFocusOnClickTest::createTestUI) + .logArea() + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Canvas canvas = new Canvas();; + Panel emptyPanel = new Panel(); + Panel panel = new Panel(); + Button buttonInPanel = new Button("BUTTON ON PANEL"); + + Frame frame = new Frame("CanvasPanelFocusOnClickTest Frame"); + frame.setLayout(new GridLayout(3, 1)); + canvas.setBackground(Color.red); + canvas.setName("RED CANVAS"); + canvas.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + println(e.toString()); + } + public void focusLost(FocusEvent e) { + println(e.toString()); + } + }); + canvas.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + printKey(e); + } + + public void keyTyped(KeyEvent e) { + printKey(e); + } + + public void keyReleased(KeyEvent e) { + printKey(e); + } + }); + frame.add(canvas); + + emptyPanel.setBackground(Color.yellow); + emptyPanel.setName("YELLOW PANEL"); + emptyPanel.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + println(e.toString()); + } + public void focusLost(FocusEvent e) { + println(e.toString()); + } + }); + emptyPanel.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + printKey(e); + } + + public void keyTyped(KeyEvent e) { + printKey(e); + } + + public void keyReleased(KeyEvent e) { + printKey(e); + } + }); + frame.add(emptyPanel); + + panel.setBackground(Color.blue); + panel.setName("BLUE PANEL"); + buttonInPanel.setName("BUTTON ON PANEL"); + buttonInPanel.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + println(e.toString()); + } + public void focusLost(FocusEvent e) { + println(e.toString()); + } + }); + buttonInPanel.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + printKey(e); + } + + public void keyTyped(KeyEvent e) { + printKey(e); + } + + public void keyReleased(KeyEvent e) { + printKey(e); + } + }); + panel.add(buttonInPanel); + panel.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + println(e.toString()); + } + public void focusLost(FocusEvent e) { + println(e.toString()); + } + }); + panel.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + printKey(e); + } + + public void keyTyped(KeyEvent e) { + printKey(e); + } + + public void keyReleased(KeyEvent e) { + printKey(e); + } + }); + frame.add(panel); + + frame.setSize(200, 200); + + return frame; + + } + + static void printKey(KeyEvent e) { + String typeStr; + switch(e.getID()) { + case KeyEvent.KEY_PRESSED: + typeStr = "KEY_PRESSED"; + break; + case KeyEvent.KEY_RELEASED: + typeStr = "KEY_RELEASED"; + break; + case KeyEvent.KEY_TYPED: + typeStr = "KEY_TYPED"; + break; + default: + typeStr = "unknown type"; + } + + Object source = e.getSource(); + if (source instanceof Component) { + typeStr += " on " + ((Component)source).getName(); + } else { + typeStr += " on " + source; + } + + println(typeStr); + } + + static void println(String messageIn) { + PassFailJFrame.log(messageIn); + } +} diff --git a/test/jdk/java/awt/Focus/FocusPolicyTest.java b/test/jdk/java/awt/Focus/FocusPolicyTest.java new file mode 100644 index 0000000000000..3ec362acaf085 --- /dev/null +++ b/test/jdk/java/awt/Focus/FocusPolicyTest.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4897459 + * @key headful + * @summary The key does not switches focus in the internal frames in Swing apps. + * @run main FocusPolicyTest + */ + +import java.awt.Container; +import java.awt.Component; +import java.awt.DefaultFocusTraversalPolicy; +import java.awt.Dialog; +import java.awt.FocusTraversalPolicy; +import java.awt.Frame; +import java.awt.KeyboardFocusManager; +import java.awt.Toolkit; +import java.awt.Window; +import javax.swing.JDialog; +import javax.swing.JInternalFrame; +import javax.swing.JFrame; +import javax.swing.JWindow; +import javax.swing.LayoutFocusTraversalPolicy; + +public class FocusPolicyTest { + static int stageNum; + static FocusTraversalPolicy customPolicy = new CustomPolicy(); + final static Class awtDefaultPolicy = DefaultFocusTraversalPolicy.class; + final static Class swingDefaultPolicy = LayoutFocusTraversalPolicy.class; + + public static void main(String[] args) { + final boolean isXawt = "sun.awt.X11.XToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName()); + + System.err.println("isXawt = " + isXawt); + + // 1. Check default policy + if (KeyboardFocusManager.getCurrentKeyboardFocusManager(). + getDefaultFocusTraversalPolicy().getClass() != awtDefaultPolicy) { + throw new RuntimeException("Error: stage 1: default policy is not DefaultFocusTraversalPolicy"); + } + + // 2. Check AWT top-levels policies + stageNum = 2; + checkAWTPoliciesFor(awtDefaultPolicy); + + // 3. Check Swing top-levels policies + stageNum = 3; + checkSwingPoliciesFor(swingDefaultPolicy); + + // 4. Check default policy if not XToolkit + if (!isXawt) { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager(). + getDefaultFocusTraversalPolicy().getClass() != swingDefaultPolicy) { + throw new RuntimeException("Error: stage 4: default policy is not LayoutFocusTraversalPolicy"); + } + } + + // 5. Check AWT top-levels policies + // this is a bug in XAWT we should change the test as soon as + // we will be able to fix this bug. + stageNum = 5; + Class defaultPolicy = swingDefaultPolicy; + if (isXawt) { + defaultPolicy = awtDefaultPolicy; + } + checkAWTPoliciesFor(defaultPolicy); + + // Set custom policy as default + KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalPolicy(customPolicy); + + // 6. Check AWT top-levels policies for custom + stageNum = 6; + checkAWTPoliciesFor(customPolicy.getClass()); + + // 7. Check Swing top-levels policies for custom + stageNum = 7; + checkSwingPoliciesFor(customPolicy.getClass()); + + return; + } + + public static void checkAWTPoliciesFor(Class expectedPolicyClass) { + Window[] tlvs = new Window[7]; + + tlvs[0] = new Frame(""); + tlvs[1] = new Frame("", tlvs[0].getGraphicsConfiguration()); + tlvs[2] = new Window((Frame)tlvs[0]); + tlvs[3] = new Dialog((Frame)tlvs[0], "", false); + tlvs[4] = new Dialog((Frame)tlvs[0], "", false, tlvs[0].getGraphicsConfiguration()); + tlvs[5] = new Dialog((Dialog)tlvs[3], "", false); + tlvs[6] = new Dialog((Dialog)tlvs[3], "", false, tlvs[0].getGraphicsConfiguration()); + + for (int i = 0; i < 7; i++) { + Class policyClass = tlvs[i].getFocusTraversalPolicy().getClass(); + if (policyClass != expectedPolicyClass) { + throw new RuntimeException("Error: stage " + stageNum + ": " + + tlvs[i].getClass().getName() + + "'s policy is " + policyClass.getName() + + " but not " + expectedPolicyClass.getName()); + } + } + } + + public static void checkSwingPoliciesFor(Class expectedPolicyClass) { + Container[] tlvs = new Container[12]; + + tlvs[0] = new JFrame(); + tlvs[1] = new JFrame(tlvs[0].getGraphicsConfiguration()); + tlvs[2] = new JFrame(""); + tlvs[3] = new JFrame("", tlvs[0].getGraphicsConfiguration()); + tlvs[4] = new JWindow((Frame)tlvs[0]); + tlvs[5] = new JWindow((Window)tlvs[4]); + tlvs[6] = new JWindow((Window)tlvs[4], tlvs[0].getGraphicsConfiguration()); + tlvs[7] = new JDialog((Frame)tlvs[0], "", false); + tlvs[8] = new JDialog((Frame)tlvs[0], "", false, tlvs[0].getGraphicsConfiguration()); + tlvs[9] = new JDialog((Dialog)tlvs[7], "", false); + tlvs[10] = new JDialog((Dialog)tlvs[7], "", false, tlvs[0].getGraphicsConfiguration()); + tlvs[11] = new JInternalFrame("", false, false, false, false); + + for (int i = 0; i < tlvs.length; i++) { + Class policyClass = tlvs[i].getFocusTraversalPolicy().getClass(); + if (policyClass != expectedPolicyClass) { + throw new RuntimeException("Error: stage " + stageNum + + ": " + tlvs[i].getClass().getName() + + "'s policy is " + policyClass.getName() + " but not " + + expectedPolicyClass.getName()); + } + } + } + + // Dummy policy. + static class CustomPolicy extends FocusTraversalPolicy { + public Component getComponentAfter(Container focusCycleRoot, + Component aComponent) { + return null; + } + + public Component getComponentBefore(Container focusCycleRoot, + Component aComponent) { + return null; + } + + public Component getFirstComponent(Container focusCycleRoot) { + return null; + } + + public Component getLastComponent(Container focusCycleRoot) { + return null; + } + + public Component getDefaultComponent(Container focusCycleRoot) { + return null; + } + } +} diff --git a/test/jdk/java/awt/Focus/RequestInInactiveFrame.java b/test/jdk/java/awt/Focus/RequestInInactiveFrame.java new file mode 100644 index 0000000000000..3297fe17501a1 --- /dev/null +++ b/test/jdk/java/awt/Focus/RequestInInactiveFrame.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6458497 + * @summary check focus requests in inactive frames + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual RequestInInactiveFrame + */ + +import java.util.ArrayList; + +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.Window; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class RequestInInactiveFrame { + + private static final String INSTRUCTIONS = """ + After the tests starts you will see two frames: \"test frame\" and \"opposite frame\" + activate the former by click on its title + Focus should be on \"press me\" button (if it's not, the test fails) + press on \"press me\" button and activate \"opposite frame\" + wait for several seconds. + Focus should either remain on button in the \"opposite frame\" + or goes to \"focus target\" button (in this case \"test frame\" should be activated + if it's not, the test failed. + Activate \"test frame\" one more time, press on \"press me\" button and switch focus + to some native window. Wait for several seconds, + If you see focus border around + \"focus target\" and \"test frame\" is not active then the test failed. + if focus transfered to that button and the frame is activated, or if there is no focus + in java - tests passed."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("RequestInInactiveFrame Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(40) + .testUI(RequestInInactiveFrame::createTestUI) + .build() + .awaitAndCheck(); + } + + private static ArrayList createTestUI() { + JFrame frame = new JFrame("test frame"); + final JButton btn2 = new JButton("focus target"); + JButton btn1 = new JButton("press me"); + btn1.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + System.out.println("waiting..."); + try { + Thread.sleep(3000); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + System.out.println("requesting focus"); + btn2.requestFocus(); + } + }); + frame.setLayout(new FlowLayout()); + frame.add(btn1); + frame.add(btn2); + frame.pack(); + frame.setLocation(200, 100); + + JFrame frame2 = new JFrame("opposite frame"); + JButton btn3 = new JButton("just a button"); + frame2.add(btn3); + frame2.pack(); + frame2.setLocation(200, 200); + + ArrayList list = new ArrayList<>(); + list.add(frame); + list.add(frame2); + return list; + } + +} From 9d639ca22488652df7bd9835dd6c556f3f041bd3 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 2 Apr 2025 10:01:24 +0000 Subject: [PATCH 111/846] 8340367: Opensource few AWT image tests Backport-of: 6c91a16f16cbeb1bb0a79459e7db1fd9f576e743 --- .../image/BufferedImage/GrayAATextTest.java | 104 +++++++++++ test/jdk/java/awt/image/GrayAlpha.java | 175 ++++++++++++++++++ test/jdk/java/awt/image/ImageOffsetTest.java | 123 ++++++++++++ test/jdk/java/awt/image/TransformImage.java | 111 +++++++++++ test/jdk/java/awt/image/duke.gif | Bin 0 -> 1929 bytes 5 files changed, 513 insertions(+) create mode 100644 test/jdk/java/awt/image/BufferedImage/GrayAATextTest.java create mode 100644 test/jdk/java/awt/image/GrayAlpha.java create mode 100644 test/jdk/java/awt/image/ImageOffsetTest.java create mode 100644 test/jdk/java/awt/image/TransformImage.java create mode 100644 test/jdk/java/awt/image/duke.gif diff --git a/test/jdk/java/awt/image/BufferedImage/GrayAATextTest.java b/test/jdk/java/awt/image/BufferedImage/GrayAATextTest.java new file mode 100644 index 0000000000000..a484dd392eb03 --- /dev/null +++ b/test/jdk/java/awt/image/BufferedImage/GrayAATextTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4309915 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Check that Antialiased text drawn on a BYTE_GRAY image + * resolves the color correctly + * @run main/manual GrayAATextTest + */ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Panel; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; + +public class GrayAATextTest extends Panel { + + public static final int WIDTH = 600; + public static final int HEIGHT = 200; + + private static final String INSTRUCTIONS = """ + All of the strings in a given column should be drawn + in the same color. If the bug is present, then the + Antialiased strings will all be of a fixed color that + is not the same as the other strings in their column."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("GrayAATextTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int)INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(GrayAATextTest::createTestUI) + .build() + .awaitAndCheck(); + } + + public void paint(Graphics g) { + BufferedImage bi = new BufferedImage(WIDTH, HEIGHT, + BufferedImage.TYPE_BYTE_GRAY); + Graphics2D g2d = bi.createGraphics(); + g2d.setFont(new Font("Helvetica", Font.PLAIN, 24)); + g2d.setColor(Color.white); + g2d.fillRect(0, 0, WIDTH / 2, HEIGHT); + drawText(g2d, Color.black, "Black", 25); + drawText(g2d, Color.lightGray, "Light Gray", 175); + g2d.setColor(Color.black); + g2d.fillRect(WIDTH / 2, 0, WIDTH / 2, HEIGHT); + drawText(g2d, Color.white, "White", 325); + drawText(g2d, Color.lightGray, "Light Gray", 475); + g2d.dispose(); + g.drawImage(bi, 0, 0, null); + } + + public void drawText(Graphics2D g2d, Color c, String colorname, int x) { + g2d.setColor(c); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_OFF); + g2d.drawString(colorname, x, 50); + g2d.drawString("Aliased", x, 100); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g2d.drawString("Antialiased", x, 150); + } + + public Dimension getPreferredSize() { + return new Dimension(WIDTH, HEIGHT); + } + + private static Frame createTestUI() { + Frame f = new Frame("GrayAATextTest Frame"); + f.add(new GrayAATextTest()); + f.setSize(WIDTH, HEIGHT); + return f; + } +} diff --git a/test/jdk/java/awt/image/GrayAlpha.java b/test/jdk/java/awt/image/GrayAlpha.java new file mode 100644 index 0000000000000..cf477c2638503 --- /dev/null +++ b/test/jdk/java/awt/image/GrayAlpha.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4243044 + * @summary This test should show two windows filled with checker + * board pattern. The transparency should runs from left to right from + * total transparent to total opaque. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual GrayAlpha + */ + +import java.util.List; +import java.awt.Frame; +import java.awt.color.ColorSpace; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.ComponentColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.awt.Point; +import java.awt.Panel; +import java.awt.Transparency; +import java.awt.Window; + +public class GrayAlpha extends Panel { + + private static final String INSTRUCTIONS = """ + This test should show two windows filled with checker board + vpattern. The transparency should runs from left to right from + totally transparent to totally opaque. If either the pattern or + the transparency is not shown correctly, click Fail, otherwise + click Pass."""; + + BufferedImage bi; + AffineTransform identityTransform = new AffineTransform(); + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("GrayAlpha Instructions") + .instructions(INSTRUCTIONS) + .rows((int)INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(GrayAlpha::createTestUI) + .build() + .awaitAndCheck(); + } + + + public GrayAlpha(int width, int height, + boolean hasAlpha, boolean isAlphaPremultiplied, + boolean useRGB) { + boolean isAlphaPremuliplied = true; + int bands = useRGB ? 3 : 1; + bands = hasAlpha ? bands + 1 : bands; + + ColorSpace cs = useRGB ? + ColorSpace.getInstance(ColorSpace.CS_sRGB) : + ColorSpace.getInstance(ColorSpace.CS_GRAY); + int transparency = hasAlpha ? + Transparency.TRANSLUCENT : Transparency.OPAQUE; + int[] bits = new int[bands]; + for (int i = 0; i < bands; i++) { + bits[i] = 8; + } + + ColorModel cm = new ComponentColorModel(cs, + bits, + hasAlpha, + isAlphaPremultiplied, + transparency, + DataBuffer.TYPE_BYTE); + WritableRaster wr = + Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, + width, height, bands, + new Point(0, 0)); + + for (int b = 0; b < bands; b++) { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int s; + + if (b != bands - 1 || !hasAlpha) { + // Gray band(s), fill with a checkerboard pattern + if (((x / 10) % 2) == ((y / 10) % 2)) { + s = 255; + } else { + s = 0; + } + if (isAlphaPremultiplied) { + int alpha = (x*255)/(width - 1); + s = (s*alpha)/255; + } + } else { + // Alpha band, increase opacity left to right + s = (x*255)/(width - 1); + } + + wr.setSample(x, y, b, s); + } + } + } + + this.bi = new BufferedImage(cm, wr, isAlphaPremultiplied, null); + } + + public Dimension getPreferredSize() { + return new Dimension(bi.getWidth(), bi.getHeight()); + } + + public void paint(Graphics g) { + if (bi != null) { + ((Graphics2D)g).drawImage(bi, 0, 0, null); + } + } + + public static Frame makeFrame(String title, + int x, int y, int width, int height, + boolean hasAlpha, + boolean isAlphaPremultiplied, + boolean useRGB) { + Frame f = new Frame(title); + f.add(new GrayAlpha(width, height, + hasAlpha, isAlphaPremultiplied, useRGB)); + f.pack(); + f.setLocation(x, y); + return f; + } + + private static List createTestUI() { + int width = 200; + int height = 200; + + int x = 100; + int y = 100; + + Frame f1 = makeFrame("Gray (non-premultiplied)", + x, y, width, height, + true, false, false); + x += width + 20; + + Frame f2 = makeFrame("Gray (premultiplied)", + x, y, width, height, + true, true, false); + + return List.of(f1, f2); + } +} diff --git a/test/jdk/java/awt/image/ImageOffsetTest.java b/test/jdk/java/awt/image/ImageOffsetTest.java new file mode 100644 index 0000000000000..c1d4c3931de91 --- /dev/null +++ b/test/jdk/java/awt/image/ImageOffsetTest.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4259548 + * @summary tests that MemoryImageSource correctly handles images with offsets + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ImageOffsetTest + */ + +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Panel; +import java.awt.Toolkit; +import java.awt.image.ColorModel; +import java.awt.image.IndexColorModel; +import java.awt.image.MemoryImageSource; + +public class ImageOffsetTest { + + static int height = 100; + static int width = 100; + static int levels = 3; + static IndexColorModel cm; + static Image image; + static boolean first = true; + + static byte[] db = new byte[height * width * levels] ; + + private static final String INSTRUCTIONS = """ + If on the appeared 'Test frame' all color squares are of one color + test failed, otherwise it's passed."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("ImageOffsetTest") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(ImageOffsetTest::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + Frame frame = new Frame("ImageOffset Frame"); + frame.add(new Panel() { + public void paint(Graphics g) { + for ( int i=0 ; i<3 ; i++ ) { + g.drawImage( + generateBuggyImage(i * width * height), 10 + i * 110, 10, null); + } + } + }); + frame.setSize(400, 200); + frame.setLocation(300, 200); + createColorModel(); + int l = 0; + for (int k = 0; k < levels; k++) { + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + if( k == 0) { + db[l] = (byte)(70 & 0xff) ; + } + if (k == 1) { + db[l] = (byte)(150 & 0xff) ; + } + if (k == 2) { + db[l] = (byte)(230 & 0xff) ; + } + l++ ; + } + } + } + return frame; + } + + private static void createColorModel() { + byte[] red = new byte[256]; + byte[] green = new byte[256]; + byte[] blue = new byte[256]; + + for (int i = 0; i < 256; i++) { + red[i] = (byte)(i & 0xff); + //green[i] = (byte)( i & 0xff ) ; + blue[i] = (byte)( i & 0xff ) ; + //commented out green so I could get purple + } + + cm = new IndexColorModel( 8, 256, red, green, blue ) ; + } + + private static Image generateBuggyImage(int offset) { + // Initialize the database, Three slices, different shades of grey + // Here the image is created using the offset, + return Toolkit.getDefaultToolkit().createImage( + new MemoryImageSource(width, height, (ColorModel)cm, + db, offset, width)); + } +} diff --git a/test/jdk/java/awt/image/TransformImage.java b/test/jdk/java/awt/image/TransformImage.java new file mode 100644 index 0000000000000..30af3d27f55c0 --- /dev/null +++ b/test/jdk/java/awt/image/TransformImage.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4090743 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Make sure that there is no garbage drawn on the rotated image + * @run main/manual TransformImage + */ + +import java.net.URL; +import java.net.MalformedURLException; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.Image; +import java.awt.image.ImageObserver; +import java.awt.MediaTracker; +import java.awt.Toolkit; + +public class TransformImage extends Canvas { + static Image image; + + private static final String INSTRUCTIONS = """ + The rotated image should be drawn without garbage."""; + + public static void main(String[] argv) throws Exception { + PassFailJFrame.builder() + .title("TransformImage Instructions") + .instructions(INSTRUCTIONS) + .rows(5) + .columns(35) + .testUI(TransformImage::createTestUI) + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Frame f = new Frame(); + String dir = System.getProperty("test.src"); + String sep = System.getProperty("file.separator"); + if (dir == null) { + dir = "."; + } + image = Toolkit.getDefaultToolkit().getImage(dir+sep+"duke.gif"); + f.add(new TransformImage()); + + f.pack(); + return f; + } + + public Dimension getPreferredSize() { + return new Dimension (256, 256); + } + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + public void paint(Graphics g) { + int w, h; + java.awt.Graphics2D g2d = (Graphics2D) g; + AffineTransform at = new AffineTransform(); + + MediaTracker mt = new MediaTracker(this); + mt.addImage(image, 0); + try { + mt.waitForAll(); + } catch (InterruptedException e) { + System.err.println("can't track"); + return; + } + w = image.getWidth(this); + h = image.getHeight(this); + g2d.drawImage(image, 0, 0, this); + g2d.drawRect(0, 0, w, h); + + double rad = .5; + at.rotate(-rad); + g2d.setTransform(at); + g2d.drawImage(image, 0, 100, this); + g2d.drawRect(0, 100, w, h); + } +} diff --git a/test/jdk/java/awt/image/duke.gif b/test/jdk/java/awt/image/duke.gif new file mode 100644 index 0000000000000000000000000000000000000000..ed32e0ff79b05c07b82863ce6fb07fa9898adaa2 GIT binary patch literal 1929 zcmWlYe^AtB8pi`HvM4_?{J2I$8$dLc1#@!R2zwgXMWdj^k;9xr+bDW&4{JlE8WpDj z7F-cwwK{H<)?L&#SJz$!;hJ{%BY2FYf)Wp^xl?aq!5Xcdi$c#hV~>m9_n-Hl=Xsy+ z=li^?*Q~;pZ+R1N1J40KRkeWM7ew3~jLM24A{CM-A}~TzqzYpq&od0GC=z71!w_=b z-==B0rt2t*nA}((5YSLs6a*Z@X__WqiSjTW6oLo{5km&|K1mGAimYjhs#wwZtvV8SV~7LCFpgub+-TTAk%UQb0dE_cj+pc?!+0o?qG$?% zVFD)%!w7Z;g)ndE8Uk6Aky=+kLaUQ{UW`XS?Nn*s@SQ{VmFgGdkV{&&98EcEQ5hjc@H$`e)fX zj@&GdchxpMUo|-A^M4iBP3(#Ib53Ap?5{nGT7SBA_V!o!TTzL5R~FUWe)4X?@iTd8 z1;TcF^rQLj?4p0uy?@ikb2eUSXdHVa_jIn=@W%a<6~57D>am6&Z!{lzc=@ZbuGB8` zpU38H8d~@82Da!+qdYG5ls&Cx?~|oPMnbqTHMw%I*KlV~?fc{rSwe29?Om}fsknG# z@n5IwY=4Mx>>0WJLG>=yJX^WbHA30iQ$H!X)3<4K zBe1|sf3NKKTS;)mg{$k(2eDJG^u5=&x{@M!V>EWgzRA((>}?o{WQBehp1mIHU!BGG zYz5_6B(+KIVdCVoum2ItM&gXZd+SB^vQTN=a zeYbbah=i-xCho2{4Pazv_i%2mH`EkM{r8XYDLbdY@(a7Ud}$%!$QrTN_DqwNXA9~g zTGKxKyfto7NDp;5A3O5zgb(hyxjN@OAG!(zy^*Ug4!yjF=Y*8aHA@ovB1({&a4;sR zTf1CVC{>Pgy`m$lG;P1$pC_6F7u%iP+qz0q4{lXT`i9g-ThiYgO^GXC`f?JNo*|@p zr{b%U-tSKw99q0|YJa9{Va?`H{IaNICo>p5lGEY*+IDR4bfIUwq~CTRuC_mGWA%~W zea{@eKJ(Iq^7MvdsPsR%&vt$@4i&s?bPptz#y#!FcRZEaMS0WFTyXMCUEfsNxnJ_9 zPwpt`Er4O>``2G{7=4r1GCSTO8#0xw+{<^L4X(K8y1wKj72KLrYD}Y7SJuY7y==wf z;UkI5?(v?h+4r;vR{P*U`ul~=D@U7K5$eV8c!%rX-38vE>azU80UrhFXCv#d`(ylZS4+i2a^vI91MTIxCx%9gd2&N&D9RC&xcpx8#f=GZv%9;F z#?CEVT%UV$nk;L%RJA+d=f8ZB@U*Xz-TZbG?HKKT(VJZMBH!)$#qRuwbFc%Aljqha zoNBs8od~V$_^vux0ZSk!iP!hI($t35SxY8`FV{pxCjpU}Ova2VIg1&>V)CvvMb_ Date: Wed, 2 Apr 2025 10:04:04 +0000 Subject: [PATCH 112/846] 8340143: Open source several Java2D rendering loop tests. Backport-of: 90c2c0b4ad4ee7d2ea149aea771cf81bd666b1dc --- test/jdk/sun/java2d/loops/ARGBBgToRGB.java | 57 ++++++++++ test/jdk/sun/java2d/loops/CopyNegative.java | 103 ++++++++++++++++++ .../sun/java2d/loops/DitheredSolidFill.java | 73 +++++++++++++ .../java2d/loops/OffsetCalculationTest.java | 68 ++++++++++++ test/jdk/sun/java2d/loops/XORClearRect.java | 93 ++++++++++++++++ 5 files changed, 394 insertions(+) create mode 100644 test/jdk/sun/java2d/loops/ARGBBgToRGB.java create mode 100644 test/jdk/sun/java2d/loops/CopyNegative.java create mode 100644 test/jdk/sun/java2d/loops/DitheredSolidFill.java create mode 100644 test/jdk/sun/java2d/loops/OffsetCalculationTest.java create mode 100644 test/jdk/sun/java2d/loops/XORClearRect.java diff --git a/test/jdk/sun/java2d/loops/ARGBBgToRGB.java b/test/jdk/sun/java2d/loops/ARGBBgToRGB.java new file mode 100644 index 0000000000000..55764af2c1354 --- /dev/null +++ b/test/jdk/sun/java2d/loops/ARGBBgToRGB.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4238978 + * @summary This test verifies that the correct blitting loop is being used. + * The correct output should have a yellow border on the top and + * left sides of a red box. The incorrect output would have only + * a red box -- no yellow border." + */ + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +public class ARGBBgToRGB { + + public static void main(String[] argv) { + BufferedImage bi = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB); + Graphics2D big = bi.createGraphics(); + big.setColor(Color.red); + big.fillRect(30, 30, 150, 150); + + BufferedImage bi2 = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB); + Graphics2D big2 = bi2.createGraphics(); + big2.drawImage(bi, 0, 0, Color.yellow, null); + + int expectYellowPix = bi2.getRGB(0, 0); + int expectRedPix = bi2.getRGB(50, 50); + if ((expectYellowPix != Color.yellow.getRGB()) || + (expectRedPix != Color.red.getRGB())) + { + throw new RuntimeException("Unexpected colors " + expectYellowPix + " " + expectRedPix); + } + } +} diff --git a/test/jdk/sun/java2d/loops/CopyNegative.java b/test/jdk/sun/java2d/loops/CopyNegative.java new file mode 100644 index 0000000000000..0b8296918ac63 --- /dev/null +++ b/test/jdk/sun/java2d/loops/CopyNegative.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4188744 + * @summary This test verifies that copyArea performs correctly for negative offset values. + * The correct output shows that the text area is moved to the left and down, + * leaving some garbage on the right and the top. + * The incorrect copy would show the text area garbled and no text is legible. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual CopyNegative + */ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Panel; + +public class CopyNegative extends Panel { + + private static final String INSTRUCTIONS = """ + This test verifies that copyArea performs correctly for negative offset values. + The test draws text in an image, then copies the contents repeatedly. + The correct output shows that the text is moved to the left and down, + leaving some garbage on the top / right and some legible text at the bottom left. + The incorrect copy would show the whole text area garbled and no text is legible. + """; + + public static void main(String[] argv) throws Exception { + PassFailJFrame.builder() + .title("CopyNegativeTest") + .instructions(INSTRUCTIONS) + .testUI(CopyNegative::createUI) + .testTimeOut(5) + .rows(10) + .columns(50) + .build() + .awaitAndCheck(); + } + + Image img; + + static final int W = 200, H = 200; + + static Frame createUI() { + Frame f = new Frame("CopyNegative"); + f.add(new CopyNegative()); + f.pack(); + return f; + } + + public Dimension getPreferredSize() { + return new Dimension(W, H); + } + + private void doCopy() { + Graphics g = img.getGraphics(); + g.setColor(Color.white); + g.fillRect(0, 0, W, H); + g.setColor(Color.black); + String text = "Some Text To Display, it is long enough to fill the entire display line."; + StringBuffer sb = new StringBuffer(text); + + for (int i = 1; i < 50; i++) { + g.drawString(sb.toString(), 5,20 * i - 10); + sb.insert(0, Integer.toString(i)); + } + for (int i = 0 ; i < 20 ; i++ ) { + g.copyArea(0, 0, W, H, -3, 3); + } + } + + public void paint(Graphics g) { + img = createImage(W, H); + doCopy(); + g.drawImage(img, 0, 0, this); + } + +} diff --git a/test/jdk/sun/java2d/loops/DitheredSolidFill.java b/test/jdk/sun/java2d/loops/DitheredSolidFill.java new file mode 100644 index 0000000000000..509b0bbe3b234 --- /dev/null +++ b/test/jdk/sun/java2d/loops/DitheredSolidFill.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4181172 + * @summary Confirm that solid white fill is not dithered on an 8-bit indexed surface. + * The test draws two areas filled with white solid color. + * The upper left square is filled in aliasing mode and + * the lower right square is filled in anti-aliasing mode. + */ + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; + +public class DitheredSolidFill { + + public static void main(String args[]) { + BufferedImage bi = new BufferedImage(120, 120, BufferedImage.TYPE_BYTE_INDEXED); + Graphics2D g2D = bi.createGraphics(); + + g2D.setColor(Color.black); + g2D.fillRect(0, 0, 100, 100); + + g2D.setColor(Color.white); + g2D.fillRect(5, 5, 40, 40); + checkPixels(bi, 5, 5, 40, 40); + + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2D.fillRect(55, 55, 40, 40); + checkPixels(bi, 55, 55, 40, 40); + } + + static void checkPixels(BufferedImage bi, int x, int y, int w, int h) { + // pixel can be off white, but must be the same in all cases. + int expectedPix = bi.getRGB(x, y); + for (int x0 = x; x0 < x + w; x0++) { + for (int y0 = y; y0 < y + h; y0++) { + if (bi.getRGB(x0, y0) != expectedPix) { + try { + javax.imageio.ImageIO.write(bi, "png", new java.io.File("failed.png")); + } catch (Exception e) { + } + throw new RuntimeException("Not expected pix : " + + Integer.toHexString(bi.getRGB(x0, y0)) + + " at " + x0 + "," + y0); + } + } + } + } +} diff --git a/test/jdk/sun/java2d/loops/OffsetCalculationTest.java b/test/jdk/sun/java2d/loops/OffsetCalculationTest.java new file mode 100644 index 0000000000000..fe30107f22a9f --- /dev/null +++ b/test/jdk/sun/java2d/loops/OffsetCalculationTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4236576 + @summary tests that a BufferedImage in TYPE_3BYTE_BGR format is correctly + drawn when there is an offset between the Graphics clip bounds + and the clip box of the underlying device context. + @run main OffsetCalculationTest +*/ + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; + +public class OffsetCalculationTest { + + public static void main(String[] args) { + BufferedImage srcImage = new BufferedImage(500, 500, BufferedImage.TYPE_3BYTE_BGR); + + DataBuffer buffer = srcImage.getRaster().getDataBuffer(); + for (int i = 2; i < buffer.getSize(); i+=3) { + // setting each pixel to blue via the data buffer elements. + buffer.setElem(i - 2, 0xff); + buffer.setElem(i - 1, 0); + buffer.setElem(i, 0); + } + + int w = 200, h = 200; + BufferedImage destImage = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR); + Graphics2D g = destImage.createGraphics(); + Rectangle r = new Rectangle(0, 0, w, h); + g.setClip(r.x - 1, r.y, r.width + 1, r.height); + g.drawImage(srcImage, 0, 0, null); + + int bluepix = Color.blue.getRGB(); + for (int y = 0; y < w; y++) { + for (int x = 0; x < h; x++) { + if (destImage.getRGB(x, y) != bluepix) { + throw new RuntimeException("Not Blue"); + } + } + } + } +} diff --git a/test/jdk/sun/java2d/loops/XORClearRect.java b/test/jdk/sun/java2d/loops/XORClearRect.java new file mode 100644 index 0000000000000..f5c30581cf1f3 --- /dev/null +++ b/test/jdk/sun/java2d/loops/XORClearRect.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4088173 + * @summary This interactive test verifies that the XOR mode is not affecting + * the clearRect() call. The correct output looks like: + * + * \ / + * \ / + * The backgound is blue. + * The lines outside the central rectangle are green. + * The central rectangle is also blue (the result of clearRect()) + * / \ + * / \ + * + * @key headful + * @run main XORClearRect + */ + +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Graphics; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; + +public class XORClearRect extends Panel { + + public static void main(String args[]) throws Exception { + EventQueue.invokeAndWait(XORClearRect::createUI); + try { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(2000); + Point p = frame.getLocationOnScreen(); + int pix = robot.getPixelColor(p.x + 100, p.y + 100).getRGB(); + if (pix != Color.blue.getRGB()) { + throw new RuntimeException("Not blue"); + } + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + } + } + + static volatile Frame frame; + + static void createUI() { + frame = new Frame("XORClearRect"); + frame.setBackground(Color.blue); + XORClearRect xor = new XORClearRect(); + frame.add(xor); + frame.setSize(200,200); + frame.setVisible(true); + } + + public XORClearRect() { + setBackground(Color.blue); + } + + public void paint(Graphics g) { + g.setColor(Color.green); + g.drawLine(0,0,200,200); + g.drawLine(0,200,200,0); + g.setXORMode(Color.blue); + g.clearRect(50,50,100,100); //expecting the rectangle to be filled + // with the background color (blue) + } +} From e33daf09e07948d9bbfbc2fab0c5de1982d77c2a Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 2 Apr 2025 10:09:08 +0000 Subject: [PATCH 113/846] 8340605: Open source several AWT PopupMenu tests Backport-of: 822a773873c42ea27a6be90da92b2b2c9fb8caee --- .../java/awt/PopupMenu/PeripheryOfScreen.java | 82 ++++++++++++++ .../PopupMenu/PopupLeadingSeparatorTest.java | 81 ++++++++++++++ .../java/awt/PopupMenu/PopupMenuShowTest.java | 77 +++++++++++++ .../awt/PopupMenu/PopupMenuWithMenuBar.java | 103 ++++++++++++++++++ .../jdk/java/awt/PopupMenu/PopupOnButton.java | 88 +++++++++++++++ 5 files changed, 431 insertions(+) create mode 100644 test/jdk/java/awt/PopupMenu/PeripheryOfScreen.java create mode 100644 test/jdk/java/awt/PopupMenu/PopupLeadingSeparatorTest.java create mode 100644 test/jdk/java/awt/PopupMenu/PopupMenuShowTest.java create mode 100644 test/jdk/java/awt/PopupMenu/PopupMenuWithMenuBar.java create mode 100644 test/jdk/java/awt/PopupMenu/PopupOnButton.java diff --git a/test/jdk/java/awt/PopupMenu/PeripheryOfScreen.java b/test/jdk/java/awt/PopupMenu/PeripheryOfScreen.java new file mode 100644 index 0000000000000..b169a7d9692a7 --- /dev/null +++ b/test/jdk/java/awt/PopupMenu/PeripheryOfScreen.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Frame; +import java.awt.MenuItem; +import java.awt.PopupMenu; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/* + * @test + * @bug 6267162 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Popup Menu gets hidden below the screen when opened near the periphery + * of the screen, XToolkit Test if popup menu window is adjusted on screen + * when trying to show outside + * @run main/manual PeripheryOfScreen + */ + +public class PeripheryOfScreen { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Click on the button to show popup menu in the center of + frame. Move frame beyond the edge of screen and click on + button to show the popup menu and see if popup menu is + adjusted to the edge. + + Press Pass if popup menu behaves as per instruction, otherwise + press Fail. + """; + + PassFailJFrame.builder() + .title("PeripheryOfScreen Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(PeripheryOfScreen::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI () { + Frame f = new Frame("PeripheryOfScreen Test frame"); + Button b = new Button("Click to show popup menu"); + PopupMenu pm = new PopupMenu("Test menu"); + MenuItem i = new MenuItem("Click me"); + pm.add(i); + b.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + pm.show(f, 100, 100); + } + }); + f.add(b); + f.add(pm); + f.setSize(300, 200); + f.toFront(); + return f; + } +} diff --git a/test/jdk/java/awt/PopupMenu/PopupLeadingSeparatorTest.java b/test/jdk/java/awt/PopupMenu/PopupLeadingSeparatorTest.java new file mode 100644 index 0000000000000..c9274e9b807f0 --- /dev/null +++ b/test/jdk/java/awt/PopupMenu/PopupLeadingSeparatorTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Component; +import java.awt.Frame; +import java.awt.Font; +import java.awt.MenuItem; +import java.awt.PopupMenu; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 4169155 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Popup menus get a leading separator on Motif system + * @run main/manual PopupLeadingSeparatorTest + */ + +public class PopupLeadingSeparatorTest { + public static void main(String[] args) throws Exception { + PopupLeadingSeparatorTest obj = new PopupLeadingSeparatorTest(); + String INSTRUCTIONS = """ + Press mouse button on the frame. Popup menu without leading + separator should appear. + If a PopupMenu behaves same, press Pass, else press Fail. + """; + + PassFailJFrame.builder() + .title("PopupLeadingSeparatorTest Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(obj::createUI) + .build() + .awaitAndCheck(); + } + + private Frame createUI() { + Frame f = new Frame("PopupLeadingSeparatorTest Test"); + PopupMenu popupMenu = new PopupMenu("Popup Menu Title"); + popupMenu.add(new MenuItem("Item1")); + PopupMenu cascadeMenu = new PopupMenu("Multifont menu"); + cascadeMenu.add(new MenuItem("Item1")); + MenuItem item2 = new MenuItem("Item2"); + item2.setFont(new Font("Serif", Font.BOLD, 36)); + cascadeMenu.add(item2); + + popupMenu.add(cascadeMenu); + f.add(popupMenu); + f.setSize(300, 150); + f.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent evt) { + popupMenu.show((Component) evt.getSource(), evt.getX(), evt.getY()); + } + }); + return f; + } +} diff --git a/test/jdk/java/awt/PopupMenu/PopupMenuShowTest.java b/test/jdk/java/awt/PopupMenu/PopupMenuShowTest.java new file mode 100644 index 0000000000000..b36fdc5d19c22 --- /dev/null +++ b/test/jdk/java/awt/PopupMenu/PopupMenuShowTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.MenuItem; +import java.awt.PopupMenu; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 4168006 4196790 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Popup menu test fails on x86/Solaris 2.6 combination. + * @run main/manual PopupMenuShowTest + */ + +public class PopupMenuShowTest { + public static void main(String[] args) throws Exception { + PopupMenuShowTest obj = new PopupMenuShowTest(); + String INSTRUCTIONS = """ + Press the right mouse button in the PopupTest window. + If a PopupMenu appears, press Pass, else press Fail. + """; + + PassFailJFrame.builder() + .title("PopupMenuShowTest Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(obj::createUI) + .build() + .awaitAndCheck(); + } + + private Frame createUI() { + Frame f = new Frame("PopupMenuShowTest Test"); + f.setLayout(new FlowLayout()); + f.add(new Label("Press right mouse button inside this frame.")); + f.add(new Label("A pop-up menu should appear.")); + PopupMenu popupMenu = new PopupMenu("Popup Menu Title"); + MenuItem mi = new MenuItem("Menu Item"); + popupMenu.add(mi); + f.add(popupMenu); + f.setSize(400, 350); + f.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + popupMenu.show(e.getComponent(), e.getX(), e.getY()); + } + }); + return f; + } +} diff --git a/test/jdk/java/awt/PopupMenu/PopupMenuWithMenuBar.java b/test/jdk/java/awt/PopupMenu/PopupMenuWithMenuBar.java new file mode 100644 index 0000000000000..1a927e29f84bc --- /dev/null +++ b/test/jdk/java/awt/PopupMenu/PopupMenuWithMenuBar.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.PopupMenu; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 4038140 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Test for functionality of PopupMenuWithMenuBar + * @run main/manual PopupMenuWithMenuBar + */ + +public class PopupMenuWithMenuBar { + public static void main(String[] args) throws Exception { + PopupMenuWithMenuBar obj = new PopupMenuWithMenuBar(); + String INSTRUCTIONS = """ + There was a bug that prevented the popup menu from appearing properly + (if even at all) for a frame window when there is also a menu bar. + + Right click inside the frame window to display the popup window. If + the popup menu appears normally, then the test is successful and the + bug has been fixed."""; + + PassFailJFrame.builder() + .title("PopupMenuWithMenuBar Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(obj::createUI) + .build() + .awaitAndCheck(); + } + + private Frame createUI() { + Frame f = new Frame("PopupMenuWithMenuBar Test"); + f.setBounds(10, 10, 300, 250); + MenuBar menuBar = new MenuBar(); + Menu fileMenu = createFileMenu(); + menuBar.add(fileMenu); + f.setMenuBar(menuBar); + PopupMenu popupMenu = createPopupMenu(); + f.add(popupMenu); + f.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + popupMenu.show(f, e.getX(), e.getY()); + } + }); + return f; + } + + private Menu createFileMenu() { + String[] menu1Labels = new String[] + {"Save As", "Save As", "Quit"}; + MenuItem menuItem; + Menu returnMenu = new Menu("File"); + for (int menu1Index = 0; menu1Index < menu1Labels.length; menu1Index++) { + menuItem = new MenuItem(menu1Labels[menu1Index]); + returnMenu.add(menuItem); + } + return returnMenu; + } + + private PopupMenu createPopupMenu() { + String[] popupLabels = new String[] + {"Popup 1", "Popup 2", "Quit"}; + MenuItem menuItem; + PopupMenu returnMenu = new PopupMenu("Popups"); + for (int popupIndex = 0; popupIndex < popupLabels.length; popupIndex++) { + menuItem = new MenuItem(popupLabels[popupIndex]); + returnMenu.add(menuItem); + } + return returnMenu; + } +} diff --git a/test/jdk/java/awt/PopupMenu/PopupOnButton.java b/test/jdk/java/awt/PopupMenu/PopupOnButton.java new file mode 100644 index 0000000000000..581714bf76a85 --- /dev/null +++ b/test/jdk/java/awt/PopupMenu/PopupOnButton.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Component; +import java.awt.Frame; +import java.awt.MenuItem; +import java.awt.PopupMenu; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 4181790 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Tests a popup menu on a button. + * @run main/manual PopupOnButton + */ + +public class PopupOnButton { + public static void main(String[] args) throws Exception { + PopupOnButton obj = new PopupOnButton(); + String INSTRUCTIONS = """ + Right-click on the button. + Popup Menu should appear and behave fine. + If a PopupMenu appears, press Pass, else press Fail. + """; + + PassFailJFrame.builder() + .title("PopupOnButton Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(obj::createUI) + .build() + .awaitAndCheck(); + } + + private Frame createUI() { + Frame f = new Frame("PopupOnButton Test"); + Button b = new Button("button with popup menu"); + PopupMenu m = new PopupMenu("popup"); + m.add(new MenuItem("item1")); + m.add(new MenuItem("item2")); + m.add(new MenuItem("item3")); + b.add(m); + b.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + if (e.isPopupTrigger()) { + m.show((Component) e.getSource(), e.getX(), e.getY()); + } + } + + @Override + public void mouseReleased(MouseEvent e) { + if (e.isPopupTrigger()) { + m.show((Component) e.getSource(), e.getX(), e.getY()); + } + } + }); + + f.add(b); + f.setSize(200, 150); + return f; + } + } From ff0d2b351c7e895275aeeac1cfd0fec03c2d9e96 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 2 Apr 2025 10:14:21 +0000 Subject: [PATCH 114/846] 8342376: More reliable OOM handling in ExceptionDuringDumpAtObjectsInitPhase test Backport-of: 37aa320f573650f007e60729e4d187c3b96b5756 --- .../javaldr/GCDuringDumpTransformer.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCDuringDumpTransformer.java b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCDuringDumpTransformer.java index f50be0cedb255..76a7ddd9e8e43 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCDuringDumpTransformer.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCDuringDumpTransformer.java @@ -34,7 +34,10 @@ public class GCDuringDumpTransformer implements ClassFileTransformer { static boolean TEST_WITH_CLEANER = Boolean.getBoolean("test.with.cleaner"); static boolean TEST_WITH_EXCEPTION = Boolean.getBoolean("test.with.exception"); static boolean TEST_WITH_OOM = Boolean.getBoolean("test.with.oom"); + + static final int WASTE_SIZE = 1024; static List waste = new ArrayList(); + static Object sink; static Cleaner cleaner; static Thread thread; @@ -59,10 +62,13 @@ public byte[] transform(ClassLoader loader, String name, Class classBeingRede return new byte[] {1, 2, 3, 4, 5, 6, 7, 8}; } if (TEST_WITH_OOM) { - // fill until OOM + // Fill until OOM and fail. This sets up heap for secondary OOM + // later on, which should be caught by CDS code. The size of waste + // array defines how much max free space would be left for later + // code to run with. System.out.println("Fill objects until OOM"); - for (;;) { - waste.add(new byte[64*1024]); + while (true) { + waste.add(new byte[WASTE_SIZE]); } } } @@ -104,8 +110,8 @@ public static void agentmain(String args, Instrumentation inst) throws Exception } public static void makeGarbage() { - for (int x=0; x<10; x++) { - Object[] a = new Object[10000]; + for (int x = 0; x < 10; x++) { + sink = new byte[WASTE_SIZE]; } } @@ -115,7 +121,7 @@ static class MyCleaner implements Runnable { public void run() { // Allocate something. This will cause G1 to allocate an EDEN region. // See JDK-8245925 - Object o = new Object(); + sink = new Object(); System.out.println("cleaning " + i); } } From f4e99de33e35826ec1fb368d6ad96005d7bd5cc4 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 2 Apr 2025 11:24:28 +0000 Subject: [PATCH 115/846] 8348597: Update HarfBuzz to 10.4.0 Reviewed-by: mbaesken, phh Backport-of: dbdbbd473061d7e8077ed07ccc6b03065a8c2ffc --- .../java.desktop/lib/Awt2dLibraries.gmk | 2 +- src/java.desktop/share/legal/harfbuzz.md | 15 +- .../native/libharfbuzz/OT/Color/CBDT/CBDT.hh | 10 +- .../native/libharfbuzz/OT/Color/COLR/COLR.hh | 513 +- .../OT/Color/COLR/colrv1-closure.hh | 50 +- .../native/libharfbuzz/OT/Color/CPAL/CPAL.hh | 16 + .../native/libharfbuzz/OT/Color/sbix/sbix.hh | 1 + .../native/libharfbuzz/OT/Color/svg/svg.hh | 1 + .../libharfbuzz/OT/Layout/Common/Coverage.hh | 23 + .../OT/Layout/Common/CoverageFormat1.hh | 2 + .../OT/Layout/Common/CoverageFormat2.hh | 2 + .../native/libharfbuzz/OT/Layout/GDEF/GDEF.hh | 166 +- .../libharfbuzz/OT/Layout/GPOS/Anchor.hh | 1 + .../OT/Layout/GPOS/AnchorFormat3.hh | 6 + .../OT/Layout/GPOS/AnchorMatrix.hh | 10 +- .../libharfbuzz/OT/Layout/GPOS/Common.hh | 2 +- .../OT/Layout/GPOS/CursivePosFormat1.hh | 14 +- .../OT/Layout/GPOS/MarkMarkPosFormat1.hh | 1 + .../OT/Layout/GPOS/PairPosFormat1.hh | 84 +- .../OT/Layout/GPOS/PairPosFormat2.hh | 118 +- .../libharfbuzz/OT/Layout/GPOS/PairSet.hh | 8 +- .../OT/Layout/GPOS/PairValueRecord.hh | 4 +- .../libharfbuzz/OT/Layout/GPOS/SinglePos.hh | 12 +- .../OT/Layout/GPOS/SinglePosFormat1.hh | 31 +- .../OT/Layout/GPOS/SinglePosFormat2.hh | 42 +- .../libharfbuzz/OT/Layout/GPOS/ValueFormat.hh | 85 +- .../OT/Layout/GSUB/AlternateSubstFormat1.hh | 2 +- .../libharfbuzz/OT/Layout/GSUB/Ligature.hh | 15 +- .../OT/Layout/GSUB/LigatureSubstFormat1.hh | 45 +- .../OT/Layout/GSUB/MultipleSubstFormat1.hh | 2 +- .../GSUB/ReverseChainSingleSubstFormat1.hh | 8 +- .../OT/Layout/GSUB/SingleSubstFormat1.hh | 2 +- .../OT/Layout/GSUB/SingleSubstFormat2.hh | 2 +- .../native/libharfbuzz/OT/Layout/types.hh | 11 +- .../native/libharfbuzz/OT/Var/VARC/VARC.hh | 218 + .../libharfbuzz/OT/Var/VARC/coord-setter.hh | 63 + .../libharfbuzz/OT/glyf/CompositeGlyph.hh | 5 +- .../share/native/libharfbuzz/OT/glyf/Glyph.hh | 202 +- .../native/libharfbuzz/OT/glyf/SimpleGlyph.hh | 18 +- .../native/libharfbuzz/OT/glyf/SubsetGlyph.hh | 13 +- .../libharfbuzz/OT/glyf/VarCompositeGlyph.hh | 401 -- .../libharfbuzz/OT/glyf/coord-setter.hh | 36 - .../libharfbuzz/OT/glyf/glyf-helpers.hh | 2 +- .../share/native/libharfbuzz/OT/glyf/glyf.hh | 162 +- .../libharfbuzz/OT/glyf/path-builder.hh | 100 +- .../share/native/libharfbuzz/OT/name/name.hh | 7 +- .../share/native/libharfbuzz/UPDATING.txt | 4 +- .../libharfbuzz/graph/classdef-graph.hh | 81 +- .../libharfbuzz/graph/coverage-graph.hh | 3 + .../share/native/libharfbuzz/graph/graph.hh | 100 +- .../libharfbuzz/graph/gsubgpos-graph.hh | 4 + .../libharfbuzz/graph/markbasepos-graph.hh | 3 + .../native/libharfbuzz/graph/pairpos-graph.hh | 13 +- .../libharfbuzz/hb-aat-layout-ankr-table.hh | 1 + .../libharfbuzz/hb-aat-layout-bsln-table.hh | 1 + .../libharfbuzz/hb-aat-layout-common.hh | 412 +- .../libharfbuzz/hb-aat-layout-feat-table.hh | 2 + .../libharfbuzz/hb-aat-layout-just-table.hh | 15 +- .../libharfbuzz/hb-aat-layout-kerx-table.hh | 274 +- .../libharfbuzz/hb-aat-layout-morx-table.hh | 646 +- .../libharfbuzz/hb-aat-layout-opbd-table.hh | 9 +- .../libharfbuzz/hb-aat-layout-trak-table.hh | 186 +- .../share/native/libharfbuzz/hb-aat-layout.cc | 99 +- .../share/native/libharfbuzz/hb-aat-layout.h | 4 +- .../share/native/libharfbuzz/hb-aat-layout.hh | 8 +- .../native/libharfbuzz/hb-aat-ltag-table.hh | 5 +- .../share/native/libharfbuzz/hb-aat-map.cc | 15 +- .../share/native/libharfbuzz/hb-algs.hh | 28 +- .../share/native/libharfbuzz/hb-array.hh | 5 +- .../share/native/libharfbuzz/hb-atomic.hh | 11 +- .../share/native/libharfbuzz/hb-bit-page.hh | 55 +- .../libharfbuzz/hb-bit-set-invertible.hh | 14 +- .../share/native/libharfbuzz/hb-bit-set.hh | 71 +- .../share/native/libharfbuzz/hb-blob.cc | 26 +- .../libharfbuzz/hb-buffer-deserialize-json.hh | 434 +- .../native/libharfbuzz/hb-buffer-verify.cc | 6 +- .../share/native/libharfbuzz/hb-buffer.cc | 89 +- .../share/native/libharfbuzz/hb-buffer.h | 13 + .../share/native/libharfbuzz/hb-buffer.hh | 20 +- .../libharfbuzz/hb-cff-interp-common.hh | 3 +- .../libharfbuzz/hb-cff-interp-dict-common.hh | 10 +- .../native/libharfbuzz/hb-cff2-interp-cs.hh | 10 +- .../share/native/libharfbuzz/hb-common.cc | 5 +- .../share/native/libharfbuzz/hb-common.h | 33 +- .../share/native/libharfbuzz/hb-config.hh | 8 +- .../share/native/libharfbuzz/hb-cplusplus.hh | 19 +- .../share/native/libharfbuzz/hb-decycler.hh | 164 + .../share/native/libharfbuzz/hb-deprecated.h | 11 +- .../share/native/libharfbuzz/hb-draw.h | 2 +- .../share/native/libharfbuzz/hb-draw.hh | 2 +- .../native/libharfbuzz/hb-face-builder.cc | 61 +- .../share/native/libharfbuzz/hb-face.cc | 176 +- .../share/native/libharfbuzz/hb-face.h | 45 +- .../share/native/libharfbuzz/hb-face.hh | 10 +- .../share/native/libharfbuzz/hb-font.cc | 2 +- .../share/native/libharfbuzz/hb-font.hh | 2 +- .../share/native/libharfbuzz/hb-ft.cc | 256 +- .../share/native/libharfbuzz/hb-ft.h | 12 +- .../share/native/libharfbuzz/hb-geometry.hh | 293 + .../share/native/libharfbuzz/hb-iter.hh | 10 + .../share/native/libharfbuzz/hb-limits.hh | 19 +- .../share/native/libharfbuzz/hb-map.hh | 56 +- .../share/native/libharfbuzz/hb-null.hh | 2 +- .../share/native/libharfbuzz/hb-object.hh | 2 +- .../share/native/libharfbuzz/hb-open-file.hh | 12 +- .../share/native/libharfbuzz/hb-open-type.hh | 986 ++- .../native/libharfbuzz/hb-ot-cff-common.hh | 287 +- .../native/libharfbuzz/hb-ot-cff1-table.cc | 9 - .../native/libharfbuzz/hb-ot-cff1-table.hh | 138 +- .../native/libharfbuzz/hb-ot-cff2-table.cc | 16 +- .../native/libharfbuzz/hb-ot-cff2-table.hh | 86 +- .../native/libharfbuzz/hb-ot-cmap-table.hh | 315 +- .../libharfbuzz/hb-ot-face-table-list.hh | 14 +- .../share/native/libharfbuzz/hb-ot-face.cc | 3 + .../share/native/libharfbuzz/hb-ot-font.cc | 82 +- .../native/libharfbuzz/hb-ot-hdmx-table.hh | 4 +- .../native/libharfbuzz/hb-ot-head-table.hh | 1 + .../native/libharfbuzz/hb-ot-hhea-table.hh | 4 +- .../native/libharfbuzz/hb-ot-hmtx-table.hh | 31 +- .../native/libharfbuzz/hb-ot-kern-table.hh | 94 +- .../libharfbuzz/hb-ot-layout-base-table.hh | 355 +- .../native/libharfbuzz/hb-ot-layout-common.hh | 1080 ++- .../libharfbuzz/hb-ot-layout-gsubgpos.hh | 375 +- .../libharfbuzz/hb-ot-layout-jstf-table.hh | 1 + .../share/native/libharfbuzz/hb-ot-layout.cc | 46 +- .../share/native/libharfbuzz/hb-ot-layout.hh | 58 +- .../share/native/libharfbuzz/hb-ot-map.cc | 14 + .../share/native/libharfbuzz/hb-ot-map.hh | 3 + .../native/libharfbuzz/hb-ot-math-table.hh | 36 +- .../native/libharfbuzz/hb-ot-maxp-table.hh | 3 +- .../native/libharfbuzz/hb-ot-meta-table.hh | 2 + .../native/libharfbuzz/hb-ot-os2-table.hh | 32 +- .../libharfbuzz/hb-ot-post-table-v2subset.hh | 21 +- .../native/libharfbuzz/hb-ot-post-table.hh | 22 +- .../libharfbuzz/hb-ot-shape-normalize.cc | 35 +- .../libharfbuzz/hb-ot-shape-normalize.hh | 34 +- .../share/native/libharfbuzz/hb-ot-shape.cc | 85 +- .../share/native/libharfbuzz/hb-ot-shape.h | 6 + .../share/native/libharfbuzz/hb-ot-shape.hh | 15 +- .../hb-ot-shaper-arabic-fallback.hh | 2 + .../hb-ot-shaper-arabic-joining-list.hh | 8 +- .../libharfbuzz/hb-ot-shaper-arabic-table.hh | 23 +- .../native/libharfbuzz/hb-ot-shaper-arabic.cc | 11 +- .../native/libharfbuzz/hb-ot-shaper-hebrew.cc | 2 +- .../libharfbuzz/hb-ot-shaper-indic-machine.hh | 1279 +++- .../libharfbuzz/hb-ot-shaper-indic-table.cc | 39 +- .../hb-ot-shaper-myanmar-machine.hh | 642 +- .../libharfbuzz/hb-ot-shaper-use-machine.hh | 1377 ++-- .../libharfbuzz/hb-ot-shaper-use-table.hh | 396 +- .../hb-ot-shaper-vowel-constraints.cc | 6 +- .../share/native/libharfbuzz/hb-ot-shaper.hh | 36 +- .../native/libharfbuzz/hb-ot-stat-table.hh | 58 +- .../native/libharfbuzz/hb-ot-tag-table.hh | 328 +- .../share/native/libharfbuzz/hb-ot-tag.cc | 2 +- .../libharfbuzz/hb-ot-var-avar-table.hh | 17 +- .../native/libharfbuzz/hb-ot-var-common.hh | 1039 ++- .../libharfbuzz/hb-ot-var-cvar-table.hh | 29 +- .../libharfbuzz/hb-ot-var-fvar-table.hh | 10 +- .../libharfbuzz/hb-ot-var-gvar-table.hh | 191 +- .../libharfbuzz/hb-ot-var-hvar-table.hh | 11 +- .../libharfbuzz/hb-ot-var-mvar-table.hh | 8 +- .../libharfbuzz/hb-ot-var-varc-table.hh | 32 + .../native/libharfbuzz/hb-ot-vorg-table.hh | 1 + .../native/libharfbuzz/hb-paint-extents.hh | 168 +- .../share/native/libharfbuzz/hb-paint.h | 2 +- .../native/libharfbuzz/hb-priority-queue.hh | 5 +- .../share/native/libharfbuzz/hb-repacker.hh | 70 +- .../share/native/libharfbuzz/hb-sanitize.hh | 9 +- .../share/native/libharfbuzz/hb-serialize.hh | 91 +- .../share/native/libharfbuzz/hb-set-digest.hh | 161 +- .../share/native/libharfbuzz/hb-set.hh | 16 +- .../share/native/libharfbuzz/hb-shape-plan.cc | 2 +- .../share/native/libharfbuzz/hb-shape.h | 2 + .../share/native/libharfbuzz/hb-style.cc | 4 +- .../libharfbuzz/hb-subset-cff-common.hh | 59 +- .../native/libharfbuzz/hb-subset-cff1.cc | 57 +- .../native/libharfbuzz/hb-subset-cff2.cc | 68 +- .../native/libharfbuzz/hb-subset-input.cc | 264 +- .../libharfbuzz/hb-subset-instancer-iup.hh | 37 + .../libharfbuzz/hb-subset-instancer-solver.cc | 107 +- .../libharfbuzz/hb-subset-instancer-solver.hh | 32 +- .../libharfbuzz/hb-subset-plan-member-list.hh | 27 + .../native/libharfbuzz/hb-subset-plan.cc | 413 +- .../native/libharfbuzz/hb-subset-plan.hh | 40 +- .../native/libharfbuzz/hb-subset-serialize.h | 83 + .../share/native/libharfbuzz/hb-subset.cc | 20 +- .../share/native/libharfbuzz/hb-subset.h | 37 +- .../share/native/libharfbuzz/hb-ucd-table.hh | 5932 +++++++++-------- .../libharfbuzz/hb-unicode-emoji-table.hh | 8 +- .../share/native/libharfbuzz/hb-utf.hh | 6 +- .../share/native/libharfbuzz/hb-vector.hh | 112 +- .../share/native/libharfbuzz/hb-version.h | 8 +- .../share/native/libharfbuzz/hb.hh | 18 +- 193 files changed, 15568 insertions(+), 8545 deletions(-) create mode 100644 src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh create mode 100644 src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/coord-setter.hh delete mode 100644 src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh delete mode 100644 src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh create mode 100644 src/java.desktop/share/native/libharfbuzz/hb-decycler.hh create mode 100644 src/java.desktop/share/native/libharfbuzz/hb-geometry.hh create mode 100644 src/java.desktop/share/native/libharfbuzz/hb-ot-var-varc-table.hh create mode 100644 src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh create mode 100644 src/java.desktop/share/native/libharfbuzz/hb-subset-serialize.h diff --git a/make/modules/java.desktop/lib/Awt2dLibraries.gmk b/make/modules/java.desktop/lib/Awt2dLibraries.gmk index bf6a987149af4..eef8ae5990b1e 100644 --- a/make/modules/java.desktop/lib/Awt2dLibraries.gmk +++ b/make/modules/java.desktop/lib/Awt2dLibraries.gmk @@ -470,7 +470,7 @@ else # range-loop-analysis -> clang on Xcode12 HARFBUZZ_DISABLED_WARNINGS_gcc := type-limits missing-field-initializers strict-aliasing \ - array-bounds parentheses + array-bounds parentheses dangling-pointer # noexcept-type required for GCC 7 builds. Not required for GCC 8+. # expansion-to-defined required for GCC 9 builds. Not required for GCC 10+. # maybe-uninitialized required for GCC 8 builds. Not required for GCC 9+. diff --git a/src/java.desktop/share/legal/harfbuzz.md b/src/java.desktop/share/legal/harfbuzz.md index 3ae73d215b046..2d0a28ed310ba 100644 --- a/src/java.desktop/share/legal/harfbuzz.md +++ b/src/java.desktop/share/legal/harfbuzz.md @@ -1,4 +1,4 @@ -## Harfbuzz v8.2.2 +## Harfbuzz v10.4.0 ### Harfbuzz License @@ -8,14 +8,14 @@ HarfBuzz is licensed under the so-called "Old MIT" license. Details follow. For parts of HarfBuzz that are licensed under different licenses see individual files names COPYING in subdirectories where applicable. -Copyright © 2010-2023 Google, Inc. +Copyright © 2010-2024 Google, Inc. Copyright © 2018-2020 Ebrahim Byagowi Copyright © 2004-2013 Red Hat, Inc. Copyright © 2019 Facebook, Inc. Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com) Copyright © 2007 Chris Wilson Copyright © 2018-2019 Adobe Inc. -Copyright © 2006-2023 Behdad Esfahbod +Copyright © 2006-2025 Behdad Esfahbod Copyright © 1998-2004 David Turner and Werner Lemberg Copyright © 2009 Keith Stribley Copyright © 2018 Khaled Hosny @@ -54,7 +54,7 @@ exception is licensed with a slightly different MIT variant: The contents of this directory are licensed under the following terms: --------------------------------- -The below license applies to the following files: +The below applies to the following file(s): libharfbuzz/hb-ucd.cc Copyright (C) 2012 Grigori Goronzy @@ -72,13 +72,14 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. --------------------------------- -The below license applies to the following files: +The below applies to the following file(s): libharfbuzz/hb-unicode-emoji-table.hh -© 2023 Unicode®, Inc. +© 2024 Unicode®, Inc. + Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -For terms of use, see https://www.unicode.org/terms_of_use.html +For terms of use and license, see https://www.unicode.org/terms_of_use.html
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh index d7b2b13e4d38c..43a611a0058bb 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh @@ -204,6 +204,7 @@ struct IndexSubtable { TRACE_SANITIZE (this); if (!u.header.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.header.indexFormat) { case 1: return_trace (u.format1.sanitize (c, glyph_count)); @@ -378,6 +379,7 @@ struct IndexSubtableRecord { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && firstGlyphIndex <= lastGlyphIndex && offsetToSubtable.sanitize (c, base, lastGlyphIndex - firstGlyphIndex + 1)); } @@ -635,6 +637,7 @@ struct BitmapSizeTable { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) && horizontal.sanitize (c) && vertical.sanitize (c)); @@ -738,7 +741,9 @@ struct CBLC { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 2 || version.major == 3) && + hb_barrier () && sizeTables.sanitize (c, this)); } @@ -936,10 +941,12 @@ struct CBDT } } - bool has_data () const { return cbdt.get_length (); } + bool has_data () const { return cbdt->version.major; } bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { + if (!has_data ()) return false; + hb_glyph_extents_t extents; hb_glyph_extents_t pixel_extents; hb_blob_t *blob = reference_png (font, glyph); @@ -975,6 +982,7 @@ struct CBDT { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 2 || version.major == 3)); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh index fb2c42a88f080..4d6272d05cb58 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh @@ -29,11 +29,14 @@ #define OT_COLOR_COLR_COLR_HH #include "../../../hb.hh" +#include "../../../hb-decycler.hh" #include "../../../hb-open-type.hh" #include "../../../hb-ot-var-common.hh" #include "../../../hb-paint.hh" #include "../../../hb-paint-extents.hh" +#include "../CPAL/CPAL.hh" + /* * COLR -- Color * https://docs.microsoft.com/en-us/typography/opentype/spec/colr @@ -66,13 +69,13 @@ public: hb_paint_funcs_t *funcs; void *data; hb_font_t *font; - unsigned int palette_index; + hb_array_t palette; hb_color_t foreground; - VarStoreInstancer &instancer; - hb_map_t current_glyphs; - hb_map_t current_layers; + ItemVarStoreInstancer &instancer; + hb_decycler_t glyphs_decycler; + hb_decycler_t layers_decycler; int depth_left = HB_MAX_NESTING_LEVEL; - int edge_count = HB_COLRV1_MAX_EDGE_COUNT; + int edge_count = HB_MAX_GRAPH_EDGE_COUNT; hb_paint_context_t (const void *base_, hb_paint_funcs_t *funcs_, @@ -80,12 +83,16 @@ public: hb_font_t *font_, unsigned int palette_, hb_color_t foreground_, - VarStoreInstancer &instancer_) : + ItemVarStoreInstancer &instancer_) : base (base_), funcs (funcs_), data (data_), font (font_), - palette_index (palette_), + palette ( +#ifndef HB_NO_COLOR + font->face->table.CPAL->get_palette_colors (palette_) +#endif + ), foreground (foreground_), instancer (instancer_) { } @@ -99,12 +106,7 @@ public: if (color_index != 0xffff) { if (!funcs->custom_palette_color (data, color_index, &color)) - { - unsigned int clen = 1; - hb_face_t *face = hb_font_get_face (font); - - hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color); - } + color = palette[color_index]; *is_foreground = false; } @@ -159,23 +161,35 @@ struct hb_colrv1_closure_context_t : void add_palette_index (unsigned palette_index) { palette_indices->add (palette_index); } + void add_var_idxes (unsigned first_var_idx, unsigned num_idxes) + { + if (!num_idxes || first_var_idx == VarIdx::NO_VARIATION) return; + variation_indices->add_range (first_var_idx, first_var_idx + num_idxes - 1); + } + public: const void *base; hb_set_t visited_paint; hb_set_t *glyphs; hb_set_t *layer_indices; hb_set_t *palette_indices; + hb_set_t *variation_indices; + unsigned num_var_idxes; unsigned nesting_level_left; hb_colrv1_closure_context_t (const void *base_, hb_set_t *glyphs_, hb_set_t *layer_indices_, hb_set_t *palette_indices_, + hb_set_t *variation_indices_, + unsigned num_var_idxes_ = 1, unsigned nesting_level_left_ = HB_MAX_NESTING_LEVEL) : base (base_), glyphs (glyphs_), layer_indices (layer_indices_), palette_indices (palette_indices_), + variation_indices (variation_indices_), + num_var_idxes (num_var_idxes_), nesting_level_left (nesting_level_left_) {} }; @@ -242,18 +256,33 @@ struct Variable } void closurev1 (hb_colrv1_closure_context_t* c) const - { value.closurev1 (c); } + { + c->num_var_idxes = 0; + // update c->num_var_idxes during value closure + value.closurev1 (c); + c->add_var_idxes (varIdxBase, c->num_var_idxes); + } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); if (!value.subset (c, instancer, varIdxBase)) return_trace (false); if (c->plan->all_axes_pinned) return_trace (true); - //TODO: update varIdxBase for partial-instancing - return_trace (c->serializer->embed (varIdxBase)); + VarIdx new_varidx; + new_varidx = varIdxBase; + if (varIdxBase != VarIdx::NO_VARIATION) + { + hb_pair_t *new_varidx_delta; + if (!c->plan->colrv1_variation_idx_delta_map.has (varIdxBase, &new_varidx_delta)) + return_trace (false); + + new_varidx = hb_first (*new_varidx_delta); + } + + return_trace (c->serializer->embed (new_varidx)); } bool sanitize (hb_sanitize_context_t *c) const @@ -270,7 +299,7 @@ struct Variable void get_color_stop (hb_paint_context_t *c, hb_color_stop_t *stop, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { value.get_color_stop (c, stop, varIdxBase, instancer); } @@ -305,7 +334,7 @@ struct NoVariable { value.closurev1 (c); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); return_trace (value.subset (c, instancer, varIdxBase)); @@ -325,7 +354,7 @@ struct NoVariable void get_color_stop (hb_paint_context_t *c, hb_color_stop_t *stop, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { value.get_color_stop (c, stop, VarIdx::NO_VARIATION, instancer); } @@ -345,10 +374,13 @@ struct NoVariable struct ColorStop { void closurev1 (hb_colrv1_closure_context_t* c) const - { c->add_palette_index (paletteIndex); } + { + c->add_palette_index (paletteIndex); + c->num_var_idxes = 2; + } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -374,7 +406,7 @@ struct ColorStop void get_color_stop (hb_paint_context_t *c, hb_color_stop_t *out, uint32_t varIdx, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { out->offset = stopOffset.to_float(instancer (varIdx, 0)); out->color = c->get_color (paletteIndex, @@ -410,7 +442,7 @@ struct ColorLine } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -439,7 +471,7 @@ struct ColorLine unsigned int start, unsigned int *count, hb_color_stop_t *color_stops, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { unsigned int len = stops.len; @@ -542,8 +574,11 @@ struct Affine2x3 return_trace (c->check_struct (this)); } + void closurev1 (hb_colrv1_closure_context_t* c) const + { c->num_var_idxes = 6; } + bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -588,7 +623,7 @@ struct PaintColrLayers void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer HB_UNUSED) const + const ItemVarStoreInstancer &instancer HB_UNUSED) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -617,10 +652,13 @@ struct PaintColrLayers struct PaintSolid { void closurev1 (hb_colrv1_closure_context_t* c) const - { c->add_palette_index (paletteIndex); } + { + c->add_palette_index (paletteIndex); + c->num_var_idxes = 1; + } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -666,10 +704,13 @@ template class Var> struct PaintLinearGradient { void closurev1 (hb_colrv1_closure_context_t* c) const - { (this+colorLine).closurev1 (c); } + { + (this+colorLine).closurev1 (c); + c->num_var_idxes = 6; + } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -733,10 +774,13 @@ template class Var> struct PaintRadialGradient { void closurev1 (hb_colrv1_closure_context_t* c) const - { (this+colorLine).closurev1 (c); } + { + (this+colorLine).closurev1 (c); + c->num_var_idxes = 6; + } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -800,10 +844,13 @@ template class Var> struct PaintSweepGradient { void closurev1 (hb_colrv1_closure_context_t* c) const - { (this+colorLine).closurev1 (c); } + { + (this+colorLine).closurev1 (c); + c->num_var_idxes = 4; + } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -863,7 +910,7 @@ struct PaintGlyph void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -906,7 +953,7 @@ struct PaintColrGlyph void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer HB_UNUSED) const + const ItemVarStoreInstancer &instancer HB_UNUSED) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -936,7 +983,7 @@ struct PaintTransform HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -958,7 +1005,7 @@ struct PaintTransform void paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); - (this+transform).paint_glyph (c); + (this+transform).paint_glyph (c); // This does a push_transform() c->recurse (this+src); c->funcs->pop_transform (c->data); } @@ -975,7 +1022,7 @@ struct PaintTranslate HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1024,7 +1071,7 @@ struct PaintScale HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1073,7 +1120,7 @@ struct PaintScaleAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1132,7 +1179,7 @@ struct PaintScaleUniform HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1176,7 +1223,7 @@ struct PaintScaleUniformAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1232,7 +1279,7 @@ struct PaintRotate HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1276,7 +1323,7 @@ struct PaintRotateAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1332,7 +1379,7 @@ struct PaintSkew HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1381,7 +1428,7 @@ struct PaintSkewAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1440,7 +1487,7 @@ struct PaintComposite void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -1491,7 +1538,7 @@ struct ClipBoxFormat1 return_trace (c->check_struct (this)); } - void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer HB_UNUSED) const + void get_clip_box (ClipBoxData &clip_box, const ItemVarStoreInstancer &instancer HB_UNUSED) const { clip_box.xMin = xMin; clip_box.yMin = yMin; @@ -1500,7 +1547,7 @@ struct ClipBoxFormat1 } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1533,7 +1580,7 @@ struct ClipBoxFormat1 struct ClipBoxFormat2 : Variable { - void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer) const + void get_clip_box (ClipBoxData &clip_box, const ItemVarStoreInstancer &instancer) const { value.get_clip_box(clip_box, instancer); if (instancer) @@ -1544,12 +1591,15 @@ struct ClipBoxFormat2 : Variable clip_box.yMax += roundf (instancer (varIdxBase, 3)); } } + + void closurev1 (hb_colrv1_closure_context_t* c) const + { c->variation_indices->add_range (varIdxBase, varIdxBase + 3); } }; struct ClipBox { bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); switch (u.format) { @@ -1559,6 +1609,14 @@ struct ClipBox } } + void closurev1 (hb_colrv1_closure_context_t* c) const + { + switch (u.format) { + case 2: u.format2.closurev1 (c); + default:return; + } + } + template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { @@ -1572,7 +1630,7 @@ struct ClipBox } bool get_extents (hb_glyph_extents_t *extents, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { ClipBoxData clip_box; switch (u.format) { @@ -1606,9 +1664,15 @@ struct ClipRecord int cmp (hb_codepoint_t g) const { return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; } + void closurev1 (hb_colrv1_closure_context_t* c, const void *base) const + { + if (!c->glyphs->intersects (startGlyphID, endGlyphID)) return; + (base+clipBox).closurev1 (c); + } + bool subset (hb_subset_context_t *c, const void *base, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (*this); @@ -1625,7 +1689,7 @@ struct ClipRecord bool get_extents (hb_glyph_extents_t *extents, const void *base, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { return (base+clipBox).get_extents (extents, instancer); } @@ -1642,7 +1706,7 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord); struct ClipList { unsigned serialize_clip_records (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, const hb_set_t& gids, const hb_map_t& gid_offset_map) const { @@ -1695,7 +1759,7 @@ struct ClipList } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); @@ -1735,7 +1799,7 @@ struct ClipList bool get_extents (hb_codepoint_t gid, hb_glyph_extents_t *extents, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { auto *rec = clips.as_array ().bsearch (gid); if (rec) @@ -1855,7 +1919,7 @@ struct BaseGlyphPaintRecord bool serialize (hb_serialize_context_t *s, const hb_map_t* glyph_map, const void* src_base, hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SERIALIZE (this); auto *out = s->embed (this); @@ -1884,7 +1948,7 @@ struct BaseGlyphPaintRecord struct BaseGlyphList : SortedArray32Of { bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -1916,7 +1980,7 @@ struct LayerList : Array32OfOffset32To { return this+(*this)[i]; } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -1941,6 +2005,76 @@ struct LayerList : Array32OfOffset32To } }; +struct delta_set_index_map_subset_plan_t +{ + unsigned get_inner_bit_count () const { return inner_bit_count; } + unsigned get_width () const { return ((outer_bit_count + inner_bit_count + 7) / 8); } + hb_array_t get_output_map () const { return output_map.as_array (); } + + delta_set_index_map_subset_plan_t (const hb_map_t &new_deltaset_idx_varidx_map) + { + map_count = 0; + outer_bit_count = 0; + inner_bit_count = 1; + output_map.init (); + + /* search backwards */ + unsigned count = new_deltaset_idx_varidx_map.get_population (); + if (!count) return; + + unsigned last_idx = (unsigned)-1; + unsigned last_varidx = (unsigned)-1; + + for (unsigned i = count; i; i--) + { + unsigned delta_set_idx = i - 1; + unsigned var_idx = new_deltaset_idx_varidx_map.get (delta_set_idx); + if (i == count) + { + last_idx = delta_set_idx; + last_varidx = var_idx; + continue; + } + if (var_idx != last_varidx) + break; + last_idx = delta_set_idx; + } + + map_count = last_idx + 1; + } + + bool remap (const hb_map_t &new_deltaset_idx_varidx_map) + { + /* recalculate bit_count */ + outer_bit_count = 1; + inner_bit_count = 1; + + if (unlikely (!output_map.resize (map_count, false))) return false; + + for (unsigned idx = 0; idx < map_count; idx++) + { + uint32_t *var_idx; + if (!new_deltaset_idx_varidx_map.has (idx, &var_idx)) return false; + output_map.arrayZ[idx] = *var_idx; + + unsigned outer = (*var_idx) >> 16; + unsigned bit_count = (outer == 0) ? 1 : hb_bit_storage (outer); + outer_bit_count = hb_max (bit_count, outer_bit_count); + + unsigned inner = (*var_idx) & 0xFFFF; + bit_count = (inner == 0) ? 1 : hb_bit_storage (inner); + inner_bit_count = hb_max (bit_count, inner_bit_count); + } + return true; + } + + private: + unsigned map_count; + unsigned outer_bit_count; + unsigned inner_bit_count; + hb_vector_t output_map; +}; + struct COLR { static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR; @@ -1948,10 +2082,11 @@ struct COLR bool has_v0_data () const { return numBaseGlyphs; } bool has_v1_data () const { - if (version == 1) - return (this+baseGlyphList).len > 0; + if (version < 1) + return false; + hb_barrier (); - return false; + return (this+baseGlyphList).len > 0; } unsigned int get_glyph_layers (hb_codepoint_t glyph, @@ -1991,8 +2126,26 @@ struct COLR void closure_forV1 (hb_set_t *glyphset, hb_set_t *layer_indices, - hb_set_t *palette_indices) const - { colr->closure_forV1 (glyphset, layer_indices, palette_indices); } + hb_set_t *palette_indices, + hb_set_t *variation_indices, + hb_set_t *delta_set_indices) const + { colr->closure_forV1 (glyphset, layer_indices, palette_indices, variation_indices, delta_set_indices); } + + bool has_var_store () const + { return colr->has_var_store (); } + + const ItemVariationStore &get_var_store () const + { return colr->get_var_store (); } + const ItemVariationStore *get_var_store_ptr () const + { return colr->get_var_store_ptr (); } + + bool has_delta_set_index_map () const + { return colr->has_delta_set_index_map (); } + + const DeltaSetIndexMap &get_delta_set_index_map () const + { return colr->get_delta_set_index_map (); } + const DeltaSetIndexMap *get_delta_set_index_map_ptr () const + { return colr->get_delta_set_index_map_ptr (); } private: hb_blob_ptr_t colr; @@ -2029,12 +2182,16 @@ struct COLR void closure_forV1 (hb_set_t *glyphset, hb_set_t *layer_indices, - hb_set_t *palette_indices) const + hb_set_t *palette_indices, + hb_set_t *variation_indices, + hb_set_t *delta_set_indices) const { - if (version != 1) return; + if (version < 1) return; + hb_barrier (); + hb_set_t visited_glyphs; - hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices); + hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices, variation_indices); const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList; for (const BaseGlyphPaintRecord &baseglyph_paintrecord: baseglyph_paintrecords.iter ()) @@ -2046,6 +2203,22 @@ struct COLR paint.dispatch (&c); } hb_set_union (glyphset, &visited_glyphs); + + const ClipList &cliplist = this+clipList; + c.glyphs = glyphset; + for (const ClipRecord &clip_record : cliplist.clips.iter()) + clip_record.closurev1 (&c, &cliplist); + + // if a DeltaSetIndexMap is included, collected variation indices are + // actually delta set indices, we need to map them into variation indices + if (has_delta_set_index_map ()) + { + const DeltaSetIndexMap &var_idx_map = this+varIdxMap; + delta_set_indices->set (*variation_indices); + variation_indices->clear (); + for (unsigned delta_set_idx : *delta_set_indices) + variation_indices->add (var_idx_map.map (delta_set_idx)); + } } const LayerList& get_layerList () const @@ -2054,14 +2227,37 @@ struct COLR const BaseGlyphList& get_baseglyphList () const { return (this+baseGlyphList); } + bool has_var_store () const + { return version >= 1 && hb_barrier () && varStore != 0; } + + bool has_delta_set_index_map () const + { return version >= 1 && hb_barrier () && varIdxMap != 0; } + + bool has_clip_list () const + { return version >= 1 && hb_barrier () && clipList != 0; } + + const DeltaSetIndexMap &get_delta_set_index_map () const + { return has_delta_set_index_map () && hb_barrier () ? this+varIdxMap : Null (DeltaSetIndexMap); } + const DeltaSetIndexMap *get_delta_set_index_map_ptr () const + { return has_delta_set_index_map () && hb_barrier () ? &(this+varIdxMap) : nullptr; } + + const ItemVariationStore &get_var_store () const + { return has_var_store () && hb_barrier () ? this+varStore : Null (ItemVariationStore); } + const ItemVariationStore *get_var_store_ptr () const + { return has_var_store () && hb_barrier () ? &(this+varStore) : nullptr; } + + const ClipList &get_clip_list () const + { return has_clip_list () && hb_barrier () ? this+clipList : Null (ClipList); } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) && (this+layersZ).sanitize (c, numLayers) && (version == 0 || - (version == 1 && + (hb_barrier () && baseGlyphList.sanitize (c, this) && layerList.sanitize (c, this) && clipList.sanitize (c, this) && @@ -2127,6 +2323,94 @@ struct COLR return record; } + bool downgrade_to_V0 (const hb_set_t &glyphset) const + { + //no more COLRv1 glyphs, downgrade to version 0 + for (const BaseGlyphPaintRecord& _ : get_baseglyphList ()) + if (glyphset.has (_.glyphId)) + return false; + + return true; + } + + bool subset_varstore (hb_subset_context_t *c, + COLR* out /* OUT */) const + { + TRACE_SUBSET (this); + if (!varStore || c->plan->all_axes_pinned || + !c->plan->colrv1_variation_idx_delta_map) + return_trace (true); + + const ItemVariationStore& var_store = this+varStore; + if (c->plan->normalized_coords) + { + item_variations_t item_vars; + /* turn off varstore optimization when varIdxMap is null, so we maintain + * original var_idx sequence */ + bool optimize = (varIdxMap != 0) ? true : false; + if (!item_vars.instantiate (var_store, c->plan, + optimize, /* optimization */ + optimize, /* use_no_variation_idx = false */ + c->plan->colrv1_varstore_inner_maps.as_array ())) + return_trace (false); + + /* do not serialize varStore if there's no variation data after + * instancing: region_list or var_data is empty */ + if (item_vars.get_region_list () && + item_vars.get_vardata_encodings () && + !out->varStore.serialize_serialize (c->serializer, + item_vars.has_long_word (), + c->plan->axis_tags, + item_vars.get_region_list (), + item_vars.get_vardata_encodings ())) + return_trace (false); + + /* if varstore is optimized, update colrv1_new_deltaset_idx_varidx_map in + * subset plan. + * If varstore is empty after instancing, varidx_map would be empty and + * all var_idxes will be updated to VarIdx::NO_VARIATION */ + if (optimize) + { + const hb_map_t &varidx_map = item_vars.get_varidx_map (); + for (auto _ : c->plan->colrv1_new_deltaset_idx_varidx_map.iter_ref ()) + { + uint32_t varidx = _.second; + uint32_t *new_varidx; + if (varidx_map.has (varidx, &new_varidx)) + _.second = *new_varidx; + else + _.second = VarIdx::NO_VARIATION; + } + } + } + else + { + if (unlikely (!out->varStore.serialize_serialize (c->serializer, + &var_store, + c->plan->colrv1_varstore_inner_maps.as_array ()))) + return_trace (false); + } + + return_trace (true); + } + + bool subset_delta_set_index_map (hb_subset_context_t *c, + COLR* out /* OUT */) const + { + TRACE_SUBSET (this); + if (!varIdxMap || c->plan->all_axes_pinned || + !c->plan->colrv1_new_deltaset_idx_varidx_map) + return_trace (true); + + const hb_map_t &deltaset_idx_varidx_map = c->plan->colrv1_new_deltaset_idx_varidx_map; + delta_set_index_map_subset_plan_t index_map_plan (deltaset_idx_varidx_map); + + if (unlikely (!index_map_plan.remap (deltaset_idx_varidx_map))) + return_trace (false); + + return_trace (out->varIdxMap.serialize_serialize (c->serializer, index_map_plan)); + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -2195,34 +2479,30 @@ struct COLR auto *colr_prime = c->serializer->start_embed (); if (unlikely (!c->serializer->extend_min (colr_prime))) return_trace (false); - if (version == 0) - return_trace (colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)); + if (version == 0 || downgrade_to_V0 (glyphset)) + return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it)); + + hb_barrier (); - auto snap = c->serializer->snapshot (); + //start version 1 if (!c->serializer->allocate_size (5 * HBUINT32::static_size)) return_trace (false); + if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false); - VarStoreInstancer instancer (varStore ? &(this+varStore) : nullptr, - varIdxMap ? &(this+varIdxMap) : nullptr, - c->plan->normalized_coords.as_array ()); + /* subset ItemVariationStore first, cause varidx_map needs to be updated + * after instancing */ + if (!subset_varstore (c, colr_prime)) return_trace (false); - if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this, instancer)) - { - if (c->serializer->in_error ()) return_trace (false); - //no more COLRv1 glyphs: downgrade to version 0 - c->serializer->revert (snap); - return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it)); - } + ItemVarStoreInstancer instancer (get_var_store_ptr (), + get_delta_set_index_map_ptr (), + c->plan->normalized_coords.as_array ()); - if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false); + if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this, instancer)) + return_trace (false); colr_prime->layerList.serialize_subset (c, layerList, this, instancer); colr_prime->clipList.serialize_subset (c, clipList, this, instancer); - if (!varStore || c->plan->all_axes_pinned) - return_trace (true); - colr_prime->varIdxMap.serialize_copy (c->serializer, varIdxMap, this); - colr_prime->varStore.serialize_copy (c->serializer, varStore, this); - return_trace (true); + return_trace (subset_delta_set_index_map (c, colr_prime)); } const Paint *get_base_glyph_paint (hb_codepoint_t glyph) const @@ -2242,12 +2522,10 @@ struct COLR bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { - if (version != 1) - return false; - VarStoreInstancer instancer (&(this+varStore), - &(this+varIdxMap), - hb_array (font->coords, font->num_coords)); + ItemVarStoreInstancer instancer (get_var_store_ptr (), + get_delta_set_index_map_ptr (), + hb_array (font->coords, font->num_coords)); if (get_clip (glyph, extents, instancer)) { @@ -2282,8 +2560,10 @@ struct COLR bool has_paint_for_glyph (hb_codepoint_t glyph) const { - if (version == 1) + if (version >= 1) { + hb_barrier (); + const Paint *paint = get_base_glyph_paint (glyph); return paint != nullptr; @@ -2294,9 +2574,9 @@ struct COLR bool get_clip (hb_codepoint_t glyph, hb_glyph_extents_t *extents, - const VarStoreInstancer instancer) const + const ItemVarStoreInstancer instancer) const { - return (this+clipList).get_extents (glyph, + return get_clip_list ().get_extents (glyph, extents, instancer); } @@ -2305,23 +2585,23 @@ struct COLR bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const { - VarStoreInstancer instancer (&(this+varStore), - &(this+varIdxMap), - hb_array (font->coords, font->num_coords)); + ItemVarStoreInstancer instancer (get_var_store_ptr (), + get_delta_set_index_map_ptr (), + hb_array (font->coords, font->num_coords)); hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer); - c.current_glyphs.add (glyph); - if (version == 1) + hb_decycler_node_t node (c.glyphs_decycler); + node.visit (glyph); + + if (version >= 1) { + hb_barrier (); + const Paint *paint = get_base_glyph_paint (glyph); if (paint) { // COLRv1 glyph - VarStoreInstancer instancer (&(this+varStore), - &(this+varIdxMap), - hb_array (font->coords, font->num_coords)); - bool is_bounded = true; if (clip) { @@ -2404,7 +2684,7 @@ struct COLR Offset32To layerList; Offset32To clipList; // Offset to ClipList table (may be NULL) Offset32To varIdxMap; // Offset to DeltaSetIndexMap table (may be NULL) - Offset32To varStore; + Offset32To varStore; public: DEFINE_SIZE_MIN (14); }; @@ -2427,19 +2707,16 @@ void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList (); + hb_decycler_node_t node (c->layers_decycler); for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) { - if (unlikely (c->current_layers.has (i))) - continue; - - c->current_layers.add (i); + if (unlikely (!node.visit (i))) + return; const Paint &paint = paint_offset_lists.get_paint (i); c->funcs->push_group (c->data); c->recurse (paint); c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); - - c->current_layers.del (i); } } @@ -2447,16 +2724,14 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); - if (unlikely (c->current_glyphs.has (gid))) + hb_decycler_node_t node (c->glyphs_decycler); + if (unlikely (!node.visit (gid))) return; - c->current_glyphs.add (gid); - c->funcs->push_inverse_root_transform (c->data, c->font); if (c->funcs->color_glyph (c->data, gid, c->font)) { c->funcs->pop_transform (c->data); - c->current_glyphs.del (gid); return; } c->funcs->pop_transform (c->data); @@ -2479,8 +2754,6 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const if (has_clip_box) c->funcs->pop_clip (c->data); - - c->current_glyphs.del (gid); } } /* namespace OT */ diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/colrv1-closure.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/colrv1-closure.hh index 705863d4ade5c..9ed0aa5632aef 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/colrv1-closure.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/colrv1-closure.hh @@ -66,34 +66,64 @@ HB_INTERNAL void PaintColrGlyph::closurev1 (hb_colrv1_closure_context_t* c) cons template class Var> HB_INTERNAL void PaintTransform::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + (this+transform).closurev1 (c); +} HB_INTERNAL void PaintTranslate::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 2; +} HB_INTERNAL void PaintScale::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 2; +} HB_INTERNAL void PaintScaleAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 4; +} HB_INTERNAL void PaintScaleUniform::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 1; +} HB_INTERNAL void PaintScaleUniformAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 3; +} HB_INTERNAL void PaintRotate::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 1; +} HB_INTERNAL void PaintRotateAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 3; +} HB_INTERNAL void PaintSkew::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 2; +} HB_INTERNAL void PaintSkewAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 4; +} HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const { diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh index ed8f5957e9615..51fc1b52af40d 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh @@ -187,6 +187,14 @@ struct CPAL hb_ot_name_id_t get_color_name_id (unsigned int color_index) const { return v1 ().get_color_name_id (this, color_index, numColors); } + hb_array_t get_palette_colors (unsigned int palette_index) const + { + if (unlikely (palette_index >= numPalettes)) + return hb_array_t (); + unsigned int start_index = colorRecordIndicesZ[palette_index]; + hb_array_t all_colors ((this+colorRecordsZ).arrayZ, numColorRecords); + return all_colors.sub_array (start_index, numColors); + } unsigned int get_palette_colors (unsigned int palette_index, unsigned int start_offset, unsigned int *color_count, /* IN/OUT. May be NULL. */ @@ -214,13 +222,17 @@ struct CPAL hb_set_t *nameids_to_retain /* OUT */) const { if (version == 1) + { + hb_barrier (); v1 ().collect_name_ids (this, numPalettes, numColors, color_index_map, nameids_to_retain); + } } private: const CPALV1Tail& v1 () const { if (version == 0) return Null (CPALV1Tail); + hb_barrier (); return StructAfter (*this); } @@ -312,7 +324,10 @@ struct CPAL return_trace (false); if (version == 1) + { + hb_barrier (); return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map)); + } return_trace (true); } @@ -321,6 +336,7 @@ struct CPAL { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && (this+colorRecordsZ).sanitize (c, numColorRecords) && colorRecordIndicesZ.sanitize (c, numPalettes) && (version == 0 || v1 ().sanitize (c, this, numPalettes, numColors))); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh index 20b06ab13e378..e95d8c13a44b5 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh @@ -368,6 +368,7 @@ struct sbix { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version >= 1 && strikes.sanitize (c, this))); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh index c8ff6ab743e8f..9f676f9689ef7 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh @@ -56,6 +56,7 @@ struct SVGDocumentIndexEntry { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && svgDoc.sanitize (c, base, svgDocLength)); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh index 257b2a3361ac5..35d73c7b8582b 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh @@ -64,6 +64,7 @@ struct Coverage { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); @@ -95,6 +96,15 @@ struct Coverage default:return NOT_COVERED; } } + unsigned int get_coverage (hb_codepoint_t glyph_id, + hb_ot_lookup_cache_t *cache) const + { + unsigned coverage; + if (cache && cache->get (glyph_id, &coverage)) return coverage; + coverage = get_coverage (glyph_id); + if (cache) cache->set (glyph_id, coverage); + return coverage; + } unsigned get_population () const { @@ -200,6 +210,19 @@ struct Coverage } } + unsigned cost () const + { + switch (u.format) { + case 1: hb_barrier (); return u.format1.cost (); + case 2: hb_barrier (); return u.format2.cost (); +#ifndef HB_NO_BEYOND_64K + case 3: hb_barrier (); return u.format3.cost (); + case 4: hb_barrier (); return u.format4.cost (); +#endif + default:return 0u; + } + } + /* Might return false if array looks unsorted. * Used for faster rejection of corrupt data. */ template diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh index 995f1ebdbda4b..4a925763bd70b 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh @@ -103,6 +103,8 @@ struct CoverageFormat1_3 intersect_glyphs << glyphArray[i]; } + unsigned cost () const { return hb_bit_storage ((unsigned) glyphArray.len); /* bsearch cost */ } + template bool collect_coverage (set_t *glyphs) const { return glyphs->add_sorted_array (glyphArray.as_array ()); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh index d47c7eea99252..247b7274b1430 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh @@ -157,6 +157,8 @@ struct CoverageFormat2_4 } } + unsigned cost () const { return hb_bit_storage ((unsigned) rangeRecord.len); /* bsearch cost */ } + template bool collect_coverage (set_t *glyphs) const { diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh index 98543f56c3bcc..542480d2dd0e7 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh @@ -189,7 +189,7 @@ struct CaretValueFormat3 friend struct CaretValue; hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, - const VariationStore &var_store) const + const ItemVariationStore &var_store) const { return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) : @@ -251,7 +251,7 @@ struct CaretValue hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, - const VariationStore &var_store) const + const ItemVariationStore &var_store) const { switch (u.format) { case 1: return u.format1.get_caret_value (font, direction); @@ -291,6 +291,7 @@ struct CaretValue { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); @@ -315,7 +316,7 @@ struct LigGlyph unsigned get_lig_carets (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, - const VariationStore &var_store, + const ItemVariationStore &var_store, unsigned start_offset, unsigned *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const @@ -371,7 +372,7 @@ struct LigCaretList unsigned int get_lig_carets (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, - const VariationStore &var_store, + const ItemVariationStore &var_store, unsigned int start_offset, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const @@ -441,6 +442,20 @@ struct MarkGlyphSetsFormat1 bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; } + void collect_used_mark_sets (const hb_set_t& glyph_set, + hb_set_t& used_mark_sets /* OUT */) const + { + unsigned i = 0; + for (const auto &offset : coverage) + { + const auto &cov = this+offset; + if (cov.intersects (&glyph_set)) + used_mark_sets.add (i); + + i++; + } + } + template void collect_coverage (hb_vector_t &sets) const { @@ -461,6 +476,7 @@ struct MarkGlyphSetsFormat1 bool ret = true; for (const Offset32To& offset : coverage.iter ()) { + auto snap = c->serializer->snapshot (); auto *o = out->coverage.serialize_append (c->serializer); if (unlikely (!o)) { @@ -468,11 +484,17 @@ struct MarkGlyphSetsFormat1 break; } - //not using o->serialize_subset (c, offset, this, out) here because - //OTS doesn't allow null offset. - //See issue: https://github.com/khaledhosny/ots/issues/172 + //skip empty coverage c->serializer->push (); - c->dispatch (this+offset); + bool res = false; + if (offset) res = c->dispatch (this+offset); + if (!res) + { + c->serializer->pop_discard (); + c->serializer->revert (snap); + (out->coverage.len)--; + continue; + } c->serializer->add_link (*o, c->serializer->pop_pack ()); } @@ -513,6 +535,15 @@ struct MarkGlyphSets } } + void collect_used_mark_sets (const hb_set_t& glyph_set, + hb_set_t& used_mark_sets /* OUT */) const + { + switch (u.format) { + case 1: u.format1.collect_used_mark_sets (glyph_set, used_mark_sets); return; + default:return; + } + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -526,6 +557,7 @@ struct MarkGlyphSets { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); default:return_trace (true); @@ -577,7 +609,7 @@ struct GDEFVersion1_2 * definitions--from beginning of GDEF * header (may be NULL). Introduced * in version 0x00010002. */ - Offset32To + Offset32To varStore; /* Offset to the table of Item Variation * Store--from beginning of GDEF * header (may be NULL). Introduced @@ -600,8 +632,9 @@ struct GDEFVersion1_2 attachList.sanitize (c, this) && ligCaretList.sanitize (c, this) && markAttachClassDef.sanitize (c, this) && - (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) && - (version.to_int () < 0x00010003u || varStore.sanitize (c, this))); + hb_barrier () && + ((version.to_int () < 0x00010002u && hb_barrier ()) || markGlyphSetsDef.sanitize (c, this)) && + ((version.to_int () < 0x00010003u && hb_barrier ()) || varStore.sanitize (c, this))); } static void remap_varidx_after_instantiation (const hb_map_t& varidx_map, @@ -627,23 +660,23 @@ struct GDEFVersion1_2 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - auto *out = c->serializer->embed (*this); - if (unlikely (!out)) return_trace (false); - - bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true); - bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); - bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); - bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - bool subset_markglyphsetsdef = false; - if (version.to_int () >= 0x00010002u) - { - subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this); - } + // Push var store first (if it's needed) so that it's last in the + // serialization order. Some font consumers assume that varstore runs to + // the end of the GDEF table. + // See: https://github.com/harfbuzz/harfbuzz/issues/4636 + auto snapshot_version0 = c->serializer->snapshot (); + if (unlikely (version.to_int () >= 0x00010002u && hb_barrier () && !c->serializer->embed (markGlyphSetsDef))) + return_trace (false); bool subset_varstore = false; - if (version.to_int () >= 0x00010003u) + unsigned varstore_index = (unsigned) -1; + auto snapshot_version2 = c->serializer->snapshot (); + if (version.to_int () >= 0x00010003u && hb_barrier ()) { + if (unlikely (!c->serializer->embed (varStore))) return_trace (false); if (c->plan->all_axes_pinned) out->varStore = 0; else if (c->plan->normalized_coords) @@ -652,27 +685,56 @@ struct GDEFVersion1_2 { item_variations_t item_vars; if (item_vars.instantiate (this+varStore, c->plan, true, true, - c->plan->gdef_varstore_inner_maps.as_array ())) + c->plan->gdef_varstore_inner_maps.as_array ())) { subset_varstore = out->varStore.serialize_serialize (c->serializer, item_vars.has_long_word (), c->plan->axis_tags, item_vars.get_region_list (), item_vars.get_vardata_encodings ()); + varstore_index = c->serializer->last_added_child_index(); + } remap_varidx_after_instantiation (item_vars.get_varidx_map (), c->plan->layout_variation_idx_delta_map); } } else + { subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ()); + varstore_index = c->serializer->last_added_child_index(); + } + } + + out->version.major = version.major; + out->version.minor = version.minor; + + if (!subset_varstore && version.to_int () >= 0x00010002u) { + c->serializer->revert (snapshot_version2); + } + + bool subset_markglyphsetsdef = false; + if (version.to_int () >= 0x00010002u && hb_barrier ()) + { + subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this); } if (subset_varstore) { out->version.minor = 3; + c->plan->has_gdef_varstore = true; } else if (subset_markglyphsetsdef) { out->version.minor = 2; } else { out->version.minor = 0; + c->serializer->revert (snapshot_version0); + } + + bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true); + bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); + bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true); + bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); + + if (subset_varstore && varstore_index != (unsigned) -1) { + c->serializer->repack_last(varstore_index); } return_trace (subset_glyphclassdef || subset_attachlist || @@ -709,6 +771,7 @@ struct GDEF { TRACE_SANITIZE (this); if (unlikely (!u.version.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.version.major) { case 1: return_trace (u.version1.sanitize (c)); #ifndef HB_NO_BEYOND_64K @@ -812,7 +875,7 @@ struct GDEF bool has_mark_glyph_sets () const { switch (u.version.major) { - case 1: return u.version.to_int () >= 0x00010002u && u.version1.markGlyphSetsDef != 0; + case 1: return u.version.to_int () >= 0x00010002u && hb_barrier () && u.version1.markGlyphSetsDef != 0; #ifndef HB_NO_BEYOND_64K case 2: return u.version2.markGlyphSetsDef != 0; #endif @@ -822,7 +885,7 @@ struct GDEF const MarkGlyphSets &get_mark_glyph_sets () const { switch (u.version.major) { - case 1: return u.version.to_int () >= 0x00010002u ? this+u.version1.markGlyphSetsDef : Null(MarkGlyphSets); + case 1: return u.version.to_int () >= 0x00010002u && hb_barrier () ? this+u.version1.markGlyphSetsDef : Null(MarkGlyphSets); #ifndef HB_NO_BEYOND_64K case 2: return this+u.version2.markGlyphSetsDef; #endif @@ -832,21 +895,21 @@ struct GDEF bool has_var_store () const { switch (u.version.major) { - case 1: return u.version.to_int () >= 0x00010003u && u.version1.varStore != 0; + case 1: return u.version.to_int () >= 0x00010003u && hb_barrier () && u.version1.varStore != 0; #ifndef HB_NO_BEYOND_64K case 2: return u.version2.varStore != 0; #endif default: return false; } } - const VariationStore &get_var_store () const + const ItemVariationStore &get_var_store () const { switch (u.version.major) { - case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(VariationStore); + case 1: return u.version.to_int () >= 0x00010003u && hb_barrier () ? this+u.version1.varStore : Null(ItemVariationStore); #ifndef HB_NO_BEYOND_64K case 2: return this+u.version2.varStore; #endif - default: return Null(VariationStore); + default: return Null(ItemVariationStore); } } @@ -959,47 +1022,6 @@ struct GDEF void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { get_lig_caret_list ().collect_variation_indices (c); } - void remap_layout_variation_indices (const hb_set_t *layout_variation_indices, - const hb_vector_t& normalized_coords, - bool calculate_delta, /* not pinned at default */ - bool no_variations, /* all axes pinned */ - hb_hashmap_t> *layout_variation_idx_delta_map /* OUT */) const - { - if (!has_var_store ()) return; - const VariationStore &var_store = get_var_store (); - float *store_cache = var_store.create_cache (); - - unsigned new_major = 0, new_minor = 0; - unsigned last_major = (layout_variation_indices->get_min ()) >> 16; - for (unsigned idx : layout_variation_indices->iter ()) - { - int delta = 0; - if (calculate_delta) - delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ, - normalized_coords.length, store_cache)); - - if (no_variations) - { - layout_variation_idx_delta_map->set (idx, hb_pair_t (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); - continue; - } - - uint16_t major = idx >> 16; - if (major >= var_store.get_sub_table_count ()) break; - if (major != last_major) - { - new_minor = 0; - ++new_major; - } - - unsigned new_idx = (new_major << 16) + new_minor; - layout_variation_idx_delta_map->set (idx, hb_pair_t (new_idx, delta)); - ++new_minor; - last_major = major; - } - var_store.destroy_cache (store_cache); - } - protected: union { FixedVersion<> version; /* Version identifier */ diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh index 49e76e77509e6..7802e397f4cf5 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh @@ -25,6 +25,7 @@ struct Anchor { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh index 23821a49c77ad..61bd90310a51a 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh @@ -38,9 +38,15 @@ struct AnchorFormat3 *y = font->em_fscale_y (yCoordinate); if ((font->x_ppem || font->num_coords) && xDeviceTable.sanitize (&c->sanitizer, this)) + { + hb_barrier (); *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache); + } if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this)) + { + hb_barrier (); *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); + } } bool subset (hb_subset_context_t *c) const diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh index b61f1413ea5a9..9da9fff50ba89 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh @@ -8,7 +8,7 @@ namespace GPOS_impl { struct AnchorMatrix { HBUINT16 rows; /* Number of rows */ - UnsizedArrayOf> + UnsizedArrayOf> matrixZ; /* Matrix of offsets to Anchor tables-- * from beginning of AnchorMatrix table */ public: @@ -18,6 +18,7 @@ struct AnchorMatrix { TRACE_SANITIZE (this); if (!c->check_struct (this)) return_trace (false); + hb_barrier (); if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false); unsigned int count = rows * cols; if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false); @@ -25,6 +26,7 @@ struct AnchorMatrix if (c->lazy_some_gpos) return_trace (true); + hb_barrier (); for (unsigned int i = 0; i < count; i++) if (!matrixZ[i].sanitize (c, this)) return_trace (false); return_trace (true); @@ -38,6 +40,7 @@ struct AnchorMatrix if (unlikely (row >= rows || col >= cols)) return Null (Anchor); auto &offset = matrixZ[row * cols + col]; if (unlikely (!offset.sanitize (&c->sanitizer, this))) return Null (Anchor); + hb_barrier (); *found = !offset.is_null (); return this+offset; } @@ -65,15 +68,14 @@ struct AnchorMatrix if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->rows = num_rows; - bool ret = false; for (const unsigned i : index_iter) { auto *offset = c->serializer->embed (matrixZ[i]); if (!offset) return_trace (false); - ret |= offset->serialize_subset (c, matrixZ[i], this); + offset->serialize_subset (c, matrixZ[i], this); } - return_trace (ret); + return_trace (true); } }; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Common.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Common.hh index 408197454f1c7..696d25d75c889 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Common.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Common.hh @@ -23,7 +23,7 @@ static void SinglePos_serialize (hb_serialize_context_t *c, const SrcLookup *src, Iterator it, const hb_hashmap_t> *layout_variation_idx_delta_map, - bool all_axes_pinned); + unsigned new_format); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh index 3a2957af1a543..361aaed658a97 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh @@ -11,21 +11,21 @@ struct EntryExitRecord { friend struct CursivePosFormat1; - bool sanitize (hb_sanitize_context_t *c, const void *base) const + bool sanitize (hb_sanitize_context_t *c, const struct CursivePosFormat1 *base) const { TRACE_SANITIZE (this); return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); } void collect_variation_indices (hb_collect_variation_indices_context_t *c, - const void *src_base) const + const struct CursivePosFormat1 *src_base) const { (src_base+entryAnchor).collect_variation_indices (c); (src_base+exitAnchor).collect_variation_indices (c); } bool subset (hb_subset_context_t *c, - const void *src_base) const + const struct CursivePosFormat1 *src_base) const { TRACE_SERIALIZE (this); auto *out = c->serializer->embed (this); @@ -38,11 +38,11 @@ struct EntryExitRecord } protected: - Offset16To + Offset16To entryAnchor; /* Offset to EntryAnchor table--from * beginning of CursivePos * subtable--may be NULL */ - Offset16To + Offset16To exitAnchor; /* Offset to ExitAnchor table--from * beginning of CursivePos * subtable--may be NULL */ @@ -128,6 +128,7 @@ struct CursivePosFormat1 const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; if (!this_record.entryAnchor || unlikely (!this_record.entryAnchor.sanitize (&c->sanitizer, this))) return_trace (false); + hb_barrier (); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); @@ -145,6 +146,7 @@ struct CursivePosFormat1 buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); return_trace (false); } + hb_barrier (); unsigned int i = skippy_iter.idx; unsigned int j = buffer->idx; @@ -262,7 +264,7 @@ struct CursivePosFormat1 hb_requires (hb_is_iterator (Iterator))> void serialize (hb_subset_context_t *c, Iterator it, - const void *src_base) + const struct CursivePosFormat1 *src_base) { if (unlikely (!c->serializer->extend_min ((*this)))) return; this->format = 1; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh index ea196581aff85..6519e79b44395 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh @@ -42,6 +42,7 @@ struct MarkMarkPosFormat1_2 mark1Coverage.sanitize (c, this) && mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this) && + hb_barrier () && mark2Array.sanitize (c, this, (unsigned int) classCount)); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh index 478c72df750bf..597ff4c088a0d 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh @@ -36,6 +36,7 @@ struct PairPosFormat1_3 TRACE_SANITIZE (this); if (!c->check_struct (this)) return_trace (false); + hb_barrier (); unsigned int len1 = valueFormat[0].get_len (); unsigned int len2 = valueFormat[1].get_len (); @@ -102,12 +103,50 @@ struct PairPosFormat1_3 const Coverage &get_coverage () const { return this+coverage; } - bool apply (hb_ot_apply_context_t *c) const + unsigned cache_cost () const + { + return (this+coverage).cost (); + } + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + { + switch (op) + { + case hb_ot_lookup_cache_op_t::CREATE: + { + hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t)); + if (likely (cache)) + cache->clear (); + return cache; + } + case hb_ot_lookup_cache_op_t::ENTER: + return (void *) true; + case hb_ot_lookup_cache_op_t::LEAVE: + return nullptr; + case hb_ot_lookup_cache_op_t::DESTROY: + { + hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p; + hb_free (cache); + return nullptr; + } + } + return nullptr; + } + + bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } + bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } + bool _apply (hb_ot_apply_context_t *c, bool cached) const { TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache); +#else unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); +#endif + if (index == NOT_COVERED) return_trace (false); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); @@ -131,21 +170,34 @@ struct PairPosFormat1_3 auto *out = c->serializer->start_embed (*this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->format = format; - out->valueFormat[0] = valueFormat[0]; - out->valueFormat[1] = valueFormat[1]; - if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + + hb_pair_t newFormats = hb_pair (valueFormat[0], valueFormat[1]); + + if (c->plan->normalized_coords) { - hb_pair_t newFormats = compute_effective_value_formats (glyphset); - out->valueFormat[0] = newFormats.first; - out->valueFormat[1] = newFormats.second; + /* all device flags will be dropped when full instancing, no need to strip + * hints, also do not strip emtpy cause we don't compute the new default + * value during stripping */ + newFormats = compute_effective_value_formats (glyphset, false, false, &c->plan->layout_variation_idx_delta_map); } - - if (c->plan->all_axes_pinned) + /* do not strip hints for VF */ + else if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) { - out->valueFormat[0] = out->valueFormat[0].drop_device_table_flags (); - out->valueFormat[1] = out->valueFormat[1].drop_device_table_flags (); + hb_blob_t* blob = hb_face_reference_table (c->plan->source, HB_TAG ('f','v','a','r')); + bool has_fvar = (blob != hb_blob_get_empty ()); + hb_blob_destroy (blob); + + bool strip = !has_fvar; + /* special case: strip hints when a VF has no GDEF varstore after + * subsetting*/ + if (has_fvar && !c->plan->has_gdef_varstore) + strip = true; + newFormats = compute_effective_value_formats (glyphset, strip, true); } + out->valueFormat[0] = newFormats.first; + out->valueFormat[1] = newFormats.second; + hb_sorted_vector_t new_coverage; + hb_zip (this+coverage, pairSet) @@ -175,7 +227,9 @@ struct PairPosFormat1_3 } - hb_pair_t compute_effective_value_formats (const hb_set_t& glyphset) const + hb_pair_t compute_effective_value_formats (const hb_set_t& glyphset, + bool strip_hints, bool strip_empty, + const hb_hashmap_t> *varidx_delta_map = nullptr) const { unsigned record_size = PairSet::get_size (valueFormat); @@ -195,8 +249,8 @@ struct PairPosFormat1_3 { if (record->intersects (glyphset)) { - format1 = format1 | valueFormat[0].get_effective_format (record->get_values_1 ()); - format2 = format2 | valueFormat[1].get_effective_format (record->get_values_2 (valueFormat[0])); + format1 = format1 | valueFormat[0].get_effective_format (record->get_values_1 (), strip_hints, strip_empty, &set, varidx_delta_map); + format2 = format2 | valueFormat[1].get_effective_format (record->get_values_2 (valueFormat[0]), strip_hints, strip_empty, &set, varidx_delta_map); } record = &StructAtOffset (record, record_size); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh index ce6eec4f20697..d85b1ac2c1777 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh @@ -8,7 +8,7 @@ namespace Layout { namespace GPOS_impl { template -struct PairPosFormat2_4 +struct PairPosFormat2_4 : ValueBase { protected: HBUINT16 format; /* Format identifier--format = 2 */ @@ -123,12 +123,61 @@ struct PairPosFormat2_4 const Coverage &get_coverage () const { return this+coverage; } - bool apply (hb_ot_apply_context_t *c) const + struct pair_pos_cache_t + { + hb_ot_lookup_cache_t coverage; + hb_ot_lookup_cache_t first; + hb_ot_lookup_cache_t second; + }; + + unsigned cache_cost () const + { + return (this+coverage).cost () + (this+classDef1).cost () + (this+classDef2).cost (); + } + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + { + switch (op) + { + case hb_ot_lookup_cache_op_t::CREATE: + { + pair_pos_cache_t *cache = (pair_pos_cache_t *) hb_malloc (sizeof (pair_pos_cache_t)); + if (likely (cache)) + { + cache->coverage.clear (); + cache->first.clear (); + cache->second.clear (); + } + return cache; + } + case hb_ot_lookup_cache_op_t::ENTER: + return (void *) true; + case hb_ot_lookup_cache_op_t::LEAVE: + return nullptr; + case hb_ot_lookup_cache_op_t::DESTROY: + { + pair_pos_cache_t *cache = (pair_pos_cache_t *) p; + hb_free (cache); + return nullptr; + } + } + return nullptr; + } + + bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } + bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } + bool _apply (hb_ot_apply_context_t *c, bool cached) const { TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + pair_pos_cache_t *cache = cached ? (pair_pos_cache_t *) c->lookup_accel->cache : nullptr; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache ? &cache->coverage : nullptr); +#else unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); +#endif + if (index == NOT_COVERED) return_trace (false); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); @@ -139,14 +188,13 @@ struct PairPosFormat2_4 return_trace (false); } - unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint); - if (!klass2) - { - buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1); - return_trace (false); - } - +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint, cache ? &cache->first : nullptr); + unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint, cache ? &cache->second : nullptr); +#else unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint); + unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint); +#endif if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) { buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1); @@ -287,18 +335,31 @@ struct PairPosFormat2_4 unsigned len2 = valueFormat2.get_len (); hb_pair_t newFormats = hb_pair (valueFormat1, valueFormat2); - if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) - newFormats = compute_effective_value_formats (klass1_map, klass2_map); - - out->valueFormat1 = newFormats.first; - out->valueFormat2 = newFormats.second; - if (c->plan->all_axes_pinned) + if (c->plan->normalized_coords) { - out->valueFormat1 = out->valueFormat1.drop_device_table_flags (); - out->valueFormat2 = out->valueFormat2.drop_device_table_flags (); + /* in case of full instancing, all var device flags will be dropped so no + * need to strip hints here */ + newFormats = compute_effective_value_formats (klass1_map, klass2_map, false, false, &c->plan->layout_variation_idx_delta_map); + } + /* do not strip hints for VF */ + else if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + { + hb_blob_t* blob = hb_face_reference_table (c->plan->source, HB_TAG ('f','v','a','r')); + bool has_fvar = (blob != hb_blob_get_empty ()); + hb_blob_destroy (blob); + + bool strip = !has_fvar; + /* special case: strip hints when a VF has no GDEF varstore after + * subsetting*/ + if (has_fvar && !c->plan->has_gdef_varstore) + strip = true; + newFormats = compute_effective_value_formats (klass1_map, klass2_map, strip, true); } + out->valueFormat1 = newFormats.first; + out->valueFormat2 = newFormats.second; + unsigned total_len = len1 + len2; hb_vector_t class2_idxs (+ hb_range ((unsigned) class2Count) | hb_filter (klass2_map)); for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map)) @@ -311,22 +372,15 @@ struct PairPosFormat2_4 } } - const hb_set_t &glyphset = *c->plan->glyphset_gsub (); - const hb_map_t &glyph_map = *c->plan->glyph_map; - - auto it = - + hb_iter (this+coverage) - | hb_filter (glyphset) - | hb_map_retains_sorting (glyph_map) - ; - - out->coverage.serialize_serialize (c->serializer, it); - return_trace (out->class1Count && out->class2Count && bool (it)); + bool ret = out->coverage.serialize_subset(c, coverage, this); + return_trace (out->class1Count && out->class2Count && ret); } hb_pair_t compute_effective_value_formats (const hb_map_t& klass1_map, - const hb_map_t& klass2_map) const + const hb_map_t& klass2_map, + bool strip_hints, bool strip_empty, + const hb_hashmap_t> *varidx_delta_map = nullptr) const { unsigned len1 = valueFormat1.get_len (); unsigned len2 = valueFormat2.get_len (); @@ -340,8 +394,8 @@ struct PairPosFormat2_4 for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map)) { unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * record_size; - format1 = format1 | valueFormat1.get_effective_format (&values[idx]); - format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1]); + format1 = format1 | valueFormat1.get_effective_format (&values[idx], strip_hints, strip_empty, this, varidx_delta_map); + format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1], strip_hints, strip_empty, this, varidx_delta_map); } if (format1 == valueFormat1 && format2 == valueFormat2) diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh index 7ccec1df841d0..e610fcd75170e 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh @@ -9,7 +9,7 @@ namespace GPOS_impl { template -struct PairSet +struct PairSet : ValueBase { template friend struct PairPosFormat1_3; @@ -45,10 +45,12 @@ struct PairSet bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const { TRACE_SANITIZE (this); - if (!(c->check_struct (this) - && c->check_range (&firstPairValueRecord, + if (!(c->check_struct (this) && + hb_barrier () && + c->check_range (&firstPairValueRecord, len, closure->stride))) return_trace (false); + hb_barrier (); unsigned int count = len; const PairValueRecord *record = &firstPairValueRecord; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh index b32abe46d21b6..fe9595f1266ce 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh @@ -29,7 +29,7 @@ struct PairValueRecord struct context_t { - const void *base; + const ValueBase *base; const ValueFormat *valueFormats; const ValueFormat *newFormats; unsigned len1; /* valueFormats[0].get_len() */ @@ -62,7 +62,7 @@ struct PairValueRecord void collect_variation_indices (hb_collect_variation_indices_context_t *c, const ValueFormat *valueFormats, - const void *base) const + const ValueBase *base) const { unsigned record1_len = valueFormats[0].get_len (); unsigned record2_len = valueFormats[1].get_len (); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh index 3af6c49965943..a0243a218c581 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh @@ -39,14 +39,12 @@ struct SinglePos const SrcLookup* src, Iterator glyph_val_iter_pairs, const hb_hashmap_t> *layout_variation_idx_delta_map, - bool all_axes_pinned) + unsigned newFormat) { if (unlikely (!c->extend_min (u.format))) return; unsigned format = 2; - ValueFormat new_format = src->get_value_format (); - - if (all_axes_pinned) - new_format = new_format.drop_device_table_flags (); + ValueFormat new_format; + new_format = newFormat; if (glyph_val_iter_pairs) format = get_format (glyph_val_iter_pairs); @@ -89,8 +87,8 @@ SinglePos_serialize (hb_serialize_context_t *c, const SrcLookup *src, Iterator it, const hb_hashmap_t> *layout_variation_idx_delta_map, - bool all_axes_pinned) -{ c->start_embed ()->serialize (c, src, it, layout_variation_idx_delta_map, all_axes_pinned); } + unsigned new_format) +{ c->start_embed ()->serialize (c, src, it, layout_variation_idx_delta_map, new_format); } } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh index 8e21c5f8e713b..1a14be020f936 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh @@ -8,7 +8,7 @@ namespace OT { namespace Layout { namespace GPOS_impl { -struct SinglePosFormat1 +struct SinglePosFormat1 : ValueBase { protected: HBUINT16 format; /* Format identifier--format = 1 */ @@ -28,6 +28,7 @@ struct SinglePosFormat1 TRACE_SANITIZE (this); return_trace (c->check_struct (this) && coverage.sanitize (c, this) && + hb_barrier () && /* The coverage table may use a range to represent a set * of glyphs, which means a small number of bytes can * generate a large glyph set. Manually modify the @@ -66,7 +67,7 @@ struct SinglePosFormat1 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) { @@ -146,6 +147,30 @@ struct SinglePosFormat1 hb_set_t intersection; (this+coverage).intersect_set (glyphset, intersection); + unsigned new_format = valueFormat; + + if (c->plan->normalized_coords) + { + new_format = valueFormat.get_effective_format (values.arrayZ, false, false, this, &c->plan->layout_variation_idx_delta_map); + } + /* do not strip hints for VF */ + else if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + { + hb_blob_t* blob = hb_face_reference_table (c->plan->source, HB_TAG ('f','v','a','r')); + bool has_fvar = (blob != hb_blob_get_empty ()); + hb_blob_destroy (blob); + + bool strip = !has_fvar; + /* special case: strip hints when a VF has no GDEF varstore after + * subsetting*/ + if (has_fvar && !c->plan->has_gdef_varstore) + strip = true; + new_format = valueFormat.get_effective_format (values.arrayZ, + strip, /* strip hints */ + true, /* strip empty */ + this, nullptr); + } + auto it = + hb_iter (intersection) | hb_map_retains_sorting (glyph_map) @@ -153,7 +178,7 @@ struct SinglePosFormat1 ; bool ret = bool (it); - SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned); + SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, new_format); return_trace (ret); } }; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh index ddc4c18ec1c49..455796b4b27e7 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh @@ -7,7 +7,7 @@ namespace OT { namespace Layout { namespace GPOS_impl { -struct SinglePosFormat2 +struct SinglePosFormat2 : ValueBase { protected: HBUINT16 format; /* Format identifier--format = 2 */ @@ -66,7 +66,7 @@ struct SinglePosFormat2 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); if (unlikely (index >= valueCount)) return_trace (false); @@ -143,6 +143,37 @@ struct SinglePosFormat2 coverage.serialize_serialize (c, glyphs); } + template + unsigned compute_effective_format (const hb_face_t *face, + Iterator it, + bool is_instancing, bool strip_hints, + bool has_gdef_varstore, + const hb_hashmap_t> *varidx_delta_map) const + { + hb_blob_t* blob = hb_face_reference_table (face, HB_TAG ('f','v','a','r')); + bool has_fvar = (blob != hb_blob_get_empty ()); + hb_blob_destroy (blob); + + unsigned new_format = 0; + if (is_instancing) + { + new_format = new_format | valueFormat.get_effective_format (+ it | hb_map (hb_second), false, false, this, varidx_delta_map); + } + /* do not strip hints for VF */ + else if (strip_hints) + { + bool strip = !has_fvar; + if (has_fvar && !has_gdef_varstore) + strip = true; + new_format = new_format | valueFormat.get_effective_format (+ it | hb_map (hb_second), strip, true, this, nullptr); + } + else + new_format = valueFormat; + + return new_format; + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -163,8 +194,13 @@ struct SinglePosFormat2 }) ; + unsigned new_format = compute_effective_format (c->plan->source, it, + bool (c->plan->normalized_coords), + bool (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING), + c->plan->has_gdef_varstore, + &c->plan->layout_variation_idx_delta_map); bool ret = bool (it); - SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned); + SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, new_format); return_trace (ret); } }; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh index 8618cddad1c73..731d1ffca1a56 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh @@ -9,6 +9,8 @@ namespace GPOS_impl { typedef HBUINT16 Value; +struct ValueBase {}; // Dummy base class tag for OffsetTo bases. + typedef UnsizedArrayOf ValueRecord; struct ValueFormat : HBUINT16 @@ -78,7 +80,7 @@ struct ValueFormat : HBUINT16 } bool apply_value (hb_ot_apply_context_t *c, - const void *base, + const ValueBase *base, const Value *values, hb_glyph_position_t &glyph_pos) const { @@ -114,7 +116,7 @@ struct ValueFormat : HBUINT16 if (!use_x_device && !use_y_device) return ret; - const VariationStore &store = c->var_store; + const ItemVariationStore &store = c->var_store; auto *cache = c->var_store_cache; /* pixel -> fractional pixel */ @@ -142,11 +144,29 @@ struct ValueFormat : HBUINT16 return ret; } - unsigned int get_effective_format (const Value *values) const + unsigned int get_effective_format (const Value *values, bool strip_hints, bool strip_empty, const ValueBase *base, + const hb_hashmap_t> *varidx_delta_map) const { unsigned int format = *this; for (unsigned flag = xPlacement; flag <= yAdvDevice; flag = flag << 1) { - if (format & flag) should_drop (*values++, (Flags) flag, &format); + if (format & flag) + { + if (strip_hints && flag >= xPlaDevice) + { + format = format & ~flag; + values++; + continue; + } + if (varidx_delta_map && flag >= xPlaDevice) + { + update_var_flag (values++, (Flags) flag, &format, base, varidx_delta_map); + continue; + } + /* do not strip empty when instancing, cause we don't know whether the new + * default value is 0 or not */ + if (strip_empty) should_drop (*values, (Flags) flag, &format); + values++; + } } return format; @@ -154,18 +174,19 @@ struct ValueFormat : HBUINT16 template - unsigned int get_effective_format (Iterator it) const { + unsigned int get_effective_format (Iterator it, bool strip_hints, bool strip_empty, const ValueBase *base, + const hb_hashmap_t> *varidx_delta_map) const { unsigned int new_format = 0; for (const hb_array_t& values : it) - new_format = new_format | get_effective_format (&values); + new_format = new_format | get_effective_format (&values, strip_hints, strip_empty, base, varidx_delta_map); return new_format; } void copy_values (hb_serialize_context_t *c, unsigned int new_format, - const void *base, + const ValueBase *base, const Value *values, const hb_hashmap_t> *layout_variation_idx_delta_map) const { @@ -217,7 +238,7 @@ struct ValueFormat : HBUINT16 } void collect_variation_indices (hb_collect_variation_indices_context_t *c, - const void *base, + const ValueBase *base, const hb_array_t& values) const { unsigned format = *this; @@ -251,17 +272,8 @@ struct ValueFormat : HBUINT16 } } - unsigned drop_device_table_flags () const - { - unsigned format = *this; - for (unsigned flag = xPlaDevice; flag <= yAdvDevice; flag = flag << 1) - format = format & ~flag; - - return format; - } - private: - bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const + bool sanitize_value_devices (hb_sanitize_context_t *c, const ValueBase *base, const Value *values) const { unsigned int format = *this; @@ -278,17 +290,17 @@ struct ValueFormat : HBUINT16 return true; } - static inline Offset16To& get_device (Value* value) + static inline Offset16To& get_device (Value* value) { - return *static_cast *> (value); + return *static_cast *> (value); } - static inline const Offset16To& get_device (const Value* value) + static inline const Offset16To& get_device (const Value* value) { - return *static_cast *> (value); + return *static_cast *> (value); } static inline const Device& get_device (const Value* value, bool *worked, - const void *base, + const ValueBase *base, hb_sanitize_context_t &c) { if (worked) *worked |= bool (*value); @@ -296,12 +308,13 @@ struct ValueFormat : HBUINT16 if (unlikely (!offset.sanitize (&c, base))) return Null(Device); + hb_barrier (); return base + offset; } void add_delta_to_value (HBINT16 *value, - const void *base, + const ValueBase *base, const Value *src_value, const hb_hashmap_t> *layout_variation_idx_delta_map) const { @@ -313,7 +326,8 @@ struct ValueFormat : HBUINT16 *value += hb_second (*varidx_delta); } - bool copy_device (hb_serialize_context_t *c, const void *base, + bool copy_device (hb_serialize_context_t *c, + const ValueBase *base, const Value *src_value, const hb_hashmap_t> *layout_variation_idx_delta_map, unsigned int new_format, Flags flag) const @@ -354,7 +368,7 @@ struct ValueFormat : HBUINT16 return (format & devices) != 0; } - bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const + bool sanitize_value (hb_sanitize_context_t *c, const ValueBase *base, const Value *values) const { TRACE_SANITIZE (this); @@ -366,7 +380,7 @@ struct ValueFormat : HBUINT16 return_trace (!has_device () || sanitize_value_devices (c, base, values)); } - bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const + bool sanitize_values (hb_sanitize_context_t *c, const ValueBase *base, const Value *values, unsigned int count) const { TRACE_SANITIZE (this); unsigned size = get_size (); @@ -376,11 +390,12 @@ struct ValueFormat : HBUINT16 if (c->lazy_some_gpos) return_trace (true); + hb_barrier (); return_trace (sanitize_values_stride_unsafe (c, base, values, count, size)); } /* Just sanitize referenced Device tables. Doesn't check the values themselves. */ - bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count, unsigned int stride) const + bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const ValueBase *base, const Value *values, unsigned int count, unsigned int stride) const { TRACE_SANITIZE (this); @@ -403,6 +418,20 @@ struct ValueFormat : HBUINT16 *format = *format & ~flag; } + void update_var_flag (const Value* value, Flags flag, + unsigned int* format, const ValueBase *base, + const hb_hashmap_t> *varidx_delta_map) const + { + if (*value) + { + unsigned varidx = (base + get_device (value)).get_variation_index (); + hb_pair_t *varidx_delta; + if (varidx_delta_map->has (varidx, &varidx_delta) && + varidx_delta->first != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) + return; + } + *format = *format & ~flag; + } }; } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh index adec65d58646f..421a6e0662788 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh @@ -74,7 +74,7 @@ struct AlternateSubstFormat1_2 TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); return_trace ((this+alternateSet[index]).apply (c)); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh index de4a111b46cfb..726da458fac35 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh @@ -90,8 +90,17 @@ struct Ligature unsigned int total_component_count = 0; + if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return false; + unsigned match_positions_stack[4]; + unsigned *match_positions = match_positions_stack; + if (unlikely (count > ARRAY_LENGTH (match_positions_stack))) + { + match_positions = (unsigned *) hb_malloc (hb_max (count, 1u) * sizeof (unsigned)); + if (unlikely (!match_positions)) + return_trace (false); + } + unsigned int match_end = 0; - unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; if (likely (!match_input (c, count, &component[1], @@ -102,6 +111,8 @@ struct Ligature &total_component_count))) { c->buffer->unsafe_to_concat (c->buffer->idx, match_end); + if (match_positions != match_positions_stack) + hb_free (match_positions); return_trace (false); } @@ -145,6 +156,8 @@ struct Ligature pos); } + if (match_positions != match_positions_stack) + hb_free (match_positions); return_trace (true); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh index 5c7df97d13aea..6ae24b3375403 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh @@ -78,12 +78,49 @@ struct LigatureSubstFormat1_2 return lig_set.would_apply (c); } - bool apply (hb_ot_apply_context_t *c) const + unsigned cache_cost () const { - TRACE_APPLY (this); + return (this+coverage).cost (); + } + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + { + switch (op) + { + case hb_ot_lookup_cache_op_t::CREATE: + { + hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t)); + if (likely (cache)) + cache->clear (); + return cache; + } + case hb_ot_lookup_cache_op_t::ENTER: + return (void *) true; + case hb_ot_lookup_cache_op_t::LEAVE: + return nullptr; + case hb_ot_lookup_cache_op_t::DESTROY: + { + hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p; + hb_free (cache); + return nullptr; + } + } + return nullptr; + } - unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } + bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } + bool _apply (hb_ot_apply_context_t *c, bool cached) const + { + TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache); +#else + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); +#endif + if (index == NOT_COVERED) return_trace (false); const auto &lig_set = this+ligatureSet[index]; return_trace (lig_set.apply (c)); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubstFormat1.hh index 4a9972c29cc51..aec8d0f2c07f8 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubstFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubstFormat1.hh @@ -66,7 +66,7 @@ struct MultipleSubstFormat1_2 TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); return_trace ((this+sequence[index]).apply (c)); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh index ec6dfa476476c..400a9e737911f 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh @@ -33,9 +33,11 @@ struct ReverseChainSingleSubstFormat1 TRACE_SANITIZE (this); if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) return_trace (false); + hb_barrier (); const auto &lookahead = StructAfter (backtrack); if (!lookahead.sanitize (c, this)) return_trace (false); + hb_barrier (); const auto &substitute = StructAfter (lookahead); return_trace (substitute.sanitize (c)); } @@ -109,12 +111,12 @@ struct ReverseChainSingleSubstFormat1 bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); + unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); + if (index == NOT_COVERED) return_trace (false); + if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL)) return_trace (false); /* No chaining to this type */ - unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); - const auto &lookahead = StructAfter (backtrack); const auto &substitute = StructAfter (lookahead); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh index 268487c5ae770..be6cd820d2842 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -128,7 +128,7 @@ struct SingleSubstFormat1_3 TRACE_APPLY (this); hb_codepoint_t glyph_id = c->buffer->cur().codepoint; unsigned int index = (this+coverage).get_coverage (glyph_id); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); hb_codepoint_t d = deltaGlyphID; hb_codepoint_t mask = get_mask (); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh index 518900116710e..e909646045111 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh @@ -104,7 +104,7 @@ struct SingleSubstFormat2_4 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); if (unlikely (index >= substitute.len)) return_trace (false); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh index 6a43403e94b2d..527f64114b406 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh @@ -29,6 +29,9 @@ #ifndef OT_LAYOUT_TYPES_HH #define OT_LAYOUT_TYPES_HH +using hb_ot_lookup_cache_t = hb_cache_t<15, 8, 7>; +static_assert (sizeof (hb_ot_lookup_cache_t) == 256, ""); + namespace OT { namespace Layout { @@ -38,8 +41,8 @@ struct SmallTypes { using HBUINT = HBUINT16; using HBGlyphID = HBGlyphID16; using Offset = Offset16; - template - using OffsetTo = OT::Offset16To; + template + using OffsetTo = OT::Offset16To; template using ArrayOf = OT::Array16Of; template @@ -52,8 +55,8 @@ struct MediumTypes { using HBUINT = HBUINT24; using HBGlyphID = HBGlyphID24; using Offset = Offset24; - template - using OffsetTo = OT::Offset24To; + template + using OffsetTo = OT::Offset24To; template using ArrayOf = OT::Array24Of; template diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh new file mode 100644 index 0000000000000..dbbbec9eee043 --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh @@ -0,0 +1,218 @@ +#ifndef OT_VAR_VARC_VARC_HH +#define OT_VAR_VARC_VARC_HH + +#include "../../../hb-decycler.hh" +#include "../../../hb-geometry.hh" +#include "../../../hb-ot-layout-common.hh" +#include "../../../hb-ot-glyf-table.hh" +#include "../../../hb-ot-cff2-table.hh" +#include "../../../hb-ot-cff1-table.hh" + +#include "coord-setter.hh" + +namespace OT { + +//namespace Var { + +/* + * VARC -- Variable Composites + * https://github.com/harfbuzz/boring-expansion-spec/blob/main/VARC.md + */ + +#ifndef HB_NO_VAR_COMPOSITES + +struct VarComponent +{ + enum class flags_t : uint32_t + { + RESET_UNSPECIFIED_AXES = 1u << 0, + HAVE_AXES = 1u << 1, + AXIS_VALUES_HAVE_VARIATION = 1u << 2, + TRANSFORM_HAS_VARIATION = 1u << 3, + HAVE_TRANSLATE_X = 1u << 4, + HAVE_TRANSLATE_Y = 1u << 5, + HAVE_ROTATION = 1u << 6, + HAVE_CONDITION = 1u << 7, + HAVE_SCALE_X = 1u << 8, + HAVE_SCALE_Y = 1u << 9, + HAVE_TCENTER_X = 1u << 10, + HAVE_TCENTER_Y = 1u << 11, + GID_IS_24BIT = 1u << 12, + HAVE_SKEW_X = 1u << 13, + HAVE_SKEW_Y = 1u << 14, + RESERVED_MASK = ~((1u << 15) - 1), + }; + + HB_INTERNAL hb_ubytes_t + get_path_at (hb_font_t *font, + hb_codepoint_t parent_gid, + hb_draw_session_t &draw_session, + hb_array_t coords, + hb_transform_t transform, + hb_ubytes_t record, + hb_decycler_t *decycler, + signed *edges_left, + signed depth_left, + hb_glyf_scratch_t &scratch, + VarRegionList::cache_t *cache = nullptr) const; +}; + +struct VarCompositeGlyph +{ + static void + get_path_at (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_session_t &draw_session, + hb_array_t coords, + hb_transform_t transform, + hb_ubytes_t record, + hb_decycler_t *decycler, + signed *edges_left, + signed depth_left, + hb_glyf_scratch_t &scratch, + VarRegionList::cache_t *cache = nullptr) + { + while (record) + { + const VarComponent &comp = * (const VarComponent *) (record.arrayZ); + record = comp.get_path_at (font, glyph, + draw_session, coords, transform, + record, + decycler, edges_left, depth_left, scratch, cache); + } + } +}; + +HB_MARK_AS_FLAG_T (VarComponent::flags_t); + +struct VARC +{ + friend struct VarComponent; + + static constexpr hb_tag_t tableTag = HB_TAG ('V', 'A', 'R', 'C'); + + HB_INTERNAL bool + get_path_at (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_session_t &draw_session, + hb_array_t coords, + hb_transform_t transform, + hb_codepoint_t parent_glyph, + hb_decycler_t *decycler, + signed *edges_left, + signed depth_left, + hb_glyf_scratch_t &scratch) const; + + bool + get_path (hb_font_t *font, + hb_codepoint_t gid, + hb_draw_session_t &draw_session, + hb_glyf_scratch_t &scratch) const + { + hb_decycler_t decycler; + signed edges = HB_MAX_GRAPH_EDGE_COUNT; + + return get_path_at (font, + gid, + draw_session, + hb_array (font->coords, font->num_coords), + HB_TRANSFORM_IDENTITY, + HB_CODEPOINT_INVALID, + &decycler, + &edges, + HB_MAX_NESTING_LEVEL, + scratch); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (version.sanitize (c) && + hb_barrier () && + version.major == 1 && + coverage.sanitize (c, this) && + varStore.sanitize (c, this) && + conditionList.sanitize (c, this) && + axisIndicesList.sanitize (c, this) && + glyphRecords.sanitize (c, this)); + } + + struct accelerator_t + { + friend struct VarComponent; + + accelerator_t (hb_face_t *face) + { + table = hb_sanitize_context_t ().reference_table (face); + } + ~accelerator_t () + { + auto *scratch = cached_scratch.get_relaxed (); + if (scratch) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + + table.destroy (); + } + + bool + get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const + { + if (!table->has_data ()) return false; + + hb_glyf_scratch_t *scratch; + + // Borrow the cached strach buffer. + { + scratch = cached_scratch.get_acquire (); + if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) + { + scratch = (hb_glyf_scratch_t *) hb_calloc (1, sizeof (hb_glyf_scratch_t)); + if (unlikely (!scratch)) + return true; + } + } + + bool ret = table->get_path (font, gid, draw_session, *scratch); + + // Put it back. + if (!cached_scratch.cmpexch (nullptr, scratch)) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + + return ret; + } + + private: + hb_blob_ptr_t table; + hb_atomic_ptr_t cached_scratch; + }; + + bool has_data () const { return version.major != 0; } + + protected: + FixedVersion<> version; /* Version identifier */ + Offset32To coverage; + Offset32To varStore; + Offset32To conditionList; + Offset32To axisIndicesList; + Offset32To*/> glyphRecords; + public: + DEFINE_SIZE_STATIC (24); +}; + +struct VARC_accelerator_t : VARC::accelerator_t { + VARC_accelerator_t (hb_face_t *face) : VARC::accelerator_t (face) {} +}; + +#endif + +//} + +} + +#endif /* OT_VAR_VARC_VARC_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/coord-setter.hh b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/coord-setter.hh new file mode 100644 index 0000000000000..70c0968e1e405 --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/coord-setter.hh @@ -0,0 +1,63 @@ +#ifndef OT_VAR_VARC_COORD_SETTER_HH +#define OT_VAR_VARC_COORD_SETTER_HH + + +#include "../../../hb.hh" + + +namespace OT { +//namespace Var { + + +struct coord_setter_t +{ + coord_setter_t (hb_array_t coords_) + { + length = coords_.length; + if (length <= ARRAY_LENGTH (static_coords)) + hb_memcpy (static_coords, coords_.arrayZ, length * sizeof (int)); + else + dynamic_coords.extend (coords_); + } + + int& operator [] (unsigned idx) + { + if (unlikely (idx >= HB_VAR_COMPOSITE_MAX_AXES)) + return Crap(int); + + if (length <= ARRAY_LENGTH (static_coords)) + { + if (idx < ARRAY_LENGTH (static_coords)) + { + while (length <= idx) + static_coords[length++] = 0; + return static_coords[idx]; + } + else + dynamic_coords.extend (hb_array (static_coords, length)); + } + + if (dynamic_coords.length <= idx) + { + if (unlikely (!dynamic_coords.resize (idx + 1))) + return Crap(int); + length = idx + 1; + } + return dynamic_coords.arrayZ[idx]; + } + + hb_array_t get_coords () + { return length <= ARRAY_LENGTH (static_coords) ? hb_array (static_coords, length) : dynamic_coords.as_array (); } + + private: + hb_vector_t dynamic_coords; + unsigned length; + int static_coords[sizeof (void *) * 8]; +}; + + +//} // namespace Var + +} // namespace OT + +#endif /* OT_VAR_VARC_COORD_SETTER_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh index 151c1ac48cb7c..fb347770e6f42 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh @@ -143,7 +143,7 @@ struct CompositeGlyphRecord float matrix[4]; contour_point_t trans; get_transformation (matrix, trans); - if (unlikely (!points.alloc (points.length + 4))) return false; // For phantom points + if (unlikely (!points.alloc (points.length + 1 + 4))) return false; // For phantom points points.push (trans); return true; } @@ -240,7 +240,8 @@ struct CompositeGlyphRecord } if (is_anchored ()) tx = ty = 0; - trans.init ((float) tx, (float) ty); + /* set is_end_point flag to true, used by IUP delta optimization */ + trans.init ((float) tx, (float) ty, true); { const F2DOT14 *points = (const F2DOT14 *) p; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh index b295e41510fd8..1805df262aa04 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh @@ -7,8 +7,6 @@ #include "GlyphHeader.hh" #include "SimpleGlyph.hh" #include "CompositeGlyph.hh" -#include "VarCompositeGlyph.hh" -#include "coord-setter.hh" namespace OT { @@ -33,9 +31,6 @@ struct Glyph EMPTY, SIMPLE, COMPOSITE, -#ifndef HB_NO_VAR_COMPOSITES - VAR_COMPOSITE, -#endif }; public: @@ -44,22 +39,10 @@ struct Glyph if (type != COMPOSITE) return composite_iter_t (); return CompositeGlyph (*header, bytes).iter (); } - var_composite_iter_t get_var_composite_iterator () const - { -#ifndef HB_NO_VAR_COMPOSITES - if (type != VAR_COMPOSITE) return var_composite_iter_t (); - return VarCompositeGlyph (*header, bytes).iter (); -#else - return var_composite_iter_t (); -#endif - } const hb_bytes_t trim_padding () const { switch (type) { -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: return VarCompositeGlyph (*header, bytes).trim_padding (); -#endif case COMPOSITE: return CompositeGlyph (*header, bytes).trim_padding (); case SIMPLE: return SimpleGlyph (*header, bytes).trim_padding (); case EMPTY: return bytes; @@ -70,9 +53,6 @@ struct Glyph void drop_hints () { switch (type) { -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: return; // No hinting -#endif case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints (); return; case SIMPLE: SimpleGlyph (*header, bytes).drop_hints (); return; case EMPTY: return; @@ -82,9 +62,6 @@ struct Glyph void set_overlaps_flag () { switch (type) { -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: return; // No overlaps flag -#endif case COMPOSITE: CompositeGlyph (*header, bytes).set_overlaps_flag (); return; case SIMPLE: SimpleGlyph (*header, bytes).set_overlaps_flag (); return; case EMPTY: return; @@ -94,15 +71,15 @@ struct Glyph void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const { switch (type) { -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: return; // No hinting -#endif case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return; case SIMPLE: SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return; case EMPTY: return; } } + bool is_composite () const + { return type == COMPOSITE; } + bool get_all_points_without_var (const hb_face_t *face, contour_point_vector_t &points /* OUT */) const { @@ -117,14 +94,6 @@ struct Glyph if (unlikely (!item.get_points (points))) return false; break; } -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: - { - for (auto &item : get_var_composite_iterator ()) - if (unlikely (!item.get_points (points))) return false; - break; - } -#endif case EMPTY: break; } @@ -282,7 +251,8 @@ struct Glyph composite_contours_p = nullptr; } - if (!get_points (font, glyf, all_points, &points_with_deltas, head_maxp_info_p, composite_contours_p, false, false)) + hb_glyf_scratch_t scratch; + if (!get_points (font, glyf, all_points, scratch, &points_with_deltas, head_maxp_info_p, composite_contours_p, false, false)) return false; // .notdef, set type to empty so we only update metrics and don't compile bytes for @@ -300,13 +270,6 @@ struct Glyph { switch (type) { -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: - // TODO - dest_end = hb_bytes_t (); - break; -#endif - case COMPOSITE: if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start, points_with_deltas, @@ -343,27 +306,23 @@ struct Glyph template bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator, contour_point_vector_t &all_points /* OUT */, + hb_glyf_scratch_t &scratch, contour_point_vector_t *points_with_deltas = nullptr, /* OUT */ head_maxp_info_t * head_maxp_info = nullptr, /* OUT */ unsigned *composite_contours = nullptr, /* OUT */ bool shift_points_hori = true, bool use_my_metrics = true, bool phantom_only = false, - hb_array_t coords = hb_array_t (), - hb_map_t *current_glyphs = nullptr, + hb_array_t coords = hb_array_t (), unsigned int depth = 0, unsigned *edge_count = nullptr) const { if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false; unsigned stack_edge_count = 0; if (!edge_count) edge_count = &stack_edge_count; - if (unlikely (*edge_count > HB_GLYF_MAX_EDGE_COUNT)) return false; + if (unlikely (*edge_count > HB_MAX_GRAPH_EDGE_COUNT)) return false; (*edge_count)++; - hb_map_t current_glyphs_stack; - if (current_glyphs == nullptr) - current_glyphs = ¤t_glyphs_stack; - if (head_maxp_info) { head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth); @@ -372,8 +331,7 @@ struct Glyph if (!coords) coords = hb_array (font->coords, font->num_coords); - contour_point_vector_t stack_points; - contour_point_vector_t &points = type == SIMPLE ? all_points : stack_points; + contour_point_vector_t &points = type == SIMPLE ? all_points : scratch.comp_points; unsigned old_length = points.length; switch (type) { @@ -391,14 +349,6 @@ struct Glyph if (unlikely (!item.get_points (points))) return false; break; } -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: - { - for (auto &item : get_var_composite_iterator ()) - if (unlikely (!item.get_points (points))) return false; - break; - } -#endif case EMPTY: break; } @@ -434,36 +384,53 @@ struct Glyph #ifndef HB_NO_VAR if (coords) - glyf_accelerator.gvar->apply_deltas_to_points (gid, - coords, - points.as_array ().sub_array (old_length), - phantom_only && type == SIMPLE); + { +#ifndef HB_NO_BEYOND_64K + if (glyf_accelerator.GVAR->has_data ()) + glyf_accelerator.GVAR->apply_deltas_to_points (gid, + coords, + points.as_array ().sub_array (old_length), + scratch, + phantom_only && type == SIMPLE); + else +#endif + glyf_accelerator.gvar->apply_deltas_to_points (gid, + coords, + points.as_array ().sub_array (old_length), + scratch, + phantom_only && type == SIMPLE); + } #endif // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it // with child glyphs' points if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE) { - if (unlikely (!points_with_deltas->resize (points.length))) return false; + assert (old_length == 0); *points_with_deltas = points; } + float shift = 0; switch (type) { case SIMPLE: if (depth == 0 && head_maxp_info) head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, all_points.length - old_length - 4); + shift = phantoms[PHANTOM_LEFT].x; break; case COMPOSITE: { + hb_decycler_node_t decycler_node (scratch.decycler); + unsigned int comp_index = 0; for (auto &item : get_composite_iterator ()) { hb_codepoint_t item_gid = item.get_gid (); - if (unlikely (current_glyphs->has (item_gid))) + if (unlikely (!decycler_node.visit (item_gid))) + { + comp_index++; continue; - - current_glyphs->add (item_gid); + } unsigned old_count = all_points.length; @@ -472,6 +439,7 @@ struct Glyph .get_points (font, glyf_accelerator, all_points, + scratch, points_with_deltas, head_maxp_info, composite_contours, @@ -479,14 +447,16 @@ struct Glyph use_my_metrics, phantom_only, coords, - current_glyphs, depth + 1, edge_count))) { - current_glyphs->del (item_gid); + points.resize (old_length); return false; } + // points might have been reallocated. Relocate phantoms. + phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); + auto comp_points = all_points.as_array ().sub_array (old_count); /* Copy phantom points from component if USE_MY_METRICS flag set */ @@ -501,7 +471,7 @@ struct Glyph item.get_transformation (matrix, default_trans); /* Apply component transformation & translation (with deltas applied) */ - item.transform_points (comp_points, matrix, points[comp_index]); + item.transform_points (comp_points, matrix, points[old_length + comp_index]); } if (item.is_anchored () && !phantom_only) @@ -522,12 +492,11 @@ struct Glyph if (all_points.length > HB_GLYF_MAX_POINTS) { - current_glyphs->del (item_gid); + points.resize (old_length); return false; } comp_index++; - current_glyphs->del (item_gid); } if (head_maxp_info && depth == 0) @@ -538,84 +507,13 @@ struct Glyph head_maxp_info->maxComponentElements = hb_max (head_maxp_info->maxComponentElements, comp_index); } all_points.extend (phantoms); + shift = phantoms[PHANTOM_LEFT].x; + points.resize (old_length); } break; -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: - { - hb_array_t points_left = points.as_array (); - for (auto &item : get_var_composite_iterator ()) - { - hb_codepoint_t item_gid = item.get_gid (); - - if (unlikely (current_glyphs->has (item_gid))) - continue; - - current_glyphs->add (item_gid); - - unsigned item_num_points = item.get_num_points (); - hb_array_t record_points = points_left.sub_array (0, item_num_points); - assert (record_points.length == item_num_points); - - auto component_coords = coords; - /* Copying coords is expensive; so we have put an arbitrary - * limit on the max number of coords for now. */ - if (item.is_reset_unspecified_axes () || - coords.length > HB_GLYF_VAR_COMPOSITE_MAX_AXES) - component_coords = hb_array (); - - coord_setter_t coord_setter (component_coords); - item.set_variations (coord_setter, record_points); - - unsigned old_count = all_points.length; - - if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) && - !glyf_accelerator.glyph_for_gid (item_gid) - .get_points (font, - glyf_accelerator, - all_points, - points_with_deltas, - head_maxp_info, - nullptr, - shift_points_hori, - use_my_metrics, - phantom_only, - coord_setter.get_coords (), - current_glyphs, - depth + 1, - edge_count))) - { - current_glyphs->del (item_gid); - return false; - } - - auto comp_points = all_points.as_array ().sub_array (old_count); - - /* Apply component transformation */ - if (comp_points) // Empty in case of phantom_only - item.transform_points (record_points, comp_points); - - /* Copy phantom points from component if USE_MY_METRICS flag set */ - if (use_my_metrics && item.is_use_my_metrics ()) - for (unsigned int i = 0; i < PHANTOM_COUNT; i++) - phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i]; - - all_points.resize (all_points.length - PHANTOM_COUNT); - - if (all_points.length > HB_GLYF_MAX_POINTS) - { - current_glyphs->del (item_gid); - return false; - } - - points_left += item_num_points; - - current_glyphs->del (item_gid); - } - all_points.extend (phantoms); - } break; -#endif case EMPTY: all_points.extend (phantoms); + shift = phantoms[PHANTOM_LEFT].x; + points.resize (old_length); break; } @@ -624,10 +522,9 @@ struct Glyph /* Undocumented rasterizer behavior: * Shift points horizontally by the updated left side bearing */ - int v = -phantoms[PHANTOM_LEFT].x; - if (v) + if (shift) for (auto &point : all_points) - point.x += v; + point.x -= shift; } return !all_points.in_error (); @@ -658,10 +555,7 @@ struct Glyph int num_contours = header->numberOfContours; if (unlikely (num_contours == 0)) type = EMPTY; else if (num_contours > 0) type = SIMPLE; - else if (num_contours == -1) type = COMPOSITE; -#ifndef HB_NO_VAR_COMPOSITES - else if (num_contours == -2) type = VAR_COMPOSITE; -#endif + else if (num_contours <= -1) type = COMPOSITE; else type = EMPTY; // Spec deviation; Spec says COMPOSITE, but not seen in the wild. } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh index 5088397266d24..601e1303792c2 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh @@ -127,19 +127,20 @@ struct SimpleGlyph hb_array_t points_ /* IN/OUT */, const HBUINT8 *end) { + auto *points = points_.arrayZ; unsigned count = points_.length; for (unsigned int i = 0; i < count;) { if (unlikely (p + 1 > end)) return false; uint8_t flag = *p++; - points_.arrayZ[i++].flag = flag; + points[i++].flag = flag; if (flag & FLAG_REPEAT) { if (unlikely (p + 1 > end)) return false; unsigned int repeat_count = *p++; unsigned stop = hb_min (i + repeat_count, count); for (; i < stop; i++) - points_.arrayZ[i].flag = flag; + points[i].flag = flag; } } return true; @@ -160,10 +161,7 @@ struct SimpleGlyph if (flag & short_flag) { if (unlikely (p + 1 > end)) return false; - if (flag & same_flag) - v += *p++; - else - v -= *p++; + v += (bool(flag & same_flag) * 2 - 1) * *p++; } else { @@ -190,7 +188,7 @@ struct SimpleGlyph unsigned int num_points = endPtsOfContours[num_contours - 1] + 1; unsigned old_length = points.length; - points.alloc (points.length + num_points + 4, true); // Allocate for phantom points, to avoid a possible copy + points.alloc (points.length + num_points + 4); // Allocate for phantom points, to avoid a possible copy if (unlikely (!points.resize (points.length + num_points, false))) return false; auto points_ = points.as_array ().sub_array (old_length); if (!phantom_only) @@ -281,9 +279,9 @@ struct SimpleGlyph unsigned num_points = all_points.length - 4; hb_vector_t flags, x_coords, y_coords; - if (unlikely (!flags.alloc (num_points, true))) return false; - if (unlikely (!x_coords.alloc (2*num_points, true))) return false; - if (unlikely (!y_coords.alloc (2*num_points, true))) return false; + if (unlikely (!flags.alloc_exact (num_points))) return false; + if (unlikely (!x_coords.alloc_exact (2*num_points))) return false; + if (unlikely (!y_coords.alloc_exact (2*num_points))) return false; unsigned lastflag = 255, repeat = 0; int prev_x = 0, prev_y = 0; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh index 9c04d890d1abc..643b0226492ef 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh @@ -53,23 +53,12 @@ struct SubsetGlyph if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid)) const_cast (_).set_gid (new_gid); } -#ifndef HB_NO_VAR_COMPOSITES - for (auto &_ : Glyph (dest_glyph).get_var_composite_iterator ()) - { - hb_codepoint_t new_gid; - if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid)) - const_cast (_).set_gid (new_gid); - } -#endif #ifndef HB_NO_BEYOND_64K auto it = Glyph (dest_glyph).get_composite_iterator (); if (it) { - /* lower GID24 to GID16 in components if possible. - * - * TODO: VarComposite. Not as critical, since VarComposite supports - * gid24 from the first version. */ + /* lower GID24 to GID16 in components if possible. */ char *p = it ? (char *) &*it : nullptr; char *q = p; const char *end = dest_glyph.arrayZ + dest_glyph.length; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh deleted file mode 100644 index 4f29f0aab37c5..0000000000000 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh +++ /dev/null @@ -1,401 +0,0 @@ -#ifndef OT_GLYF_VARCOMPOSITEGLYPH_HH -#define OT_GLYF_VARCOMPOSITEGLYPH_HH - - -#include "../../hb-open-type.hh" -#include "coord-setter.hh" - - -namespace OT { -namespace glyf_impl { - - -struct VarCompositeGlyphRecord -{ - protected: - enum var_composite_glyph_flag_t - { - USE_MY_METRICS = 0x0001, - AXIS_INDICES_ARE_SHORT = 0x0002, - UNIFORM_SCALE = 0x0004, - HAVE_TRANSLATE_X = 0x0008, - HAVE_TRANSLATE_Y = 0x0010, - HAVE_ROTATION = 0x0020, - HAVE_SCALE_X = 0x0040, - HAVE_SCALE_Y = 0x0080, - HAVE_SKEW_X = 0x0100, - HAVE_SKEW_Y = 0x0200, - HAVE_TCENTER_X = 0x0400, - HAVE_TCENTER_Y = 0x0800, - GID_IS_24BIT = 0x1000, - AXES_HAVE_VARIATION = 0x2000, - RESET_UNSPECIFIED_AXES = 0x4000, - }; - - public: - - unsigned int get_size () const - { - unsigned fl = flags; - unsigned int size = min_size; - - unsigned axis_width = (fl & AXIS_INDICES_ARE_SHORT) ? 4 : 3; - size += numAxes * axis_width; - - if (fl & GID_IS_24BIT) size += 1; - - // 2 bytes each for the following flags - fl = fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y | - HAVE_ROTATION | - HAVE_SCALE_X | HAVE_SCALE_Y | - HAVE_SKEW_X | HAVE_SKEW_Y | - HAVE_TCENTER_X | HAVE_TCENTER_Y); - size += hb_popcount (fl) * 2; - - return size; - } - - bool has_more () const { return true; } - - bool is_use_my_metrics () const { return flags & USE_MY_METRICS; } - bool is_reset_unspecified_axes () const { return flags & RESET_UNSPECIFIED_AXES; } - - hb_codepoint_t get_gid () const - { - if (flags & GID_IS_24BIT) - return * (const HBGlyphID24 *) &pad; - else - return * (const HBGlyphID16 *) &pad; - } - - void set_gid (hb_codepoint_t gid) - { - if (flags & GID_IS_24BIT) - * (HBGlyphID24 *) &pad = gid; - else - * (HBGlyphID16 *) &pad = gid; - } - - unsigned get_numAxes () const - { - return numAxes; - } - - unsigned get_num_points () const - { - unsigned fl = flags; - unsigned num = 0; - if (fl & AXES_HAVE_VARIATION) num += numAxes; - - /* Hopefully faster code, relying on the value of the flags. */ - fl = (((fl & (HAVE_TRANSLATE_Y | HAVE_SCALE_Y | HAVE_SKEW_Y | HAVE_TCENTER_Y)) >> 1) | fl) & - (HAVE_TRANSLATE_X | HAVE_ROTATION | HAVE_SCALE_X | HAVE_SKEW_X | HAVE_TCENTER_X); - num += hb_popcount (fl); - return num; - - /* Slower but more readable code. */ - if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) num++; - if (fl & HAVE_ROTATION) num++; - if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y)) num++; - if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y)) num++; - if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) num++; - return num; - } - - void transform_points (hb_array_t record_points, - hb_array_t points) const - { - float matrix[4]; - contour_point_t trans; - - get_transformation_from_points (record_points.arrayZ, matrix, trans); - - auto arrayZ = points.arrayZ; - unsigned count = points.length; - - if (matrix[0] != 1.f || matrix[1] != 0.f || - matrix[2] != 0.f || matrix[3] != 1.f) - for (unsigned i = 0; i < count; i++) - arrayZ[i].transform (matrix); - - if (trans.x != 0.f || trans.y != 0.f) - for (unsigned i = 0; i < count; i++) - arrayZ[i].translate (trans); - } - - static inline void transform (float (&matrix)[4], contour_point_t &trans, - float (other)[6]) - { - // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L268 - float xx1 = other[0]; - float xy1 = other[1]; - float yx1 = other[2]; - float yy1 = other[3]; - float dx1 = other[4]; - float dy1 = other[5]; - float xx2 = matrix[0]; - float xy2 = matrix[1]; - float yx2 = matrix[2]; - float yy2 = matrix[3]; - float dx2 = trans.x; - float dy2 = trans.y; - - matrix[0] = xx1*xx2 + xy1*yx2; - matrix[1] = xx1*xy2 + xy1*yy2; - matrix[2] = yx1*xx2 + yy1*yx2; - matrix[3] = yx1*xy2 + yy1*yy2; - trans.x = xx2*dx1 + yx2*dy1 + dx2; - trans.y = xy2*dx1 + yy2*dy1 + dy2; - } - - static void translate (float (&matrix)[4], contour_point_t &trans, - float translateX, float translateY) - { - if (!translateX && !translateY) - return; - - trans.x += matrix[0] * translateX + matrix[2] * translateY; - trans.y += matrix[1] * translateX + matrix[3] * translateY; - } - - static void scale (float (&matrix)[4], contour_point_t &trans, - float scaleX, float scaleY) - { - if (scaleX == 1.f && scaleY == 1.f) - return; - - matrix[0] *= scaleX; - matrix[1] *= scaleX; - matrix[2] *= scaleY; - matrix[3] *= scaleY; - } - - static void rotate (float (&matrix)[4], contour_point_t &trans, - float rotation) - { - if (!rotation) - return; - - // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240 - rotation = rotation * HB_PI; - float c; - float s; -#ifdef HAVE_SINCOSF - sincosf (rotation, &s, &c); -#else - c = cosf (rotation); - s = sinf (rotation); -#endif - float other[6] = {c, s, -s, c, 0.f, 0.f}; - transform (matrix, trans, other); - } - - static void skew (float (&matrix)[4], contour_point_t &trans, - float skewX, float skewY) - { - if (!skewX && !skewY) - return; - - // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255 - skewX = skewX * HB_PI; - skewY = skewY * HB_PI; - float other[6] = {1.f, - skewY ? tanf (skewY) : 0.f, - skewX ? tanf (skewX) : 0.f, - 1.f, - 0.f, 0.f}; - transform (matrix, trans, other); - } - - bool get_points (contour_point_vector_t &points) const - { - unsigned num_points = get_num_points (); - - points.alloc (points.length + num_points + 4); // For phantom points - if (unlikely (!points.resize (points.length + num_points, false))) return false; - contour_point_t *rec_points = points.arrayZ + (points.length - num_points); - hb_memset (rec_points, 0, num_points * sizeof (rec_points[0])); - - unsigned fl = flags; - - unsigned num_axes = numAxes; - unsigned axis_width = (fl & AXIS_INDICES_ARE_SHORT) ? 2 : 1; - unsigned axes_size = num_axes * axis_width; - - const F2DOT14 *q = (const F2DOT14 *) (axes_size + - (fl & GID_IS_24BIT ? 3 : 2) + - (const HBUINT8 *) &pad); - - unsigned count = num_axes; - if (fl & AXES_HAVE_VARIATION) - { - for (unsigned i = 0; i < count; i++) - rec_points++->x = q++->to_int (); - } - else - q += count; - - const HBUINT16 *p = (const HBUINT16 *) q; - - if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) - { - int translateX = (fl & HAVE_TRANSLATE_X) ? * (const FWORD *) p++ : 0; - int translateY = (fl & HAVE_TRANSLATE_Y) ? * (const FWORD *) p++ : 0; - rec_points->x = translateX; - rec_points->y = translateY; - rec_points++; - } - if (fl & HAVE_ROTATION) - { - int rotation = (fl & HAVE_ROTATION) ? ((const F4DOT12 *) p++)->to_int () : 0; - rec_points->x = rotation; - rec_points++; - } - if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y)) - { - int scaleX = (fl & HAVE_SCALE_X) ? ((const F6DOT10 *) p++)->to_int () : 1 << 10; - int scaleY = (fl & HAVE_SCALE_Y) ? ((const F6DOT10 *) p++)->to_int () : 1 << 10; - if ((fl & UNIFORM_SCALE) && !(fl & HAVE_SCALE_Y)) - scaleY = scaleX; - rec_points->x = scaleX; - rec_points->y = scaleY; - rec_points++; - } - if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y)) - { - int skewX = (fl & HAVE_SKEW_X) ? ((const F4DOT12 *) p++)->to_int () : 0; - int skewY = (fl & HAVE_SKEW_Y) ? ((const F4DOT12 *) p++)->to_int () : 0; - rec_points->x = skewX; - rec_points->y = skewY; - rec_points++; - } - if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) - { - int tCenterX = (fl & HAVE_TCENTER_X) ? * (const FWORD *) p++ : 0; - int tCenterY = (fl & HAVE_TCENTER_Y) ? * (const FWORD *) p++ : 0; - rec_points->x = tCenterX; - rec_points->y = tCenterY; - rec_points++; - } - - return true; - } - - void get_transformation_from_points (const contour_point_t *rec_points, - float (&matrix)[4], contour_point_t &trans) const - { - unsigned fl = flags; - - if (fl & AXES_HAVE_VARIATION) - rec_points += numAxes; - - matrix[0] = matrix[3] = 1.f; - matrix[1] = matrix[2] = 0.f; - trans.init (0.f, 0.f); - - float translateX = 0.f; - float translateY = 0.f; - float rotation = 0.f; - float scaleX = 1.f; - float scaleY = 1.f; - float skewX = 0.f; - float skewY = 0.f; - float tCenterX = 0.f; - float tCenterY = 0.f; - - if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) - { - translateX = rec_points->x; - translateY = rec_points->y; - rec_points++; - } - if (fl & HAVE_ROTATION) - { - rotation = rec_points->x / (1 << 12); - rec_points++; - } - if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y)) - { - scaleX = rec_points->x / (1 << 10); - scaleY = rec_points->y / (1 << 10); - rec_points++; - } - if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y)) - { - skewX = rec_points->x / (1 << 12); - skewY = rec_points->y / (1 << 12); - rec_points++; - } - if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) - { - tCenterX = rec_points->x; - tCenterY = rec_points->y; - rec_points++; - } - - translate (matrix, trans, translateX + tCenterX, translateY + tCenterY); - rotate (matrix, trans, rotation); - scale (matrix, trans, scaleX, scaleY); - skew (matrix, trans, -skewX, skewY); - translate (matrix, trans, -tCenterX, -tCenterY); - } - - void set_variations (coord_setter_t &setter, - hb_array_t rec_points) const - { - bool have_variations = flags & AXES_HAVE_VARIATION; - unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1; - unsigned num_axes = numAxes; - - const HBUINT8 *p = (const HBUINT8 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2)); - const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2)); - - const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + num_axes) : (HBUINT8 *) (q + num_axes))); - - unsigned count = num_axes; - for (unsigned i = 0; i < count; i++) - { - unsigned axis_index = axis_width == 1 ? (unsigned) *p++ : (unsigned) *q++; - - signed v = have_variations ? rec_points.arrayZ[i].x : a++->to_int (); - - v = hb_clamp (v, -(1<<14), (1<<14)); - setter[axis_index] = v; - } - } - - protected: - HBUINT16 flags; - HBUINT8 numAxes; - HBUINT16 pad; - public: - DEFINE_SIZE_MIN (5); -}; - -using var_composite_iter_t = composite_iter_tmpl; - -struct VarCompositeGlyph -{ - const GlyphHeader &header; - hb_bytes_t bytes; - VarCompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) : - header (header_), bytes (bytes_) {} - - var_composite_iter_t iter () const - { return var_composite_iter_t (bytes, &StructAfter (header)); } - - const hb_bytes_t trim_padding () const - { - unsigned length = GlyphHeader::static_size; - for (auto &comp : iter ()) - length += comp.get_size (); - return bytes.sub_array (0, length); - } -}; - - -} /* namespace glyf_impl */ -} /* namespace OT */ - - -#endif /* OT_GLYF_VARCOMPOSITEGLYPH_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh deleted file mode 100644 index cf05929362f59..0000000000000 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef OT_GLYF_COORD_SETTER_HH -#define OT_GLYF_COORD_SETTER_HH - - -#include "../../hb.hh" - - -namespace OT { -namespace glyf_impl { - - -struct coord_setter_t -{ - coord_setter_t (hb_array_t coords) : - coords (coords) {} - - int& operator [] (unsigned idx) - { - if (unlikely (idx >= HB_GLYF_VAR_COMPOSITE_MAX_AXES)) - return Crap(int); - if (coords.length < idx + 1) - coords.resize (idx + 1); - return coords[idx]; - } - - hb_array_t get_coords () - { return coords.as_array (); } - - hb_vector_t coords; -}; - - -} /* namespace glyf_impl */ -} /* namespace OT */ - -#endif /* OT_GLYF_COORD_SETTER_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh index 3462e4d1ea5fd..bd07e941393f3 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh @@ -38,7 +38,7 @@ _write_loca (IteratorIn&& it, unsigned padded_size = *it++; offset += padded_size; - DEBUG_MSG (SUBSET, nullptr, "loca entry gid %u offset %u padded-size %u", gid, offset, padded_size); + DEBUG_MSG (SUBSET, nullptr, "loca entry gid %" PRIu32 " offset %u padded-size %u", gid, offset, padded_size); value = offset >> right_shift; *dest++ = value; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh index 175e1de308c51..681c3b9a007eb 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh @@ -94,7 +94,7 @@ struct glyf } hb_vector_t padded_offsets; - if (unlikely (!padded_offsets.alloc (c->plan->new_to_old_gid_list.length, true))) + if (unlikely (!padded_offsets.alloc_exact (c->plan->new_to_old_gid_list.length))) return_trace (false); hb_vector_t glyphs; @@ -172,6 +172,9 @@ struct glyf_accelerator_t glyf_table = nullptr; #ifndef HB_NO_VAR gvar = nullptr; +#ifndef HB_NO_BEYOND_64K + GVAR = nullptr; +#endif #endif hmtx = nullptr; #ifndef HB_NO_VERTICAL @@ -187,6 +190,9 @@ struct glyf_accelerator_t glyf_table = hb_sanitize_context_t ().reference_table (face); #ifndef HB_NO_VAR gvar = face->table.gvar; +#ifndef HB_NO_BEYOND_64K + GVAR = face->table.GVAR; +#endif #endif hmtx = face->table.hmtx; #ifndef HB_NO_VERTICAL @@ -198,6 +204,13 @@ struct glyf_accelerator_t } ~glyf_accelerator_t () { + auto *scratch = cached_scratch.get_relaxed (); + if (scratch) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + glyf_table.destroy (); } @@ -205,18 +218,17 @@ struct glyf_accelerator_t protected: template - bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer) const + bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer, + hb_array_t coords, + hb_glyf_scratch_t &scratch) const { if (gid >= num_glyphs) return false; - /* Making this allocfree is not that easy - https://github.com/harfbuzz/harfbuzz/issues/2095 - mostly because of gvar handling in VF fonts, - perhaps a separate path for non-VF fonts can be considered */ - contour_point_vector_t all_points; + auto &all_points = scratch.all_points; + all_points.resize (0); bool phantom_only = !consumer.is_consuming_contour_points (); - if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, nullptr, nullptr, true, true, phantom_only))) + if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, scratch, nullptr, nullptr, nullptr, true, true, phantom_only, coords))) return false; unsigned count = all_points.length; @@ -225,8 +237,61 @@ struct glyf_accelerator_t if (consumer.is_consuming_contour_points ()) { - for (auto &point : all_points.as_array ().sub_array (0, count)) - consumer.consume_point (point); + auto *points = all_points.arrayZ; + + if (false) + { + /* Our path-builder was designed to work with this simple loop. + * But FreeType and CoreText do it differently, so we match those + * with the other, more complicated, code branch below. */ + for (unsigned i = 0; i < count; i++) + { + consumer.consume_point (points[i]); + if (points[i].is_end_point) + consumer.contour_end (); + } + } + else + { + for (unsigned i = 0; i < count; i++) + { + // Start of a contour. + if (points[i].flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE) + { + // First point is on-curve. Draw the contour. + for (; i < count; i++) + { + consumer.consume_point (points[i]); + if (points[i].is_end_point) + { + consumer.contour_end (); + break; + } + } + } + else + { + unsigned start = i; + + // Find end of the contour. + for (; i < count; i++) + if (points[i].is_end_point) + break; + + unsigned end = i; + + // Enough to start from the end. Our path-builder takes care of the rest. + if (likely (end < count)) // Can only fail in case of alloc failure *maybe*. + consumer.consume_point (points[end]); + + for (i = start; i < end; i++) + consumer.consume_point (points[i]); + + consumer.contour_end (); + } + } + } + consumer.points_end (); } @@ -299,6 +364,7 @@ struct glyf_accelerator_t HB_ALWAYS_INLINE void consume_point (const contour_point_t &point) { bounds.add (point); } + void contour_end () {} void points_end () { bounds.get_extents (font, extents, scaled); } bool is_consuming_contour_points () { return extents; } @@ -314,7 +380,12 @@ struct glyf_accelerator_t contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; if (font->num_coords) - success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false)); + { + hb_glyf_scratch_t scratch; + success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false), + hb_array (font->coords, font->num_coords), + scratch); + } if (unlikely (!success)) return @@ -334,9 +405,11 @@ struct glyf_accelerator_t if (unlikely (gid >= num_glyphs)) return false; hb_glyph_extents_t extents; - + hb_glyf_scratch_t scratch; contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; - if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false)))) + if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false), + hb_array (font->coords, font->num_coords), + scratch))) return false; *lsb = is_vertical @@ -362,20 +435,16 @@ struct glyf_accelerator_t #ifndef HB_NO_VAR if (font->num_coords) - return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true)); + { + hb_glyf_scratch_t scratch; + return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true), + hb_array (font->coords, font->num_coords), + scratch); + } #endif return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents); } - bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const - { - funcs->push_clip_glyph (data, gid, font); - funcs->color (data, true, foreground); - funcs->pop_clip (data); - - return true; - } - const glyf_impl::Glyph glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const { @@ -406,10 +475,52 @@ struct glyf_accelerator_t bool get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const - { return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session)); } + { + if (!has_data ()) return false; + + hb_glyf_scratch_t *scratch; + + // Borrow the cached strach buffer. + { + scratch = cached_scratch.get_acquire (); + if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) + { + scratch = (hb_glyf_scratch_t *) hb_calloc (1, sizeof (hb_glyf_scratch_t)); + if (unlikely (!scratch)) + return true; + } + } + + bool ret = get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), + hb_array (font->coords, font->num_coords), + *scratch); + + // Put it back. + if (!cached_scratch.cmpexch (nullptr, scratch)) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + + return ret; + } + + bool + get_path_at (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session, + hb_array_t coords, + hb_glyf_scratch_t &scratch) const + { + if (!has_data ()) return false; + return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), + coords, + scratch); + } #ifndef HB_NO_VAR const gvar_accelerator_t *gvar; +#ifndef HB_NO_BEYOND_64K + const GVAR_accelerator_t *GVAR; +#endif #endif const hmtx_accelerator_t *hmtx; #ifndef HB_NO_VERTICAL @@ -421,6 +532,7 @@ struct glyf_accelerator_t unsigned int num_glyphs; hb_blob_ptr_t loca_table; hb_blob_ptr_t glyf_table; + hb_atomic_ptr_t cached_scratch; }; @@ -430,7 +542,7 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan, hb_vector_t& glyphs /* OUT */) const { OT::glyf_accelerator_t glyf (plan->source); - if (!glyphs.alloc (plan->new_to_old_gid_list.length, true)) return false; + if (!glyphs.alloc_exact (plan->new_to_old_gid_list.length)) return false; for (const auto &pair : plan->new_to_old_gid_list) { diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh index d56ea3e45ff4b..f5495f923328b 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh @@ -42,7 +42,7 @@ struct path_builder_t { bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE; #ifdef HB_NO_CUBIC_GLYF - bool is_cubic = false; + constexpr bool is_cubic = false; #else bool is_cubic = !is_on_curve && (point.flag & glyf_impl::SimpleGlyph::FLAG_CUBIC); #endif @@ -124,58 +124,60 @@ struct path_builder_t } } - if (unlikely (point.is_end_point)) - { - if (first_offcurve && last_offcurve) - { - optional_point_t mid = last_offcurve.mid (first_offcurve2 ? - first_offcurve2 : - first_offcurve); - if (last_offcurve2) - draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, - last_offcurve.x, last_offcurve.y, - mid.x, mid.y); - else - draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, - mid.x, mid.y); - last_offcurve = optional_point_t (); - } - /* now check the rest */ + } - if (first_offcurve && first_oncurve) - { - if (first_offcurve2) - draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y, - first_offcurve.x, first_offcurve.y, - first_oncurve.x, first_oncurve.y); - else - draw_session->quadratic_to (first_offcurve.x, first_offcurve.y, - first_oncurve.x, first_oncurve.y); - } - else if (last_offcurve && first_oncurve) - { - if (last_offcurve2) - draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, - last_offcurve.x, last_offcurve.y, - first_oncurve.x, first_oncurve.y); - else - draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, - first_oncurve.x, first_oncurve.y); - } - else if (first_oncurve) - draw_session->line_to (first_oncurve.x, first_oncurve.y); - else if (first_offcurve) - { - float x = first_offcurve.x, y = first_offcurve.y; - draw_session->move_to (x, y); - draw_session->quadratic_to (x, y, x, y); - } + void contour_end () + { + if (first_offcurve && last_offcurve) + { + optional_point_t mid = last_offcurve.mid (first_offcurve2 ? + first_offcurve2 : + first_offcurve); + if (last_offcurve2) + draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, + last_offcurve.x, last_offcurve.y, + mid.x, mid.y); + else + draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, + mid.x, mid.y); + last_offcurve = optional_point_t (); + } + /* now check the rest */ - /* Getting ready for the next contour */ - first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t (); - draw_session->close_path (); + if (first_offcurve && first_oncurve) + { + if (first_offcurve2) + draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y, + first_offcurve.x, first_offcurve.y, + first_oncurve.x, first_oncurve.y); + else + draw_session->quadratic_to (first_offcurve.x, first_offcurve.y, + first_oncurve.x, first_oncurve.y); } + else if (last_offcurve && first_oncurve) + { + if (last_offcurve2) + draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, + last_offcurve.x, last_offcurve.y, + first_oncurve.x, first_oncurve.y); + else + draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, + first_oncurve.x, first_oncurve.y); + } + else if (first_oncurve) + draw_session->line_to (first_oncurve.x, first_oncurve.y); + else if (first_offcurve) + { + float x = first_offcurve.x, y = first_offcurve.y; + draw_session->move_to (x, y); + draw_session->quadratic_to (x, y, x, y); + } + + /* Getting ready for the next contour */ + first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t (); + draw_session->close_path (); } + void points_end () {} bool is_consuming_contour_points () { return true; } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh b/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh index f14c2da2de68f..b440379afbe67 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh @@ -242,7 +242,9 @@ struct NameRecord bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && offset.sanitize (c, base, length)); + return_trace (c->check_struct (this) && + hb_barrier () && + offset.sanitize (c, base, length)); } HBUINT16 platformID; /* Platform ID. */ @@ -465,6 +467,7 @@ struct name { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (format == 0 || format == 1) && c->check_array (nameRecordZ.arrayZ, count) && c->check_range (this, stringOffset) && @@ -482,7 +485,7 @@ struct name const hb_array_t all_names (this->table->nameRecordZ.arrayZ, this->table->count); - this->names.alloc (all_names.length, true); + this->names.alloc_exact (all_names.length); for (unsigned int i = 0; i < all_names.length; i++) { diff --git a/src/java.desktop/share/native/libharfbuzz/UPDATING.txt b/src/java.desktop/share/native/libharfbuzz/UPDATING.txt index 3f72983a45576..d536fad05ac50 100644 --- a/src/java.desktop/share/native/libharfbuzz/UPDATING.txt +++ b/src/java.desktop/share/native/libharfbuzz/UPDATING.txt @@ -53,9 +53,9 @@ STEP 2: BUILD CHANGES INCREMENTALLY STEP 3: COMPILER WARNINGS AND SETTING FLAGS ------------------------------------------- -- Update make parameters in Awt2DLibraries.gmk +- Update make parameters in make/modules/java.desktop/lib/ClientLibraries.gmk Since we don't use configure we need to manually specify the options - we need in the Harfbuzz section of Awt2DLibraries.gmk. + we need in the Harfbuzz section of ClientLibraries.gmk. As well as adding new options, we may need to clean up obsolete options. Note there may be platform variations in the flags. diff --git a/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh index c1432883ffaae..da6378820bbc8 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh @@ -39,6 +39,7 @@ struct ClassDefFormat1 : public OT::ClassDefFormat1_3 int64_t vertex_len = vertex.obj.tail - vertex.obj.head; constexpr unsigned min_size = OT::ClassDefFormat1_3::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + classValue.get_size () - classValue.len.get_size (); } }; @@ -50,6 +51,7 @@ struct ClassDefFormat2 : public OT::ClassDefFormat2_4 int64_t vertex_len = vertex.obj.tail - vertex.obj.head; constexpr unsigned min_size = OT::ClassDefFormat2_4::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size (); } }; @@ -114,6 +116,7 @@ struct ClassDef : public OT::ClassDef { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::ClassDef::min_size) return false; + hb_barrier (); switch (u.format) { case 1: return ((ClassDefFormat1*)this)->sanitize (vertex); @@ -131,20 +134,23 @@ struct ClassDef : public OT::ClassDef struct class_def_size_estimator_t { + // TODO(garretrieger): update to support beyond64k coverage/classdef tables. + constexpr static unsigned class_def_format1_base_size = 6; + constexpr static unsigned class_def_format2_base_size = 4; + constexpr static unsigned coverage_base_size = 4; + constexpr static unsigned bytes_per_range = 6; + constexpr static unsigned bytes_per_glyph = 2; + template class_def_size_estimator_t (It glyph_and_class) - : gids_consecutive (true), num_ranges_per_class (), glyphs_per_class () + : num_ranges_per_class (), glyphs_per_class () { - unsigned last_gid = (unsigned) -1; + reset(); for (auto p : + glyph_and_class) { unsigned gid = p.first; unsigned klass = p.second; - if (last_gid != (unsigned) -1 && gid != last_gid + 1) - gids_consecutive = false; - last_gid = gid; - hb_set_t* glyphs; if (glyphs_per_class.has (klass, &glyphs) && glyphs) { glyphs->add (gid); @@ -174,28 +180,54 @@ struct class_def_size_estimator_t } } - // Incremental increase in the Coverage and ClassDef table size - // (worst case) if all glyphs associated with 'klass' were added. - unsigned incremental_coverage_size (unsigned klass) const + void reset() { + class_def_1_size = class_def_format1_base_size; + class_def_2_size = class_def_format2_base_size; + included_glyphs.clear(); + included_classes.clear(); + } + + // Compute the size of coverage for all glyphs added via 'add_class_def_size'. + unsigned coverage_size () const { - // Coverage takes 2 bytes per glyph worst case, - return 2 * glyphs_per_class.get (klass).get_population (); + unsigned format1_size = coverage_base_size + bytes_per_glyph * included_glyphs.get_population(); + unsigned format2_size = coverage_base_size + bytes_per_range * num_glyph_ranges(); + return hb_min(format1_size, format2_size); } - // Incremental increase in the Coverage and ClassDef table size - // (worst case) if all glyphs associated with 'klass' were added. - unsigned incremental_class_def_size (unsigned klass) const + // Compute the new size of the ClassDef table if all glyphs associated with 'klass' were added. + unsigned add_class_def_size (unsigned klass) { - // ClassDef takes 6 bytes per range - unsigned class_def_2_size = 6 * num_ranges_per_class.get (klass); - if (gids_consecutive) - { - // ClassDef1 takes 2 bytes per glyph, but only can be used - // when gids are consecutive. - return hb_min (2 * glyphs_per_class.get (klass).get_population (), class_def_2_size); + if (!included_classes.has(klass)) { + hb_set_t* glyphs = nullptr; + if (glyphs_per_class.has(klass, &glyphs)) { + included_glyphs.union_(*glyphs); + } + + class_def_1_size = class_def_format1_base_size; + if (!included_glyphs.is_empty()) { + unsigned min_glyph = included_glyphs.get_min(); + unsigned max_glyph = included_glyphs.get_max(); + class_def_1_size += bytes_per_glyph * (max_glyph - min_glyph + 1); + } + + class_def_2_size += bytes_per_range * num_ranges_per_class.get (klass); + + included_classes.add(klass); } - return class_def_2_size; + return hb_min (class_def_1_size, class_def_2_size); + } + + unsigned num_glyph_ranges() const { + hb_codepoint_t start = HB_SET_VALUE_INVALID; + hb_codepoint_t end = HB_SET_VALUE_INVALID; + + unsigned count = 0; + while (included_glyphs.next_range (&start, &end)) { + count++; + } + return count; } bool in_error () @@ -211,9 +243,12 @@ struct class_def_size_estimator_t } private: - bool gids_consecutive; hb_hashmap_t num_ranges_per_class; hb_hashmap_t glyphs_per_class; + hb_set_t included_classes; + hb_set_t included_glyphs; + unsigned class_def_1_size; + unsigned class_def_2_size; }; diff --git a/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh index 4f44e076d1f3e..61ca063e34519 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh @@ -39,6 +39,7 @@ struct CoverageFormat1 : public OT::Layout::Common::CoverageFormat1_3::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + glyphArray.get_size () - glyphArray.len.get_size (); } }; @@ -50,6 +51,7 @@ struct CoverageFormat2 : public OT::Layout::Common::CoverageFormat2_4::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size (); } }; @@ -138,6 +140,7 @@ struct Coverage : public OT::Layout::Common::Coverage { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::Layout::Common::Coverage::min_size) return false; + hb_barrier (); switch (u.format) { case 1: return ((CoverageFormat1*)this)->sanitize (vertex); diff --git a/src/java.desktop/share/native/libharfbuzz/graph/graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/graph.hh index 4a1f7ebf5a5c1..ed1026f58663c 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/graph.hh @@ -195,6 +195,15 @@ struct graph_t return incoming_edges_; } + unsigned incoming_edges_from_parent (unsigned parent_index) const { + if (single_parent != (unsigned) -1) { + return single_parent == parent_index ? 1 : 0; + } + + unsigned* count; + return parents.has(parent_index, &count) ? *count : 0; + } + void reset_parents () { incoming_edges_ = 0; @@ -334,6 +343,16 @@ struct graph_t return true; } + bool give_max_priority () + { + bool result = false; + while (!has_max_priority()) { + result = true; + priority++; + } + return result; + } + bool has_max_priority () const { return priority >= 3; } @@ -349,7 +368,7 @@ struct graph_t // it's parent where possible. int64_t modified_distance = - hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFFF); + hb_clamp (distance + distance_modifier (), (int64_t) 0, 0x7FFFFFFFFFF); if (has_max_priority ()) { modified_distance = 0; } @@ -567,6 +586,7 @@ struct graph_t update_distances (); hb_priority_queue_t queue; + queue.alloc (vertices_.length); hb_vector_t &sorted_graph = vertices_scratch_; if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return; hb_vector_t id_map; @@ -1022,6 +1042,11 @@ struct graph_t * Creates a copy of child and re-assigns the link from * parent to the clone. The copy is a shallow copy, objects * linked from child are not duplicated. + * + * Returns the index of the newly created duplicate. + * + * If the child_idx only has incoming edges from parent_idx, this + * will do nothing and return the original child_idx. */ unsigned duplicate_if_shared (unsigned parent_idx, unsigned child_idx) { @@ -1035,18 +1060,20 @@ struct graph_t * Creates a copy of child and re-assigns the link from * parent to the clone. The copy is a shallow copy, objects * linked from child are not duplicated. + * + * Returns the index of the newly created duplicate. + * + * If the child_idx only has incoming edges from parent_idx, + * duplication isn't possible and this will return -1. */ unsigned duplicate (unsigned parent_idx, unsigned child_idx) { update_parents (); - unsigned links_to_child = 0; - for (const auto& l : vertices_[parent_idx].obj.all_links ()) - { - if (l.objidx == child_idx) links_to_child++; - } + const auto& child = vertices_[child_idx]; + unsigned links_to_child = child.incoming_edges_from_parent(parent_idx); - if (vertices_[child_idx].incoming_edges () <= links_to_child) + if (child.incoming_edges () <= links_to_child) { // Can't duplicate this node, doing so would orphan the original one as all remaining links // to child are from parent. @@ -1059,7 +1086,7 @@ struct graph_t parent_idx, child_idx); unsigned clone_idx = duplicate (child_idx); - if (clone_idx == (unsigned) -1) return false; + if (clone_idx == (unsigned) -1) return -1; // duplicate shifts the root node idx, so if parent_idx was root update it. if (parent_idx == clone_idx) parent_idx++; @@ -1075,6 +1102,62 @@ struct graph_t return clone_idx; } + /* + * Creates a copy of child and re-assigns the links from + * parents to the clone. The copy is a shallow copy, objects + * linked from child are not duplicated. + * + * Returns the index of the newly created duplicate. + * + * If the child_idx only has incoming edges from parents, + * duplication isn't possible or duplication fails and this will + * return -1. + */ + unsigned duplicate (const hb_set_t* parents, unsigned child_idx) + { + if (parents->is_empty()) { + return -1; + } + + update_parents (); + + const auto& child = vertices_[child_idx]; + unsigned links_to_child = 0; + unsigned last_parent = parents->get_max(); + unsigned first_parent = parents->get_min(); + for (unsigned parent_idx : *parents) { + links_to_child += child.incoming_edges_from_parent(parent_idx); + } + + if (child.incoming_edges () <= links_to_child) + { + // Can't duplicate this node, doing so would orphan the original one as all remaining links + // to child are from parent. + DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %u, ..., %u => %u", first_parent, last_parent, child_idx); + return -1; + } + + DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %u, ..., %u => %u", first_parent, last_parent, child_idx); + + unsigned clone_idx = duplicate (child_idx); + if (clone_idx == (unsigned) -1) return false; + + for (unsigned parent_idx : *parents) { + // duplicate shifts the root node idx, so if parent_idx was root update it. + if (parent_idx == clone_idx) parent_idx++; + auto& parent = vertices_[parent_idx]; + for (auto& l : parent.obj.all_links_writer ()) + { + if (l.objidx != child_idx) + continue; + + reassign_link (l, parent_idx, clone_idx); + } + } + + return clone_idx; + } + /* * Adds a new node to the graph, not connected to anything. @@ -1370,6 +1453,7 @@ struct graph_t vertices_.tail ().distance = 0; hb_priority_queue_t queue; + queue.alloc (count); queue.insert (0, vertices_.length - 1); hb_vector_t visited; diff --git a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh index a5f9223e6059e..7ad2ba430b717 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh @@ -76,6 +76,7 @@ struct Lookup : public OT::Lookup { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::Lookup::min_size) return false; + hb_barrier (); return vertex_len >= this->get_size (); } @@ -351,6 +352,7 @@ struct LookupList : public OT::LookupList { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::LookupList::min_size) return false; + hb_barrier (); return vertex_len >= OT::LookupList::item_size * this->len; } }; @@ -364,6 +366,7 @@ struct GSTAR : public OT::GSUBGPOS GSTAR* gstar = (GSTAR*) r.obj.head; if (!gstar || !gstar->sanitize (r)) return nullptr; + hb_barrier (); return gstar; } @@ -383,6 +386,7 @@ struct GSTAR : public OT::GSUBGPOS { int64_t len = vertex.obj.tail - vertex.obj.head; if (len < OT::GSUBGPOS::min_size) return false; + hb_barrier (); return len >= get_size (); } diff --git a/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh index ae5ebd0d16756..fb4166128a952 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh @@ -40,6 +40,7 @@ struct AnchorMatrix : public OT::Layout::GPOS_impl::AnchorMatrix { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < AnchorMatrix::min_size) return false; + hb_barrier (); return vertex_len >= AnchorMatrix::min_size + OT::Offset16::static_size * class_count * this->rows; @@ -128,6 +129,7 @@ struct MarkArray : public OT::Layout::GPOS_impl::MarkArray int64_t vertex_len = vertex.obj.tail - vertex.obj.head; unsigned min_size = MarkArray::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= get_size (); } @@ -495,6 +497,7 @@ struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < u.format.get_size ()) return false; + hb_barrier (); switch (u.format) { case 1: diff --git a/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh index ad158cc9e8fae..fd46861de462a 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh @@ -42,6 +42,7 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + pairSet.get_size () - pairSet.len.get_size(); @@ -198,6 +199,7 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4::min_size; if (vertex_len < min_size) return false; + hb_barrier (); const unsigned class1_count = class1Count; return vertex_len >= @@ -245,8 +247,8 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4check_struct (this) && + hb_barrier () && version == 0 && c->check_range (this, anchorData) && lookupTable.sanitize (c, this, &(this+anchorData)))); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-bsln-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-bsln-table.hh index 24d53e224c788..b14540f3a7141 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-bsln-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-bsln-table.hh @@ -123,6 +123,7 @@ struct bsln TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && defaultBaseline < 32))) return_trace (false); + hb_barrier (); switch (format) { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh index b2d1b7b67e0cf..673c7fbe9454c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh @@ -30,6 +30,10 @@ #include "hb-aat-layout.hh" #include "hb-aat-map.hh" #include "hb-open-type.hh" +#include "hb-cache.hh" +#include "hb-bit-set.hh" +#include "hb-bit-page.hh" + namespace OT { struct GDEF; @@ -39,15 +43,18 @@ namespace AAT { using namespace OT; - struct ankr; +using hb_aat_class_cache_t = hb_cache_t<15, 8, 7>; +static_assert (sizeof (hb_aat_class_cache_t) == 256, ""); + struct hb_aat_apply_context_t : hb_dispatch_context_t { const char *get_name () { return "APPLY"; } - template - return_t dispatch (const T &obj) { return obj.apply (this); } + template + return_t dispatch (const T &obj, Ts&&... ds) + { return obj.apply (this, std::forward (ds)...); } static return_t default_return_value () { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } @@ -59,6 +66,12 @@ struct hb_aat_apply_context_t : const ankr *ankr_table; const OT::GDEF *gdef_table; const hb_sorted_vector_t *range_flags = nullptr; + bool using_buffer_glyph_set = false; + hb_bit_set_t buffer_glyph_set; + const hb_bit_set_t *left_set = nullptr; + const hb_bit_set_t *right_set = nullptr; + const hb_bit_set_t *machine_glyph_set = nullptr; + hb_aat_class_cache_t *machine_class_cache = nullptr; hb_mask_t subtable_flags = 0; /* Unused. For debug tracing only. */ @@ -74,6 +87,25 @@ struct hb_aat_apply_context_t : HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_); void set_lookup_index (unsigned int i) { lookup_index = i; } + + void setup_buffer_glyph_set () + { + using_buffer_glyph_set = buffer->len >= 4; + + if (using_buffer_glyph_set) + buffer->collect_codepoints (buffer_glyph_set); + } + bool buffer_intersects_machine () const + { + if (using_buffer_glyph_set) + return buffer_glyph_set.intersects (*machine_glyph_set); + + // Faster for shorter buffers. + for (unsigned i = 0; i < buffer->len; i++) + if (machine_glyph_set->has (buffer->info[i].codepoint)) + return true; + return false; + } }; @@ -81,6 +113,8 @@ struct hb_aat_apply_context_t : * Lookup Table */ +enum { DELETED_GLYPH = 0xFFFF }; + template struct Lookup; template @@ -95,6 +129,19 @@ struct LookupFormat0 return &arrayZ[glyph_id]; } + template + void collect_glyphs (set_t &glyphs, unsigned num_glyphs) const + { + glyphs.add_range (0, num_glyphs - 1); + } + template + void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const + { + for (unsigned i = 0; i < num_glyphs; i++) + if (filter (arrayZ[i])) + glyphs.add (i); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -123,6 +170,19 @@ struct LookupSegmentSingle int cmp (hb_codepoint_t g) const { return g < first ? -1 : g <= last ? 0 : +1 ; } + template + void collect_glyphs (set_t &glyphs) const + { + if (first == DELETED_GLYPH) return; + glyphs.add_range (first, last); + } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (!filter (value)) return; + glyphs.add_range (first, last); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -153,6 +213,21 @@ struct LookupFormat2 return v ? &v->value : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + unsigned count = segments.get_length (); + for (unsigned int i = 0; i < count; i++) + segments[i].collect_glyphs (glyphs); + } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + unsigned count = segments.get_length (); + for (unsigned int i = 0; i < count; i++) + segments[i].collect_glyphs_filtered (glyphs, filter); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -184,6 +259,21 @@ struct LookupSegmentArray return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + if (first == DELETED_GLYPH) return; + glyphs.add_range (first, last); + } + template + void collect_glyphs_filtered (set_t &glyphs, const void *base, const filter_t &filter) const + { + const auto &values = base+valuesZ; + for (hb_codepoint_t i = first; i <= last; i++) + if (filter (values[i - first])) + glyphs.add (i); + } + int cmp (hb_codepoint_t g) const { return g < first ? -1 : g <= last ? 0 : +1; } @@ -191,6 +281,7 @@ struct LookupSegmentArray { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && first <= last && valuesZ.sanitize (c, base, last - first + 1)); } @@ -199,6 +290,7 @@ struct LookupSegmentArray { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && first <= last && valuesZ.sanitize (c, base, last - first + 1, std::forward (ds)...)); } @@ -224,6 +316,21 @@ struct LookupFormat4 return v ? v->get_value (glyph_id, this) : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + unsigned count = segments.get_length (); + for (unsigned i = 0; i < count; i++) + segments[i].collect_glyphs (glyphs); + } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + unsigned count = segments.get_length (); + for (unsigned i = 0; i < count; i++) + segments[i].collect_glyphs_filtered (glyphs, this, filter); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -252,6 +359,19 @@ struct LookupSingle int cmp (hb_codepoint_t g) const { return glyph.cmp (g); } + template + void collect_glyphs (set_t &glyphs) const + { + if (glyph == DELETED_GLYPH) return; + glyphs.add (glyph); + } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (!filter (value)) return; + glyphs.add (glyph); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -281,6 +401,21 @@ struct LookupFormat6 return v ? &v->value : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + unsigned count = entries.get_length (); + for (unsigned i = 0; i < count; i++) + entries[i].collect_glyphs (glyphs); + } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + unsigned count = entries.get_length (); + for (unsigned i = 0; i < count; i++) + entries[i].collect_glyphs_filtered (glyphs, filter); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -312,6 +447,24 @@ struct LookupFormat8 &valueArrayZ[glyph_id - firstGlyph] : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; + glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1); + } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; + const T *p = valueArrayZ.arrayZ; + for (unsigned i = 0; i < glyphCount; i++) + if (filter (p[i])) + glyphs.add (firstGlyph + i); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -356,10 +509,19 @@ struct LookupFormat10 return v; } + template + void collect_glyphs (set_t &glyphs) const + { + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; + glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && valueSize <= 4 && valueArrayZ.sanitize (c, glyphCount * valueSize)); } @@ -383,11 +545,11 @@ struct Lookup const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const { switch (u.format) { - case 0: return u.format0.get_value (glyph_id, num_glyphs); - case 2: return u.format2.get_value (glyph_id); - case 4: return u.format4.get_value (glyph_id); - case 6: return u.format6.get_value (glyph_id); - case 8: return u.format8.get_value (glyph_id); + case 0: hb_barrier (); return u.format0.get_value (glyph_id, num_glyphs); + case 2: hb_barrier (); return u.format2.get_value (glyph_id); + case 4: hb_barrier (); return u.format4.get_value (glyph_id); + case 6: hb_barrier (); return u.format6.get_value (glyph_id); + case 8: hb_barrier (); return u.format8.get_value (glyph_id); default:return nullptr; } } @@ -396,13 +558,39 @@ struct Lookup { switch (u.format) { /* Format 10 cannot return a pointer. */ - case 10: return u.format10.get_value_or_null (glyph_id); + case 10: hb_barrier (); return u.format10.get_value_or_null (glyph_id); default: const T *v = get_value (glyph_id, num_glyphs); return v ? *v : Null (T); } } + template + void collect_glyphs (set_t &glyphs, unsigned int num_glyphs) const + { + switch (u.format) { + case 0: hb_barrier (); u.format0.collect_glyphs (glyphs, num_glyphs); return; + case 2: hb_barrier (); u.format2.collect_glyphs (glyphs); return; + case 4: hb_barrier (); u.format4.collect_glyphs (glyphs); return; + case 6: hb_barrier (); u.format6.collect_glyphs (glyphs); return; + case 8: hb_barrier (); u.format8.collect_glyphs (glyphs); return; + case 10: hb_barrier (); u.format10.collect_glyphs (glyphs); return; + default:return; + } + } + template + void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const + { + switch (u.format) { + case 0: hb_barrier (); u.format0.collect_glyphs_filtered (glyphs, num_glyphs, filter); return; + case 2: hb_barrier (); u.format2.collect_glyphs_filtered (glyphs, filter); return; + case 4: hb_barrier (); u.format4.collect_glyphs_filtered (glyphs, filter); return; + case 6: hb_barrier (); u.format6.collect_glyphs_filtered (glyphs, filter); return; + case 8: hb_barrier (); u.format8.collect_glyphs_filtered (glyphs, filter); return; + default:return; + } + } + typename T::type get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs, unsigned int outOfRange) const @@ -415,13 +603,14 @@ struct Lookup { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { - case 0: return_trace (u.format0.sanitize (c)); - case 2: return_trace (u.format2.sanitize (c)); - case 4: return_trace (u.format4.sanitize (c)); - case 6: return_trace (u.format6.sanitize (c)); - case 8: return_trace (u.format8.sanitize (c)); - case 10: return_trace (u.format10.sanitize (c)); + case 0: hb_barrier (); return_trace (u.format0.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); + case 4: hb_barrier (); return_trace (u.format4.sanitize (c)); + case 6: hb_barrier (); return_trace (u.format6.sanitize (c)); + case 8: hb_barrier (); return_trace (u.format8.sanitize (c)); + case 10: hb_barrier (); return_trace (u.format10.sanitize (c)); default:return_trace (true); } } @@ -429,12 +618,13 @@ struct Lookup { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { - case 0: return_trace (u.format0.sanitize (c, base)); - case 2: return_trace (u.format2.sanitize (c, base)); - case 4: return_trace (u.format4.sanitize (c, base)); - case 6: return_trace (u.format6.sanitize (c, base)); - case 8: return_trace (u.format8.sanitize (c, base)); + case 0: hb_barrier (); return_trace (u.format0.sanitize (c, base)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c, base)); + case 4: hb_barrier (); return_trace (u.format4.sanitize (c, base)); + case 6: hb_barrier (); return_trace (u.format6.sanitize (c, base)); + case 8: hb_barrier (); return_trace (u.format8.sanitize (c, base)); case 10: return_trace (false); /* We don't support format10 here currently. */ default:return_trace (true); } @@ -455,8 +645,6 @@ struct Lookup }; DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2); -enum { DELETED_GLYPH = 0xFFFF }; - /* * (Extended) State Table */ @@ -464,7 +652,7 @@ enum { DELETED_GLYPH = 0xFFFF }; template struct Entry { - // This does seem like it's ever called. + // This doesn't seem like it's ever called. bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -507,6 +695,14 @@ struct Entry DEFINE_SIZE_STATIC (4); }; +enum Class +{ + CLASS_END_OF_TEXT = 0, + CLASS_OUT_OF_BOUNDS = 1, + CLASS_DELETED_GLYPH = 2, + CLASS_END_OF_LINE = 3, +}; + template struct StateTable { @@ -519,21 +715,53 @@ struct StateTable STATE_START_OF_TEXT = 0, STATE_START_OF_LINE = 1, }; - enum Class + + template + void collect_glyphs (set_t &glyphs, unsigned num_glyphs) const { - CLASS_END_OF_TEXT = 0, - CLASS_OUT_OF_BOUNDS = 1, - CLASS_DELETED_GLYPH = 2, - CLASS_END_OF_LINE = 3, - }; + (this+classTable).collect_glyphs (glyphs, num_glyphs); + } + template + void collect_initial_glyphs (set_t &glyphs, unsigned num_glyphs, const table_t &table) const + { + unsigned num_classes = nClasses; + + if (unlikely (num_classes > hb_bit_page_t::BITS)) + { + (this+classTable).collect_glyphs (glyphs, num_glyphs); + return; + } + + // Collect all classes going out from the start state. + hb_bit_page_t filter; + + for (unsigned i = 0; i < num_classes; i++) + { + const auto &entry = get_entry (STATE_START_OF_TEXT, i); + if (new_state (entry.newState) == STATE_START_OF_TEXT && + !table.is_action_initiable (entry) && !table.is_actionable (entry)) + continue; + + filter.add (i); + } + + // And glyphs in those classes. + (this+classTable).collect_glyphs_filtered (glyphs, num_glyphs, filter); + } int new_state (unsigned int newState) const { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; } - unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const + unsigned int get_class (hb_codepoint_t glyph_id, + unsigned int num_glyphs, + hb_aat_class_cache_t *cache = nullptr) const { + unsigned klass; + if (cache && cache->get (glyph_id, &klass)) return klass; if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH; - return (this+classTable).get_class (glyph_id, num_glyphs, 1); + klass = (this+classTable).get_class (glyph_id, num_glyphs, CLASS_OUT_OF_BOUNDS); + if (cache) cache->set (glyph_id, klass); + return klass; } const Entry *get_entries () const @@ -541,13 +769,14 @@ struct StateTable const Entry &get_entry (int state, unsigned int klass) const { - if (unlikely (klass >= nClasses)) - klass = StateTable::CLASS_OUT_OF_BOUNDS; + unsigned n_classes = nClasses; + if (unlikely (klass >= n_classes)) + klass = CLASS_OUT_OF_BOUNDS; const HBUSHORT *states = (this+stateArrayTable).arrayZ; const Entry *entries = (this+entryTable).arrayZ; - unsigned int entry = states[state * nClasses + klass]; + unsigned int entry = states[state * n_classes + klass]; DEBUG_MSG (APPLY, nullptr, "e%u", entry); return entries[entry]; @@ -558,6 +787,7 @@ struct StateTable { TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && + hb_barrier () && nClasses >= 4 /* Ensure pre-defined classes fit. */ && classTable.sanitize (c, this)))) return_trace (false); @@ -684,6 +914,22 @@ struct ClassTable { return get_class (glyph_id, outOfRange); } + + template + void collect_glyphs (set_t &glyphs, unsigned num_glyphs) const + { + for (unsigned i = 0; i < classArray.len; i++) + if (classArray.arrayZ[i] != CLASS_OUT_OF_BOUNDS) + glyphs.add (firstGlyph + i); + } + template + void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const + { + for (unsigned i = 0; i < classArray.len; i++) + if (filter (classArray.arrayZ[i])) + glyphs.add (firstGlyph + i); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -697,6 +943,38 @@ struct ClassTable DEFINE_SIZE_ARRAY (4, classArray); }; +struct SubtableGlyphCoverage +{ + bool sanitize (hb_sanitize_context_t *c, unsigned subtable_count) const + { + TRACE_SANITIZE (this); + + if (unlikely (!c->check_array (&subtableOffsets, subtable_count))) + return_trace (false); + + unsigned bytes = (c->get_num_glyphs () + CHAR_BIT - 1) / CHAR_BIT; + for (unsigned i = 0; i < subtable_count; i++) + { + uint32_t offset = (uint32_t) subtableOffsets[i]; + if (offset == 0 || offset == 0xFFFFFFFF) + continue; + if (unlikely (!subtableOffsets[i].sanitize (c, this, bytes))) + return_trace (false); + } + + return_trace (true); + } + protected: + UnsizedArrayOf>> subtableOffsets; + /* Array of offsets from the beginning of the + * subtable glyph coverage table to the glyph + * coverage bitfield for a given subtable; there + * is one offset for each subtable in the chain */ + /* UnsizedArrayOf coverageBitfields; *//* The individual coverage bitfields. */ + public: + DEFINE_SIZE_ARRAY (0, subtableOffsets); +}; + struct ObsoleteTypes { static constexpr bool extended = false; @@ -766,22 +1044,22 @@ struct ExtendedTypes } }; -template +template struct StateTableDriver { using StateTableT = StateTable; using EntryT = Entry; StateTableDriver (const StateTableT &machine_, - hb_buffer_t *buffer_, hb_face_t *face_) : machine (machine_), - buffer (buffer_), num_glyphs (face_->get_num_glyphs ()) {} template void drive (context_t *c, hb_aat_apply_context_t *ac) { + hb_buffer_t *buffer = ac->buffer; + if (!c->in_place) buffer->clear_output (); @@ -816,9 +1094,9 @@ struct StateTableDriver } } - unsigned int klass = buffer->idx < buffer->len ? - machine.get_class (buffer->cur().codepoint, num_glyphs) : - (unsigned) StateTableT::CLASS_END_OF_TEXT; + unsigned int klass = likely (buffer->idx < buffer->len) ? + machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_class_cache) : + (unsigned) CLASS_END_OF_TEXT; DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); const EntryT &entry = machine.get_entry (state, klass); const int next_state = machine.new_state (entry.newState); @@ -851,44 +1129,39 @@ struct StateTableDriver * * https://github.com/harfbuzz/harfbuzz/issues/2860 */ - - const auto is_safe_to_break_extra = [&]() - { - /* 2c. */ - const auto wouldbe_entry = machine.get_entry(StateTableT::STATE_START_OF_TEXT, klass); - - /* 2c'. */ - if (c->is_actionable (this, wouldbe_entry)) - return false; - - /* 2c". */ - return next_state == machine.new_state(wouldbe_entry.newState) - && (entry.flags & context_t::DontAdvance) == (wouldbe_entry.flags & context_t::DontAdvance); - }; - - const auto is_safe_to_break = [&]() - { + const EntryT *wouldbe_entry; + bool is_safe_to_break = + ( /* 1. */ - if (c->is_actionable (this, entry)) - return false; + !c->table->is_actionable (entry) && /* 2. */ // This one is meh, I know... - const auto ok = + ( state == StateTableT::STATE_START_OF_TEXT - || ((entry.flags & context_t::DontAdvance) && next_state == StateTableT::STATE_START_OF_TEXT) - || is_safe_to_break_extra(); - if (!ok) - return false; + || ((entry.flags & Flags::DontAdvance) && next_state == StateTableT::STATE_START_OF_TEXT) + || ( + /* 2c. */ + wouldbe_entry = &machine.get_entry(StateTableT::STATE_START_OF_TEXT, klass) + , + /* 2c'. */ + !c->table->is_actionable (*wouldbe_entry) && + /* 2c". */ + ( + next_state == machine.new_state(wouldbe_entry->newState) && + (entry.flags & Flags::DontAdvance) == (wouldbe_entry->flags & Flags::DontAdvance) + ) + ) + ) && /* 3. */ - return !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT)); - }; + !c->table->is_actionable (machine.get_entry (state, CLASS_END_OF_TEXT)) + ); - if (!is_safe_to_break () && buffer->backtrack_len () && buffer->idx < buffer->len) + if (!is_safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len) buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1); - c->transition (this, entry); + c->transition (buffer, this, entry); state = next_state; DEBUG_MSG (APPLY, nullptr, "s%d", state); @@ -896,7 +1169,7 @@ struct StateTableDriver if (buffer->idx == buffer->len || unlikely (!buffer->successful)) break; - if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0) + if (!(entry.flags & Flags::DontAdvance) || buffer->max_ops-- <= 0) (void) buffer->next_glyph (); } @@ -906,7 +1179,6 @@ struct StateTableDriver public: const StateTableT &machine; - hb_buffer_t *buffer; unsigned int num_glyphs; }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-feat-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-feat-table.hh index 04260a946168a..7b68a932c3f1e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-feat-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-feat-table.hh @@ -138,6 +138,7 @@ struct FeatureName { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && (base+settingTableZ).sanitize (c, nSettings))); } @@ -200,6 +201,7 @@ struct feat { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && namesZ.sanitize (c, featureNameCount, this))); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-just-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-just-table.hh index 0588310b53b78..193d14d94d075 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-just-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-just-table.hh @@ -185,15 +185,16 @@ struct ActionSubrecord TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (u.header.actionType) { - case 0: return_trace (u.decompositionAction.sanitize (c)); - case 1: return_trace (u.unconditionalAddGlyphAction.sanitize (c)); - case 2: return_trace (u.conditionalAddGlyphAction.sanitize (c)); - // case 3: return_trace (u.stretchGlyphAction.sanitize (c)); - case 4: return_trace (u.decompositionAction.sanitize (c)); - case 5: return_trace (u.decompositionAction.sanitize (c)); + case 0: hb_barrier (); return_trace (u.decompositionAction.sanitize (c)); + case 1: hb_barrier (); return_trace (u.unconditionalAddGlyphAction.sanitize (c)); + case 2: hb_barrier (); return_trace (u.conditionalAddGlyphAction.sanitize (c)); + // case 3: hb_barrier (); return_trace (u.stretchGlyphAction.sanitize (c)); + case 4: hb_barrier (); return_trace (u.decompositionAction.sanitize (c)); + case 5: hb_barrier (); return_trace (u.decompositionAction.sanitize (c)); default: return_trace (true); } } @@ -220,6 +221,7 @@ struct PostcompensationActionChain TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); unsigned int offset = min_size; for (unsigned int i = 0; i < count; i++) @@ -389,6 +391,7 @@ struct just TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && horizData.sanitize (c, this, this) && vertData.sanitize (c, this, this))); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh index 2bc7b03ce896f..a091b05660c5a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh @@ -30,6 +30,7 @@ #include "hb-kern.hh" #include "hb-aat-layout-ankr-table.hh" +#include "hb-set-digest.hh" /* * kerx -- Extended Kerning @@ -54,6 +55,7 @@ kerxTupleKern (int value, unsigned int offset = value; const FWORD *pv = &StructAtOffset (base, offset); if (unlikely (!c->sanitizer.check_array (pv, tupleCount))) return 0; + hb_barrier (); return *pv; } @@ -81,7 +83,7 @@ struct KernPair return_trace (c->check_struct (this)); } - protected: + public: HBGlyphID16 left; HBGlyphID16 right; FWORD value; @@ -105,10 +107,10 @@ struct KerxSubTableFormat0 TRACE_APPLY (this); if (!c->plan->requested_kerning) - return false; + return_trace (false); if (header.coverage & header.Backwards) - return false; + return_trace (false); accelerator_t accel (*this, c); hb_kern_machine_t machine (accel, header.coverage & header.CrossStream); @@ -117,6 +119,16 @@ struct KerxSubTableFormat0 return_trace (true); } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + for (const KernPair& pair : pairs) + { + left_set.add (pair.left); + right_set.add (pair.right); + } + } + struct accelerator_t { const KerxSubTableFormat0 &table; @@ -127,7 +139,10 @@ struct KerxSubTableFormat0 table (table_), c (c_) {} int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return table.get_kerning (left, right, c); } + { + if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; + return table.get_kerning (left, right, c); + } }; @@ -192,6 +207,9 @@ struct Format1Entry typedef void EntryData; + static bool initiateAction (const Entry &entry) + { return entry.flags & Push; } + static bool performAction (const Entry &entry) { return entry.flags & Offset; } @@ -208,13 +226,23 @@ struct KerxSubTableFormat1 typedef Format1Entry Format1EntryT; typedef typename Format1EntryT::EntryData EntryData; + enum Flags + { + DontAdvance = Format1EntryT::DontAdvance, + }; + + bool is_action_initiable (const Entry &entry) const + { + return Format1EntryT::initiateAction (entry); + } + bool is_actionable (const Entry &entry) const + { + return Format1EntryT::performAction (entry); + } + struct driver_context_t { static constexpr bool in_place = true; - enum - { - DontAdvance = Format1EntryT::DontAdvance, - }; driver_context_t (const KerxSubTableFormat1 *table_, hb_aat_apply_context_t *c_) : @@ -227,13 +255,10 @@ struct KerxSubTableFormat1 depth (0), crossStream (table->header.coverage & table->header.CrossStream) {} - bool is_actionable (StateTableDriver *driver HB_UNUSED, - const Entry &entry) - { return Format1EntryT::performAction (entry); } - void transition (StateTableDriver *driver, + void transition (hb_buffer_t *buffer, + StateTableDriver *driver, const Entry &entry) { - hb_buffer_t *buffer = driver->buffer; unsigned int flags = entry.flags; if (flags & Format1EntryT::Reset) @@ -259,6 +284,7 @@ struct KerxSubTableFormat1 depth = 0; return; } + hb_barrier (); hb_mask_t kern_mask = c->plan->kern_mask; @@ -330,9 +356,10 @@ struct KerxSubTableFormat1 } } - private: + public: hb_aat_apply_context_t *c; const KerxSubTableFormat1 *table; + private: const UnsizedArrayOf &kernAction; unsigned int stack[8]; unsigned int depth; @@ -349,7 +376,8 @@ struct KerxSubTableFormat1 driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->font->face); + StateTableDriver driver (machine, c->font->face); + driver.drive (&dc, c); return_trace (true); @@ -363,12 +391,21 @@ struct KerxSubTableFormat1 machine.sanitize (c))); } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + set_t set; + machine.collect_glyphs (set, num_glyphs); + left_set.union_ (set); + right_set.union_ (set); + } + protected: KernSubTableHeader header; StateTable machine; NNOffsetTo, HBUINT> kernAction; public: - DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 5 * sizeof (HBUINT)); + DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + (StateTable::static_size + HBUINT::static_size)); }; template @@ -389,6 +426,7 @@ struct KerxSubTableFormat2 kern_idx = Types::offsetToIndex (kern_idx, this, arrayZ.arrayZ); const FWORD *v = &arrayZ[kern_idx]; if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + hb_barrier (); return kerxTupleKern (*v, header.tuple_count (), this, c); } @@ -398,10 +436,10 @@ struct KerxSubTableFormat2 TRACE_APPLY (this); if (!c->plan->requested_kerning) - return false; + return_trace (false); if (header.coverage & header.Backwards) - return false; + return_trace (false); accelerator_t accel (*this, c); hb_kern_machine_t machine (accel, header.coverage & header.CrossStream); @@ -410,6 +448,13 @@ struct KerxSubTableFormat2 return_trace (true); } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + (this+leftClassTable).collect_glyphs (left_set, num_glyphs); + (this+rightClassTable).collect_glyphs (right_set, num_glyphs); + } + struct accelerator_t { const KerxSubTableFormat2 &table; @@ -420,7 +465,10 @@ struct KerxSubTableFormat2 table (table_), c (c_) {} int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return table.get_kerning (left, right, c); } + { + if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; + return table.get_kerning (left, right, c); + } }; bool sanitize (hb_sanitize_context_t *c) const @@ -429,6 +477,7 @@ struct KerxSubTableFormat2 return_trace (likely (c->check_struct (this) && leftClassTable.sanitize (c, this) && rightClassTable.sanitize (c, this) && + hb_barrier () && c->check_range (this, array))); } @@ -461,17 +510,26 @@ struct KerxSubTableFormat4 DEFINE_SIZE_STATIC (2); }; - struct driver_context_t + enum Flags { - static constexpr bool in_place = true; - enum Flags - { - Mark = 0x8000, /* If set, remember this glyph as the marked glyph. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + Mark = 0x8000, /* If set, remember this glyph as the marked glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before * going to the new state. */ - Reserved = 0x3FFF, /* Not used; set to 0. */ - }; + Reserved = 0x3FFF, /* Not used; set to 0. */ + }; + + bool is_action_initiable (const Entry &entry) const + { + return (entry.flags & Mark); + } + bool is_actionable (const Entry &entry) const + { + return entry.data.ankrActionIndex != 0xFFFF; + } + struct driver_context_t + { + static constexpr bool in_place = true; enum SubTableFlags { ActionType = 0xC0000000, /* A two-bit field containing the action type. */ @@ -481,22 +539,19 @@ struct KerxSubTableFormat4 * point table. */ }; - driver_context_t (const KerxSubTableFormat4 *table, + driver_context_t (const KerxSubTableFormat4 *table_, hb_aat_apply_context_t *c_) : c (c_), + table (table_), action_type ((table->flags & ActionType) >> 30), ankrData ((HBUINT16 *) ((const char *) &table->machine + (table->flags & Offset))), mark_set (false), mark (0) {} - bool is_actionable (StateTableDriver *driver HB_UNUSED, - const Entry &entry) - { return entry.data.ankrActionIndex != 0xFFFF; } - void transition (StateTableDriver *driver, + void transition (hb_buffer_t *buffer, + StateTableDriver *driver, const Entry &entry) { - hb_buffer_t *buffer = driver->buffer; - if (mark_set && entry.data.ankrActionIndex != 0xFFFF && buffer->idx < buffer->len) { hb_glyph_position_t &o = buffer->cur_pos(); @@ -509,6 +564,7 @@ struct KerxSubTableFormat4 double the ankrActionIndex to get the correct offset here. */ const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex * 2]; if (!c->sanitizer.check_array (data, 2)) return; + hb_barrier (); unsigned int markControlPoint = *data++; unsigned int currControlPoint = *data++; hb_position_t markX = 0; @@ -537,6 +593,7 @@ struct KerxSubTableFormat4 double the ankrActionIndex to get the correct offset here. */ const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex * 2]; if (!c->sanitizer.check_array (data, 2)) return; + hb_barrier (); unsigned int markAnchorPoint = *data++; unsigned int currAnchorPoint = *data++; const Anchor &markAnchor = c->ankr_table->get_anchor (c->buffer->info[mark].codepoint, @@ -557,6 +614,7 @@ struct KerxSubTableFormat4 by 4 to get the correct offset for the given action. */ const FWORD *data = (const FWORD *) &ankrData[entry.data.ankrActionIndex * 4]; if (!c->sanitizer.check_array (data, 4)) return; + hb_barrier (); int markX = *data++; int markY = *data++; int currX = *data++; @@ -579,8 +637,10 @@ struct KerxSubTableFormat4 } } - private: + public: hb_aat_apply_context_t *c; + const KerxSubTableFormat4 *table; + private: unsigned int action_type; const HBUINT16 *ankrData; bool mark_set; @@ -593,7 +653,8 @@ struct KerxSubTableFormat4 driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->font->face); + StateTableDriver driver (machine, c->font->face); + driver.drive (&dc, c); return_trace (true); @@ -607,12 +668,21 @@ struct KerxSubTableFormat4 machine.sanitize (c))); } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + set_t set; + machine.collect_glyphs (set, num_glyphs); + left_set.union_ (set); + right_set.union_ (set); + } + protected: KernSubTableHeader header; StateTable machine; HBUINT32 flags; public: - DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 20); + DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + (StateTable::static_size + HBUINT32::static_size)); }; template @@ -631,7 +701,7 @@ struct KerxSubTableFormat6 unsigned int num_glyphs = c->sanitizer.get_num_glyphs (); if (is_long ()) { - const typename U::Long &t = u.l; + const auto &t = u.l; unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs); unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs); unsigned int offset = l + r; @@ -639,16 +709,18 @@ struct KerxSubTableFormat6 if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0; const FWORD32 *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD32)); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + hb_barrier (); return kerxTupleKern (*v, header.tuple_count (), &(this+vector), c); } else { - const typename U::Short &t = u.s; + const auto &t = u.s; unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs); unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs); unsigned int offset = l + r; const FWORD *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD)); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + hb_barrier (); return kerxTupleKern (*v, header.tuple_count (), &(this+vector), c); } } @@ -658,10 +730,10 @@ struct KerxSubTableFormat6 TRACE_APPLY (this); if (!c->plan->requested_kerning) - return false; + return_trace (false); if (header.coverage & header.Backwards) - return false; + return_trace (false); accelerator_t accel (*this, c); hb_kern_machine_t machine (accel, header.coverage & header.CrossStream); @@ -674,6 +746,7 @@ struct KerxSubTableFormat6 { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && (is_long () ? ( u.l.rowIndexTable.sanitize (c, this) && @@ -688,6 +761,23 @@ struct KerxSubTableFormat6 c->check_range (this, vector)))); } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + if (is_long ()) + { + const auto &t = u.l; + (this+t.rowIndexTable).collect_glyphs (left_set, num_glyphs); + (this+t.columnIndexTable).collect_glyphs (right_set, num_glyphs); + } + else + { + const auto &t = u.s; + (this+t.rowIndexTable).collect_glyphs (left_set, num_glyphs); + (this+t.columnIndexTable).collect_glyphs (right_set, num_glyphs); + } + } + struct accelerator_t { const KerxSubTableFormat6 &table; @@ -698,7 +788,10 @@ struct KerxSubTableFormat6 table (table_), c (c_) {} int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return table.get_kerning (left, right, c); } + { + if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; + return table.get_kerning (left, right, c); + } }; protected: @@ -784,12 +877,27 @@ struct KerxSubTable } } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + unsigned int subtable_type = get_type (); + switch (subtable_type) { + case 0: u.format0.collect_glyphs (left_set, right_set, num_glyphs); return; + case 1: u.format1.collect_glyphs (left_set, right_set, num_glyphs); return; + case 2: u.format2.collect_glyphs (left_set, right_set, num_glyphs); return; + case 4: u.format4.collect_glyphs (left_set, right_set, num_glyphs); return; + case 6: u.format6.collect_glyphs (left_set, right_set, num_glyphs); return; + default: return; + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.header.sanitize (c) || - u.header.length <= u.header.static_size || - !c->check_range (this, u.header.length)) + if (!(u.header.sanitize (c) && + hb_barrier () && + u.header.length >= u.header.static_size && + c->check_range (this, u.header.length))) return_trace (false); return_trace (dispatch (c)); @@ -813,6 +921,8 @@ struct KerxSubTable * The 'kerx' Table */ +using kern_accelerator_data_t = hb_vector_t>; + template struct KerxTable { @@ -829,6 +939,9 @@ struct KerxTable { if (st->get_type () == 1) return true; + + // TODO: What about format 4? What's this API used for anyway? + st = &StructAfter (*st); } return false; @@ -867,7 +980,8 @@ struct KerxTable return v; } - bool apply (AAT::hb_aat_apply_context_t *c) const + bool apply (AAT::hb_aat_apply_context_t *c, + const kern_accelerator_data_t &accel_data) const { c->buffer->unsafe_to_concat (); @@ -914,6 +1028,9 @@ struct KerxTable if (reverse) c->buffer->reverse (); + c->left_set = &accel_data[i].first; + c->right_set = &accel_data[i].second; + { /* See comment in sanitize() for conditional here. */ hb_sanitize_with_object_t with (&c->sanitizer, i < count - 1 ? st : (const SubTable *) nullptr); @@ -936,9 +1053,10 @@ struct KerxTable bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!thiz()->version.sanitize (c) || - (unsigned) thiz()->version < (unsigned) T::minVersion || - !thiz()->tableCount.sanitize (c))) + if (unlikely (!(thiz()->version.sanitize (c) && + hb_barrier () && + (unsigned) thiz()->version >= (unsigned) T::minVersion && + thiz()->tableCount.sanitize (c)))) return_trace (false); typedef typename T::SubTable SubTable; @@ -949,6 +1067,7 @@ struct KerxTable { if (unlikely (!st->u.header.sanitize (c))) return_trace (false); + hb_barrier (); /* OpenType kern table has 2-byte subtable lengths. That's limiting. * MS implementation also only supports one subtable, of format 0, * anyway. Certain versions of some fonts, like Calibry, contain @@ -964,8 +1083,61 @@ struct KerxTable st = &StructAfter (*st); } + unsigned majorVersion = thiz()->version; + if (sizeof (thiz()->version) == 4) + majorVersion = majorVersion >> 16; + if (majorVersion >= 3) + { + const SubtableGlyphCoverage *coverage = (const SubtableGlyphCoverage *) st; + if (!coverage->sanitize (c, count)) + return_trace (false); + } + return_trace (true); } + + kern_accelerator_data_t create_accelerator_data (unsigned num_glyphs) const + { + kern_accelerator_data_t accel_data; + + typedef typename T::SubTable SubTable; + + const SubTable *st = &thiz()->firstSubTable; + unsigned int count = thiz()->tableCount; + for (unsigned int i = 0; i < count; i++) + { + hb_bit_set_t left_set, right_set; + st->collect_glyphs (left_set, right_set, num_glyphs); + accel_data.push (hb_pair (left_set, right_set)); + st = &StructAfter (*st); + } + + return accel_data; + } + + struct accelerator_t + { + accelerator_t (hb_face_t *face) + { + hb_sanitize_context_t sc; + this->table = sc.reference_table (face); + this->accel_data = this->table->create_accelerator_data (face->get_num_glyphs ()); + } + ~accelerator_t () + { + this->table.destroy (); + } + + hb_blob_t *get_blob () const { return table.get_blob (); } + + bool apply (AAT::hb_aat_apply_context_t *c) const + { + return table->apply (c, accel_data); + } + + hb_blob_ptr_t table; + kern_accelerator_data_t accel_data; + }; }; struct kerx : KerxTable @@ -994,8 +1166,10 @@ struct kerx : KerxTable DEFINE_SIZE_MIN (8); }; +struct kerx_accelerator_t : kerx::accelerator_t { + kerx_accelerator_t (hb_face_t *face) : kerx::accelerator_t (face) {} +}; } /* namespace AAT */ - #endif /* HB_AAT_LAYOUT_KERX_TABLE_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh index 81e126d5eb11a..cabdc0eb555ac 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh @@ -29,6 +29,7 @@ #include "hb-open-type.hh" #include "hb-aat-layout-common.hh" +#include "hb-ot-layout.hh" #include "hb-ot-layout-common.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-aat-map.hh" @@ -53,36 +54,42 @@ struct RearrangementSubtable typedef void EntryData; - struct driver_context_t + enum Flags { - static constexpr bool in_place = true; - enum Flags - { - MarkFirst = 0x8000, /* If set, make the current glyph the first + MarkFirst = 0x8000, /* If set, make the current glyph the first * glyph to be rearranged. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph + DontAdvance = 0x4000, /* If set, don't advance to the next glyph * before going to the new state. This means * that the glyph index doesn't change, even * if the glyph at that index has changed. */ - MarkLast = 0x2000, /* If set, make the current glyph the last + MarkLast = 0x2000, /* If set, make the current glyph the last * glyph to be rearranged. */ - Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */ - Verb = 0x000F, /* The type of rearrangement specified. */ - }; + Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */ + Verb = 0x000F, /* The type of rearrangement specified. */ + }; + + bool is_action_initiable (const Entry &entry) const + { + return (entry.flags & MarkFirst); + } + bool is_actionable (const Entry &entry) const + { + return (entry.flags & Verb); + } + + struct driver_context_t + { + static constexpr bool in_place = true; - driver_context_t (const RearrangementSubtable *table HB_UNUSED) : + driver_context_t (const RearrangementSubtable *table_) : ret (false), + table (table_), start (0), end (0) {} - bool is_actionable (StateTableDriver *driver HB_UNUSED, - const Entry &entry) - { - return (entry.flags & Verb) && start < end; - } - void transition (StateTableDriver *driver, + void transition (hb_buffer_t *buffer, + StateTableDriver *driver, const Entry &entry) { - hb_buffer_t *buffer = driver->buffer; unsigned int flags = entry.flags; if (flags & MarkFirst) @@ -157,6 +164,7 @@ struct RearrangementSubtable public: bool ret; + const RearrangementSubtable *table; private: unsigned int start; unsigned int end; @@ -168,7 +176,14 @@ struct RearrangementSubtable driver_context_t dc (this); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->face); + + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); + return_trace (false); + } + driver.drive (&dc, c); return_trace (dc.ret); @@ -180,10 +195,10 @@ struct RearrangementSubtable return_trace (machine.sanitize (c)); } - protected: + public: StateTable machine; public: - DEFINE_SIZE_STATIC (16); + DEFINE_SIZE_STATIC ((StateTable::static_size)); }; template @@ -201,43 +216,42 @@ struct ContextualSubtable DEFINE_SIZE_STATIC (4); }; + enum Flags + { + SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + * going to the new state. */ + Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */ + }; + + bool is_action_initiable (const Entry &entry) const + { + return (entry.flags & SetMark); + } + bool is_actionable (const Entry &entry) const + { + return entry.data.markIndex != 0xFFFF || entry.data.currentIndex != 0xFFFF; + } + struct driver_context_t { static constexpr bool in_place = true; - enum Flags - { - SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph before - * going to the new state. */ - Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */ - }; driver_context_t (const ContextualSubtable *table_, hb_aat_apply_context_t *c_) : ret (false), c (c_), + table (table_), gdef (*c->gdef_table), mark_set (false), has_glyph_classes (gdef.has_glyph_classes ()), mark (0), - table (table_), subs (table+table->substitutionTables) {} - bool is_actionable (StateTableDriver *driver, - const Entry &entry) - { - hb_buffer_t *buffer = driver->buffer; - - if (buffer->idx == buffer->len && !mark_set) - return false; - - return entry.data.markIndex != 0xFFFF || entry.data.currentIndex != 0xFFFF; - } - void transition (StateTableDriver *driver, + void transition (hb_buffer_t *buffer, + StateTableDriver *driver, const Entry &entry) { - hb_buffer_t *buffer = driver->buffer; - /* Looks like CoreText applies neither mark nor current substitution for * end-of-text if mark was not explicitly set. */ if (buffer->idx == buffer->len && !mark_set) @@ -259,13 +273,17 @@ struct ContextualSubtable unsigned int offset = entry.data.markIndex + buffer->info[mark].codepoint; const UnsizedArrayOf &subs_old = (const UnsizedArrayOf &) subs; replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)]; - if (!replacement->sanitize (&c->sanitizer) || !*replacement) + if (!(replacement->sanitize (&c->sanitizer) && + hb_barrier () && + *replacement)) replacement = nullptr; } if (replacement) { buffer->unsafe_to_break (mark, hb_min (buffer->idx + 1, buffer->len)); - buffer->info[mark].codepoint = *replacement; + hb_codepoint_t glyph = *replacement; + buffer->info[mark].codepoint = glyph; + c->buffer_glyph_set.add (glyph); if (has_glyph_classes) _hb_glyph_info_set_glyph_props (&buffer->info[mark], gdef.get_glyph_props (*replacement)); @@ -287,12 +305,16 @@ struct ContextualSubtable unsigned int offset = entry.data.currentIndex + buffer->info[idx].codepoint; const UnsizedArrayOf &subs_old = (const UnsizedArrayOf &) subs; replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)]; - if (!replacement->sanitize (&c->sanitizer) || !*replacement) + if (!(replacement->sanitize (&c->sanitizer) && + hb_barrier () && + *replacement)) replacement = nullptr; } if (replacement) { - buffer->info[idx].codepoint = *replacement; + hb_codepoint_t glyph = *replacement; + buffer->info[idx].codepoint = glyph; + c->buffer_glyph_set.add (glyph); if (has_glyph_classes) _hb_glyph_info_set_glyph_props (&buffer->info[idx], gdef.get_glyph_props (*replacement)); @@ -308,14 +330,14 @@ struct ContextualSubtable public: bool ret; - private: hb_aat_apply_context_t *c; + const ContextualSubtable *table; + private: const OT::GDEF &gdef; bool mark_set; bool has_glyph_classes; unsigned int mark; - const ContextualSubtable *table; - const UnsizedListOfOffset16To, HBUINT, false> &subs; + const UnsizedListOfOffset16To, HBUINT, void, false> &subs; }; bool apply (hb_aat_apply_context_t *c) const @@ -324,7 +346,14 @@ struct ContextualSubtable driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->face); + + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); + return_trace (false); + } + driver.drive (&dc, c); return_trace (dc.ret); @@ -336,6 +365,7 @@ struct ContextualSubtable unsigned int num_entries = 0; if (unlikely (!machine.sanitize (c, &num_entries))) return_trace (false); + hb_barrier (); if (!Types::extended) return_trace (substitutionTables.sanitize (c, this, 0)); @@ -356,13 +386,14 @@ struct ContextualSubtable return_trace (substitutionTables.sanitize (c, this, num_lookups)); } - protected: + public: StateTable machine; - NNOffsetTo, HBUINT, false>, HBUINT> + protected: + NNOffsetTo, HBUINT, void, false>, HBUINT> substitutionTables; public: - DEFINE_SIZE_STATIC (20); + DEFINE_SIZE_STATIC ((StateTable::static_size + HBUINT::static_size)); }; @@ -372,6 +403,16 @@ struct LigatureEntry; template <> struct LigatureEntry { + + struct EntryData + { + HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry + * for processing this group, if indicated + * by the flags. */ + public: + DEFINE_SIZE_STATIC (2); + }; + enum Flags { SetComponent = 0x8000, /* Push this glyph onto the component stack for @@ -383,14 +424,8 @@ struct LigatureEntry Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */ }; - struct EntryData - { - HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry - * for processing this group, if indicated - * by the flags. */ - public: - DEFINE_SIZE_STATIC (2); - }; + static bool initiateAction (const Entry &entry) + { return entry.flags & SetComponent; } static bool performAction (const Entry &entry) { return entry.flags & PerformAction; } @@ -401,6 +436,8 @@ struct LigatureEntry template <> struct LigatureEntry { + typedef void EntryData; + enum Flags { SetComponent = 0x8000, /* Push this glyph onto the component stack for @@ -412,7 +449,8 @@ struct LigatureEntry * multiple of 4. */ }; - typedef void EntryData; + static bool initiateAction (const Entry &entry) + { return entry.flags & SetComponent; } static bool performAction (const Entry &entry) { return entry.flags & Offset; } @@ -430,13 +468,23 @@ struct LigatureSubtable typedef LigatureEntry LigatureEntryT; typedef typename LigatureEntryT::EntryData EntryData; + enum Flags + { + DontAdvance = LigatureEntryT::DontAdvance, + }; + + bool is_action_initiable (const Entry &entry) const + { + return LigatureEntryT::initiateAction (entry); + } + bool is_actionable (const Entry &entry) const + { + return LigatureEntryT::performAction (entry); + } + struct driver_context_t { static constexpr bool in_place = false; - enum - { - DontAdvance = LigatureEntryT::DontAdvance, - }; enum LigActionFlags { LigActionLast = 0x80000000, /* This is the last action in the list. This also @@ -459,16 +507,10 @@ struct LigatureSubtable ligature (table+table->ligature), match_length (0) {} - bool is_actionable (StateTableDriver *driver HB_UNUSED, - const Entry &entry) - { - return LigatureEntryT::performAction (entry); - } - void transition (StateTableDriver *driver, + void transition (hb_buffer_t *buffer, + StateTableDriver *driver, const Entry &entry) { - hb_buffer_t *buffer = driver->buffer; - DEBUG_MSG (APPLY, nullptr, "Ligature transition at %u", buffer->idx); if (entry.flags & LigatureEntryT::SetComponent) { @@ -513,6 +555,7 @@ struct LigatureSubtable if (unlikely (!buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]))) return; if (unlikely (!actionData->sanitize (&c->sanitizer))) break; + hb_barrier (); action = *actionData; uint32_t uoffset = action & LigActionOffset; @@ -523,6 +566,7 @@ struct LigatureSubtable component_idx = Types::wordOffsetToIndex (component_idx, table, component.arrayZ); const HBUINT16 &componentData = component[component_idx]; if (unlikely (!componentData.sanitize (&c->sanitizer))) break; + hb_barrier (); ligature_idx += componentData; DEBUG_MSG (APPLY, nullptr, "Action store %d last %d", @@ -533,6 +577,7 @@ struct LigatureSubtable ligature_idx = Types::offsetToIndex (ligature_idx, table, ligature.arrayZ); const HBGlyphID16 &ligatureData = ligature[ligature_idx]; if (unlikely (!ligatureData.sanitize (&c->sanitizer))) break; + hb_barrier (); hb_codepoint_t lig = ligatureData; DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig); @@ -544,6 +589,7 @@ struct LigatureSubtable { DEBUG_MSG (APPLY, nullptr, "Skipping ligature component"); if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return; + _hb_glyph_info_set_default_ignorable (&buffer->cur()); if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return; } @@ -560,9 +606,9 @@ struct LigatureSubtable public: bool ret; - private: hb_aat_apply_context_t *c; const LigatureSubtable *table; + private: const UnsizedArrayOf &ligAction; const UnsizedArrayOf &component; const UnsizedArrayOf &ligature; @@ -576,7 +622,14 @@ struct LigatureSubtable driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->face); + + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); + return_trace (false); + } + driver.drive (&dc, c); return_trace (dc.ret); @@ -587,12 +640,14 @@ struct LigatureSubtable TRACE_SANITIZE (this); /* The rest of array sanitizations are done at run-time. */ return_trace (c->check_struct (this) && machine.sanitize (c) && + hb_barrier () && ligAction && component && ligature); } - protected: + public: StateTable machine; + protected: NNOffsetTo, HBUINT> ligAction; /* Offset to the ligature action table. */ NNOffsetTo, HBUINT> @@ -600,7 +655,7 @@ struct LigatureSubtable NNOffsetTo, HBUINT> ligature; /* Offset to the actual ligature lists. */ public: - DEFINE_SIZE_STATIC (28); + DEFINE_SIZE_STATIC ((StateTable::static_size + 3 * HBUINT::static_size)); }; template @@ -610,6 +665,12 @@ struct NoncontextualSubtable { TRACE_APPLY (this); + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); + return_trace (false); + } + const OT::GDEF &gdef (*c->gdef_table); bool has_glyph_classes = gdef.has_glyph_classes (); @@ -642,7 +703,9 @@ struct NoncontextualSubtable const HBGlyphID16 *replacement = substitute.get_value (info[i].codepoint, num_glyphs); if (replacement) { - info[i].codepoint = *replacement; + hb_codepoint_t glyph = *replacement; + info[i].codepoint = glyph; + c->buffer_glyph_set.add (glyph); if (has_glyph_classes) _hb_glyph_info_set_glyph_props (&info[i], gdef.get_glyph_props (*replacement)); @@ -653,6 +716,12 @@ struct NoncontextualSubtable return_trace (ret); } + template + void collect_initial_glyphs (set_t &glyphs, unsigned num_glyphs) const + { + substitute.collect_glyphs (glyphs, num_glyphs); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -686,74 +755,80 @@ struct InsertionSubtable DEFINE_SIZE_STATIC (4); }; + enum Flags + { + SetMark = 0x8000, /* If set, mark the current glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + * going to the new state. This does not mean + * that the glyph pointed to is the same one as + * before. If you've made insertions immediately + * downstream of the current glyph, the next glyph + * processed would in fact be the first one + * inserted. */ + CurrentIsKashidaLike= 0x2000, /* If set, and the currentInsertList is nonzero, + * then the specified glyph list will be inserted + * as a kashida-like insertion, either before or + * after the current glyph (depending on the state + * of the currentInsertBefore flag). If clear, and + * the currentInsertList is nonzero, then the + * specified glyph list will be inserted as a + * split-vowel-like insertion, either before or + * after the current glyph (depending on the state + * of the currentInsertBefore flag). */ + MarkedIsKashidaLike= 0x1000, /* If set, and the markedInsertList is nonzero, + * then the specified glyph list will be inserted + * as a kashida-like insertion, either before or + * after the marked glyph (depending on the state + * of the markedInsertBefore flag). If clear, and + * the markedInsertList is nonzero, then the + * specified glyph list will be inserted as a + * split-vowel-like insertion, either before or + * after the marked glyph (depending on the state + * of the markedInsertBefore flag). */ + CurrentInsertBefore= 0x0800, /* If set, specifies that insertions are to be made + * to the left of the current glyph. If clear, + * they're made to the right of the current glyph. */ + MarkedInsertBefore= 0x0400, /* If set, specifies that insertions are to be + * made to the left of the marked glyph. If clear, + * they're made to the right of the marked glyph. */ + CurrentInsertCount= 0x3E0, /* This 5-bit field is treated as a count of the + * number of glyphs to insert at the current + * position. Since zero means no insertions, the + * largest number of insertions at any given + * current location is 31 glyphs. */ + MarkedInsertCount= 0x001F, /* This 5-bit field is treated as a count of the + * number of glyphs to insert at the marked + * position. Since zero means no insertions, the + * largest number of insertions at any given + * marked location is 31 glyphs. */ + }; + + bool is_action_initiable (const Entry &entry) const + { + return (entry.flags & SetMark); + } + bool is_actionable (const Entry &entry) const + { + return (entry.flags & (CurrentInsertCount | MarkedInsertCount)) && + (entry.data.currentInsertIndex != 0xFFFF ||entry.data.markedInsertIndex != 0xFFFF); + } + struct driver_context_t { static constexpr bool in_place = false; - enum Flags - { - SetMark = 0x8000, /* If set, mark the current glyph. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph before - * going to the new state. This does not mean - * that the glyph pointed to is the same one as - * before. If you've made insertions immediately - * downstream of the current glyph, the next glyph - * processed would in fact be the first one - * inserted. */ - CurrentIsKashidaLike= 0x2000, /* If set, and the currentInsertList is nonzero, - * then the specified glyph list will be inserted - * as a kashida-like insertion, either before or - * after the current glyph (depending on the state - * of the currentInsertBefore flag). If clear, and - * the currentInsertList is nonzero, then the - * specified glyph list will be inserted as a - * split-vowel-like insertion, either before or - * after the current glyph (depending on the state - * of the currentInsertBefore flag). */ - MarkedIsKashidaLike= 0x1000, /* If set, and the markedInsertList is nonzero, - * then the specified glyph list will be inserted - * as a kashida-like insertion, either before or - * after the marked glyph (depending on the state - * of the markedInsertBefore flag). If clear, and - * the markedInsertList is nonzero, then the - * specified glyph list will be inserted as a - * split-vowel-like insertion, either before or - * after the marked glyph (depending on the state - * of the markedInsertBefore flag). */ - CurrentInsertBefore= 0x0800, /* If set, specifies that insertions are to be made - * to the left of the current glyph. If clear, - * they're made to the right of the current glyph. */ - MarkedInsertBefore= 0x0400, /* If set, specifies that insertions are to be - * made to the left of the marked glyph. If clear, - * they're made to the right of the marked glyph. */ - CurrentInsertCount= 0x3E0, /* This 5-bit field is treated as a count of the - * number of glyphs to insert at the current - * position. Since zero means no insertions, the - * largest number of insertions at any given - * current location is 31 glyphs. */ - MarkedInsertCount= 0x001F, /* This 5-bit field is treated as a count of the - * number of glyphs to insert at the marked - * position. Since zero means no insertions, the - * largest number of insertions at any given - * marked location is 31 glyphs. */ - }; - driver_context_t (const InsertionSubtable *table, + driver_context_t (const InsertionSubtable *table_, hb_aat_apply_context_t *c_) : ret (false), c (c_), + table (table_), mark (0), insertionAction (table+table->insertionAction) {} - bool is_actionable (StateTableDriver *driver HB_UNUSED, - const Entry &entry) - { - return (entry.flags & (CurrentInsertCount | MarkedInsertCount)) && - (entry.data.currentInsertIndex != 0xFFFF ||entry.data.markedInsertIndex != 0xFFFF); - } - void transition (StateTableDriver *driver, + void transition (hb_buffer_t *buffer, + StateTableDriver *driver, const Entry &entry) { - hb_buffer_t *buffer = driver->buffer; unsigned int flags = entry.flags; unsigned mark_loc = buffer->out_len; @@ -765,6 +840,7 @@ struct InsertionSubtable unsigned int start = entry.data.markedInsertIndex; const HBGlyphID16 *glyphs = &insertionAction[start]; if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0; + hb_barrier (); bool before = flags & MarkedInsertBefore; @@ -775,6 +851,9 @@ struct InsertionSubtable if (unlikely (!buffer->copy_glyph ())) return; /* TODO We ignore KashidaLike setting. */ if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return; + for (unsigned int i = 0; i < count; i++) + c->buffer_glyph_set.add (glyphs[i]); + ret = true; if (buffer->idx < buffer->len && !before) buffer->skip_glyph (); @@ -793,6 +872,7 @@ struct InsertionSubtable unsigned int start = entry.data.currentInsertIndex; const HBGlyphID16 *glyphs = &insertionAction[start]; if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0; + hb_barrier (); bool before = flags & CurrentInsertBefore; @@ -826,8 +906,9 @@ struct InsertionSubtable public: bool ret; - private: hb_aat_apply_context_t *c; + const InsertionSubtable *table; + private: unsigned int mark; const UnsizedArrayOf &insertionAction; }; @@ -838,7 +919,14 @@ struct InsertionSubtable driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->face); + + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); + return_trace (false); + } + driver.drive (&dc, c); return_trace (dc.ret); @@ -849,17 +937,19 @@ struct InsertionSubtable TRACE_SANITIZE (this); /* The rest of array sanitizations are done at run-time. */ return_trace (c->check_struct (this) && machine.sanitize (c) && + hb_barrier () && insertionAction); } - protected: + public: StateTable machine; + protected: NNOffsetTo, HBUINT> insertionAction; /* Byte offset from stateHeader to the start of * the insertion glyph table. */ public: - DEFINE_SIZE_STATIC (20); + DEFINE_SIZE_STATIC ((StateTable::static_size + HBUINT::static_size)); }; @@ -883,6 +973,107 @@ struct Feature DEFINE_SIZE_STATIC (12); }; + +struct hb_accelerate_subtables_context_t : + hb_dispatch_context_t +{ + struct hb_applicable_t + { + friend struct hb_accelerate_subtables_context_t; + friend struct hb_aat_layout_lookup_accelerator_t; + + public: + hb_bit_set_t glyph_set; + mutable hb_aat_class_cache_t class_cache; + + template + auto init_ (const T &obj_, unsigned num_glyphs, hb_priority<1>) HB_AUTO_RETURN + ( + obj_.machine.collect_initial_glyphs (glyph_set, num_glyphs, obj_) + ) + + template + void init_ (const T &obj_, unsigned num_glyphs, hb_priority<0>) + { + obj_.collect_initial_glyphs (glyph_set, num_glyphs); + } + + template + void init (const T &obj_, unsigned num_glyphs) + { + glyph_set.init (); + init_ (obj_, num_glyphs, hb_prioritize); + class_cache.clear (); + } + + void + fini () + { + glyph_set.fini (); + } + }; + + /* Dispatch interface. */ + template + return_t dispatch (const T &obj) + { + hb_applicable_t *entry = &array[i++]; + + entry->init (obj, num_glyphs); + + return hb_empty_t (); + } + static return_t default_return_value () { return hb_empty_t (); } + + bool stop_sublookup_iteration (return_t r) const { return false; } + + hb_accelerate_subtables_context_t (hb_applicable_t *array_, unsigned num_glyphs_) : + hb_dispatch_context_t (), + array (array_), num_glyphs (num_glyphs_) {} + + hb_applicable_t *array; + unsigned num_glyphs; + unsigned i = 0; +}; + +struct hb_aat_layout_chain_accelerator_t +{ + template + static hb_aat_layout_chain_accelerator_t *create (const TChain &chain, unsigned num_glyphs) + { + unsigned count = chain.get_subtable_count (); + + unsigned size = sizeof (hb_aat_layout_chain_accelerator_t) - + HB_VAR_ARRAY * sizeof (hb_accelerate_subtables_context_t::hb_applicable_t) + + count * sizeof (hb_accelerate_subtables_context_t::hb_applicable_t); + + /* The following is a calloc because when we are collecting subtables, + * some of them might be invalid and hence not collect; as a result, + * we might not fill in all the count entries of the subtables array. + * Zeroing it allows the set digest to gatekeep it without having to + * initialize it further. */ + auto *thiz = (hb_aat_layout_chain_accelerator_t *) hb_calloc (1, size); + if (unlikely (!thiz)) + return nullptr; + + thiz->count = count; + + hb_accelerate_subtables_context_t c_accelerate_subtables (thiz->subtables, num_glyphs); + chain.dispatch (&c_accelerate_subtables); + + return thiz; + } + + void destroy () + { + for (unsigned i = 0; i < count; i++) + subtables[i].fini (); + } + + unsigned count; + hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY]; +}; + template struct ChainSubtable { @@ -937,19 +1128,22 @@ struct ChainSubtable bool apply (hb_aat_apply_context_t *c) const { TRACE_APPLY (this); - hb_sanitize_with_object_t with (&c->sanitizer, this); + // Disabled for https://github.com/harfbuzz/harfbuzz/issues/4873 + //hb_sanitize_with_object_t with (&c->sanitizer, this); return_trace (dispatch (c)); } bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!length.sanitize (c) || - length <= min_size || - !c->check_range (this, length)) + if (!(length.sanitize (c) && + hb_barrier () && + length >= min_size && + c->check_range (this, length))) return_trace (false); - hb_sanitize_with_object_t with (c, this); + // Disabled for https://github.com/harfbuzz/harfbuzz/issues/4873 + //hb_sanitize_with_object_t with (c, this); return_trace (dispatch (c)); } @@ -973,6 +1167,8 @@ struct Chain { typedef typename Types::HBUINT HBUINT; + unsigned get_subtable_count () const { return subtableCount; } + hb_mask_t compile_flags (const hb_aat_map_builder_t *map) const { hb_mask_t flags = defaultFlags; @@ -1013,7 +1209,8 @@ struct Chain return flags; } - void apply (hb_aat_apply_context_t *c) const + void apply (hb_aat_apply_context_t *c, + const hb_aat_layout_chain_accelerator_t *accel) const { const ChainSubtable *subtable = &StructAfter> (featureZ.as_array (featureCount)); unsigned int count = subtableCount; @@ -1021,14 +1218,19 @@ struct Chain { bool reverse; + auto coverage = subtable->get_coverage (); + + hb_mask_t subtable_flags = subtable->subFeatureFlags; if (hb_none (hb_iter (c->range_flags) | - hb_map ([&subtable] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable->subFeatureFlags & (_.flags); }))) + hb_map ([subtable_flags] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable_flags & (_.flags); }))) goto skip; - c->subtable_flags = subtable->subFeatureFlags; + c->subtable_flags = subtable_flags; + c->machine_glyph_set = accel ? &accel->subtables[i].glyph_set : &Null(hb_bit_set_t); + c->machine_class_cache = accel ? &accel->subtables[i].class_cache : nullptr; - if (!(subtable->get_coverage() & ChainSubtable::AllDirections) && + if (!(coverage & ChainSubtable::AllDirections) && HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != - bool (subtable->get_coverage() & ChainSubtable::Vertical)) + bool (coverage & ChainSubtable::Vertical)) goto skip; /* Buffer contents is always in logical direction. Determine if @@ -1058,9 +1260,9 @@ struct Chain (the order opposite that of the characters, which may be right-to-left or left-to-right). */ - reverse = subtable->get_coverage () & ChainSubtable::Logical ? - bool (subtable->get_coverage () & ChainSubtable::Backwards) : - bool (subtable->get_coverage () & ChainSubtable::Backwards) != + reverse = coverage & ChainSubtable::Logical ? + bool (coverage & ChainSubtable::Backwards) : + bool (coverage & ChainSubtable::Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); if (!c->buffer->message (c->font, "start chainsubtable %u", c->lookup_index)) @@ -1086,12 +1288,28 @@ struct Chain unsigned int get_size () const { return length; } - bool sanitize (hb_sanitize_context_t *c, unsigned int version HB_UNUSED) const + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { + const ChainSubtable *subtable = &StructAfter> (featureZ.as_array (featureCount)); + unsigned int count = subtableCount; + for (unsigned int i = 0; i < count; i++) + { + typename context_t::return_t ret = subtable->dispatch (c, std::forward (ds)...); + if (c->stop_sublookup_iteration (ret)) + return ret; + subtable = &StructAfter> (*subtable); + } + return c->default_return_value (); + } + + bool sanitize (hb_sanitize_context_t *c, unsigned int version) const { TRACE_SANITIZE (this); - if (!length.sanitize (c) || - length < min_size || - !c->check_range (this, length)) + if (!(length.sanitize (c) && + hb_barrier () && + length >= min_size && + c->check_range (this, length))) return_trace (false); if (!c->check_array (featureZ.arrayZ, featureCount)) @@ -1103,9 +1321,17 @@ struct Chain { if (!subtable->sanitize (c)) return_trace (false); + hb_barrier (); subtable = &StructAfter> (*subtable); } + if (version >= 3) + { + const SubtableGlyphCoverage *coverage = (const SubtableGlyphCoverage *) subtable; + if (!coverage->sanitize (c, count)) + return_trace (false); + } + return_trace (true); } @@ -1117,7 +1343,7 @@ struct Chain UnsizedArrayOf featureZ; /* Features. */ /*ChainSubtable firstSubtable;*//* Subtables. */ -/*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */ +/*SubtableGlyphCoverage coverages*//* Only if version >= 3. */ public: DEFINE_SIZE_MIN (8 + 2 * sizeof (HBUINT)); @@ -1128,13 +1354,79 @@ struct Chain * The 'mort'/'morx' Table */ -template +template struct mortmorx { static constexpr hb_tag_t tableTag = TAG; bool has_data () const { return version != 0; } + struct accelerator_t + { + accelerator_t (hb_face_t *face) + { + hb_sanitize_context_t sc; + this->table = sc.reference_table (face); + + if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face))) + { + hb_blob_destroy (this->table.get_blob ()); + this->table = hb_blob_get_empty (); + } + + this->chain_count = table->get_chain_count (); + + this->accels = (hb_atomic_ptr_t *) hb_calloc (this->chain_count, sizeof (*accels)); + if (unlikely (!this->accels)) + { + this->chain_count = 0; + this->table.destroy (); + this->table = hb_blob_get_empty (); + } + } + ~accelerator_t () + { + for (unsigned int i = 0; i < this->chain_count; i++) + { + if (this->accels[i]) + this->accels[i]->destroy (); + hb_free (this->accels[i]); + } + hb_free (this->accels); + this->table.destroy (); + } + + hb_blob_t *get_blob () const { return table.get_blob (); } + + template + hb_aat_layout_chain_accelerator_t *get_accel (unsigned chain_index, const Chain &chain, unsigned num_glyphs) const + { + if (unlikely (chain_index >= chain_count)) return nullptr; + + retry: + auto *accel = accels[chain_index].get_acquire (); + if (unlikely (!accel)) + { + accel = hb_aat_layout_chain_accelerator_t::create (chain, num_glyphs); + if (unlikely (!accel)) + return nullptr; + + if (unlikely (!accels[chain_index].cmpexch (nullptr, accel))) + { + hb_free (accel); + goto retry; + } + } + + return accel; + } + + hb_blob_ptr_t table; + unsigned int chain_count; + hb_atomic_ptr_t *accels; + }; + + void compile_flags (const hb_aat_map_builder_t *mapper, hb_aat_map_t *map) const { @@ -1151,20 +1443,28 @@ struct mortmorx } } + unsigned get_chain_count () const + { + return chainCount; + } void apply (hb_aat_apply_context_t *c, - const hb_aat_map_t &map) const + const hb_aat_map_t &map, + const accelerator_t &accel) const { if (unlikely (!c->buffer->successful)) return; c->buffer->unsafe_to_concat (); + c->setup_buffer_glyph_set (); + c->set_lookup_index (0); const Chain *chain = &firstChain; unsigned int count = chainCount; for (unsigned int i = 0; i < count; i++) { + auto *chain_accel = accel.get_accel (i, *chain, c->face->get_num_glyphs ()); c->range_flags = &map.chain_flags[i]; - chain->apply (c); + chain->apply (c, chain_accel); if (unlikely (!c->buffer->successful)) return; chain = &StructAfter> (*chain); } @@ -1173,7 +1473,10 @@ struct mortmorx bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!version.sanitize (c) || !version || !chainCount.sanitize (c)) + if (!(version.sanitize (c) && + hb_barrier () && + version && + chainCount.sanitize (c))) return_trace (false); const Chain *chain = &firstChain; @@ -1182,6 +1485,7 @@ struct mortmorx { if (!chain->sanitize (c, version)) return_trace (false); + hb_barrier (); chain = &StructAfter> (*chain); } @@ -1200,8 +1504,24 @@ struct mortmorx DEFINE_SIZE_MIN (8); }; -struct morx : mortmorx {}; -struct mort : mortmorx {}; +struct morx : mortmorx +{ + HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const; +}; + +struct mort : mortmorx +{ + HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const; +}; + +struct morx_accelerator_t : morx::accelerator_t { + morx_accelerator_t (hb_face_t *face) : morx::accelerator_t (face) {} +}; +struct mort_accelerator_t : mort::accelerator_t { + mort_accelerator_t (hb_face_t *face) : mort::accelerator_t (face) {} +}; } /* namespace AAT */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-opbd-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-opbd-table.hh index 959382f356fb0..f28ec326b4596 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-opbd-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-opbd-table.hh @@ -133,8 +133,8 @@ struct opbd { switch (format) { - case 0: return u.format0.get_bounds (font, glyph_id, extents, this); - case 1: return u.format1.get_bounds (font, glyph_id, extents, this); + case 0: hb_barrier (); return u.format0.get_bounds (font, glyph_id, extents, this); + case 1: hb_barrier (); return u.format1.get_bounds (font, glyph_id, extents, this); default:return false; } } @@ -144,11 +144,12 @@ struct opbd TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this) || version.major != 1)) return_trace (false); + hb_barrier (); switch (format) { - case 0: return_trace (u.format0.sanitize (c, this)); - case 1: return_trace (u.format1.sanitize (c, this)); + case 0: hb_barrier (); return_trace (u.format0.sanitize (c, this)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c, this)); default:return_trace (true); } } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh index 5c49d1f0562c0..0db4035fd8c4d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh @@ -48,17 +48,69 @@ struct TrackTableEntry float get_track_value () const { return track.to_float (); } - int get_value (const void *base, unsigned int index, - unsigned int table_size) const - { return (base+valuesZ).as_array (table_size)[index]; } + float interpolate_at (unsigned int idx, + float ptem, + const void *base, + hb_array_t size_table) const + { + const FWORD *values = (base+valuesZ).arrayZ; + + float s0 = size_table[idx].to_float (); + float s1 = size_table[idx + 1].to_float (); + int v0 = values[idx]; + int v1 = values[idx + 1]; + + // Deal with font bugs. + if (unlikely (s1 < s0)) + { hb_swap (s0, s1); hb_swap (v0, v1); } + if (unlikely (ptem < s0)) return v0; + if (unlikely (ptem > s1)) return v1; + if (unlikely (s0 == s1)) return (v0 + v1) * 0.5f; + + float t = (ptem - s0) / (s1 - s0); + return v0 + t * (v1 - v0); + } + + float get_value (float ptem, + const void *base, + hb_array_t size_table) const + { + const FWORD *values = (base+valuesZ).arrayZ; + + unsigned int n_sizes = size_table.length; + + /* + * Choose size. + */ + if (!n_sizes) return 0.f; + if (n_sizes == 1) return values[0]; + + // At least two entries. + + unsigned i; + for (i = 0; i < n_sizes; i++) + if (size_table[i].to_float () >= ptem) + break; + + // Boundary conditions. + if (i == 0) return values[0]; + if (i == n_sizes) return values[n_sizes - 1]; + + // Exact match. + if (size_table[i].to_float () == ptem) return values[i]; + + // Interpolate. + return interpolate_at (i - 1, ptem, base, size_table); + } public: - bool sanitize (hb_sanitize_context_t *c, const void *base, - unsigned int table_size) const + bool sanitize (hb_sanitize_context_t *c, + const void *base, + unsigned int n_sizes) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - (valuesZ.sanitize (c, base, table_size)))); + (valuesZ.sanitize (c, base, n_sizes)))); } protected: @@ -76,64 +128,45 @@ struct TrackTableEntry struct TrackData { - float interpolate_at (unsigned int idx, - float target_size, - const TrackTableEntry &trackTableEntry, - const void *base) const + float get_tracking (const void *base, float ptem, float track = 0.f) const { - unsigned int sizes = nSizes; - hb_array_t size_table ((base+sizeTable).arrayZ, sizes); + unsigned count = nTracks; + hb_array_t size_table = (base+sizeTable).as_array (nSizes); - float s0 = size_table[idx].to_float (); - float s1 = size_table[idx + 1].to_float (); - float t = unlikely (s0 == s1) ? 0.f : (target_size - s0) / (s1 - s0); - return t * trackTableEntry.get_value (base, idx + 1, sizes) + - (1.f - t) * trackTableEntry.get_value (base, idx, sizes); - } + if (!count) return 0.f; + if (count == 1) return trackTable[0].get_value (ptem, base, size_table); - int get_tracking (const void *base, float ptem) const - { - /* - * Choose track. - */ - const TrackTableEntry *trackTableEntry = nullptr; - unsigned int count = nTracks; - for (unsigned int i = 0; i < count; i++) - { - /* Note: Seems like the track entries are sorted by values. But the - * spec doesn't explicitly say that. It just mentions it in the example. */ - - /* For now we only seek for track entries with zero tracking value */ - - if (trackTable[i].get_track_value () == 0.f) - { - trackTableEntry = &trackTable[i]; - break; - } - } - if (!trackTableEntry) return 0; + // At least two entries. - /* - * Choose size. - */ - unsigned int sizes = nSizes; - if (!sizes) return 0; - if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes); - - hb_array_t size_table ((base+sizeTable).arrayZ, sizes); - unsigned int size_index; - for (size_index = 0; size_index < sizes - 1; size_index++) - if (size_table[size_index].to_float () >= ptem) - break; + unsigned i = 0; + unsigned j = count - 1; + + // Find the two entries that track is between. + while (i + 1 < count && trackTable[i + 1].get_track_value () < track) + i++; + while (j > 0 && trackTable[j - 1].get_track_value () > track) + j--; + + // Exact match. + if (i == j) return trackTable[i].get_value (ptem, base, size_table); + + // Interpolate. - return roundf (interpolate_at (size_index ? size_index - 1 : 0, ptem, - *trackTableEntry, base)); + float t0 = trackTable[i].get_track_value (); + float t1 = trackTable[j].get_track_value (); + + float t = (track - t0) / (t1 - t0); + + float a = trackTable[i].get_value (ptem, base, size_table); + float b = trackTable[j].get_value (ptem, base, size_table); + return a + t * (b - a); } bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && sizeTable.sanitize (c, base, nSizes) && trackTable.sanitize (c, nTracks, base, nSizes))); } @@ -157,45 +190,15 @@ struct trak bool has_data () const { return version.to_int (); } - bool apply (hb_aat_apply_context_t *c) const + hb_position_t get_h_tracking (hb_font_t *font, float track = 0.f) const + { + float ptem = font->ptem > 0.f ? font->ptem : HB_CORETEXT_DEFAULT_FONT_SIZE; + return font->em_scalef_x ((this+horizData).get_tracking (this, ptem, track)); + } + hb_position_t get_v_tracking (hb_font_t *font, float track = 0.f) const { - TRACE_APPLY (this); - - hb_mask_t trak_mask = c->plan->trak_mask; - - const float ptem = c->font->ptem; - if (unlikely (ptem <= 0.f)) - return_trace (false); - - hb_buffer_t *buffer = c->buffer; - if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) - { - const TrackData &trackData = this+horizData; - int tracking = trackData.get_tracking (this, ptem); - hb_position_t offset_to_add = c->font->em_scalef_x (tracking / 2); - hb_position_t advance_to_add = c->font->em_scalef_x (tracking); - foreach_grapheme (buffer, start, end) - { - if (!(buffer->info[start].mask & trak_mask)) continue; - buffer->pos[start].x_advance += advance_to_add; - buffer->pos[start].x_offset += offset_to_add; - } - } - else - { - const TrackData &trackData = this+vertData; - int tracking = trackData.get_tracking (this, ptem); - hb_position_t offset_to_add = c->font->em_scalef_y (tracking / 2); - hb_position_t advance_to_add = c->font->em_scalef_y (tracking); - foreach_grapheme (buffer, start, end) - { - if (!(buffer->info[start].mask & trak_mask)) continue; - buffer->pos[start].y_advance += advance_to_add; - buffer->pos[start].y_offset += offset_to_add; - } - } - - return_trace (true); + float ptem = font->ptem > 0.f ? font->ptem : HB_CORETEXT_DEFAULT_FONT_SIZE; + return font->em_scalef_y ((this+vertData).get_tracking (this, ptem, track)); } bool sanitize (hb_sanitize_context_t *c) const @@ -203,6 +206,7 @@ struct trak TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && horizData.sanitize (c, this, this) && vertData.sanitize (c, this, this))); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc index fc5834c7ca1b1..2cc94257aa73a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc @@ -34,9 +34,12 @@ #include "hb-aat-layout-just-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-layout-kerx-table.hh" #include "hb-aat-layout-morx-table.hh" -#include "hb-aat-layout-trak-table.hh" +#include "hb-aat-layout-trak-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-ltag-table.hh" +#include "hb-ot-layout-gsub-table.hh" +#include "hb-ot-layout-gdef-table.hh" + /* * hb_aat_apply_context_t @@ -207,18 +210,48 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag) */ +bool +AAT::morx::is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const +{ +#ifdef HB_NO_AAT_LAYOUT_BLOCKLIST + return false; +#endif + + switch HB_CODEPOINT_ENCODE3 (blob->length, + face->table.GSUB->table.get_length (), + face->table.GDEF->table.get_length ()) + { + /* https://github.com/harfbuzz/harfbuzz/issues/4108 + sha1sum:a71ca6813b7e56a772cffff7c24a5166b087197c AALMAGHRIBI.ttf */ + case HB_CODEPOINT_ENCODE3 (19892, 2794, 340): + return true; + } + return false; +} + +bool +AAT::mort::is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const +{ +#ifdef HB_NO_AAT_LAYOUT_BLOCKLIST + return false; +#endif + return false; +} + void hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, hb_aat_map_t *map) { - const AAT::morx& morx = *mapper->face->table.morx; + const AAT::morx& morx = *mapper->face->table.morx->table; if (morx.has_data ()) { morx.compile_flags (mapper, map); return; } - const AAT::mort& mort = *mapper->face->table.mort; + const AAT::mort& mort = *mapper->face->table.mort->table; if (mort.has_data ()) { mort.compile_flags (mapper, map); @@ -243,8 +276,8 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, hb_bool_t hb_aat_layout_has_substitution (hb_face_t *face) { - return face->table.morx->has_data () || - face->table.mort->has_data (); + return face->table.morx->table->has_data () || + face->table.mort->table->has_data (); } void @@ -260,26 +293,30 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, hb_aat_map_t map; builder.compile (map); - hb_blob_t *morx_blob = font->face->table.morx.get_blob (); - const AAT::morx& morx = *morx_blob->as (); - if (morx.has_data ()) { - AAT::hb_aat_apply_context_t c (plan, font, buffer, morx_blob); - if (!buffer->message (font, "start table morx")) return; - morx.apply (&c, map); - (void) buffer->message (font, "end table morx"); - return; + auto &accel = *font->face->table.morx; + const AAT::morx& morx = *accel.table; + if (morx.has_data ()) + { + AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); + if (!buffer->message (font, "start table morx")) return; + morx.apply (&c, map, accel); + (void) buffer->message (font, "end table morx"); + return; + } } - hb_blob_t *mort_blob = font->face->table.mort.get_blob (); - const AAT::mort& mort = *mort_blob->as (); - if (mort.has_data ()) { - AAT::hb_aat_apply_context_t c (plan, font, buffer, mort_blob); - if (!buffer->message (font, "start table mort")) return; - mort.apply (&c, map); - (void) buffer->message (font, "end table mort"); - return; + auto &accel = *font->face->table.mort; + const AAT::mort& mort = *accel.table; + if (mort.has_data ()) + { + AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); + if (!buffer->message (font, "start table mort")) return; + mort.apply (&c, map, accel); + (void) buffer->message (font, "end table mort"); + return; + } } } @@ -322,7 +359,7 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) hb_bool_t hb_aat_layout_has_positioning (hb_face_t *face) { - return face->table.kerx->has_data (); + return face->table.kerx->table->has_data (); } void @@ -330,13 +367,12 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - hb_blob_t *kerx_blob = font->face->table.kerx.get_blob (); - const AAT::kerx& kerx = *kerx_blob->as (); + auto &accel = *font->face->table.kerx; - AAT::hb_aat_apply_context_t c (plan, font, buffer, kerx_blob); + AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); if (!buffer->message (font, "start table kerx")) return; c.set_ankr_table (font->face->table.ankr.get ()); - kerx.apply (&c); + accel.apply (&c); (void) buffer->message (font, "end table kerx"); } @@ -358,17 +394,6 @@ hb_aat_layout_has_tracking (hb_face_t *face) return face->table.trak->has_data (); } -void -hb_aat_layout_track (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer) -{ - const AAT::trak& trak = *font->face->table.trak; - - AAT::hb_aat_apply_context_t c (plan, font, buffer); - trak.apply (&c); -} - /** * hb_aat_layout_get_feature_types: * @face: #hb_face_t to work upon diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.h b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.h index c833ea8f62378..88e040d7e2b43 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.h @@ -40,7 +40,7 @@ HB_BEGIN_DECLS * @HB_AAT_LAYOUT_FEATURE_TYPE_INVALID: Initial, unset feature type * @HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC: [All Typographic Features](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type0) * @HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES: [Ligatures](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type1) - * @HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION: [Cursive Connection](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type2) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION: [Cursive Connection](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type2) * @HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE: [Letter Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type3) * @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION: [Vertical Substitution](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type4) * @HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT: [Linguistic Rearrangement](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type5) @@ -88,7 +88,7 @@ typedef enum HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC = 0, HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES = 1, - HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION = 2, + HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION = 2, HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE = 3, HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION = 4, HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT = 5, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh index 36bb0ef07ddb0..ee33223651a07 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh @@ -32,6 +32,9 @@ #include "hb-ot-shape.hh" #include "hb-aat-ltag-table.hh" +/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ +#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f + struct hb_aat_feature_mapping_t { hb_tag_t otFeatureTag; @@ -68,10 +71,5 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -HB_INTERNAL void -hb_aat_layout_track (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); - #endif /* HB_AAT_LAYOUT_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-ltag-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-ltag-table.hh index 17b341ef277ea..da4dcb1212fd5 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-ltag-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-ltag-table.hh @@ -46,7 +46,9 @@ struct FTStringRange bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && (base+tag).sanitize (c, length)); + return_trace (c->check_struct (this) && + hb_barrier () && + (base+tag).sanitize (c, length)); } protected: @@ -73,6 +75,7 @@ struct ltag { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version >= 1 && tagRanges.sanitize (c, this))); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc b/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc index 122f29dc6816f..e0e9d14d9b8fc 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc @@ -88,22 +88,23 @@ hb_aat_map_builder_t::compile (hb_aat_map_t &m) /* Sort features by start/end events. */ hb_vector_t feature_events; + feature_events.alloc_exact (features.length * 2 + 1); for (unsigned int i = 0; i < features.length; i++) { - auto &feature = features[i]; + auto &feature = features.arrayZ[i]; - if (features[i].start == features[i].end) + if (feature.start == feature.end) continue; feature_event_t *event; event = feature_events.push (); - event->index = features[i].start; + event->index = feature.start; event->start = true; event->feature = feature.info; event = feature_events.push (); - event->index = features[i].end; + event->index = feature.end; event->start = false; event->feature = feature.info; } @@ -139,12 +140,12 @@ hb_aat_map_builder_t::compile (hb_aat_map_t &m) current_features.qsort (); unsigned int j = 0; for (unsigned int i = 1; i < current_features.length; i++) - if (current_features[i].type != current_features[j].type || + if (current_features.arrayZ[i].type != current_features.arrayZ[j].type || /* Nonexclusive feature selectors come in even/odd pairs to turn a setting on/off * respectively, so we mask out the low-order bit when checking for "duplicates" * (selectors referring to the same feature setting) here. */ - (!current_features[i].is_exclusive && ((current_features[i].setting & ~1) != (current_features[j].setting & ~1)))) - current_features[++j] = current_features[i]; + (!current_features.arrayZ[i].is_exclusive && ((current_features.arrayZ[i].setting & ~1) != (current_features.arrayZ[j].setting & ~1)))) + current_features.arrayZ[++j] = current_features.arrayZ[i]; current_features.shrink (j + 1); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-algs.hh b/src/java.desktop/share/native/libharfbuzz/hb-algs.hh index b2b7c2567392f..6e250bfdef0ea 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-algs.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-algs.hh @@ -202,8 +202,12 @@ struct BEInt /* Floats. */ /* We want our rounding towards +infinity. */ +static inline double +_hb_roundf (double x) { return floor (x + .5); } + static inline float _hb_roundf (float x) { return floorf (x + .5f); } + #define roundf(x) _hb_roundf(x) @@ -282,7 +286,7 @@ HB_FUNCOBJ (hb_bool); // Compression function for Merkle-Damgard construction. // This function is generated using the framework provided. -#define mix(h) ( \ +#define fasthash_mix(h) ( \ (void) ((h) ^= (h) >> 23), \ (void) ((h) *= 0x2127599bf4325c37ULL), \ (h) ^= (h) >> 47) @@ -306,7 +310,7 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) #pragma GCC diagnostic ignored "-Wcast-align" v = * (const uint64_t *) (pos++); #pragma GCC diagnostic pop - h ^= mix(v); + h ^= fasthash_mix(v); h *= m; } } @@ -316,7 +320,7 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) while (pos != end) { v = pos++->v; - h ^= mix(v); + h ^= fasthash_mix(v); h *= m; } } @@ -332,11 +336,11 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) case 3: v ^= (uint64_t)pos2[2] << 16; HB_FALLTHROUGH; case 2: v ^= (uint64_t)pos2[1] << 8; HB_FALLTHROUGH; case 1: v ^= (uint64_t)pos2[0]; - h ^= mix(v); + h ^= fasthash_mix(v); h *= m; } - return mix(h); + return fasthash_mix(h); } static inline uint32_t fasthash32(const void *buf, size_t len, uint32_t seed) @@ -671,7 +675,7 @@ struct hb_pair_t return 0; } - friend void swap (hb_pair_t& a, hb_pair_t& b) + friend void swap (hb_pair_t& a, hb_pair_t& b) noexcept { hb_swap (a.first, b.first); hb_swap (a.second, b.second); @@ -1053,6 +1057,18 @@ _hb_cmp_method (const void *pkey, const void *pval, Ts... ds) return val.cmp (key, ds...); } +template +static int +_hb_cmp_operator (const void *pkey, const void *pval) +{ + const K& key = * (const K*) pkey; + const V& val = * (const V*) pval; + + if (key < val) return -1; + if (key > val) return 1; + return 0; +} + template static inline bool hb_bsearch_impl (unsigned *pos, /* Out */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-array.hh b/src/java.desktop/share/native/libharfbuzz/hb-array.hh index 439f18259cf52..d65bbc5c7115d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-array.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-array.hh @@ -47,6 +47,8 @@ enum hb_not_found_t template struct hb_array_t : hb_iter_with_fallback_t, Type&> { + static constexpr bool realloc_move = true; + /* * Constructors. */ @@ -249,7 +251,8 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> if (end < start + 2) return; - for (unsigned lhs = start, rhs = end - 1; lhs < rhs; lhs++, rhs--) + unsigned stop = start + (end - start) / 2; + for (unsigned lhs = start, rhs = end - 1; lhs < stop; lhs++, rhs--) hb_swap (arrayZ[rhs], arrayZ[lhs]); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh b/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh index 459d82e0f2e78..d2de5f693f017 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh @@ -118,12 +118,12 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) */ #ifndef _hb_compiler_memory_r_barrier #if defined(__ATOMIC_ACQUIRE) // gcc-like -#define _hb_compiler_memory_r_barrier() asm volatile("": : :"memory") +static inline void _hb_compiler_memory_r_barrier () { asm volatile("": : :"memory"); } #elif !defined(_MSC_VER) #include #define _hb_compiler_memory_r_barrier() std::atomic_signal_fence (std::memory_order_acquire) #else -#define _hb_compiler_memory_r_barrier() do {} while (0) +static inline void _hb_compiler_memory_r_barrier () {} #endif #endif @@ -212,11 +212,18 @@ struct hb_atomic_ptr_t T *get_acquire () const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); } bool cmpexch (const T *old, T *new_) const { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } + operator bool () const { return get_acquire () != nullptr; } T * operator -> () const { return get_acquire (); } template operator C * () const { return get_acquire (); } T *v = nullptr; }; +static inline bool hb_barrier () +{ + _hb_compiler_memory_r_barrier (); + return true; +} + #endif /* HB_ATOMIC_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh index 404a19ce557f8..9562a9674a551 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh @@ -78,6 +78,28 @@ struct hb_vector_size_t hb_vector_size_t operator ~ () const { return process (hb_bitwise_neg); } + operator bool () const + { + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + if (v[i]) + return true; + return false; + } + operator unsigned int () const + { + unsigned int r = 0; + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + r += hb_popcount (v[i]); + return r; + } + bool operator == (const hb_vector_size_t &o) const + { + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + if (v[i] != o.v[i]) + return false; + return true; + } + hb_array_t iter () const { return hb_array (v); } @@ -89,6 +111,8 @@ struct hb_vector_size_t struct hb_bit_page_t { + hb_bit_page_t () { init0 (); } + void init0 () { v.init0 (); population = 0; } void init1 () { v.init1 (); population = PAGE_BITS; } @@ -101,10 +125,9 @@ struct hb_bit_page_t bool is_empty () const { if (has_population ()) return !population; - return - + hb_iter (v) - | hb_none - ; + bool empty = !v; + if (empty) population = 0; + return empty; } uint32_t hash () const { @@ -115,6 +138,10 @@ struct hb_bit_page_t void del (hb_codepoint_t g) { elt (g) &= ~mask (g); dirty (); } void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); } bool get (hb_codepoint_t g) const { return elt (g) & mask (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } + + bool operator [] (hb_codepoint_t g) const { return get (g); } + bool operator () (hb_codepoint_t g) const { return get (g); } void add_range (hb_codepoint_t a, hb_codepoint_t b) { @@ -220,13 +247,17 @@ struct hb_bit_page_t } bool operator == (const hb_bit_page_t &other) const { return is_equal (other); } - bool is_equal (const hb_bit_page_t &other) const + bool is_equal (const hb_bit_page_t &other) const { return v == other.v; } + bool intersects (const hb_bit_page_t &other) const { for (unsigned i = 0; i < len (); i++) - if (v[i] != other.v[i]) - return false; - return true; + if (v[i] & other.v[i]) + return true; + return false; } + bool may_intersect (const hb_bit_page_t &other) const + { return intersects (other); } + bool operator <= (const hb_bit_page_t &larger_page) const { return is_subset (larger_page); } bool is_subset (const hb_bit_page_t &larger_page) const { @@ -241,14 +272,10 @@ struct hb_bit_page_t } bool has_population () const { return population != UINT_MAX; } - unsigned int get_population () const + unsigned get_population () const { if (has_population ()) return population; - population = - + hb_iter (v) - | hb_reduce ([] (unsigned pop, const elt_t &_) { return pop + hb_popcount (_); }, 0u) - ; - return population; + return population = v; } bool next (hb_codepoint_t *codepoint) const diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh index 2e335549e2603..740a2437671a6 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh @@ -39,10 +39,10 @@ struct hb_bit_set_invertible_t hb_bit_set_invertible_t () = default; hb_bit_set_invertible_t (const hb_bit_set_invertible_t& o) = default; - hb_bit_set_invertible_t (hb_bit_set_invertible_t&& other) : hb_bit_set_invertible_t () { hb_swap (*this, other); } + hb_bit_set_invertible_t (hb_bit_set_invertible_t&& other) noexcept : hb_bit_set_invertible_t () { hb_swap (*this, other); } hb_bit_set_invertible_t& operator= (const hb_bit_set_invertible_t& o) = default; - hb_bit_set_invertible_t& operator= (hb_bit_set_invertible_t&& other) { hb_swap (*this, other); return *this; } - friend void swap (hb_bit_set_invertible_t &a, hb_bit_set_invertible_t &b) + hb_bit_set_invertible_t& operator= (hb_bit_set_invertible_t&& other) noexcept { hb_swap (*this, other); return *this; } + friend void swap (hb_bit_set_invertible_t &a, hb_bit_set_invertible_t &b) noexcept { if (likely (!a.s.successful || !b.s.successful)) return; @@ -126,6 +126,7 @@ struct hb_bit_set_invertible_t { unlikely (inverted) ? (void) s.add_range (a, b) : s.del_range (a, b); } bool get (hb_codepoint_t g) const { return s.get (g) ^ inverted; } + bool may_have (hb_codepoint_t g) const { return get (g); } /* Has interface. */ bool operator [] (hb_codepoint_t k) const { return get (k); } @@ -139,6 +140,9 @@ struct hb_bit_set_invertible_t hb_bit_set_invertible_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } + bool may_intersect (const hb_bit_set_invertible_t &other) const + { return inverted || other.inverted || s.intersects (other.s); } + bool intersects (hb_codepoint_t first, hb_codepoint_t last) const { hb_codepoint_t c = first - 1; @@ -359,8 +363,8 @@ struct hb_bit_set_invertible_t typedef hb_codepoint_t __item_t__; hb_codepoint_t __item__ () const { return v; } bool __more__ () const { return v != INVALID; } - void __next__ () { s->next (&v); if (l) l--; } - void __prev__ () { s->previous (&v); } + void __next__ () { s->next (&v); if (likely (l)) l--; } + void __prev__ () { s->previous (&v); l++; } unsigned __len__ () const { return l; } iter_t end () const { return iter_t (*s, false); } bool operator != (const iter_t& o) const diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh index b900711a33a97..c42e617f67a4b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh @@ -38,10 +38,10 @@ struct hb_bit_set_t ~hb_bit_set_t () = default; hb_bit_set_t (const hb_bit_set_t& other) : hb_bit_set_t () { set (other, true); } - hb_bit_set_t ( hb_bit_set_t&& other) : hb_bit_set_t () { hb_swap (*this, other); } + hb_bit_set_t ( hb_bit_set_t&& other) noexcept : hb_bit_set_t () { hb_swap (*this, other); } hb_bit_set_t& operator= (const hb_bit_set_t& other) { set (other); return *this; } - hb_bit_set_t& operator= (hb_bit_set_t&& other) { hb_swap (*this, other); return *this; } - friend void swap (hb_bit_set_t &a, hb_bit_set_t &b) + hb_bit_set_t& operator= (hb_bit_set_t&& other) noexcept { hb_swap (*this, other); return *this; } + friend void swap (hb_bit_set_t &a, hb_bit_set_t &b) noexcept { if (likely (!a.successful || !b.successful)) return; @@ -88,10 +88,11 @@ struct hb_bit_set_t { if (unlikely (!successful)) return false; - if (pages.length == 0 && count == 1) + if (pages.length < count && count <= 2) exact_size = true; // Most sets are small and local - if (unlikely (!pages.resize (count, clear, exact_size) || !page_map.resize (count, clear, exact_size))) + if (unlikely (!pages.resize (count, clear, exact_size) || + !page_map.resize (count, clear))) { pages.resize (page_map.length, clear, exact_size); successful = false; @@ -297,9 +298,9 @@ struct hb_bit_set_t unsigned int write_index = 0; for (unsigned int i = 0; i < page_map.length; i++) { - int m = (int) page_map[i].major; + int m = (int) page_map.arrayZ[i].major; if (m < ds || de < m) - page_map[write_index++] = page_map[i]; + page_map.arrayZ[write_index++] = page_map.arrayZ[i]; } compact (compact_workspace, write_index); resize (write_index); @@ -345,6 +346,7 @@ struct hb_bit_set_t return false; return page->get (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } /* Has interface. */ bool operator [] (hb_codepoint_t k) const { return get (k); } @@ -358,6 +360,31 @@ struct hb_bit_set_t hb_bit_set_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } + bool intersects (const hb_bit_set_t &other) const + { + unsigned int na = pages.length; + unsigned int nb = other.pages.length; + + unsigned int a = 0, b = 0; + for (; a < na && b < nb; ) + { + if (page_map.arrayZ[a].major == other.page_map.arrayZ[b].major) + { + if (page_at (a).intersects (other.page_at (b))) + return true; + a++; + b++; + } + else if (page_map.arrayZ[a].major < other.page_map.arrayZ[b].major) + a++; + else + b++; + } + return false; + } + bool may_intersect (const hb_bit_set_t &other) const + { return intersects (other); } + bool intersects (hb_codepoint_t first, hb_codepoint_t last) const { hb_codepoint_t c = first - 1; @@ -389,7 +416,7 @@ struct hb_bit_set_t { if (page_at (a).is_empty ()) { a++; continue; } if (other.page_at (b).is_empty ()) { b++; continue; } - if (page_map[a].major != other.page_map[b].major || + if (page_map.arrayZ[a].major != other.page_map.arrayZ[b].major || !page_at (a).is_equal (other.page_at (b))) return false; a++; @@ -412,8 +439,8 @@ struct hb_bit_set_t uint32_t spi = 0; for (uint32_t lpi = 0; spi < page_map.length && lpi < larger_set.page_map.length; lpi++) { - uint32_t spm = page_map[spi].major; - uint32_t lpm = larger_set.page_map[lpi].major; + uint32_t spm = page_map.arrayZ[spi].major; + uint32_t lpm = larger_set.page_map.arrayZ[lpi].major; auto sp = page_at (spi); if (spm < lpm && !sp.is_empty ()) @@ -503,7 +530,7 @@ struct hb_bit_set_t for (; a < na && b < nb; ) { - if (page_map[a].major == other.page_map[b].major) + if (page_map.arrayZ[a].major == other.page_map.arrayZ[b].major) { if (!passthru_left) { @@ -512,7 +539,7 @@ struct hb_bit_set_t // passthru_left is set since no left side pages will be removed // in that case. if (write_index < a) - page_map[write_index] = page_map[a]; + page_map.arrayZ[write_index] = page_map.arrayZ[a]; write_index++; } @@ -520,7 +547,7 @@ struct hb_bit_set_t a++; b++; } - else if (page_map[a].major < other.page_map[b].major) + else if (page_map.arrayZ[a].major < other.page_map.arrayZ[b].major) { if (passthru_left) count++; @@ -765,8 +792,8 @@ struct hb_bit_set_t unsigned int initial_size = size; for (unsigned int i = start_page; i < page_map.length && size; i++) { - uint32_t base = major_start (page_map[i].major); - unsigned int n = pages[page_map[i].index].write (base, start_page_value, out, size); + uint32_t base = major_start (page_map.arrayZ[i].major); + unsigned int n = pages[page_map.arrayZ[i].index].write (base, start_page_value, out, size); out += n; size -= n; start_page_value = 0; @@ -814,8 +841,8 @@ struct hb_bit_set_t hb_codepoint_t next_value = codepoint + 1; for (unsigned int i=start_page; i= 0; i--) { - const auto& map = page_map[(unsigned) i]; - const auto& page = pages[map.index]; + const auto& map = page_map.arrayZ[(unsigned) i]; + const auto& page = pages.arrayZ[map.index]; if (!page.is_empty ()) return map.major * page_t::PAGE_BITS + page.get_max (); @@ -961,7 +988,7 @@ struct hb_bit_set_t return nullptr; last_page_lookup = i; - return &pages.arrayZ[page_map[i].index]; + return &pages.arrayZ[page_map.arrayZ[i].index]; } page_t &page_at (unsigned int i) { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-blob.cc b/src/java.desktop/share/native/libharfbuzz/hb-blob.cc index 2a43afa1a435f..a19599fac09a0 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-blob.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-blob.cc @@ -598,6 +598,11 @@ _open_resource_fork (const char *file_name, hb_mapped_file_t *file) * Creates a new blob containing the data from the * specified binary font file. * + * The filename is passed directly to the system on all platforms, + * except on Windows, where the filename is interpreted as UTF-8. + * Only if the filename is not valid UTF-8, it will be interpreted + * according to the system codepage. + * * Returns: An #hb_blob_t pointer with the content of the file, * or hb_blob_get_empty() if failed. * @@ -612,10 +617,14 @@ hb_blob_create_from_file (const char *file_name) /** * hb_blob_create_from_file_or_fail: - * @file_name: A font filename + * @file_name: A filename * - * Creates a new blob containing the data from the - * specified binary font file. + * Creates a new blob containing the data from the specified file. + * + * The filename is passed directly to the system on all platforms, + * except on Windows, where the filename is interpreted as UTF-8. + * Only if the filename is not valid UTF-8, it will be interpreted + * according to the system codepage. * * Returns: An #hb_blob_t pointer with the content of the file, * or `NULL` if failed. @@ -672,10 +681,19 @@ hb_blob_create_from_file_or_fail (const char *file_name) if (unlikely (!file)) return nullptr; HANDLE fd; + int conversion; unsigned int size = strlen (file_name) + 1; wchar_t * wchar_file_name = (wchar_t *) hb_malloc (sizeof (wchar_t) * size); if (unlikely (!wchar_file_name)) goto fail_without_close; - mbstowcs (wchar_file_name, file_name, size); + + /* Assume file name is given in UTF-8 encoding */ + conversion = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, file_name, -1, wchar_file_name, size); + if (conversion <= 0) + { + /* Conversion failed due to invalid UTF-8 characters, + Repeat conversion based on system code page */ + mbstowcs(wchar_file_name, file_name, size); + } #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) { CREATEFILE2_EXTENDED_PARAMETERS ceparams = { 0 }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh index 2a90cbfe3eaef..69cc16402300a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh @@ -34,36 +34,36 @@ #line 36 "hb-buffer-deserialize-json.hh" static const unsigned char _deserialize_json_trans_keys[] = { - 0u, 0u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, - 48u, 57u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, + 0u, 0u, 9u, 123u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, + 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u, 9u, 125u, 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, - 9u, 123u, 0u, 0u, 0 + 9u, 93u, 9u, 123u, 0u, 0u, 0 }; static const char _deserialize_json_key_spans[] = { - 0, 115, 26, 21, 2, 1, 50, 49, - 10, 117, 117, 85, 117, 1, 50, 49, + 0, 115, 115, 26, 21, 2, 1, 50, + 49, 10, 117, 117, 117, 1, 50, 49, 10, 117, 117, 1, 1, 50, 49, 117, 117, 2, 1, 50, 49, 10, 117, 117, 1, 50, 49, 10, 117, 117, 1, 1, 50, 49, 117, 117, 1, 50, 49, 59, 117, 59, 117, 117, 1, 50, 49, 117, - 115, 0 + 85, 115, 0 }; static const short _deserialize_json_index_offsets[] = { - 0, 0, 116, 143, 165, 168, 170, 221, - 271, 282, 400, 518, 604, 722, 724, 775, - 825, 836, 954, 1072, 1074, 1076, 1127, 1177, - 1295, 1413, 1416, 1418, 1469, 1519, 1530, 1648, - 1766, 1768, 1819, 1869, 1880, 1998, 2116, 2118, - 2120, 2171, 2221, 2339, 2457, 2459, 2510, 2560, - 2620, 2738, 2798, 2916, 3034, 3036, 3087, 3137, - 3255, 3371 + 0, 0, 116, 232, 259, 281, 284, 286, + 337, 387, 398, 516, 634, 752, 754, 805, + 855, 866, 984, 1102, 1104, 1106, 1157, 1207, + 1325, 1443, 1446, 1448, 1499, 1549, 1560, 1678, + 1796, 1798, 1849, 1899, 1910, 2028, 2146, 2148, + 2150, 2201, 2251, 2369, 2487, 2489, 2540, 2590, + 2650, 2768, 2828, 2946, 3064, 3066, 3117, 3167, + 3285, 3371, 3487 }; static const char _deserialize_json_indicies[] = { @@ -77,51 +77,51 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 1, 2, 2, 2, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 1, 3, 3, 3, - 3, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 4, 1, - 5, 1, 6, 7, 1, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 10, 1, 11, 12, - 1, 13, 1, 13, 13, 13, 13, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 14, 1, 14, 14, - 14, 14, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 15, 1, 1, 16, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 1, - 18, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 1, 20, 20, 20, 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 20, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 21, 1, + 1, 1, 1, 1, 1, 1, 1, 3, + 1, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 4, 1, 5, 1, 6, 1, 7, 8, + 1, 9, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 11, 1, 12, 13, 1, 14, 1, 14, + 14, 14, 14, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 15, 1, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 22, - 1, 23, 23, 23, 23, 23, 1, 1, + 1, 15, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 16, 1, + 1, 17, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 1, 19, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 1, 21, + 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 23, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 1, 1, + 1, 1, 22, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -131,94 +131,99 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 24, 1, 25, - 25, 25, 25, 25, 1, 1, 1, 1, + 1, 1, 1, 23, 1, 24, 24, 24, + 24, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 25, 1, + 1, 1, 1, 1, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 26, 1, 1, 1, 1, 1, + 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 27, 1, 20, 20, 20, - 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 21, 1, 1, 1, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 25, 1, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 21, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 22, 1, + 1, 1, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 22, 1, 28, 1, 28, 28, 28, - 28, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 29, 1, - 29, 29, 29, 29, 29, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 23, + 1, 26, 1, 26, 26, 26, 26, 26, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 29, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 30, 1, 1, 31, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 1, 33, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 1, 35, 35, 35, - 35, 35, 1, 1, 1, 1, 1, 1, + 1, 1, 26, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 35, 1, 1, 1, + 1, 1, 1, 1, 27, 1, 27, 27, + 27, 27, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 36, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 28, 1, 1, 29, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 1, + 31, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 1, 33, 33, 33, 33, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 33, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 34, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 37, 1, 35, 35, 35, 35, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 35, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 36, 1, - 1, 1, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 35, + 1, 33, 33, 33, 33, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 33, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 34, 1, 1, 1, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 37, - 1, 38, 1, 39, 1, 39, 39, 39, - 39, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 40, 1, - 40, 40, 40, 40, 40, 1, 1, 1, + 1, 1, 1, 1, 1, 35, 1, 36, + 1, 37, 1, 37, 37, 37, 37, 37, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 40, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 37, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 38, 1, 38, 38, + 38, 38, 38, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 38, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 39, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 1, + 41, 41, 41, 41, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 41, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 1, 43, 43, 43, 43, 43, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 42, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 43, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -227,15 +232,14 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 43, 1, 41, 41, + 41, 41, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 45, 1, - 43, 43, 43, 43, 43, 1, 1, 1, + 1, 1, 1, 1, 1, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 43, + 1, 42, 1, 1, 1, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 44, 1, 1, 1, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -243,26 +247,26 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 45, 1, 47, 48, - 1, 49, 1, 49, 49, 49, 49, 49, + 1, 1, 43, 1, 45, 46, 1, 47, + 1, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 49, 1, 1, 1, 1, 1, + 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 50, 1, 50, 50, - 50, 50, 50, 1, 1, 1, 1, 1, + 1, 1, 48, 1, 48, 48, 48, 48, + 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 50, 1, 1, + 1, 1, 1, 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 51, 1, 1, 52, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 1, - 54, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 1, 56, 56, 56, 56, 56, + 49, 1, 1, 50, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 1, 52, 53, + 53, 53, 53, 53, 53, 53, 53, 53, + 1, 54, 54, 54, 54, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 56, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 57, 1, + 54, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -272,14 +276,13 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 58, - 1, 56, 56, 56, 56, 56, 1, 1, + 1, 1, 1, 1, 1, 56, 1, 54, + 54, 54, 54, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 56, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 57, 1, 1, 1, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 1, 1, 1, 1, 1, 1, + 1, 1, 55, 1, 1, 1, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -287,119 +290,120 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 58, 1, 59, - 1, 59, 59, 59, 59, 59, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 56, 1, 57, 1, 57, + 57, 57, 57, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 59, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 57, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 58, 1, 58, 58, 58, 58, 58, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 58, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 59, 1, + 1, 60, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 1, 62, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 1, 64, + 64, 64, 64, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 60, 1, 60, 60, 60, 60, - 60, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 61, 1, 1, 62, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 1, 64, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 1, 66, 66, 66, 66, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 66, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 66, 1, 64, 64, 64, + 64, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 65, 1, 1, 1, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 68, 1, 66, - 66, 66, 66, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 67, 1, 1, 1, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 66, 1, 67, 1, 68, 1, 68, + 68, 68, 68, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 68, 1, 69, 1, 70, - 1, 70, 70, 70, 70, 70, 1, 1, + 69, 1, 69, 69, 69, 69, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 70, 1, 1, 1, 1, 1, 1, 1, + 1, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 70, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 1, 72, 72, 72, 72, + 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 71, 1, 71, 71, 71, 71, - 71, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 72, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 73, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 71, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 72, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 1, 74, 74, - 74, 74, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 74, 1, 72, 72, 72, 72, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 72, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 73, 1, 1, + 1, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 76, 1, 74, 74, 74, 74, - 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 74, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 75, - 1, 1, 1, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 74, 1, + 76, 1, 76, 76, 76, 76, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 76, 1, 78, 1, 78, 78, 78, 78, - 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 78, 1, 1, 1, 1, + 1, 1, 1, 77, 1, 77, 77, 77, + 77, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 77, 1, 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 79, 1, 79, - 79, 79, 79, 79, 1, 1, 1, 1, + 1, 1, 1, 1, 79, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 1, 82, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 83, 81, 84, 84, 84, 84, 84, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 79, 1, - 80, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 81, 82, - 82, 82, 82, 82, 82, 82, 82, 82, - 1, 84, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 85, 83, 86, 86, 86, - 86, 86, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 86, 1, 1, 1, + 1, 1, 84, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -408,20 +412,21 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 86, + 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 88, 1, 83, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 81, 1, 87, 87, 87, + 87, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 83, 1, 89, - 89, 89, 89, 89, 1, 1, 1, 1, + 1, 1, 1, 1, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 89, 1, + 88, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -430,97 +435,107 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 89, 1, 87, 87, 87, 87, 87, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 91, 1, 89, 89, 89, - 89, 89, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 89, 1, 1, 1, + 1, 1, 87, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 88, 1, + 1, 1, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 90, 1, 1, 1, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 89, + 1, 91, 1, 91, 91, 91, 91, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 91, 1, 93, 1, 93, 93, 93, - 93, 93, 1, 1, 1, 1, 1, 1, + 1, 1, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 93, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 92, 1, 92, 92, + 92, 92, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 94, 1, - 94, 94, 94, 94, 94, 1, 1, 1, + 1, 1, 1, 1, 1, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 94, + 1, 1, 1, 1, 1, 93, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 1, + 87, 87, 87, 87, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 95, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 1, 89, 89, 89, 89, 89, 1, + 1, 1, 1, 1, 1, 1, 1, 87, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 88, 1, 1, 1, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 89, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 90, 1, 1, - 1, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 89, 1, 96, 96, + 96, 96, 96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 91, 1, - 0, 0, 0, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, + 1, 97, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 98, 1, 2, 2, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 1, 1, 0 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 1, + 1, 0 }; static const char _deserialize_json_trans_targs[] = { - 1, 0, 2, 2, 3, 4, 19, 25, - 38, 44, 52, 5, 13, 6, 7, 8, - 9, 12, 9, 12, 10, 2, 11, 10, - 11, 11, 56, 57, 14, 15, 16, 17, - 18, 17, 18, 10, 2, 11, 20, 21, - 22, 23, 24, 10, 2, 11, 24, 26, - 32, 27, 28, 29, 30, 31, 30, 31, - 10, 2, 11, 33, 34, 35, 36, 37, - 36, 37, 10, 2, 11, 39, 40, 41, - 42, 43, 10, 2, 11, 43, 45, 46, - 47, 50, 51, 47, 48, 49, 10, 2, - 11, 10, 2, 11, 51, 53, 54, 50, - 55, 55 + 1, 0, 2, 3, 3, 4, 5, 19, + 25, 38, 44, 52, 6, 13, 7, 8, + 9, 10, 12, 10, 12, 11, 3, 56, + 11, 56, 14, 15, 16, 17, 18, 17, + 18, 11, 3, 56, 20, 21, 22, 23, + 24, 11, 3, 56, 24, 26, 32, 27, + 28, 29, 30, 31, 30, 31, 11, 3, + 56, 33, 34, 35, 36, 37, 36, 37, + 11, 3, 56, 39, 40, 41, 42, 43, + 11, 3, 56, 43, 45, 46, 47, 50, + 51, 47, 48, 49, 11, 3, 56, 11, + 3, 56, 51, 53, 54, 50, 55, 55, + 56, 57, 58 }; static const char _deserialize_json_trans_actions[] = { - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, - 2, 2, 0, 0, 3, 3, 4, 0, - 5, 0, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 6, 6, 7, 0, 0, - 0, 2, 2, 8, 8, 9, 0, 0, - 0, 0, 0, 2, 2, 2, 0, 0, - 10, 10, 11, 0, 0, 2, 2, 2, - 0, 0, 12, 12, 13, 0, 0, 0, - 2, 2, 14, 14, 15, 0, 0, 0, - 2, 16, 16, 0, 17, 0, 18, 18, - 19, 20, 20, 21, 17, 0, 0, 22, - 22, 23 + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 0, 0, 3, 3, 4, + 0, 5, 0, 0, 2, 2, 2, 0, + 0, 6, 6, 7, 0, 0, 0, 2, + 2, 8, 8, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 0, 0, 10, 10, + 11, 0, 0, 2, 2, 2, 0, 0, + 12, 12, 13, 0, 0, 0, 2, 2, + 14, 14, 15, 0, 0, 0, 2, 16, + 16, 0, 17, 0, 18, 18, 19, 20, + 20, 21, 17, 0, 0, 22, 22, 23, + 0, 0, 0 }; static const int deserialize_json_start = 1; @@ -545,22 +560,17 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer, /* Ensure we have positions. */ (void) hb_buffer_get_glyph_positions (buffer, nullptr); - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? ',' : '[')) - *end_ptr = ++p; - const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 559 "hb-buffer-deserialize-json.hh" +#line 569 "hb-buffer-deserialize-json.hh" { cs = deserialize_json_start; } -#line 564 "hb-buffer-deserialize-json.hh" +#line 574 "hb-buffer-deserialize-json.hh" { int _slen; int _trans; @@ -772,7 +782,7 @@ _resume: *end_ptr = p; } break; -#line 776 "hb-buffer-deserialize-json.hh" +#line 786 "hb-buffer-deserialize-json.hh" } _again: @@ -784,7 +794,7 @@ _again: _out: {} } -#line 137 "hb-buffer-deserialize-json.rl" +#line 132 "hb-buffer-deserialize-json.rl" *end_ptr = p; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc index 3bdea30ed36c7..3a4c9c9f31762 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc @@ -149,7 +149,7 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, } assert (text_start < text_end); - if (0) + if (false) printf("start %u end %u text start %u end %u\n", start, end, text_start, text_end); hb_buffer_clear_contents (fragment); @@ -288,7 +288,7 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, } assert (text_start < text_end); - if (0) + if (false) printf("start %u end %u text start %u end %u\n", start, end, text_start, text_end); #if 0 @@ -412,7 +412,7 @@ hb_buffer_t::verify (hb_buffer_t *text_buffer, &len, HB_BUFFER_SERIALIZE_FORMAT_TEXT, HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS); - buffer_verify_error (this, font, BUFFER_VERIFY_ERROR "text was: %s.", bytes.arrayZ); + buffer_verify_error (this, font, BUFFER_VERIFY_ERROR "text was: %s.", bytes.arrayZ ? bytes.arrayZ : ""); } #endif } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc index 5f9329e07edf7..72970c9c2f71a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc @@ -271,6 +271,7 @@ hb_buffer_t::similar (const hb_buffer_t &src) replacement = src.replacement; invisible = src.invisible; not_found = src.not_found; + not_found_variation_selector = src.not_found_variation_selector; } void @@ -283,6 +284,7 @@ hb_buffer_t::reset () replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; invisible = 0; not_found = 0; + not_found_variation_selector = HB_CODEPOINT_INVALID; clear (); } @@ -309,6 +311,7 @@ hb_buffer_t::clear () deallocate_var_all (); serial = 0; + random_state = 1; scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; } @@ -704,6 +707,7 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, 0, /* invisible */ 0, /* not_found */ + HB_CODEPOINT_INVALID, /* not_found_variation_selector */ HB_BUFFER_CONTENT_TYPE_INVALID, @@ -1359,6 +1363,89 @@ hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer) return buffer->not_found; } +/** + * hb_buffer_set_not_found_variation_selector_glyph: + * @buffer: An #hb_buffer_t + * @not_found_variation_selector: the not-found-variation-selector #hb_codepoint_t + * + * Sets the #hb_codepoint_t that replaces variation-selector characters not resolved + * in the font during shaping. + * + * The not-found-variation-selector glyph defaults to #HB_CODEPOINT_INVALID, + * in which case an unresolved variation-selector will be removed from the glyph + * string during shaping. This API allows for changing that and retaining a glyph, + * such that the situation can be detected by the client and handled accordingly + * (e.g. by using a different font). + * + * Since: 10.0.0 + **/ +void +hb_buffer_set_not_found_variation_selector_glyph (hb_buffer_t *buffer, + hb_codepoint_t not_found_variation_selector) +{ + buffer->not_found_variation_selector = not_found_variation_selector; +} + +/** + * hb_buffer_get_not_found_variation_selector_glyph: + * @buffer: An #hb_buffer_t + * + * See hb_buffer_set_not_found_variation_selector_glyph(). + * + * Return value: + * The @buffer not-found-variation-selector #hb_codepoint_t + * + * Since: 10.0.0 + **/ +hb_codepoint_t +hb_buffer_get_not_found_variation_selector_glyph (const hb_buffer_t *buffer) +{ + return buffer->not_found_variation_selector; +} + +/** + * hb_buffer_set_random_state: + * @buffer: An #hb_buffer_t + * @state: the new random state + * + * Sets the random state of the buffer. The state changes + * every time a glyph uses randomness (eg. the `rand` + * OpenType feature). This function together with + * hb_buffer_get_random_state() allow for transferring + * the current random state to a subsequent buffer, to + * get better randomness distribution. + * + * Defaults to 1 and when buffer contents are cleared. + * A value of 0 disables randomness during shaping. + * + * Since: 8.4.0 + **/ +void +hb_buffer_set_random_state (hb_buffer_t *buffer, + unsigned state) +{ + if (unlikely (hb_object_is_immutable (buffer))) + return; + + buffer->random_state = state; +} + +/** + * hb_buffer_get_random_state: + * @buffer: An #hb_buffer_t + * + * See hb_buffer_set_random_state(). + * + * Return value: + * The @buffer random state + * + * Since: 8.4.0 + **/ +unsigned +hb_buffer_get_random_state (const hb_buffer_t *buffer) +{ + return buffer->random_state; +} /** * hb_buffer_clear_contents: @@ -1896,7 +1983,7 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer, * @buffer: An #hb_buffer_t * @source: source #hb_buffer_t * @start: start index into source buffer to copy. Use 0 to copy from start of buffer. - * @end: end index into source buffer to copy. Use @HB_FEATURE_GLOBAL_END to copy to end of buffer. + * @end: end index into source buffer to copy. Use @UINT_MAX (or ((unsigned int) -1)) to copy to end of buffer. * * Append (part of) contents of another buffer to this buffer. * diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.h b/src/java.desktop/share/native/libharfbuzz/hb-buffer.h index 6fc215d162779..d2258634ff42f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.h @@ -487,6 +487,19 @@ hb_buffer_set_not_found_glyph (hb_buffer_t *buffer, HB_EXTERN hb_codepoint_t hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer); +HB_EXTERN void +hb_buffer_set_not_found_variation_selector_glyph (hb_buffer_t *buffer, + hb_codepoint_t not_found_variation_selector); + +HB_EXTERN hb_codepoint_t +hb_buffer_get_not_found_variation_selector_glyph (const hb_buffer_t *buffer); + +HB_EXTERN void +hb_buffer_set_random_state (hb_buffer_t *buffer, + unsigned state); + +HB_EXTERN unsigned +hb_buffer_get_random_state (const hb_buffer_t *buffer); /* * Content API. diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh index 7f8ce14e90d58..c92e7df320efa 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh @@ -32,7 +32,6 @@ #include "hb.hh" #include "hb-unicode.hh" -#include "hb-set-digest.hh" static_assert ((sizeof (hb_glyph_info_t) == 20), ""); @@ -52,6 +51,7 @@ enum hb_buffer_scratch_flags_t { HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000010u, HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS = 0x00000020u, HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE = 0x00000040u, + HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK= 0x00000080u, /* Reserved for shapers' internal use. */ HB_BUFFER_SCRATCH_FLAG_SHAPER0 = 0x01000000u, @@ -80,6 +80,7 @@ struct hb_buffer_t hb_codepoint_t replacement; /* U+FFFD or something else. */ hb_codepoint_t invisible; /* 0 or something else. */ hb_codepoint_t not_found; /* 0 or something else. */ + hb_codepoint_t not_found_variation_selector; /* HB_CODEPOINT_INVALID or something else. */ /* * Buffer contents @@ -116,6 +117,7 @@ struct hb_buffer_t uint8_t allocated_var_bits; uint8_t serial; + uint32_t random_state; hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */ unsigned int max_len; /* Maximum allowed len. */ int max_ops; /* Maximum allowed operations. */ @@ -179,22 +181,24 @@ struct hb_buffer_t allocated_var_bits = 0; } + HB_ALWAYS_INLINE hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; } + HB_ALWAYS_INLINE hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; } - hb_set_digest_t digest () const - { - hb_set_digest_t d; - d.init (); - d.add_array (&info[0].codepoint, len, sizeof (info[0])); - return d; - } + template + void collect_codepoints (set_t &d) const + { d.clear (); d.add_array (&info[0].codepoint, len, sizeof (info[0])); } HB_INTERNAL void similar (const hb_buffer_t &src); HB_INTERNAL void reset (); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh index 8d9ff5faf6d7e..79d7c4c7133bf 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh @@ -522,7 +522,7 @@ struct parsed_values_t void alloc (unsigned n) { - values.alloc (n, true); + values.alloc_exact (n); } void add_op (op_code_t op, const byte_str_ref_t& str_ref = byte_str_ref_t (), const VAL &v = VAL ()) @@ -624,7 +624,6 @@ struct opset_t } else { /* invalid unknown operator */ env.clear_args (); - env.set_error (); } break; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-dict-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-dict-common.hh index 0c0cec9986a84..6a227e5e81eed 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-dict-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-dict-common.hh @@ -54,8 +54,8 @@ struct top_dict_values_t : dict_values_t } void fini () { dict_values_t::fini (); } - unsigned int charStringsOffset; - unsigned int FDArrayOffset; + int charStringsOffset; + int FDArrayOffset; }; struct dict_opset_t : opset_t @@ -84,7 +84,7 @@ struct dict_opset_t : opset_t enum Nibble { DECIMAL=10, EXP_POS, EXP_NEG, RESERVED, NEG, END }; - char buf[32]; + char buf[32] = {0}; unsigned char byte = 0; for (unsigned i = 0, count = 0; count < ARRAY_LENGTH (buf); ++i, ++count) { @@ -157,11 +157,11 @@ struct top_dict_opset_t : dict_opset_t { switch (op) { case OpCode_CharStrings: - dictval.charStringsOffset = env.argStack.pop_uint (); + dictval.charStringsOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FDArray: - dictval.FDArrayOffset = env.argStack.pop_uint (); + dictval.FDArrayOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FontMatrix: diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh b/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh index c970633e06416..ab17d68318ba3 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh @@ -76,16 +76,12 @@ struct cff2_cs_interp_env_t : cs_interp_env_t coords = coords_; num_coords = num_coords_; varStore = acc.varStore; - seen_blend = false; - seen_vsindex_ = false; - scalars.init (); do_blend = num_coords && coords && varStore->size; set_ivs (acc.privateDicts[fd].ivs); } void fini () { - scalars.fini (); SUPER::fini (); } @@ -168,13 +164,13 @@ struct cff2_cs_interp_env_t : cs_interp_env_t protected: const int *coords; unsigned int num_coords; - const CFF2VariationStore *varStore; + const CFF2ItemVariationStore *varStore; unsigned int region_count; unsigned int ivs; hb_vector_t scalars; bool do_blend; - bool seen_vsindex_; - bool seen_blend; + bool seen_vsindex_ = false; + bool seen_blend = false; typedef cs_interp_env_t SUPER; }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-common.cc b/src/java.desktop/share/native/libharfbuzz/hb-common.cc index 3afab4284e68a..bce0d09d20a16 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-common.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-common.cc @@ -625,6 +625,9 @@ hb_script_get_horizontal_direction (hb_script_t script) /* Unicode-14.0 additions */ case HB_SCRIPT_OLD_UYGHUR: + /* Unicode-16.0 additions */ + case HB_SCRIPT_GARAY: + return HB_DIRECTION_RTL; @@ -996,7 +999,7 @@ hb_feature_to_string (hb_feature_t *feature, if (feature->value > 1) { s[len++] = '='; - len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value)); + len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%" PRIu32, feature->value)); } assert (len < ARRAY_LENGTH (s)); len = hb_min (len, size - 1); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-common.h b/src/java.desktop/share/native/libharfbuzz/hb-common.h index 0d7956764cff6..a8bae366f7ede 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-common.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-common.h @@ -47,14 +47,10 @@ # endif /* !__cplusplus */ #endif -#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || \ - defined (_sgi) || defined (__sun) || defined (sun) || \ - defined (__digital__) || defined (__HP_cc) -# include -#elif defined (_AIX) +#if defined (_AIX) # include #elif defined (_MSC_VER) && _MSC_VER < 1600 -/* VS 2010 (_MSC_VER 1600) has stdint.h */ +/* VS 2010 (_MSC_VER 1600) has stdint.h */ typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; @@ -63,10 +59,11 @@ typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; -#elif defined (__KERNEL__) -# include -#else +#elif defined (_MSC_VER) && _MSC_VER < 1800 +/* VS 2013 (_MSC_VER 1800) has inttypes.h */ # include +#else +# include #endif #if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) @@ -507,6 +504,13 @@ hb_language_matches (hb_language_t language, * @HB_SCRIPT_MATH: `Zmth`, Since: 3.4.0 * @HB_SCRIPT_KAWI: `Kawi`, Since: 5.2.0 * @HB_SCRIPT_NAG_MUNDARI: `Nagm`, Since: 5.2.0 + * @HB_SCRIPT_GARAY: `Gara`, Since: 10.0.0 + * @HB_SCRIPT_GURUNG_KHEMA: `Gukh`, Since: 10.0.0 + * @HB_SCRIPT_KIRAT_RAI: `Krai`, Since: 10.0.0 + * @HB_SCRIPT_OL_ONAL: `Onao`, Since: 10.0.0 + * @HB_SCRIPT_SUNUWAR: `Sunu`, Since: 10.0.0 + * @HB_SCRIPT_TODHRI: `Todr`, Since: 10.0.0 + * @HB_SCRIPT_TULU_TIGALARI: `Tutg`, Since: 10.0.0 * @HB_SCRIPT_INVALID: No script set * * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding @@ -734,6 +738,17 @@ typedef enum HB_SCRIPT_KAWI = HB_TAG ('K','a','w','i'), /*15.0*/ HB_SCRIPT_NAG_MUNDARI = HB_TAG ('N','a','g','m'), /*15.0*/ + /* + * Since 10.0.0 + */ + HB_SCRIPT_GARAY = HB_TAG ('G','a','r','a'), /*16.0*/ + HB_SCRIPT_GURUNG_KHEMA = HB_TAG ('G','u','k','h'), /*16.0*/ + HB_SCRIPT_KIRAT_RAI = HB_TAG ('K','r','a','i'), /*16.0*/ + HB_SCRIPT_OL_ONAL = HB_TAG ('O','n','a','o'), /*16.0*/ + HB_SCRIPT_SUNUWAR = HB_TAG ('S','u','n','u'), /*16.0*/ + HB_SCRIPT_TODHRI = HB_TAG ('T','o','d','r'), /*16.0*/ + HB_SCRIPT_TULU_TIGALARI = HB_TAG ('T','u','t','g'), /*16.0*/ + /* No script set. */ HB_SCRIPT_INVALID = HB_TAG_NONE, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-config.hh b/src/java.desktop/share/native/libharfbuzz/hb-config.hh index 816c55c7d367a..40cc2403c18c9 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-config.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-config.hh @@ -56,7 +56,6 @@ #ifdef HB_LEAN #define HB_DISABLE_DEPRECATED -#define HB_NDEBUG #define HB_NO_ATEXIT #define HB_NO_BUFFER_MESSAGE #define HB_NO_BUFFER_SERIALIZE @@ -69,8 +68,6 @@ #define HB_NO_FACE_COLLECT_UNICODES #define HB_NO_GETENV #define HB_NO_HINTING -#define HB_NO_LANGUAGE_LONG -#define HB_NO_LANGUAGE_PRIVATE_SUBTAG #define HB_NO_LAYOUT_FEATURE_PARAMS #define HB_NO_LAYOUT_COLLECT_GLYPHS #define HB_NO_LAYOUT_RARELY_USED @@ -118,6 +115,10 @@ #define HB_NO_VAR_COMPOSITES #endif +#ifdef HB_NO_VAR +#define HB_NO_VAR_COMPOSITES +#endif + #ifdef HB_DISABLE_DEPRECATED #define HB_IF_NOT_DEPRECATED(x) #else @@ -156,6 +157,7 @@ #define HB_NO_FALLBACK_SHAPE #define HB_NO_OT_KERN #define HB_NO_OT_LAYOUT_BLOCKLIST +#define HB_NO_AAT_LAYOUT_BLOCKLIST #define HB_NO_OT_SHAPE_FALLBACK #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cplusplus.hh b/src/java.desktop/share/native/libharfbuzz/hb-cplusplus.hh index eac4ff03ed5f7..82d397415279f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-cplusplus.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-cplusplus.hh @@ -27,9 +27,6 @@ #include "hb.h" -HB_BEGIN_DECLS -HB_END_DECLS - #ifdef __cplusplus #include @@ -56,15 +53,15 @@ struct shared_ptr explicit shared_ptr (T *p = nullptr) : p (p) {} shared_ptr (const shared_ptr &o) : p (v::reference (o.p)) {} - shared_ptr (shared_ptr &&o) : p (o.p) { o.p = nullptr; } + shared_ptr (shared_ptr &&o) noexcept : p (o.p) { o.p = nullptr; } shared_ptr& operator = (const shared_ptr &o) { if (p != o.p) { destroy (); p = o.p; reference (); } return *this; } - shared_ptr& operator = (shared_ptr &&o) { v::destroy (p); p = o.p; o.p = nullptr; return *this; } + shared_ptr& operator = (shared_ptr &&o) noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; } ~shared_ptr () { v::destroy (p); p = nullptr; } T* get() const { return p; } - void swap (shared_ptr &o) { std::swap (p, o.p); } - friend void swap (shared_ptr &a, shared_ptr &b) { std::swap (a.p, b.p); } + void swap (shared_ptr &o) noexcept { std::swap (p, o.p); } + friend void swap (shared_ptr &a, shared_ptr &b) noexcept { std::swap (a.p, b.p); } operator T * () const { return p; } T& operator * () const { return *get (); } @@ -98,16 +95,16 @@ struct unique_ptr explicit unique_ptr (T *p = nullptr) : p (p) {} unique_ptr (const unique_ptr &o) = delete; - unique_ptr (unique_ptr &&o) : p (o.p) { o.p = nullptr; } + unique_ptr (unique_ptr &&o) noexcept : p (o.p) { o.p = nullptr; } unique_ptr& operator = (const unique_ptr &o) = delete; - unique_ptr& operator = (unique_ptr &&o) { v::destroy (p); p = o.p; o.p = nullptr; return *this; } + unique_ptr& operator = (unique_ptr &&o) noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; } ~unique_ptr () { v::destroy (p); p = nullptr; } T* get() const { return p; } T* release () { T* v = p; p = nullptr; return v; } - void swap (unique_ptr &o) { std::swap (p, o.p); } - friend void swap (unique_ptr &a, unique_ptr &b) { std::swap (a.p, b.p); } + void swap (unique_ptr &o) noexcept { std::swap (p, o.p); } + friend void swap (unique_ptr &a, unique_ptr &b) noexcept { std::swap (a.p, b.p); } operator T * () const { return p; } T& operator * () const { return *get (); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-decycler.hh b/src/java.desktop/share/native/libharfbuzz/hb-decycler.hh new file mode 100644 index 0000000000000..95b961027bf22 --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/hb-decycler.hh @@ -0,0 +1,164 @@ +/* + * Copyright © 2025 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_DECYCLER_HH +#define HB_DECYCLER_HH + +#include "hb.hh" + +/* + * hb_decycler_t is an efficient cycle detector for graph traversal. + * It's a simple tortoise-and-hare algorithm with a twist: it's + * designed to detect cycles while traversing a graph in a DFS manner, + * instead of just a linked list. + * + * For Floyd's tortoise and hare algorithm, see: + * https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare + * + * hb_decycler_t is O(n) in the number of nodes in the DFS traversal + * if there are no cycles. Unlike Floyd's algorithm, hb_decycler_t + * can be used in a DFS traversal, where the graph is not a simple + * linked list, but a tree with possible cycles. Like Floyd's algorithm, + * it is constant-memory (~three pointers). + * + * The decycler works by creating an implicit linked-list on the stack, + * of the path from the root to the current node, and apply Floyd's + * algorithm on that list as it goes. + * + * The decycler is malloc-free, and as such, much faster to use than a + * hb_set_t or hb_map_t equivalent. + * + * The decycler detects cycles in the graph *eventually*, not *immediately*. + * That is, it may not detect a cycle until the cycle is fully traversed, + * even multiple times. See Floyd's algorithm analysis for details. + * + * The implementation saves a pointer storage on the stack by combining + * this->u.decycler and this->u.next into a union. This is possible because + * at any point we only need one of those values. The invariant is that + * after construction, and before destruction, of a node, the u.decycler + * field is always valid. The u.next field is only valid when the node is + * in the traversal path, parent to another node. + * + * There are three method's: + * + * - hb_decycler_node_t() constructor: Creates a new node in the traversal. + * The constructor takes a reference to the decycler object and inserts + * itself as the latest node in the traversal path, by advancing the hare + * pointer, and for every other descent, advancing the tortoise pointer. + * + * - ~hb_decycler_node_t() destructor: Restores the decycler object to its + * previous state by removing the node from the traversal path. + * + * - bool visit(uintptr_t value): Called on every node in the graph. Returns + * true if the node is not part of a cycle, and false if it is. The value + * parameter is used to detect cycles. It's the caller's responsibility + * to ensure that the value is unique for each node in the graph. + * The cycle detection is as simple as comparing the value to the value + * held by the tortoise pointer, which is the Floyd's algorithm. + * + * For usage examples see test-decycler.cc. + */ + +struct hb_decycler_node_t; + +struct hb_decycler_t +{ + friend struct hb_decycler_node_t; + + private: + bool tortoise_awake = false; + hb_decycler_node_t *tortoise = nullptr; + hb_decycler_node_t *hare = nullptr; +}; + +struct hb_decycler_node_t +{ + hb_decycler_node_t (hb_decycler_t &decycler) + { + u.decycler = &decycler; + + decycler.tortoise_awake = !decycler.tortoise_awake; + + if (!decycler.tortoise) + { + // First node. + assert (decycler.tortoise_awake); + assert (!decycler.hare); + decycler.tortoise = decycler.hare = this; + return; + } + + if (decycler.tortoise_awake) + decycler.tortoise = decycler.tortoise->u.next; // Time to move. + + this->prev = decycler.hare; + decycler.hare->u.next = this; + decycler.hare = this; + } + + ~hb_decycler_node_t () + { + hb_decycler_t &decycler = *u.decycler; + + // Inverse of the constructor. + + assert (decycler.hare == this); + decycler.hare = prev; + if (prev) + prev->u.decycler = &decycler; + + assert (decycler.tortoise); + if (decycler.tortoise_awake) + decycler.tortoise = decycler.tortoise->prev; + + decycler.tortoise_awake = !decycler.tortoise_awake; + } + + bool visit (uintptr_t value_) + { + value = value_; + + hb_decycler_t &decycler = *u.decycler; + + if (decycler.tortoise == this) + return true; // First node; not a cycle. + + if (decycler.tortoise->value == value) + return false; // Cycle detected. + + return true; + } + + private: + union { + hb_decycler_t *decycler; + hb_decycler_node_t *next; + } u = {nullptr}; + hb_decycler_node_t *prev = nullptr; + uintptr_t value = 0; +}; + +#endif /* HB_DECYCLER_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h b/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h index 200e8ff49288b..d854a2b16f5fc 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h @@ -56,7 +56,7 @@ HB_BEGIN_DECLS /** * HB_SCRIPT_CANADIAN_ABORIGINAL: * - * Use #HB_SCRIPT_CANADIAN_SYLLABICS instead: + * Use #HB_SCRIPT_CANADIAN_SYLLABICS instead. * * Deprecated: 0.9.20 */ @@ -301,6 +301,15 @@ hb_font_get_glyph_shape (hb_font_t *font, hb_draw_funcs_t *dfuncs, void *draw_data); +/** + * HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION: + * + * Use #HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION instead. + * + * Deprecated: 8.3.0 + */ +#define HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION + #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-draw.h b/src/java.desktop/share/native/libharfbuzz/hb-draw.h index eba791d10c08d..4556b082d6032 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-draw.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-draw.h @@ -70,7 +70,7 @@ typedef struct hb_draw_state_t { * * The default #hb_draw_state_t at the start of glyph drawing. */ -#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, {0.}, {0.}, {0.}} +#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, {0.}, {0.}, {0.}, {0.}, {0.}, {0.}, {0.}} /** diff --git a/src/java.desktop/share/native/libharfbuzz/hb-draw.hh b/src/java.desktop/share/native/libharfbuzz/hb-draw.hh index e1adf9ddc9f5c..2c30843de64f8 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-draw.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-draw.hh @@ -232,7 +232,7 @@ struct hb_draw_session_t funcs->close_path (draw_data, st); } - protected: + public: float slant; bool not_slanted; hb_draw_funcs_t *funcs; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc b/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc index ff723ac700040..6b7e1913024b5 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc @@ -42,7 +42,7 @@ struct face_table_info_t { hb_blob_t* data; - signed order; + unsigned order; }; struct hb_face_builder_data_t @@ -153,6 +153,50 @@ _hb_face_builder_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void return hb_blob_reference (data->tables[tag].data); } +static unsigned +_hb_face_builder_get_table_tags (const hb_face_t *face HB_UNUSED, + unsigned int start_offset, + unsigned int *table_count, + hb_tag_t *table_tags, + void *user_data) +{ + hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data; + + unsigned population = data->tables.get_population (); + + if (!table_count) + return population; + + if (unlikely (start_offset >= population)) + { + if (table_count) + *table_count = 0; + return population; + } + + // Sort the tags. + hb_vector_t sorted_tags; + data->tables.keys () | hb_sink (sorted_tags); + if (unlikely (sorted_tags.in_error ())) + { + // Not much to do... + } + sorted_tags.qsort ([] (const void* a, const void* b) { + return * (hb_tag_t *) a < * (hb_tag_t *) b ? -1 : + * (hb_tag_t *) a == * (hb_tag_t *) b ? 0 : + +1; + }); + + auto array = sorted_tags.as_array ().sub_array (start_offset, table_count); + auto out = hb_array (table_tags, *table_count); + + + array.iter () + | hb_sink (out) + ; + + return population; +} + /** * hb_face_builder_create: @@ -171,9 +215,16 @@ hb_face_builder_create () hb_face_builder_data_t *data = _hb_face_builder_data_create (); if (unlikely (!data)) return hb_face_get_empty (); - return hb_face_create_for_tables (_hb_face_builder_reference_table, - data, - _hb_face_builder_data_destroy); + hb_face_t *face = hb_face_create_for_tables (_hb_face_builder_reference_table, + data, + _hb_face_builder_data_destroy); + + hb_face_set_get_table_tags_func (face, + _hb_face_builder_get_table_tags, + data, + nullptr); + + return face; } /** @@ -199,7 +250,7 @@ hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob) hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data; hb_blob_t* previous = data->tables.get (tag).data; - if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), -1})) + if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), (unsigned) -1})) { hb_blob_destroy (blob); return false; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face.cc b/src/java.desktop/share/native/libharfbuzz/hb-face.cc index bc19bb9d5c970..7967ae3241bd6 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-face.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-face.cc @@ -90,10 +90,6 @@ DEFINE_NULL_INSTANCE (hb_face_t) = { HB_OBJECT_HEADER_STATIC, - nullptr, /* reference_table_func */ - nullptr, /* user_data */ - nullptr, /* destroy */ - 0, /* index */ 1000, /* upem */ 0, /* num_glyphs */ @@ -110,8 +106,9 @@ DEFINE_NULL_INSTANCE (hb_face_t) = * * Variant of hb_face_create(), built for those cases where it is more * convenient to provide data for individual tables instead of the whole font - * data. With the caveat that hb_face_get_table_tags() does not currently work - * with faces created this way. + * data. With the caveat that hb_face_get_table_tags() would not work + * with faces created this way. You can address that by calling the + * hb_face_set_get_table_tags_func() function and setting the appropriate callback. * * Creates a new face object from the specified @user_data and @reference_table_func, * with the @destroy callback. @@ -194,6 +191,22 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void return blob; } +static unsigned +_hb_face_for_data_get_table_tags (const hb_face_t *face HB_UNUSED, + unsigned int start_offset, + unsigned int *table_count, + hb_tag_t *table_tags, + void *user_data) +{ + hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; + + const OT::OpenTypeFontFile &ot_file = *data->blob->as (); + const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); + + return ot_face.get_table_tags (start_offset, table_count, table_tags); +} + + /** * hb_face_create: * @blob: #hb_blob_t to work upon @@ -240,12 +253,73 @@ hb_face_create (hb_blob_t *blob, face = hb_face_create_for_tables (_hb_face_for_data_reference_table, closure, _hb_face_for_data_closure_destroy); + hb_face_set_get_table_tags_func (face, + _hb_face_for_data_get_table_tags, + closure, + nullptr); face->index = index; return face; } +/** + * hb_face_create_or_fail: + * @blob: #hb_blob_t to work upon + * @index: The index of the face within @blob + * + * Like hb_face_create(), but returns `NULL` if the blob data + * contains no usable font face at the specified index. + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index. + * + * Since: 10.1.0 + **/ +hb_face_t * +hb_face_create_or_fail (hb_blob_t *blob, + unsigned int index) +{ + unsigned num_faces = hb_face_count (blob); + if (index >= num_faces) + return nullptr; + + hb_face_t *face = hb_face_create (blob, index); + if (hb_object_is_immutable (face)) + return nullptr; + + return face; +} + +#ifndef HB_NO_OPEN +/** + * hb_face_create_from_file_or_fail: + * @file_name: A font filename + * @index: The index of the face within the file + * + * A thin wrapper around hb_blob_create_from_file_or_fail() + * followed by hb_face_create_or_fail(). + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index or the file cannot be read. + * + * Since: 10.1.0 + **/ +HB_EXTERN hb_face_t * +hb_face_create_from_file_or_fail (const char *file_name, + unsigned int index) +{ + hb_blob_t *blob = hb_blob_create_from_file_or_fail (file_name); + if (unlikely (!blob)) + return nullptr; + + hb_face_t *face = hb_face_create_or_fail (blob, index); + hb_blob_destroy (blob); + + return face; +} +#endif + /** * hb_face_get_empty: * @@ -306,6 +380,9 @@ hb_face_destroy (hb_face_t *face) face->data.fini (); face->table.fini (); + if (face->get_table_tags_destroy) + face->get_table_tags_destroy (face->get_table_tags_user_data); + if (face->destroy) face->destroy (face->user_data); @@ -395,7 +472,8 @@ hb_face_is_immutable (const hb_face_t *face) * @tag: The #hb_tag_t of the table to query * * Fetches a reference to the specified table within - * the specified face. + * the specified face. Returns an empty blob if referencing table data is not + * possible. * * Return value: (transfer full): A pointer to the @tag table within @face * @@ -415,9 +493,10 @@ hb_face_reference_table (const hb_face_t *face, * hb_face_reference_blob: * @face: A face object * - * Fetches a pointer to the binary blob that contains the - * specified face. Returns an empty blob if referencing face data is not - * possible. + * Fetches a pointer to the binary blob that contains the specified face. + * If referencing the face data is not possible, this function creates a blob + * out of individual table blobs if hb_face_get_table_tags() works with this + * face, otherwise it returns an empty blob. * * Return value: (transfer full): A pointer to the blob for @face * @@ -426,7 +505,41 @@ hb_face_reference_table (const hb_face_t *face, hb_blob_t * hb_face_reference_blob (hb_face_t *face) { - return face->reference_table (HB_TAG_NONE); + hb_blob_t *blob = face->reference_table (HB_TAG_NONE); + + if (blob == hb_blob_get_empty ()) + { + // If referencing the face blob is not possible (e.g. not implemented by the + // font functions), use face builder to create a blob out of individual + // table blobs. + unsigned total_count = hb_face_get_table_tags (face, 0, nullptr, nullptr); + if (total_count) + { + hb_tag_t tags[64]; + unsigned count = ARRAY_LENGTH (tags); + hb_face_t* builder = hb_face_builder_create (); + + for (unsigned offset = 0; offset < total_count; offset += count) + { + hb_face_get_table_tags (face, offset, &count, tags); + if (unlikely (!count)) + break; // Allocation error + for (unsigned i = 0; i < count; i++) + { + if (unlikely (!tags[i])) + continue; + hb_blob_t *table = hb_face_reference_table (face, tags[i]); + hb_face_builder_add_table (builder, tags[i], table); + hb_blob_destroy (table); + } + } + + blob = hb_face_reference_blob (builder); + hb_face_destroy (builder); + } + } + + return blob; } /** @@ -547,6 +660,38 @@ hb_face_get_glyph_count (const hb_face_t *face) return face->get_num_glyphs (); } +/** + * hb_face_set_get_table_tags_func: + * @face: A face object + * @func: (closure user_data) (destroy destroy) (scope notified): The table-tag-fetching function + * @user_data: A pointer to the user data, to be destroyed by @destroy when not needed anymore + * @destroy: (nullable): A callback to call when @func is not needed anymore + * + * Sets the table-tag-fetching function for the specified face object. + * + * Since: 10.0.0 + */ +HB_EXTERN void +hb_face_set_get_table_tags_func (hb_face_t *face, + hb_get_table_tags_func_t func, + void *user_data, + hb_destroy_func_t destroy) +{ + if (hb_object_is_immutable (face)) + { + if (destroy) + destroy (user_data); + return; + } + + if (face->get_table_tags_destroy) + face->get_table_tags_destroy (face->get_table_tags_user_data); + + face->get_table_tags_func = func; + face->get_table_tags_user_data = user_data; + face->get_table_tags_destroy = destroy; +} + /** * hb_face_get_table_tags: * @face: A face object @@ -568,19 +713,14 @@ hb_face_get_table_tags (const hb_face_t *face, unsigned int *table_count, /* IN/OUT */ hb_tag_t *table_tags /* OUT */) { - if (face->destroy != (hb_destroy_func_t) _hb_face_for_data_closure_destroy) + if (!face->get_table_tags_func) { if (table_count) *table_count = 0; return 0; } - hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) face->user_data; - - const OT::OpenTypeFontFile &ot_file = *data->blob->as (); - const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); - - return ot_face.get_table_tags (start_offset, table_count, table_tags); + return face->get_table_tags_func (face, start_offset, table_count, table_tags, face->get_table_tags_user_data); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face.h b/src/java.desktop/share/native/libharfbuzz/hb-face.h index 2e5fb1509272b..953298fa50b4f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-face.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-face.h @@ -59,15 +59,28 @@ HB_EXTERN hb_face_t * hb_face_create (hb_blob_t *blob, unsigned int index); +HB_EXTERN hb_face_t * +hb_face_create_or_fail (hb_blob_t *blob, + unsigned int index); + +HB_EXTERN hb_face_t * +hb_face_create_from_file_or_fail (const char *file_name, + unsigned int index); + /** * hb_reference_table_func_t: * @face: an #hb_face_t to reference table for * @tag: the tag of the table to reference * @user_data: User data pointer passed by the caller * - * Callback function for hb_face_create_for_tables(). + * Callback function for hb_face_create_for_tables(). The @tag is the tag of the + * table to reference, and the special tag #HB_TAG_NONE is used to reference the + * blob of the face itself. If referencing the face blob is not possible, it is + * recommended to set hb_get_table_tags_func_t on the @face to allow + * hb_face_reference_blob() to create a face blob out of individual table blobs. * - * Return value: (transfer full): A pointer to the @tag table within @face + * Return value: (transfer full): A pointer to the @tag table within @face or + * `NULL` if the table is not found or cannot be referenced. * * Since: 0.9.2 */ @@ -135,6 +148,34 @@ hb_face_set_glyph_count (hb_face_t *face, HB_EXTERN unsigned int hb_face_get_glyph_count (const hb_face_t *face); + +/** + * hb_get_table_tags_func_t: + * @face: A face object + * @start_offset: The index of first table tag to retrieve + * @table_count: (inout): Input = the maximum number of table tags to return; + * Output = the actual number of table tags returned (may be zero) + * @table_tags: (out) (array length=table_count): The array of table tags found + * @user_data: User data pointer passed by the caller + * + * Callback function for hb_face_get_table_tags(). + * + * Return value: Total number of tables, or zero if it is not possible to list + * + * Since: 10.0.0 + */ +typedef unsigned int (*hb_get_table_tags_func_t) (const hb_face_t *face, + unsigned int start_offset, + unsigned int *table_count, /* IN/OUT */ + hb_tag_t *table_tags /* OUT */, + void *user_data); + +HB_EXTERN void +hb_face_set_get_table_tags_func (hb_face_t *face, + hb_get_table_tags_func_t func, + void *user_data, + hb_destroy_func_t destroy); + HB_EXTERN unsigned int hb_face_get_table_tags (const hb_face_t *face, unsigned int start_offset, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face.hh b/src/java.desktop/share/native/libharfbuzz/hb-face.hh index 4c6b252e88eaf..4d12030f18732 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-face.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-face.hh @@ -48,13 +48,17 @@ struct hb_face_t { hb_object_header_t header; + unsigned int index; /* Face index in a collection, zero-based. */ + mutable hb_atomic_int_t upem; /* Units-per-EM. */ + mutable hb_atomic_int_t num_glyphs; /* Number of glyphs. */ + hb_reference_table_func_t reference_table_func; void *user_data; hb_destroy_func_t destroy; - unsigned int index; /* Face index in a collection, zero-based. */ - mutable hb_atomic_int_t upem; /* Units-per-EM. */ - mutable hb_atomic_int_t num_glyphs; /* Number of glyphs. */ + hb_get_table_tags_func_t get_table_tags_func; + void *get_table_tags_user_data; + hb_destroy_func_t get_table_tags_destroy; hb_shaper_object_dataset_t data;/* Various shaper data. */ hb_ot_face_t table; /* All the face's tables. */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-font.cc b/src/java.desktop/share/native/libharfbuzz/hb-font.cc index 9ce55bbeb89f3..0c9084c574fef 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-font.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-font.cc @@ -231,7 +231,7 @@ hb_font_get_glyph_v_advance_nil (hb_font_t *font, void *user_data HB_UNUSED) { /* TODO use font_extents.ascender+descender */ - return font->y_scale; + return -font->y_scale; } static hb_position_t diff --git a/src/java.desktop/share/native/libharfbuzz/hb-font.hh b/src/java.desktop/share/native/libharfbuzz/hb-font.hh index c3198830cd33b..8273f34756206 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-font.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-font.hh @@ -651,7 +651,7 @@ struct hb_font_t { if (get_glyph_name (glyph, s, size)) return; - if (size && snprintf (s, size, "gid%u", glyph) < 0) + if (size && snprintf (s, size, "gid%" PRIu32, glyph) < 0) *s = '\0'; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ft.cc b/src/java.desktop/share/native/libharfbuzz/hb-ft.cc index 32f5d3012da80..b126d2022d1e3 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ft.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ft.cc @@ -37,10 +37,15 @@ #include "hb-draw.hh" #include "hb-font.hh" #include "hb-machinery.hh" +#ifndef HB_NO_AAT +#include "hb-aat-layout-trak-table.hh" +#endif #include "hb-ot-os2-table.hh" +#include "hb-ot-stat-table.hh" #include "hb-ot-shaper-arabic-pua.hh" #include "hb-paint.hh" +#include FT_MODULE_H #include FT_ADVANCES_H #include FT_MULTIPLE_MASTERS_H #include FT_OUTLINE_H @@ -225,7 +230,7 @@ _hb_ft_hb_font_check_changed (hb_font_t *font, * Sets the FT_Load_Glyph load flags for the specified #hb_font_t. * * For more information, see - * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx + * * * This function works with #hb_font_t objects created by * hb_ft_font_create() or hb_ft_font_create_referenced(). @@ -253,7 +258,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags) * Fetches the FT_Load_Glyph load flags of the specified #hb_font_t. * * For more information, see - * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx + * * * This function works with #hb_font_t objects created by * hb_ft_font_create() or hb_ft_font_create_referenced(). @@ -274,7 +279,7 @@ hb_ft_font_get_load_flags (hb_font_t *font) } /** - * hb_ft_font_get_face: (skip) + * hb_ft_font_get_ft_face: (skip) * @font: #hb_font_t to work upon * * Fetches the FT_Face associated with the specified #hb_font_t @@ -285,10 +290,10 @@ hb_ft_font_get_load_flags (hb_font_t *font) * * Return value: (nullable): the FT_Face found or `NULL` * - * Since: 0.9.2 + * Since: 10.4.0 **/ FT_Face -hb_ft_font_get_face (hb_font_t *font) +hb_ft_font_get_ft_face (hb_font_t *font) { if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) return nullptr; @@ -298,6 +303,31 @@ hb_ft_font_get_face (hb_font_t *font) return ft_font->ft_face; } +#ifndef HB_DISABLE_DEPRECATED + +/** + * hb_ft_font_get_face: (skip) + * @font: #hb_font_t to work upon + * + * Fetches the FT_Face associated with the specified #hb_font_t + * font object. + * + * This function works with #hb_font_t objects created by + * hb_ft_font_create() or hb_ft_font_create_referenced(). + * + * Return value: (nullable): the FT_Face found or `NULL` + * + * Since: 0.9.2 + * Deprecated: 10.4.0: Use hb_ft_font_get_ft_face() instead. + **/ +FT_Face +hb_ft_font_get_face (hb_font_t *font) +{ + return hb_ft_font_get_ft_face (font); +} + +#endif + /** * hb_ft_font_lock_face: (skip) * @font: #hb_font_t to work upon @@ -501,6 +531,26 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } } + +#ifndef HB_NO_AAT + /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ +#ifndef HB_NO_STYLE + bool apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); +#else + bool apply_trak = false; +#endif + if (apply_trak) + { + hb_position_t tracking = font->face->table.trak->get_h_tracking (font); + first_advance = orig_first_advance; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += tracking; + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } +#endif } #ifndef HB_NO_VERTICAL @@ -537,7 +587,20 @@ hb_ft_get_glyph_v_advance (hb_font_t *font, * have a Y growing upward. Hence the extra negation. */ hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength; - return ((-v + (1<<9)) >> 10) + (font->embolden_in_place ? 0 : y_strength); + v = ((-v + (1<<9)) >> 10) + (font->embolden_in_place ? 0 : y_strength); + +#ifndef HB_NO_AAT + /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ +#ifndef HB_NO_STYLE + bool apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); +#else + bool apply_trak = false; +#endif + if (apply_trak) + v += font->face->table.trak->get_v_tracking (font); +#endif + + return v; } #endif @@ -930,11 +993,15 @@ hb_ft_paint_glyph (hb_font_t *font, hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; + FT_Long load_flags = ft_font->load_flags | FT_LOAD_NO_BITMAP | FT_LOAD_COLOR; +#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21301 + load_flags |= FT_LOAD_NO_SVG; +#endif + /* We release the lock before calling into glyph callbacks, such that * eg. draw API can call back into the face.*/ - if (unlikely (FT_Load_Glyph (ft_face, gid, - ft_font->load_flags | FT_LOAD_COLOR))) + if (unlikely (FT_Load_Glyph (ft_face, gid, load_flags))) return; if (ft_face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) @@ -1104,6 +1171,45 @@ _hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data buffer, hb_free); } +static unsigned +_hb_ft_get_table_tags (const hb_face_t *face HB_UNUSED, + unsigned int start_offset, + unsigned int *table_count, + hb_tag_t *table_tags, + void *user_data) +{ + FT_Face ft_face = (FT_Face) user_data; + + FT_ULong population = 0; + FT_Sfnt_Table_Info (ft_face, + 0, // table_index; ignored + nullptr, + &population); + + if (!table_count) + return population; + else + *table_count = 0; + + if (unlikely (start_offset >= population)) + return population; + + unsigned end_offset = hb_min (start_offset + *table_count, (unsigned) population); + if (unlikely (end_offset < start_offset)) + return population; + + *table_count = end_offset - start_offset; + for (unsigned i = start_offset; i < end_offset; i++) + { + FT_ULong tag = 0, length; + FT_Sfnt_Table_Info (ft_face, i, &tag, &length); + table_tags[i - start_offset] = tag; + } + + return population; +} + + /** * hb_ft_face_create: * @ft_face: (destroy destroy) (scope notified): FT_Face to work upon @@ -1145,6 +1251,7 @@ hb_ft_face_create (FT_Face ft_face, hb_blob_destroy (blob); } else { face = hb_face_create_for_tables (_hb_ft_reference_table, ft_face, destroy); + hb_face_set_get_table_tags_func (face, _hb_ft_get_table_tags, ft_face, nullptr); } hb_face_set_index (face, ft_face->face_index); @@ -1215,7 +1322,7 @@ hb_ft_face_finalize (void *arg) hb_face_t * hb_ft_face_create_cached (FT_Face ft_face) { - if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer) hb_ft_face_finalize)) + if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != hb_ft_face_finalize)) { if (ft_face->generic.finalizer) ft_face->generic.finalizer (ft_face); @@ -1245,7 +1352,7 @@ hb_ft_face_create_cached (FT_Face ft_face) * * If you know you have valid reasons not to use hb_ft_font_create_referenced(), * then it is the client program's responsibility to destroy @ft_face - * after the #hb_font_t font object has been destroyed. + * only after the #hb_font_t font object has been destroyed. * * HarfBuzz will use the @destroy callback on the #hb_font_t font object * if it is supplied when you use this function. However, even if @destroy @@ -1392,6 +1499,24 @@ hb_ft_font_create_referenced (FT_Face ft_face) return hb_ft_font_create (ft_face, _hb_ft_face_destroy); } + +static void * _hb_ft_alloc (FT_Memory memory, long size) +{ return hb_malloc (size); } + +static void _hb_ft_free (FT_Memory memory, void *block) +{ hb_free (block); } + +static void * _hb_ft_realloc (FT_Memory memory, long cur_size, long new_size, void *block) +{ return hb_realloc (block, new_size); } + +static FT_MemoryRec_ m = +{ + nullptr, + _hb_ft_alloc, + _hb_ft_free, + _hb_ft_realloc +}; + static inline void free_static_ft_library (); static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t, @@ -1400,16 +1525,19 @@ static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_tgeneric.data); +} + +static void +destroy_ft_library (void *arg) +{ + FT_Done_Library ((FT_Library) arg); +} + +/** + * hb_ft_face_create_from_file_or_fail: + * @file_name: A font filename + * @index: The index of the face within the file + * + * Creates an #hb_face_t face object from the specified + * font file and face index. + * + * This is similar in functionality to hb_face_create_from_file_or_fail(), + * but uses the FreeType library for loading the font file. + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index or the file cannot be read. + * + * Since: 10.1.0 + */ +hb_face_t * +hb_ft_face_create_from_file_or_fail (const char *file_name, + unsigned int index) { - return static_ft_library.get_unconst (); + FT_Library ft_library = reference_ft_library (); + if (unlikely (!ft_library)) + { + DEBUG_MSG (FT, ft_library, "reference_ft_library failed"); + return nullptr; + } + + FT_Face ft_face; + if (unlikely (FT_New_Face (ft_library, + file_name, + index, + &ft_face))) + return nullptr; + + hb_face_t *face = hb_ft_face_create_referenced (ft_face); + FT_Done_Face (ft_face); + + ft_face->generic.data = ft_library; + ft_face->generic.finalizer = finalize_ft_library; + + if (hb_face_is_immutable (face)) + return nullptr; + + return face; } static void @@ -1465,32 +1660,47 @@ _release_blob (void *arg) void hb_ft_font_set_funcs (hb_font_t *font) { + // In case of failure... + hb_font_set_funcs (font, + hb_font_funcs_get_empty (), + nullptr, nullptr); + hb_blob_t *blob = hb_face_reference_blob (font->face); unsigned int blob_length; const char *blob_data = hb_blob_get_data (blob, &blob_length); if (unlikely (!blob_length)) DEBUG_MSG (FT, font, "Font face has empty blob"); - FT_Face ft_face = nullptr; - FT_Error err = FT_New_Memory_Face (get_ft_library (), - (const FT_Byte *) blob_data, - blob_length, - hb_face_get_index (font->face), - &ft_face); + FT_Library ft_library = reference_ft_library (); + if (unlikely (!ft_library)) + { + hb_blob_destroy (blob); + DEBUG_MSG (FT, font, "reference_ft_library failed"); + return; + } - if (unlikely (err)) { + FT_Face ft_face = nullptr; + if (unlikely (FT_New_Memory_Face (ft_library, + (const FT_Byte *) blob_data, + blob_length, + hb_face_get_index (font->face), + &ft_face))) + { hb_blob_destroy (blob); - DEBUG_MSG (FT, font, "Font face FT_New_Memory_Face() failed"); + DEBUG_MSG (FT, font, "FT_New_Memory_Face() failed"); return; } if (FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL)) FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE); - + // Hook the blob to the FT_Face ft_face->generic.data = blob; ft_face->generic.finalizer = _release_blob; + // And the FT_Library to the blob + hb_blob_set_user_data (blob, &ft_library_key, ft_library, destroy_ft_library, true); + _hb_ft_font_set_funcs (font, ft_face, true); hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ft.h b/src/java.desktop/share/native/libharfbuzz/hb-ft.h index b2d148014c06a..94952f48a0533 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ft.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-ft.h @@ -84,6 +84,9 @@ hb_ft_face_create_cached (FT_Face ft_face); HB_EXTERN hb_face_t * hb_ft_face_create_referenced (FT_Face ft_face); +HB_EXTERN hb_face_t * +hb_ft_face_create_from_file_or_fail (const char *file_name, + unsigned int index); /* * hb-font from ft-face. @@ -108,7 +111,7 @@ HB_EXTERN hb_font_t * hb_ft_font_create_referenced (FT_Face ft_face); HB_EXTERN FT_Face -hb_ft_font_get_face (hb_font_t *font); +hb_ft_font_get_ft_face (hb_font_t *font); HB_EXTERN FT_Face hb_ft_font_lock_face (hb_font_t *font); @@ -139,6 +142,13 @@ hb_ft_hb_font_changed (hb_font_t *font); HB_EXTERN void hb_ft_font_set_funcs (hb_font_t *font); +#ifndef HB_DISABLE_DEPRECATED + +HB_DEPRECATED_FOR (hb_ft_font_get_ft_face) +HB_EXTERN FT_Face +hb_ft_font_get_face (hb_font_t *font); + +#endif HB_END_DECLS diff --git a/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh b/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh new file mode 100644 index 0000000000000..e91e371dc0c20 --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh @@ -0,0 +1,293 @@ +/* + * Copyright © 2022 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ +#ifndef HB_GEOMETRY_HH +#define HB_GEOMETRY_HH + +#include "hb.hh" + + +struct hb_extents_t +{ + hb_extents_t () {} + hb_extents_t (float xmin, float ymin, float xmax, float ymax) : + xmin (xmin), ymin (ymin), xmax (xmax), ymax (ymax) {} + + bool is_empty () const { return xmin >= xmax || ymin >= ymax; } + bool is_void () const { return xmin > xmax; } + + void union_ (const hb_extents_t &o) + { + xmin = hb_min (xmin, o.xmin); + ymin = hb_min (ymin, o.ymin); + xmax = hb_max (xmax, o.xmax); + ymax = hb_max (ymax, o.ymax); + } + + void intersect (const hb_extents_t &o) + { + xmin = hb_max (xmin, o.xmin); + ymin = hb_max (ymin, o.ymin); + xmax = hb_min (xmax, o.xmax); + ymax = hb_min (ymax, o.ymax); + } + + void + add_point (float x, float y) + { + if (unlikely (is_void ())) + { + xmin = xmax = x; + ymin = ymax = y; + } + else + { + xmin = hb_min (xmin, x); + ymin = hb_min (ymin, y); + xmax = hb_max (xmax, x); + ymax = hb_max (ymax, y); + } + } + + float xmin = 0.f; + float ymin = 0.f; + float xmax = -1.f; + float ymax = -1.f; +}; + +struct hb_transform_t +{ + hb_transform_t () {} + hb_transform_t (float xx, float yx, + float xy, float yy, + float x0, float y0) : + xx (xx), yx (yx), xy (xy), yy (yy), x0 (x0), y0 (y0) {} + + bool is_identity () const + { + return xx == 1.f && yx == 0.f && + xy == 0.f && yy == 1.f && + x0 == 0.f && y0 == 0.f; + } + + void multiply (const hb_transform_t &o) + { + /* Copied from cairo, with "o" being "a" there and "this" being "b" there. */ + hb_transform_t r; + + r.xx = o.xx * xx + o.yx * xy; + r.yx = o.xx * yx + o.yx * yy; + + r.xy = o.xy * xx + o.yy * xy; + r.yy = o.xy * yx + o.yy * yy; + + r.x0 = o.x0 * xx + o.y0 * xy + x0; + r.y0 = o.x0 * yx + o.y0 * yy + y0; + + *this = r; + } + + void transform_distance (float &dx, float &dy) const + { + float new_x = xx * dx + xy * dy; + float new_y = yx * dx + yy * dy; + dx = new_x; + dy = new_y; + } + + void transform_point (float &x, float &y) const + { + transform_distance (x, y); + x += x0; + y += y0; + } + + void transform_extents (hb_extents_t &extents) const + { + float quad_x[4], quad_y[4]; + + quad_x[0] = extents.xmin; + quad_y[0] = extents.ymin; + quad_x[1] = extents.xmin; + quad_y[1] = extents.ymax; + quad_x[2] = extents.xmax; + quad_y[2] = extents.ymin; + quad_x[3] = extents.xmax; + quad_y[3] = extents.ymax; + + extents = hb_extents_t {}; + for (unsigned i = 0; i < 4; i++) + { + transform_point (quad_x[i], quad_y[i]); + extents.add_point (quad_x[i], quad_y[i]); + } + } + + void transform (const hb_transform_t &o) { multiply (o); } + + void translate (float x, float y) + { + if (x == 0.f && y == 0.f) + return; + + x0 += xx * x + xy * y; + y0 += yx * x + yy * y; + } + + void scale (float scaleX, float scaleY) + { + if (scaleX == 1.f && scaleY == 1.f) + return; + + xx *= scaleX; + yx *= scaleX; + xy *= scaleY; + yy *= scaleY; + } + + void rotate (float rotation) + { + if (rotation == 0.f) + return; + + // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240 + rotation = rotation * HB_PI; + float c; + float s; +#ifdef HAVE_SINCOSF + sincosf (rotation, &s, &c); +#else + c = cosf (rotation); + s = sinf (rotation); +#endif + auto other = hb_transform_t{c, s, -s, c, 0.f, 0.f}; + transform (other); + } + + void skew (float skewX, float skewY) + { + if (skewX == 0.f && skewY == 0.f) + return; + + // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255 + skewX = skewX * HB_PI; + skewY = skewY * HB_PI; + auto other = hb_transform_t{1.f, + skewY ? tanf (skewY) : 0.f, + skewX ? tanf (skewX) : 0.f, + 1.f, + 0.f, 0.f}; + transform (other); + } + + float xx = 1.f; + float yx = 0.f; + float xy = 0.f; + float yy = 1.f; + float x0 = 0.f; + float y0 = 0.f; +}; + +#define HB_TRANSFORM_IDENTITY hb_transform_t{1.f, 0.f, 0.f, 1.f, 0.f, 0.f} + +struct hb_bounds_t +{ + enum status_t { + UNBOUNDED, + BOUNDED, + EMPTY, + }; + + hb_bounds_t (status_t status) : status (status) {} + hb_bounds_t (const hb_extents_t &extents) : + status (extents.is_empty () ? EMPTY : BOUNDED), extents (extents) {} + + void union_ (const hb_bounds_t &o) + { + if (o.status == UNBOUNDED) + status = UNBOUNDED; + else if (o.status == BOUNDED) + { + if (status == EMPTY) + *this = o; + else if (status == BOUNDED) + extents.union_ (o.extents); + } + } + + void intersect (const hb_bounds_t &o) + { + if (o.status == EMPTY) + status = EMPTY; + else if (o.status == BOUNDED) + { + if (status == UNBOUNDED) + *this = o; + else if (status == BOUNDED) + { + extents.intersect (o.extents); + if (extents.is_empty ()) + status = EMPTY; + } + } + } + + status_t status; + hb_extents_t extents; +}; + +struct hb_transform_decomposed_t +{ + float translateX = 0; + float translateY = 0; + float rotation = 0; // in degrees, counter-clockwise + float scaleX = 1; + float scaleY = 1; + float skewX = 0; // in degrees, counter-clockwise + float skewY = 0; // in degrees, counter-clockwise + float tCenterX = 0; + float tCenterY = 0; + + operator bool () const + { + return translateX || translateY || + rotation || + scaleX != 1 || scaleY != 1 || + skewX || skewY || + tCenterX || tCenterY; + } + + hb_transform_t to_transform () const + { + hb_transform_t t; + t.translate (translateX + tCenterX, translateY + tCenterY); + t.rotate (rotation); + t.scale (scaleX, scaleY); + t.skew (-skewX, skewY); + t.translate (-tCenterX, -tCenterY); + return t; + } +}; + + +#endif /* HB_GEOMETRY_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-iter.hh b/src/java.desktop/share/native/libharfbuzz/hb-iter.hh index ad45dcf2c1d4b..21d9544a74b0e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-iter.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-iter.hh @@ -324,6 +324,16 @@ struct hb_is_sink_of (hb_is_source_of(Iter, Item) && Iter::is_sorted_iterator) +struct +{ + template + unsigned operator () (const Iterable &_) const { return hb_len (hb_iter (_)); } + + unsigned operator () (unsigned _) const { return _; } +} +HB_FUNCOBJ (hb_len_of); + /* Range-based 'for' for iterables. */ template struct hb_hashmap_t { + static constexpr bool realloc_move = true; + hb_hashmap_t () { init (); } ~hb_hashmap_t () { fini (); } - hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { alloc (o.population); hb_copy (o, *this); } - hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); } + hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () + { + if (unlikely (!o.mask)) return; + + if (item_t::is_trivial) + { + items = (item_t *) hb_malloc (sizeof (item_t) * (o.mask + 1)); + if (unlikely (!items)) + { + successful = false; + return; + } + population = o.population; + occupancy = o.occupancy; + mask = o.mask; + prime = o.prime; + max_chain_length = o.max_chain_length; + memcpy (items, o.items, sizeof (item_t) * (mask + 1)); + return; + } + + alloc (o.population); hb_copy (o, *this); + } + hb_hashmap_t (hb_hashmap_t&& o) noexcept : hb_hashmap_t () { hb_swap (*this, o); } hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); alloc (o.population); hb_copy (o, *this); return *this; } - hb_hashmap_t& operator= (hb_hashmap_t&& o) { hb_swap (*this, o); return *this; } + hb_hashmap_t& operator= (hb_hashmap_t&& o) noexcept { hb_swap (*this, o); return *this; } hb_hashmap_t (std::initializer_list> lst) : hb_hashmap_t () { @@ -113,26 +137,23 @@ struct hb_hashmap_t }; hb_object_header_t header; - unsigned int successful : 1; /* Allocations successful */ - unsigned int population : 31; /* Not including tombstones. */ + bool successful; /* Allocations successful */ + unsigned short max_chain_length; + unsigned int population; /* Not including tombstones. */ unsigned int occupancy; /* Including tombstones. */ unsigned int mask; unsigned int prime; - unsigned int max_chain_length; item_t *items; - friend void swap (hb_hashmap_t& a, hb_hashmap_t& b) + friend void swap (hb_hashmap_t& a, hb_hashmap_t& b) noexcept { if (unlikely (!a.successful || !b.successful)) return; - unsigned tmp = a.population; - a.population = b.population; - b.population = tmp; - //hb_swap (a.population, b.population); + hb_swap (a.max_chain_length, b.max_chain_length); + hb_swap (a.population, b.population); hb_swap (a.occupancy, b.occupancy); hb_swap (a.mask, b.mask); hb_swap (a.prime, b.prime); - hb_swap (a.max_chain_length, b.max_chain_length); hb_swap (a.items, b.items); } void init () @@ -140,10 +161,10 @@ struct hb_hashmap_t hb_object_init (this); successful = true; + max_chain_length = 0; population = occupancy = 0; mask = 0; prime = 0; - max_chain_length = 0; items = nullptr; } void fini () @@ -209,9 +230,10 @@ struct hb_hashmap_t old_items[i].hash, std::move (old_items[i].value)); } - if (!item_t::is_trivial) - old_items[i].~item_t (); } + if (!item_t::is_trivial) + for (unsigned int i = 0; i < old_size; i++) + old_items[i].~item_t (); hb_free (old_items); @@ -285,7 +307,7 @@ struct hb_hashmap_t const V& get_with_hash (const K &key, uint32_t hash) const { if (!items) return item_t::default_value (); - auto *item = fetch_item (key, hb_hash (key)); + auto *item = fetch_item (key, hash); if (item) return item->value; return item_t::default_value (); @@ -533,7 +555,7 @@ struct hb_map_t : hb_hashmap_t lst) : hashmap (lst) {} diff --git a/src/java.desktop/share/native/libharfbuzz/hb-null.hh b/src/java.desktop/share/native/libharfbuzz/hb-null.hh index 4a5270e340025..63ec9a7c64d07 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-null.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-null.hh @@ -176,7 +176,7 @@ template static inline Type& Crap () { static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); Type *obj = reinterpret_cast (_hb_CrapPool); - memcpy (obj, std::addressof (Null (Type)), sizeof (*obj)); + memcpy (reinterpret_cast(obj), std::addressof (Null (Type)), sizeof (*obj)); return *obj; } template diff --git a/src/java.desktop/share/native/libharfbuzz/hb-object.hh b/src/java.desktop/share/native/libharfbuzz/hb-object.hh index ef675f835f119..c02ec8bfacf21 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-object.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-object.hh @@ -325,7 +325,7 @@ retry: hb_user_data_array_t *user_data = obj->header.user_data.get_acquire (); if (unlikely (!user_data)) { - user_data = (hb_user_data_array_t *) hb_calloc (sizeof (hb_user_data_array_t), 1); + user_data = (hb_user_data_array_t *) hb_calloc (1, sizeof (hb_user_data_array_t)); if (unlikely (!user_data)) return false; user_data->init (); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh b/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh index 387b1430ac1ec..382ee2ddaf24c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh @@ -250,7 +250,7 @@ struct TTCHeader { switch (u.header.version.major) { case 2: /* version 2 is compatible with version 1 */ - case 1: return u.version1.get_face_count (); + case 1: hb_barrier (); return u.version1.get_face_count (); default:return 0; } } @@ -258,7 +258,7 @@ struct TTCHeader { switch (u.header.version.major) { case 2: /* version 2 is compatible with version 1 */ - case 1: return u.version1.get_face (i); + case 1: hb_barrier (); return u.version1.get_face (i); default:return Null (OpenTypeFontFace); } } @@ -267,9 +267,10 @@ struct TTCHeader { TRACE_SANITIZE (this); if (unlikely (!u.header.version.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.header.version.major) { case 2: /* version 2 is compatible with version 1 */ - case 1: return_trace (u.version1.sanitize (c)); + case 1: hb_barrier (); return_trace (u.version1.sanitize (c)); default:return_trace (true); } } @@ -302,6 +303,7 @@ struct ResourceRecord TRACE_SANITIZE (this); return_trace (c->check_struct (this) && offset.sanitize (c, data_base) && + hb_barrier () && get_face (data_base).sanitize (c)); } @@ -337,6 +339,7 @@ struct ResourceTypeRecord { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && resourcesZ.sanitize (c, type_base, get_resource_count (), data_base)); @@ -385,6 +388,7 @@ struct ResourceMap { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && typeList.sanitize (c, this, &(this+typeList), data_base)); @@ -428,6 +432,7 @@ struct ResourceForkHeader { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && data.sanitize (c, this, dataLen) && map.sanitize (c, this, &(this+data))); } @@ -508,6 +513,7 @@ struct OpenTypeFontFile { TRACE_SANITIZE (this); if (unlikely (!u.tag.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.tag) { case CFFTag: /* All the non-collection tags */ case TrueTag: diff --git a/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh b/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh index 25142da44a6cb..89da9c7bc95ce 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh @@ -86,21 +86,12 @@ struct IntType return pb->cmp (*pa); } - template ::value && - sizeof (Type2) < sizeof (int) && - sizeof (Type) < sizeof (int))> - int cmp (Type2 a) const - { - Type b = v; - return (int) a - (int) b; - } template int cmp (Type2 a) const { Type b = v; - return a < b ? -1 : a == b ? 0 : +1; + return (a > b) - (a < b); } bool sanitize (hb_sanitize_context_t *c) const { @@ -132,6 +123,89 @@ struct HBUINT15 : HBUINT16 DEFINE_SIZE_STATIC (2); }; +/* 32-bit unsigned integer with variable encoding. */ +struct HBUINT32VAR +{ + unsigned get_size () const + { + unsigned b0 = v[0]; + if (b0 < 0x80) + return 1; + else if (b0 < 0xC0) + return 2; + else if (b0 < 0xE0) + return 3; + else if (b0 < 0xF0) + return 4; + else + return 5; + } + + static unsigned get_size (uint32_t v) + { + if (v < 0x80) + return 1; + else if (v < 0x4000) + return 2; + else if (v < 0x200000) + return 3; + else if (v < 0x10000000) + return 4; + else + return 5; + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_range (v, 1) && + hb_barrier () && + c->check_range (v, get_size ())); + } + + operator uint32_t () const + { + unsigned b0 = v[0]; + if (b0 < 0x80) + return b0; + else if (b0 < 0xC0) + return ((b0 & 0x3F) << 8) | v[1]; + else if (b0 < 0xE0) + return ((b0 & 0x1F) << 16) | (v[1] << 8) | v[2]; + else if (b0 < 0xF0) + return ((b0 & 0x0F) << 24) | (v[1] << 16) | (v[2] << 8) | v[3]; + else + return (v[1] << 24) | (v[2] << 16) | (v[3] << 8) | v[4]; + } + + static bool serialize (hb_serialize_context_t *c, uint32_t v) + { + unsigned len = get_size (v); + + unsigned char *buf = c->allocate_size (len, false); + if (unlikely (!buf)) + return false; + + unsigned char *p = buf + len; + for (unsigned i = 0; i < len; i++) + { + *--p = v & 0xFF; + v >>= 8; + } + + if (len > 1) + buf[0] |= ((1 << (len - 1)) - 1) << (9 - len); + + return true; + } + + protected: + unsigned char v[5]; + + public: + DEFINE_SIZE_MIN (1); +}; + /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */ typedef HBINT16 FWORD; @@ -149,6 +223,7 @@ struct HBFixed : Type operator signed () const = delete; operator unsigned () const = delete; + explicit operator float () const { return to_float (); } typename Type::type to_int () const { return Type::v; } void set_int (typename Type::type i ) { Type::v = i; } float to_float (float offset = 0) const { return ((int32_t) Type::v + offset) / shift; } @@ -215,11 +290,6 @@ typedef Index NameID; struct VarIdx : HBUINT32 { static constexpr unsigned NO_VARIATION = 0xFFFFFFFFu; static_assert (NO_VARIATION == HB_OT_LAYOUT_NO_VARIATIONS_INDEX, ""); - static uint32_t add (uint32_t i, unsigned short v) - { - if (i == NO_VARIATION) return i; - return i + v; - } VarIdx& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; } }; DECLARE_NULL_NAMESPACE_BYTES (OT, VarIdx); @@ -309,7 +379,7 @@ struct _hb_has_null static Type *get_crap () { return &Crap (Type); } }; -template +template struct OffsetTo : Offset { using target_t = Type; @@ -335,22 +405,22 @@ struct OffsetTo : Offset } template + hb_enable_if (hb_is_convertible (const Base, const BaseType *))> friend const Type& operator + (const Base &base, const OffsetTo &offset) { return offset ((const void *) base); } template + hb_enable_if (hb_is_convertible (const Base, const BaseType *))> friend const Type& operator + (const OffsetTo &offset, const Base &base) { return offset ((const void *) base); } template + hb_enable_if (hb_is_convertible (Base, BaseType *))> friend Type& operator + (Base &&base, OffsetTo &offset) { return offset ((void *) base); } template + hb_enable_if (hb_is_convertible (Base, BaseType *))> friend Type& operator + (OffsetTo &offset, Base &&base) { return offset ((void *) base); } - template + template bool serialize_subset (hb_subset_context_t *c, const OffsetTo& src, - const void *src_base, Ts&&... ds) + const Base *src_base, Ts&&... ds) { *this = 0; if (src.is_null ()) @@ -414,10 +484,11 @@ struct OffsetTo : Offset const void *src_base, unsigned dst_bias = 0) { return serialize_copy (c, src, src_base, dst_bias, hb_serialize_context_t::Head); } - bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const + bool sanitize_shallow (hb_sanitize_context_t *c, const BaseType *base) const { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); //if (unlikely (this->is_null ())) return_trace (true); if (unlikely ((const char *) base + (unsigned) *this < (const char *) base)) return_trace (false); return_trace (true); @@ -427,10 +498,11 @@ struct OffsetTo : Offset #ifndef HB_OPTIMIZE_SIZE HB_ALWAYS_INLINE #endif - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const + bool sanitize (hb_sanitize_context_t *c, const BaseType *base, Ts&&... ds) const { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && + hb_barrier () && (this->is_null () || c->dispatch (StructAtOffset (base, *this), std::forward (ds)...) || neuter (c))); @@ -445,14 +517,14 @@ struct OffsetTo : Offset DEFINE_SIZE_STATIC (sizeof (OffsetType)); }; /* Partial specializations. */ -template using Offset16To = OffsetTo; -template using Offset24To = OffsetTo; -template using Offset32To = OffsetTo; +template using Offset16To = OffsetTo; +template using Offset24To = OffsetTo; +template using Offset32To = OffsetTo; -template using NNOffsetTo = OffsetTo; -template using NNOffset16To = Offset16To; -template using NNOffset24To = Offset24To; -template using NNOffset32To = Offset32To; +template using NNOffsetTo = OffsetTo; +template using NNOffset16To = Offset16To; +template using NNOffset24To = Offset24To; +template using NNOffset32To = Offset32To; /* @@ -536,6 +608,7 @@ struct UnsizedArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) return_trace (false); @@ -555,27 +628,27 @@ struct UnsizedArrayOf }; /* Unsized array of offset's */ -template -using UnsizedArray16OfOffsetTo = UnsizedArrayOf>; +template +using UnsizedArray16OfOffsetTo = UnsizedArrayOf>; /* Unsized array of offsets relative to the beginning of the array itself. */ -template -struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo +template +struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo { const Type& operator [] (int i_) const { unsigned int i = (unsigned int) i_; - const OffsetTo *p = &this->arrayZ[i]; + const OffsetTo *p = &this->arrayZ[i]; if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Null (Type); /* Overflowed. */ - _hb_compiler_memory_r_barrier (); + hb_barrier (); return this+*p; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; - const OffsetTo *p = &this->arrayZ[i]; + const OffsetTo *p = &this->arrayZ[i]; if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Crap (Type); /* Overflowed. */ - _hb_compiler_memory_r_barrier (); + hb_barrier (); return this+*p; } @@ -583,7 +656,7 @@ struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo + return_trace ((UnsizedArray16OfOffsetTo ::sanitize (c, count, this, std::forward (ds)...))); } }; @@ -626,14 +699,14 @@ struct ArrayOf { unsigned int i = (unsigned int) i_; if (unlikely (i >= len)) return Null (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return arrayZ[i]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= len)) return Crap (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return arrayZ[i]; } @@ -725,6 +798,7 @@ struct ArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) @@ -735,7 +809,9 @@ struct ArrayOf bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (len.sanitize (c) && c->check_array_sized (arrayZ, len, sizeof (LenType))); + return_trace (len.sanitize (c) && + hb_barrier () && + c->check_array_sized (arrayZ, len, sizeof (LenType))); } public: @@ -750,6 +826,7 @@ template using Array32Of = ArrayOf; using PString = ArrayOf; /* Array of Offset's */ +template using Array8OfOffset24To = ArrayOf, HBUINT8>; template using Array16OfOffset16To = ArrayOf, HBUINT16>; template using Array16OfOffset32To = ArrayOf, HBUINT16>; template using Array32OfOffset32To = ArrayOf, HBUINT32>; @@ -762,14 +839,14 @@ struct List16OfOffsetTo : ArrayOf, HBUINT16> { unsigned int i = (unsigned int) i_; if (unlikely (i >= this->len)) return Null (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return this+this->arrayZ[i]; } const Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= this->len)) return Crap (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return this+this->arrayZ[i]; } @@ -807,14 +884,14 @@ struct HeadlessArrayOf { unsigned int i = (unsigned int) i_; if (unlikely (i >= lenP1 || !i)) return Null (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return arrayZ[i-1]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= lenP1 || !i)) return Crap (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return arrayZ[i-1]; } unsigned int get_size () const @@ -866,6 +943,7 @@ struct HeadlessArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) @@ -878,6 +956,7 @@ struct HeadlessArrayOf { TRACE_SANITIZE (this); return_trace (lenP1.sanitize (c) && + hb_barrier () && (!lenP1 || c->check_array_sized (arrayZ, lenP1 - 1, sizeof (LenType)))); } @@ -899,14 +978,14 @@ struct ArrayOfM1 { unsigned int i = (unsigned int) i_; if (unlikely (i > lenM1)) return Null (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return arrayZ[i]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i > lenM1)) return Crap (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return arrayZ[i]; } unsigned int get_size () const @@ -919,6 +998,7 @@ struct ArrayOfM1 TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = lenM1 + 1; for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) @@ -931,6 +1011,7 @@ struct ArrayOfM1 { TRACE_SANITIZE (this); return_trace (lenM1.sanitize (c) && + hb_barrier () && (c->check_array_sized (arrayZ, lenM1 + 1, sizeof (LenType)))); } @@ -975,6 +1056,13 @@ struct SortedArrayOf : ArrayOf return_trace (ret); } + SortedArrayOf* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + SortedArrayOf* out = reinterpret_cast (ArrayOf::copy (c)); + return_trace (out); + } + template Type &bsearch (const T &x, Type ¬_found = Crap (Type)) { return *as_array ().bsearch (x, ¬_found); } @@ -1082,14 +1170,14 @@ struct VarSizedBinSearchArrayOf { unsigned int i = (unsigned int) i_; if (unlikely (i >= get_length ())) return Null (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return StructAtOffset (&bytesZ, i * header.unitSize); } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= get_length ())) return Crap (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return StructAtOffset (&bytesZ, i * header.unitSize); } unsigned int get_length () const @@ -1104,6 +1192,7 @@ struct VarSizedBinSearchArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!(*this)[i].sanitize (c, std::forward (ds)...))) @@ -1130,6 +1219,7 @@ struct VarSizedBinSearchArrayOf { TRACE_SANITIZE (this); return_trace (header.sanitize (c) && + hb_barrier () && Type::static_size <= header.unitSize && c->check_range (bytesZ.arrayZ, header.nUnits, @@ -1144,6 +1234,800 @@ struct VarSizedBinSearchArrayOf }; +/* CFF INDEX */ + +template +struct CFFIndex +{ + unsigned int offset_array_size () const + { return offSize * (count + 1); } + + template + bool serialize (hb_serialize_context_t *c, + const Iterable &iterable, + const unsigned *p_data_size = nullptr, + unsigned min_off_size = 0) + { + TRACE_SERIALIZE (this); + unsigned data_size; + if (p_data_size) + data_size = *p_data_size; + else + total_size (iterable, &data_size); + + auto it = hb_iter (iterable); + if (unlikely (!serialize_header (c, +it, data_size, min_off_size))) return_trace (false); + unsigned char *ret = c->allocate_size (data_size, false); + if (unlikely (!ret)) return_trace (false); + for (const auto &_ : +it) + { + unsigned len = _.length; + if (!len) + continue; + if (len <= 1) + { + *ret++ = *_.arrayZ; + continue; + } + hb_memcpy (ret, _.arrayZ, len); + ret += len; + } + return_trace (true); + } + + template + bool serialize_header (hb_serialize_context_t *c, + Iterator it, + unsigned data_size, + unsigned min_off_size = 0) + { + TRACE_SERIALIZE (this); + + unsigned off_size = (hb_bit_storage (data_size + 1) + 7) / 8; + off_size = hb_max(min_off_size, off_size); + + /* serialize CFFIndex header */ + if (unlikely (!c->extend_min (this))) return_trace (false); + this->count = hb_len (it); + if (!this->count) return_trace (true); + if (unlikely (!c->extend (this->offSize))) return_trace (false); + this->offSize = off_size; + if (unlikely (!c->allocate_size (off_size * (this->count + 1), false))) + return_trace (false); + + /* serialize indices */ + unsigned int offset = 1; + if (HB_OPTIMIZE_SIZE_VAL) + { + unsigned int i = 0; + for (const auto &_ : +it) + { + set_offset_at (i++, offset); + offset += hb_len_of (_); + } + set_offset_at (i, offset); + } + else + switch (off_size) + { + case 1: + { + HBUINT8 *p = (HBUINT8 *) offsets; + for (const auto &_ : +it) + { + *p++ = offset; + offset += hb_len_of (_); + } + *p = offset; + } + break; + case 2: + { + HBUINT16 *p = (HBUINT16 *) offsets; + for (const auto &_ : +it) + { + *p++ = offset; + offset += hb_len_of (_); + } + *p = offset; + } + break; + case 3: + { + HBUINT24 *p = (HBUINT24 *) offsets; + for (const auto &_ : +it) + { + *p++ = offset; + offset += hb_len_of (_); + } + *p = offset; + } + break; + case 4: + { + HBUINT32 *p = (HBUINT32 *) offsets; + for (const auto &_ : +it) + { + *p++ = offset; + offset += hb_len_of (_); + } + *p = offset; + } + break; + default: + break; + } + + assert (offset == data_size + 1); + return_trace (true); + } + + template + static unsigned total_size (const Iterable &iterable, unsigned *data_size = nullptr, unsigned min_off_size = 0) + { + auto it = + hb_iter (iterable); + if (!it) + { + if (data_size) *data_size = 0; + return min_size; + } + + unsigned total = 0; + for (const auto &_ : +it) + total += hb_len_of (_); + + if (data_size) *data_size = total; + + unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8; + off_size = hb_max(min_off_size, off_size); + + return min_size + HBUINT8::static_size + (hb_len (it) + 1) * off_size + total; + } + + void set_offset_at (unsigned int index, unsigned int offset) + { + assert (index <= count); + + unsigned int size = offSize; + const HBUINT8 *p = offsets; + switch (size) + { + case 1: ((HBUINT8 *) p)[index] = offset; break; + case 2: ((HBUINT16 *) p)[index] = offset; break; + case 3: ((HBUINT24 *) p)[index] = offset; break; + case 4: ((HBUINT32 *) p)[index] = offset; break; + default: return; + } + } + + private: + unsigned int offset_at (unsigned int index) const + { + assert (index <= count); + + unsigned int size = offSize; + const HBUINT8 *p = offsets; + switch (size) + { + case 1: return ((HBUINT8 *) p)[index]; + case 2: return ((HBUINT16 *) p)[index]; + case 3: return ((HBUINT24 *) p)[index]; + case 4: return ((HBUINT32 *) p)[index]; + default: return 0; + } + } + + const unsigned char *data_base () const + { return (const unsigned char *) this + min_size + offSize.static_size - 1 + offset_array_size (); } + public: + + hb_ubytes_t operator [] (unsigned int index) const + { + if (unlikely (index >= count)) return hb_ubytes_t (); + hb_barrier (); + unsigned offset0 = offset_at (index); + unsigned offset1 = offset_at (index + 1); + if (unlikely (offset1 < offset0 || offset1 > offset_at (count))) + return hb_ubytes_t (); + return hb_ubytes_t (data_base () + offset0, offset1 - offset0); + } + + unsigned int get_size () const + { + if (count) + return min_size + offSize.static_size + offset_array_size () + (offset_at (count) - 1); + return min_size; /* empty CFFIndex contains count only */ + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + hb_barrier () && + (count == 0 || /* empty INDEX */ + (count < count + 1u && + c->check_struct (&offSize) && offSize >= 1 && offSize <= 4 && + c->check_array (offsets, offSize, count + 1u) && + c->check_range (data_base (), offset_at (count)))))); + } + + public: + COUNT count; /* Number of object data. Note there are (count+1) offsets */ + private: + HBUINT8 offSize; /* The byte size of each offset in the offsets array. */ + HBUINT8 offsets[HB_VAR_ARRAY]; + /* The array of (count + 1) offsets into objects array (1-base). */ + /* HBUINT8 data[HB_VAR_ARRAY]; Object data */ + public: + DEFINE_SIZE_MIN (COUNT::static_size); +}; +typedef CFFIndex CFF1Index; +typedef CFFIndex CFF2Index; + + +/* TupleValues */ +struct TupleValues +{ + enum packed_value_flag_t + { + VALUES_ARE_ZEROS = 0x80, + VALUES_ARE_BYTES = 0x00, + VALUES_ARE_WORDS = 0x40, + VALUES_ARE_LONGS = 0xC0, + VALUES_SIZE_MASK = 0xC0, + VALUE_RUN_COUNT_MASK = 0x3F + }; + + static unsigned compile (hb_array_t values, /* IN */ + hb_array_t encoded_bytes /* OUT */) + { + unsigned num_values = values.length; + unsigned encoded_len = 0; + unsigned i = 0; + while (i < num_values) + { + int val = values.arrayZ[i]; + if (val == 0) + encoded_len += encode_value_run_as_zeroes (i, encoded_bytes.sub_array (encoded_len), values); + else if (val >= -128 && val <= 127) + encoded_len += encode_value_run_as_bytes (i, encoded_bytes.sub_array (encoded_len), values); + else if (val >= -32768 && val <= 32767) + encoded_len += encode_value_run_as_words (i, encoded_bytes.sub_array (encoded_len), values); + else + encoded_len += encode_value_run_as_longs (i, encoded_bytes.sub_array (encoded_len), values); + } + return encoded_len; + } + + static unsigned encode_value_run_as_zeroes (unsigned& i, + hb_array_t encoded_bytes, + hb_array_t values) + { + unsigned num_values = values.length; + unsigned run_length = 0; + auto it = encoded_bytes.iter (); + unsigned encoded_len = 0; + while (i < num_values && values.arrayZ[i] == 0) + { + i++; + run_length++; + } + + while (run_length >= 64) + { + *it++ = char (VALUES_ARE_ZEROS | 63); + run_length -= 64; + encoded_len++; + } + + if (run_length) + { + *it++ = char (VALUES_ARE_ZEROS | (run_length - 1)); + encoded_len++; + } + return encoded_len; + } + + static unsigned encode_value_run_as_bytes (unsigned &i, + hb_array_t encoded_bytes, + hb_array_t values) + { + unsigned start = i; + unsigned num_values = values.length; + while (i < num_values) + { + int val = values.arrayZ[i]; + if (val > 127 || val < -128) + break; + + /* from fonttools: if there're 2 or more zeros in a sequence, + * it is better to start a new run to save bytes. */ + if (val == 0 && i + 1 < num_values && values.arrayZ[i+1] == 0) + break; + + i++; + } + unsigned run_length = i - start; + + unsigned encoded_len = 0; + auto it = encoded_bytes.iter (); + + while (run_length >= 64) + { + *it++ = (VALUES_ARE_BYTES | 63); + encoded_len++; + + for (unsigned j = 0; j < 64; j++) + { + *it++ = static_cast (values.arrayZ[start + j]); + encoded_len++; + } + + start += 64; + run_length -= 64; + } + + if (run_length) + { + *it++ = (VALUES_ARE_BYTES | (run_length - 1)); + encoded_len++; + + while (start < i) + { + *it++ = static_cast (values.arrayZ[start++]); + encoded_len++; + } + } + + return encoded_len; + } + + static unsigned encode_value_run_as_words (unsigned &i, + hb_array_t encoded_bytes, + hb_array_t values) + { + unsigned start = i; + unsigned num_values = values.length; + while (i < num_values) + { + int val = values.arrayZ[i]; + + /* start a new run for a single zero value*/ + if (val == 0) break; + + /* from fonttools: continue word-encoded run if there's only one + * single value in the range [-128, 127] because it is more compact. + * Only start a new run when there're 2 continuous such values. */ + if (val >= -128 && val <= 127 && + i + 1 < num_values && + values.arrayZ[i+1] >= -128 && values.arrayZ[i+1] <= 127) + break; + + i++; + } + + unsigned run_length = i - start; + auto it = encoded_bytes.iter (); + unsigned encoded_len = 0; + while (run_length >= 64) + { + *it++ = (VALUES_ARE_WORDS | 63); + encoded_len++; + + for (unsigned j = 0; j < 64; j++) + { + int16_t value_val = values.arrayZ[start + j]; + *it++ = static_cast (value_val >> 8); + *it++ = static_cast (value_val & 0xFF); + + encoded_len += 2; + } + + start += 64; + run_length -= 64; + } + + if (run_length) + { + *it++ = (VALUES_ARE_WORDS | (run_length - 1)); + encoded_len++; + while (start < i) + { + int16_t value_val = values.arrayZ[start++]; + *it++ = static_cast (value_val >> 8); + *it++ = static_cast (value_val & 0xFF); + + encoded_len += 2; + } + } + return encoded_len; + } + + static unsigned encode_value_run_as_longs (unsigned &i, + hb_array_t encoded_bytes, + hb_array_t values) + { + unsigned start = i; + unsigned num_values = values.length; + while (i < num_values) + { + int val = values.arrayZ[i]; + + if (val >= -32768 && val <= 32767) + break; + + i++; + } + + unsigned run_length = i - start; + auto it = encoded_bytes.iter (); + unsigned encoded_len = 0; + while (run_length >= 64) + { + *it++ = (VALUES_ARE_LONGS | 63); + encoded_len++; + + for (unsigned j = 0; j < 64; j++) + { + int32_t value_val = values.arrayZ[start + j]; + *it++ = static_cast (value_val >> 24); + *it++ = static_cast (value_val >> 16); + *it++ = static_cast (value_val >> 8); + *it++ = static_cast (value_val & 0xFF); + + encoded_len += 4; + } + + start += 64; + run_length -= 64; + } + + if (run_length) + { + *it++ = (VALUES_ARE_LONGS | (run_length - 1)); + encoded_len++; + while (start < i) + { + int32_t value_val = values.arrayZ[start++]; + *it++ = static_cast (value_val >> 24); + *it++ = static_cast (value_val >> 16); + *it++ = static_cast (value_val >> 8); + *it++ = static_cast (value_val & 0xFF); + + encoded_len += 4; + } + } + return encoded_len; + } + + template + static bool decompile (const HBUINT8 *&p /* IN/OUT */, + hb_vector_t &values /* IN/OUT */, + const HBUINT8 *end, + bool consume_all = false) + { + unsigned i = 0; + unsigned count = consume_all ? UINT_MAX : values.length; + if (consume_all) + values.alloc ((end - p) / 2); + while (i < count) + { + if (unlikely (p + 1 > end)) return consume_all; + unsigned control = *p++; + unsigned run_count = (control & VALUE_RUN_COUNT_MASK) + 1; + if (consume_all) + { + if (unlikely (!values.resize (values.length + run_count, false))) + return false; + } + unsigned stop = i + run_count; + if (unlikely (stop > count)) return false; + if ((control & VALUES_SIZE_MASK) == VALUES_ARE_ZEROS) + { + for (; i < stop; i++) + values.arrayZ[i] = 0; + } + else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_WORDS) + { + if (unlikely (p + run_count * HBINT16::static_size > end)) return false; +#ifndef HB_OPTIMIZE_SIZE + for (; i + 3 < stop; i += 4) + { + values.arrayZ[i] = * (const HBINT16 *) p; + p += HBINT16::static_size; + values.arrayZ[i + 1] = * (const HBINT16 *) p; + p += HBINT16::static_size; + values.arrayZ[i + 2] = * (const HBINT16 *) p; + p += HBINT16::static_size; + values.arrayZ[i + 3] = * (const HBINT16 *) p; + p += HBINT16::static_size; + } +#endif + for (; i < stop; i++) + { + values.arrayZ[i] = * (const HBINT16 *) p; + p += HBINT16::static_size; + } + } + else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_LONGS) + { + if (unlikely (p + run_count * HBINT32::static_size > end)) return false; + for (; i < stop; i++) + { + values.arrayZ[i] = * (const HBINT32 *) p; + p += HBINT32::static_size; + } + } + else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_BYTES) + { + if (unlikely (p + run_count > end)) return false; +#ifndef HB_OPTIMIZE_SIZE + for (; i + 3 < stop; i += 4) + { + values.arrayZ[i] = * (const HBINT8 *) p++; + values.arrayZ[i + 1] = * (const HBINT8 *) p++; + values.arrayZ[i + 2] = * (const HBINT8 *) p++; + values.arrayZ[i + 3] = * (const HBINT8 *) p++; + } +#endif + for (; i < stop; i++) + values.arrayZ[i] = * (const HBINT8 *) p++; + } + } + return true; + } + + struct iter_t : hb_iter_with_fallback_t + { + iter_t (const unsigned char *p_, unsigned len_) + : p (p_), endp (p_ + len_) + { if (ensure_run ()) read_value (); } + + private: + const unsigned char *p; + const unsigned char * const endp; + int current_value = 0; + signed run_count = 0; + unsigned width = 0; + + bool ensure_run () + { + if (likely (run_count > 0)) return true; + + if (unlikely (p >= endp)) + { + run_count = 0; + current_value = 0; + return false; + } + + unsigned control = *p++; + run_count = (control & VALUE_RUN_COUNT_MASK) + 1; + width = control & VALUES_SIZE_MASK; + switch (width) + { + case VALUES_ARE_ZEROS: width = 0; break; + case VALUES_ARE_BYTES: width = HBINT8::static_size; break; + case VALUES_ARE_WORDS: width = HBINT16::static_size; break; + case VALUES_ARE_LONGS: width = HBINT32::static_size; break; + default: assert (false); + } + + if (unlikely (p + run_count * width > endp)) + { + run_count = 0; + current_value = 0; + return false; + } + + return true; + } + void read_value () + { + switch (width) + { + case 0: current_value = 0; break; + case 1: current_value = * (const HBINT8 *) p; break; + case 2: current_value = * (const HBINT16 *) p; break; + case 4: current_value = * (const HBINT32 *) p; break; + } + p += width; + } + + public: + + typedef int __item_t__; + __item_t__ __item__ () const + { return current_value; } + + bool __more__ () const { return run_count || p < endp; } + void __next__ () + { + run_count--; + if (unlikely (!ensure_run ())) + return; + read_value (); + } + void __forward__ (unsigned n) + { + if (unlikely (!ensure_run ())) + return; + while (n) + { + unsigned i = hb_min (n, (unsigned) run_count); + run_count -= i; + n -= i; + p += (i - 1) * width; + if (unlikely (!ensure_run ())) + return; + read_value (); + } + } + bool operator != (const iter_t& o) const + { return p != o.p || run_count != o.run_count; } + iter_t __end__ () const + { + iter_t it (endp, 0); + return it; + } + }; + + struct fetcher_t + { + fetcher_t (const unsigned char *p_, unsigned len_) + : p (p_), end (p_ + len_) {} + + private: + const unsigned char *p; + const unsigned char * const end; + signed run_count = 0; + unsigned width = 0; + + bool ensure_run () + { + if (likely (run_count > 0)) return true; + + if (unlikely (p >= end)) + { + run_count = 0; + return false; + } + + unsigned control = *p++; + run_count = (control & VALUE_RUN_COUNT_MASK) + 1; + width = control & VALUES_SIZE_MASK; + switch (width) + { + case VALUES_ARE_ZEROS: width = 0; break; + case VALUES_ARE_BYTES: width = HBINT8::static_size; break; + case VALUES_ARE_WORDS: width = HBINT16::static_size; break; + case VALUES_ARE_LONGS: width = HBINT32::static_size; break; + default: assert (false); + } + + if (unlikely (p + run_count * width > end)) + { + run_count = 0; + return false; + } + + return true; + } + + void skip (unsigned n) + { + while (n) + { + if (unlikely (!ensure_run ())) + return; + unsigned i = hb_min (n, (unsigned) run_count); + run_count -= i; + n -= i; + p += i * width; + } + } + + template + void _add_to (hb_array_t out, float scale = 1.0f) + { + unsigned n = out.length; + float *arrayZ = out.arrayZ; + + for (unsigned i = 0; i < n;) + { + if (unlikely (!ensure_run ())) + break; + unsigned count = hb_min (n - i, (unsigned) run_count); + switch (width) + { + case 1: + { + const auto *pp = (const HBINT8 *) p; + unsigned j = 0; +#ifndef HB_OPTIMIZE_SIZE + for (; j + 3 < count; j += 4) + { + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } +#endif + for (; j < count; j++) + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } + break; + case 2: + { + const auto *pp = (const HBINT16 *) p; + unsigned j = 0; +#ifndef HB_OPTIMIZE_SIZE + for (; j + 3 < count; j += 4) + { + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } +#endif + for (; j < count; j++) + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } + break; + case 4: + { + const auto *pp = (const HBINT32 *) p; + for (unsigned j = 0; j < count; j++) + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } + break; + } + p += count * width; + run_count -= count; + i += count; + } + } + + public: + void add_to (hb_array_t out, float scale = 1.0f) + { + unsigned n = out.length; + + if (scale == 0.0f) + { + skip (n); + return; + } + +#ifndef HB_OPTIMIZE_SIZE + if (scale == 1.0f) + _add_to (out); + else +#endif + _add_to (out, scale); + } + }; +}; + +struct TupleList : CFF2Index +{ + TupleValues::iter_t operator [] (unsigned i) const + { + auto bytes = CFF2Index::operator [] (i); + return TupleValues::iter_t (bytes.arrayZ, bytes.length); + } + + TupleValues::fetcher_t fetcher (unsigned i) const + { + auto bytes = CFF2Index::operator [] (i); + return TupleValues::fetcher_t (bytes.arrayZ, bytes.length); + } +}; + + } /* namespace OT */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh index 081c333f50f52..1e3e0be510629 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh @@ -41,10 +41,21 @@ using namespace OT; using objidx_t = hb_serialize_context_t::objidx_t; using whence_t = hb_serialize_context_t::whence_t; -/* utility macro */ -template -static inline const Type& StructAtOffsetOrNull (const void *P, unsigned int offset) -{ return offset ? StructAtOffset (P, offset) : Null (Type); } +/* CFF offsets can technically be negative */ +template +static inline const Type& StructAtOffsetOrNull (const void *P, int offset, hb_sanitize_context_t &sc, Ts&&... ds) +{ + if (!offset) return Null (Type); + + const char *p = (const char *) P + offset; + if (!sc.check_point (p)) return Null (Type); + + const Type &obj = *reinterpret_cast (p); + if (!obj.sanitize (&sc, std::forward (ds)...)) return Null (Type); + + return obj; +} + struct code_pair_t { @@ -57,241 +68,6 @@ using str_buff_t = hb_vector_t; using str_buff_vec_t = hb_vector_t; using glyph_to_sid_map_t = hb_vector_t; -struct length_f_t -{ - template - unsigned operator () (const Iterable &_) const { return hb_len (hb_iter (_)); } - - unsigned operator () (unsigned _) const { return _; } -} -HB_FUNCOBJ (length_f); - -/* CFF INDEX */ -template -struct CFFIndex -{ - unsigned int offset_array_size () const - { return offSize * (count + 1); } - - template - bool serialize (hb_serialize_context_t *c, - const Iterable &iterable, - const unsigned *p_data_size = nullptr) - { - TRACE_SERIALIZE (this); - unsigned data_size; - if (p_data_size) - data_size = *p_data_size; - else - total_size (iterable, &data_size); - - auto it = hb_iter (iterable); - if (unlikely (!serialize_header (c, +it, data_size))) return_trace (false); - unsigned char *ret = c->allocate_size (data_size, false); - if (unlikely (!ret)) return_trace (false); - for (const auto &_ : +it) - { - unsigned len = _.length; - if (!len) - continue; - if (len <= 1) - { - *ret++ = *_.arrayZ; - continue; - } - hb_memcpy (ret, _.arrayZ, len); - ret += len; - } - return_trace (true); - } - - template - bool serialize_header (hb_serialize_context_t *c, - Iterator it, - unsigned data_size) - { - TRACE_SERIALIZE (this); - - unsigned off_size = (hb_bit_storage (data_size + 1) + 7) / 8; - - /* serialize CFFIndex header */ - if (unlikely (!c->extend_min (this))) return_trace (false); - this->count = hb_len (it); - if (!this->count) return_trace (true); - if (unlikely (!c->extend (this->offSize))) return_trace (false); - this->offSize = off_size; - if (unlikely (!c->allocate_size (off_size * (this->count + 1), false))) - return_trace (false); - - /* serialize indices */ - unsigned int offset = 1; - if (HB_OPTIMIZE_SIZE_VAL) - { - unsigned int i = 0; - for (const auto &_ : +it) - { - set_offset_at (i++, offset); - offset += length_f (_); - } - set_offset_at (i, offset); - } - else - switch (off_size) - { - case 1: - { - HBUINT8 *p = (HBUINT8 *) offsets; - for (const auto &_ : +it) - { - *p++ = offset; - offset += length_f (_); - } - *p = offset; - } - break; - case 2: - { - HBUINT16 *p = (HBUINT16 *) offsets; - for (const auto &_ : +it) - { - *p++ = offset; - offset += length_f (_); - } - *p = offset; - } - break; - case 3: - { - HBUINT24 *p = (HBUINT24 *) offsets; - for (const auto &_ : +it) - { - *p++ = offset; - offset += length_f (_); - } - *p = offset; - } - break; - case 4: - { - HBUINT32 *p = (HBUINT32 *) offsets; - for (const auto &_ : +it) - { - *p++ = offset; - offset += length_f (_); - } - *p = offset; - } - break; - default: - break; - } - - assert (offset == data_size + 1); - return_trace (true); - } - - template - static unsigned total_size (const Iterable &iterable, unsigned *data_size = nullptr) - { - auto it = + hb_iter (iterable); - if (!it) - { - if (data_size) *data_size = 0; - return min_size; - } - - unsigned total = 0; - for (const auto &_ : +it) - total += length_f (_); - - if (data_size) *data_size = total; - - unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8; - - return min_size + HBUINT8::static_size + (hb_len (it) + 1) * off_size + total; - } - - void set_offset_at (unsigned int index, unsigned int offset) - { - assert (index <= count); - - unsigned int size = offSize; - const HBUINT8 *p = offsets; - switch (size) - { - case 1: ((HBUINT8 *) p)[index] = offset; break; - case 2: ((HBUINT16 *) p)[index] = offset; break; - case 3: ((HBUINT24 *) p)[index] = offset; break; - case 4: ((HBUINT32 *) p)[index] = offset; break; - default: return; - } - } - - private: - unsigned int offset_at (unsigned int index) const - { - assert (index <= count); - - unsigned int size = offSize; - const HBUINT8 *p = offsets; - switch (size) - { - case 1: return ((HBUINT8 *) p)[index]; - case 2: return ((HBUINT16 *) p)[index]; - case 3: return ((HBUINT24 *) p)[index]; - case 4: return ((HBUINT32 *) p)[index]; - default: return 0; - } - } - - const unsigned char *data_base () const - { return (const unsigned char *) this + min_size + offSize.static_size - 1 + offset_array_size (); } - public: - - hb_ubytes_t operator [] (unsigned int index) const - { - if (unlikely (index >= count)) return hb_ubytes_t (); - _hb_compiler_memory_r_barrier (); - unsigned offset0 = offset_at (index); - unsigned offset1 = offset_at (index + 1); - if (unlikely (offset1 < offset0 || offset1 > offset_at (count))) - return hb_ubytes_t (); - return hb_ubytes_t (data_base () + offset0, offset1 - offset0); - } - - unsigned int get_size () const - { - if (count) - return min_size + offSize.static_size + offset_array_size () + (offset_at (count) - 1); - return min_size; /* empty CFFIndex contains count only */ - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - (count == 0 || /* empty INDEX */ - (count < count + 1u && - c->check_struct (&offSize) && offSize >= 1 && offSize <= 4 && - c->check_array (offsets, offSize, count + 1u) && - c->check_array ((const HBUINT8*) data_base (), 1, offset_at (count)))))); - } - - public: - COUNT count; /* Number of object data. Note there are (count+1) offsets */ - private: - HBUINT8 offSize; /* The byte size of each offset in the offsets array. */ - HBUINT8 offsets[HB_VAR_ARRAY]; - /* The array of (count + 1) offsets into objects array (1-base). */ - /* HBUINT8 data[HB_VAR_ARRAY]; Object data */ - public: - DEFINE_SIZE_MIN (COUNT::static_size); -}; - /* Top Dict, Font Dict, Private Dict */ struct Dict : UnsizedByteStr { @@ -412,6 +188,7 @@ struct FDSelect0 { TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this)))) return_trace (false); + hb_barrier (); if (unlikely (!c->check_array (fds, c->get_num_glyphs ()))) return_trace (false); @@ -438,7 +215,9 @@ struct FDSelect3_4_Range bool sanitize (hb_sanitize_context_t *c, const void * /*nullptr*/, unsigned int fdcount) const { TRACE_SANITIZE (this); - return_trace (first < c->get_num_glyphs () && (fd < fdcount)); + return_trace (c->check_struct (this) && + hb_barrier () && + first < c->get_num_glyphs () && (fd < fdcount)); } GID_TYPE first; @@ -456,15 +235,20 @@ struct FDSelect3_4 bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this) || !ranges.sanitize (c, nullptr, fdcount) || - (nRanges () == 0) || ranges[0].first != 0)) + if (unlikely (!(c->check_struct (this) && + ranges.sanitize (c, nullptr, fdcount) && + hb_barrier () && + (nRanges () != 0) && + ranges[0].first == 0))) return_trace (false); for (unsigned int i = 1; i < nRanges (); i++) if (unlikely (ranges[i - 1].first >= ranges[i].first)) return_trace (false); - if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ()))) + if (unlikely (!(sentinel().sanitize (c) && + hb_barrier () && + (sentinel() == c->get_num_glyphs ())))) return_trace (false); return_trace (true); @@ -524,8 +308,8 @@ struct FDSelect { switch (format) { - case 0: return format.static_size + u.format0.get_size (num_glyphs); - case 3: return format.static_size + u.format3.get_size (); + case 0: hb_barrier (); return format.static_size + u.format0.get_size (num_glyphs); + case 3: hb_barrier (); return format.static_size + u.format3.get_size (); default:return 0; } } @@ -536,8 +320,8 @@ struct FDSelect switch (format) { - case 0: return u.format0.get_fd (glyph); - case 3: return u.format3.get_fd (glyph); + case 0: hb_barrier (); return u.format0.get_fd (glyph); + case 3: hb_barrier (); return u.format3.get_fd (glyph); default:return 0; } } @@ -548,8 +332,8 @@ struct FDSelect switch (format) { - case 0: return u.format0.get_fd_range (glyph); - case 3: return u.format3.get_fd_range (glyph); + case 0: hb_barrier (); return u.format0.get_fd_range (glyph); + case 3: hb_barrier (); return u.format3.get_fd_range (glyph); default:return {0, 1}; } } @@ -559,11 +343,12 @@ struct FDSelect TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (format) { - case 0: return_trace (u.format0.sanitize (c, fdcount)); - case 3: return_trace (u.format3.sanitize (c, fdcount)); + case 0: hb_barrier (); return_trace (u.format0.sanitize (c, fdcount)); + case 3: hb_barrier (); return_trace (u.format3.sanitize (c, fdcount)); default:return_trace (false); } } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc index 6fcc8c4658782..b06936f94c898 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc @@ -553,15 +553,6 @@ bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoin return true; } -bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const -{ - funcs->push_clip_glyph (data, glyph, font); - funcs->color (data, true, foreground); - funcs->pop_clip (data); - - return true; -} - bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const { #ifdef HB_NO_OT_FONT_CFF diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh index d1310c66fde18..0116a0c91923b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh @@ -51,9 +51,6 @@ namespace CFF { enum EncodingID { StandardEncoding = 0, ExpertEncoding = 1 }; enum CharsetID { ISOAdobeCharset = 0, ExpertCharset = 1, ExpertSubsetCharset = 2 }; -typedef CFFIndex CFF1Index; - -typedef CFFIndex CFF1Index; typedef CFF1Index CFF1CharStrings; typedef Subrs CFF1Subrs; @@ -242,8 +239,8 @@ struct Encoding unsigned int size = min_size; switch (table_format ()) { - case 0: size += u.format0.get_size (); break; - case 1: size += u.format1.get_size (); break; + case 0: hb_barrier (); size += u.format0.get_size (); break; + case 1: hb_barrier (); size += u.format1.get_size (); break; } if (has_supplement ()) size += suppEncData ().get_size (); @@ -254,8 +251,8 @@ struct Encoding { switch (table_format ()) { - case 0: return u.format0.get_code (glyph); - case 1: return u.format1.get_code (glyph); + case 0: hb_barrier (); return u.format0.get_code (glyph); + case 1: hb_barrier (); return u.format1.get_code (glyph); default:return 0; } } @@ -275,11 +272,12 @@ struct Encoding TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (table_format ()) { - case 0: if (unlikely (!u.format0.sanitize (c))) { return_trace (false); } break; - case 1: if (unlikely (!u.format1.sanitize (c))) { return_trace (false); } break; + case 0: hb_barrier (); if (unlikely (!u.format0.sanitize (c))) { return_trace (false); } break; + case 1: hb_barrier (); if (unlikely (!u.format1.sanitize (c))) { return_trace (false); } break; default:return_trace (false); } return_trace (likely (!has_supplement () || suppEncData ().sanitize (c))); @@ -290,8 +288,8 @@ struct Encoding { switch (table_format ()) { - case 0: return StructAfter (u.format0.codes[u.format0.nCodes ()-1]); - case 1: return StructAfter (u.format1.ranges[u.format1.nRanges ()-1]); + case 0: hb_barrier (); return StructAfter (u.format0.codes[u.format0.nCodes ()-1]); + case 1: hb_barrier (); return StructAfter (u.format1.ranges[u.format1.nRanges ()-1]); default:return Null (CFF1SuppEncData); } } @@ -376,13 +374,13 @@ struct Charset1_2 { bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs, unsigned *num_charset_entries) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) - return_trace (false); num_glyphs--; unsigned i; for (i = 0; num_glyphs > 0; i++) { - if (unlikely (!ranges[i].sanitize (c) || (num_glyphs < ranges[i].nLeft + 1))) + if (unlikely (!(ranges[i].sanitize (c) && + hb_barrier () && + (num_glyphs >= ranges[i].nLeft + 1)))) return_trace (false); num_glyphs -= (ranges[i].nLeft + 1); } @@ -569,9 +567,9 @@ struct Charset { switch (format) { - case 0: return min_size + u.format0.get_size (num_glyphs); - case 1: return min_size + u.format1.get_size (num_glyphs); - case 2: return min_size + u.format2.get_size (num_glyphs); + case 0: hb_barrier (); return min_size + u.format0.get_size (num_glyphs); + case 1: hb_barrier (); return min_size + u.format1.get_size (num_glyphs); + case 2: hb_barrier (); return min_size + u.format2.get_size (num_glyphs); default:return 0; } } @@ -581,9 +579,9 @@ struct Charset { switch (format) { - case 0: return u.format0.get_sid (glyph, num_glyphs); - case 1: return u.format1.get_sid (glyph, num_glyphs, cache); - case 2: return u.format2.get_sid (glyph, num_glyphs, cache); + case 0: hb_barrier (); return u.format0.get_sid (glyph, num_glyphs); + case 1: hb_barrier (); return u.format1.get_sid (glyph, num_glyphs, cache); + case 2: hb_barrier (); return u.format2.get_sid (glyph, num_glyphs, cache); default:return 0; } } @@ -592,9 +590,9 @@ struct Charset { switch (format) { - case 0: u.format0.collect_glyph_to_sid_map (mapping, num_glyphs); return; - case 1: u.format1.collect_glyph_to_sid_map (mapping, num_glyphs); return; - case 2: u.format2.collect_glyph_to_sid_map (mapping, num_glyphs); return; + case 0: hb_barrier (); u.format0.collect_glyph_to_sid_map (mapping, num_glyphs); return; + case 1: hb_barrier (); u.format1.collect_glyph_to_sid_map (mapping, num_glyphs); return; + case 2: hb_barrier (); u.format2.collect_glyph_to_sid_map (mapping, num_glyphs); return; default:return; } } @@ -603,9 +601,9 @@ struct Charset { switch (format) { - case 0: return u.format0.get_glyph (sid, num_glyphs); - case 1: return u.format1.get_glyph (sid, num_glyphs); - case 2: return u.format2.get_glyph (sid, num_glyphs); + case 0: hb_barrier (); return u.format0.get_glyph (sid, num_glyphs); + case 1: hb_barrier (); return u.format1.get_glyph (sid, num_glyphs); + case 2: hb_barrier (); return u.format2.get_glyph (sid, num_glyphs); default:return 0; } } @@ -615,12 +613,13 @@ struct Charset TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (format) { - case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs (), num_charset_entries)); - case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs (), num_charset_entries)); - case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs (), num_charset_entries)); + case 0: hb_barrier (); return_trace (u.format0.sanitize (c, c->get_num_glyphs (), num_charset_entries)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c, c->get_num_glyphs (), num_charset_entries)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c, c->get_num_glyphs (), num_charset_entries)); default:return_trace (false); } } @@ -761,9 +760,9 @@ struct cff1_top_dict_values_t : top_dict_values_t unsigned int ros_supplement; unsigned int cidCount; - unsigned int EncodingOffset; - unsigned int CharsetOffset; - unsigned int FDSelectOffset; + int EncodingOffset; + int CharsetOffset; + int FDSelectOffset; table_info_t privateDictInfo; }; @@ -819,24 +818,24 @@ struct cff1_top_dict_opset_t : top_dict_opset_t break; case OpCode_Encoding: - dictval.EncodingOffset = env.argStack.pop_uint (); + dictval.EncodingOffset = env.argStack.pop_int (); env.clear_args (); if (unlikely (dictval.EncodingOffset == 0)) return; break; case OpCode_charset: - dictval.CharsetOffset = env.argStack.pop_uint (); + dictval.CharsetOffset = env.argStack.pop_int (); env.clear_args (); if (unlikely (dictval.CharsetOffset == 0)) return; break; case OpCode_FDSelect: - dictval.FDSelectOffset = env.argStack.pop_uint (); + dictval.FDSelectOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_Private: - dictval.privateDictInfo.offset = env.argStack.pop_uint (); + dictval.privateDictInfo.offset = env.argStack.pop_int (); dictval.privateDictInfo.size = env.argStack.pop_uint (); env.clear_args (); break; @@ -911,7 +910,7 @@ struct cff1_private_dict_values_base_t : dict_values_t } void fini () { dict_values_t::fini (); } - unsigned int subrsOffset; + int subrsOffset; const CFF1Subrs *localSubrs; }; @@ -946,7 +945,7 @@ struct cff1_private_dict_opset_t : dict_opset_t env.clear_args (); break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -988,7 +987,7 @@ struct cff1_private_dict_opset_subset_t : dict_opset_t break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -1055,6 +1054,7 @@ struct cff1 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 1)); } @@ -1085,14 +1085,17 @@ struct cff1 nameIndex = &cff->nameIndex (cff); if ((nameIndex == &Null (CFF1NameIndex)) || !nameIndex->sanitize (&sc)) goto fail; + hb_barrier (); - topDictIndex = &StructAtOffset (nameIndex, nameIndex->get_size ()); - if ((topDictIndex == &Null (CFF1TopDictIndex)) || !topDictIndex->sanitize (&sc) || (topDictIndex->count == 0)) + topDictIndex = &StructAtOffsetOrNull (nameIndex, nameIndex->get_size (), sc); + if (topDictIndex == &Null (CFF1TopDictIndex) || (topDictIndex->count == 0)) goto fail; + hb_barrier (); { /* parse top dict */ const hb_ubytes_t topDictStr = (*topDictIndex)[0]; if (unlikely (!topDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff1_top_dict_interp_env_t env (topDictStr); cff1_top_dict_interpreter_t top_interp (env); if (unlikely (!top_interp.interpret (topDict))) goto fail; @@ -1102,17 +1105,17 @@ struct cff1 charset = &Null (Charset); else { - charset = &StructAtOffsetOrNull (cff, topDict.CharsetOffset); - if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc, &num_charset_entries))) goto fail; + charset = &StructAtOffsetOrNull (cff, topDict.CharsetOffset, sc, &num_charset_entries); + if (unlikely (charset == &Null (Charset))) goto fail; } fdCount = 1; if (is_CID ()) { - fdArray = &StructAtOffsetOrNull (cff, topDict.FDArrayOffset); - fdSelect = &StructAtOffsetOrNull (cff, topDict.FDSelectOffset); - if (unlikely ((fdArray == &Null (CFF1FDArray)) || !fdArray->sanitize (&sc) || - (fdSelect == &Null (CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count))) + fdArray = &StructAtOffsetOrNull (cff, topDict.FDArrayOffset, sc); + fdSelect = &StructAtOffsetOrNull (cff, topDict.FDSelectOffset, sc, fdArray->count); + if (unlikely (fdArray == &Null (CFF1FDArray) || + fdSelect == &Null (CFF1FDSelect))) goto fail; fdCount = fdArray->count; @@ -1132,22 +1135,18 @@ struct cff1 { if (!is_predef_encoding ()) { - encoding = &StructAtOffsetOrNull (cff, topDict.EncodingOffset); - if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) goto fail; + encoding = &StructAtOffsetOrNull (cff, topDict.EncodingOffset, sc); + if (unlikely (encoding == &Null (Encoding))) goto fail; } } - stringIndex = &StructAtOffset (topDictIndex, topDictIndex->get_size ()); - if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc)) + stringIndex = &StructAtOffsetOrNull (topDictIndex, topDictIndex->get_size (), sc); + if (stringIndex == &Null (CFF1StringIndex)) goto fail; - globalSubrs = &StructAtOffset (stringIndex, stringIndex->get_size ()); - if ((globalSubrs != &Null (CFF1Subrs)) && !globalSubrs->sanitize (&sc)) - goto fail; - - charStrings = &StructAtOffsetOrNull (cff, topDict.charStringsOffset); - - if ((charStrings == &Null (CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc))) + globalSubrs = &StructAtOffsetOrNull (stringIndex, stringIndex->get_size (), sc); + charStrings = &StructAtOffsetOrNull (cff, topDict.charStringsOffset, sc); + if (charStrings == &Null (CFF1CharStrings)) goto fail; num_glyphs = charStrings->count; @@ -1166,6 +1165,7 @@ struct cff1 { hb_ubytes_t fontDictStr = (*fdArray)[i]; if (unlikely (!fontDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff1_font_dict_values_t *font; cff1_top_dict_interp_env_t env (fontDictStr); cff1_font_dict_interpreter_t font_interp (env); @@ -1175,17 +1175,14 @@ struct cff1 font->init (); if (unlikely (!font_interp.interpret (*font))) goto fail; PRIVDICTVAL *priv = &privateDicts[i]; - const hb_ubytes_t privDictStr = StructAtOffset (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) goto fail; + const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); + if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; num_interp_env_t env2 (privDictStr); dict_interpreter_t priv_interp (env2); priv->init (); if (unlikely (!priv_interp.interpret (*priv))) goto fail; - priv->localSubrs = &StructAtOffsetOrNull (&privDictStr, priv->subrsOffset); - if (priv->localSubrs != &Null (CFF1Subrs) && - unlikely (!priv->localSubrs->sanitize (&sc))) - goto fail; + priv->localSubrs = &StructAtOffsetOrNull (&privDictStr, priv->subrsOffset, sc); } } else /* non-CID */ @@ -1193,17 +1190,15 @@ struct cff1 cff1_top_dict_values_t *font = &topDict; PRIVDICTVAL *priv = &privateDicts[0]; - const hb_ubytes_t privDictStr = StructAtOffset (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) goto fail; + const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); + if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; num_interp_env_t env (privDictStr); dict_interpreter_t priv_interp (env); priv->init (); if (unlikely (!priv_interp.interpret (*priv))) goto fail; - priv->localSubrs = &StructAtOffsetOrNull (&privDictStr, priv->subrsOffset); - if (priv->localSubrs != &Null (CFF1Subrs) && - unlikely (!priv->localSubrs->sanitize (&sc))) - goto fail; + priv->localSubrs = &StructAtOffsetOrNull (&privDictStr, priv->subrsOffset, sc); + hb_barrier (); } return; @@ -1420,7 +1415,7 @@ struct cff1 hb_sorted_vector_t *names = glyph_names.get_acquire (); if (unlikely (!names)) { - names = (hb_sorted_vector_t *) hb_calloc (sizeof (hb_sorted_vector_t), 1); + names = (hb_sorted_vector_t *) hb_calloc (1, sizeof (hb_sorted_vector_t)); if (likely (names)) { names->init (); @@ -1467,7 +1462,6 @@ struct cff1 } HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; - HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; private: diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc index ed430ee59d56b..fce39da21ce3c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc @@ -143,15 +143,6 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, return true; } -bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const -{ - funcs->push_clip_glyph (data, glyph, font); - funcs->color (data, true, foreground); - funcs->pop_clip (data); - - return true; -} - struct cff2_path_param_t { cff2_path_param_t (hb_font_t *font_, hb_draw_session_t &draw_session_) @@ -202,6 +193,11 @@ struct cff2_path_procs_path_t : path_procs_t {}; bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const +{ + return get_path_at (font, glyph, draw_session, hb_array (font->coords, font->num_coords)); +} + +bool OT::cff2::accelerator_t::get_path_at (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session, hb_array_t coords) const { #ifdef HB_NO_OT_FONT_CFF /* XXX Remove check when this code moves to .hh file. */ @@ -212,7 +208,7 @@ bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, h unsigned int fd = fdSelect->get_fd (glyph); const hb_ubytes_t str = (*charStrings)[glyph]; - cff2_cs_interp_env_t env (str, *this, fd, font->coords, font->num_coords); + cff2_cs_interp_env_t env (str, *this, fd, coords.arrayZ, coords.length); cff2_cs_interpreter_t interp (env); cff2_path_param_t param (font, draw_session); if (unlikely (!interp.interpret (param))) return false; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh index db10f22ec52e6..81d30f57a2838 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh @@ -40,8 +40,6 @@ namespace CFF { */ #define HB_OT_TAG_CFF2 HB_TAG('C','F','F','2') -typedef CFFIndex CFF2Index; - typedef CFF2Index CFF2CharStrings; typedef Subrs CFF2Subrs; @@ -64,9 +62,9 @@ struct CFF2FDSelect { switch (format) { - case 0: return format.static_size + u.format0.get_size (num_glyphs); - case 3: return format.static_size + u.format3.get_size (); - case 4: return format.static_size + u.format4.get_size (); + case 0: hb_barrier (); return format.static_size + u.format0.get_size (num_glyphs); + case 3: hb_barrier (); return format.static_size + u.format3.get_size (); + case 4: hb_barrier (); return format.static_size + u.format4.get_size (); default:return 0; } } @@ -78,9 +76,9 @@ struct CFF2FDSelect switch (format) { - case 0: return u.format0.get_fd (glyph); - case 3: return u.format3.get_fd (glyph); - case 4: return u.format4.get_fd (glyph); + case 0: hb_barrier (); return u.format0.get_fd (glyph); + case 3: hb_barrier (); return u.format3.get_fd (glyph); + case 4: hb_barrier (); return u.format4.get_fd (glyph); default:return 0; } } @@ -90,12 +88,13 @@ struct CFF2FDSelect TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (format) { - case 0: return_trace (u.format0.sanitize (c, fdcount)); - case 3: return_trace (u.format3.sanitize (c, fdcount)); - case 4: return_trace (u.format4.sanitize (c, fdcount)); + case 0: hb_barrier (); return_trace (u.format0.sanitize (c, fdcount)); + case 3: hb_barrier (); return_trace (u.format3.sanitize (c, fdcount)); + case 4: hb_barrier (); return_trace (u.format4.sanitize (c, fdcount)); default:return_trace (false); } } @@ -110,19 +109,22 @@ struct CFF2FDSelect DEFINE_SIZE_MIN (2); }; -struct CFF2VariationStore +struct CFF2ItemVariationStore { bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this)) && c->check_range (&varStore, size) && varStore.sanitize (c)); + return_trace (c->check_struct (this) && + hb_barrier () && + c->check_range (&varStore, size) && + varStore.sanitize (c)); } - bool serialize (hb_serialize_context_t *c, const CFF2VariationStore *varStore) + bool serialize (hb_serialize_context_t *c, const CFF2ItemVariationStore *varStore) { TRACE_SERIALIZE (this); unsigned int size_ = varStore->get_size (); - CFF2VariationStore *dest = c->allocate_size (size_); + CFF2ItemVariationStore *dest = c->allocate_size (size_); if (unlikely (!dest)) return_trace (false); hb_memcpy (dest, varStore, size_); return_trace (true); @@ -131,9 +133,9 @@ struct CFF2VariationStore unsigned int get_size () const { return HBUINT16::static_size + size; } HBUINT16 size; - VariationStore varStore; + ItemVariationStore varStore; - DEFINE_SIZE_MIN (2 + VariationStore::min_size); + DEFINE_SIZE_MIN (2 + ItemVariationStore::min_size); }; struct cff2_top_dict_values_t : top_dict_values_t<> @@ -146,8 +148,8 @@ struct cff2_top_dict_values_t : top_dict_values_t<> } void fini () { top_dict_values_t<>::fini (); } - unsigned int vstoreOffset; - unsigned int FDSelectOffset; + int vstoreOffset; + int FDSelectOffset; }; struct cff2_top_dict_opset_t : top_dict_opset_t<> @@ -165,11 +167,11 @@ struct cff2_top_dict_opset_t : top_dict_opset_t<> break; case OpCode_vstore: - dictval.vstoreOffset = env.argStack.pop_uint (); + dictval.vstoreOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FDSelect: - dictval.FDSelectOffset = env.argStack.pop_uint (); + dictval.FDSelectOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -237,7 +239,7 @@ struct cff2_private_dict_values_base_t : dict_values_t } void fini () { dict_values_t::fini (); } - unsigned int subrsOffset; + int subrsOffset; const CFF2Subrs *localSubrs; unsigned int ivs; }; @@ -291,7 +293,7 @@ struct cff2_private_dict_opset_t : dict_opset_t env.clear_args (); break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_vsindexdict: @@ -340,7 +342,7 @@ struct cff2_private_dict_opset_subset_t : dict_opset_t return; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -384,6 +386,7 @@ struct cff2 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 2)); } @@ -414,23 +417,22 @@ struct cff2 { /* parse top dict */ hb_ubytes_t topDictStr = (cff2 + cff2->topDict).as_ubytes (cff2->topDictSize); if (unlikely (!topDictStr.sanitize (&sc))) goto fail; + hb_barrier (); num_interp_env_t env (topDictStr); cff2_top_dict_interpreter_t top_interp (env); topDict.init (); if (unlikely (!top_interp.interpret (topDict))) goto fail; } - globalSubrs = &StructAtOffset (cff2, cff2->topDict + cff2->topDictSize); - varStore = &StructAtOffsetOrNull (cff2, topDict.vstoreOffset); - charStrings = &StructAtOffsetOrNull (cff2, topDict.charStringsOffset); - fdArray = &StructAtOffsetOrNull (cff2, topDict.FDArrayOffset); - fdSelect = &StructAtOffsetOrNull (cff2, topDict.FDSelectOffset); - - if (((varStore != &Null (CFF2VariationStore)) && unlikely (!varStore->sanitize (&sc))) || - (charStrings == &Null (CFF2CharStrings)) || unlikely (!charStrings->sanitize (&sc)) || - (globalSubrs == &Null (CFF2Subrs)) || unlikely (!globalSubrs->sanitize (&sc)) || - (fdArray == &Null (CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) || - (((fdSelect != &Null (CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count))))) + globalSubrs = &StructAtOffsetOrNull (cff2, cff2->topDict + cff2->topDictSize, sc); + varStore = &StructAtOffsetOrNull (cff2, topDict.vstoreOffset, sc); + charStrings = &StructAtOffsetOrNull (cff2, topDict.charStringsOffset, sc); + fdArray = &StructAtOffsetOrNull (cff2, topDict.FDArrayOffset, sc); + fdSelect = &StructAtOffsetOrNull (cff2, topDict.FDSelectOffset, sc, fdArray->count); + + if (charStrings == &Null (CFF2CharStrings) || + globalSubrs == &Null (CFF2Subrs) || + fdArray == &Null (CFF2FDArray)) goto fail; num_glyphs = charStrings->count; @@ -446,6 +448,7 @@ struct cff2 { const hb_ubytes_t fontDictStr = (*fdArray)[i]; if (unlikely (!fontDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff2_font_dict_values_t *font; num_interp_env_t env (fontDictStr); cff2_font_dict_interpreter_t font_interp (env); @@ -454,17 +457,14 @@ struct cff2 font->init (); if (unlikely (!font_interp.interpret (*font))) goto fail; - const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff2, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) goto fail; + const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff2, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); + if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; cff2_priv_dict_interp_env_t env2 (privDictStr); dict_interpreter_t priv_interp (env2); privateDicts[i].init (); if (unlikely (!priv_interp.interpret (privateDicts[i]))) goto fail; - privateDicts[i].localSubrs = &StructAtOffsetOrNull (&privDictStr[0], privateDicts[i].subrsOffset); - if (privateDicts[i].localSubrs != &Null (CFF2Subrs) && - unlikely (!privateDicts[i].localSubrs->sanitize (&sc))) - goto fail; + privateDicts[i].localSubrs = &StructAtOffsetOrNull (&privDictStr[0], privateDicts[i].subrsOffset, sc); } return; @@ -499,7 +499,7 @@ struct cff2 hb_blob_t *blob = nullptr; cff2_top_dict_values_t topDict; const CFF2Subrs *globalSubrs = nullptr; - const CFF2VariationStore *varStore = nullptr; + const CFF2ItemVariationStore *varStore = nullptr; const CFF2CharStrings *charStrings = nullptr; const CFF2FDArray *fdArray = nullptr; const CFF2FDSelect *fdSelect = nullptr; @@ -518,8 +518,8 @@ struct cff2 HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; - HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; + HB_INTERNAL bool get_path_at (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session, hb_array_t coords) const; }; struct accelerator_subset_t : accelerator_templ_t diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh index 7e6ced3df4c0d..249d4cac5db7b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh @@ -41,6 +41,148 @@ namespace OT { +static inline uint8_t unicode_to_macroman (hb_codepoint_t u) +{ + static const struct unicode_to_macroman_t + { + uint16_t unicode; + uint8_t macroman; + } + mapping[] = + { + { 0x00A0, 0xCA }, + { 0x00A1, 0xC1 }, + { 0x00A2, 0xA2 }, + { 0x00A3, 0xA3 }, + { 0x00A5, 0xB4 }, + { 0x00A7, 0xA4 }, + { 0x00A8, 0xAC }, + { 0x00A9, 0xA9 }, + { 0x00AA, 0xBB }, + { 0x00AB, 0xC7 }, + { 0x00AC, 0xC2 }, + { 0x00AE, 0xA8 }, + { 0x00AF, 0xF8 }, + { 0x00B0, 0xA1 }, + { 0x00B1, 0xB1 }, + { 0x00B4, 0xAB }, + { 0x00B5, 0xB5 }, + { 0x00B6, 0xA6 }, + { 0x00B7, 0xE1 }, + { 0x00B8, 0xFC }, + { 0x00BA, 0xBC }, + { 0x00BB, 0xC8 }, + { 0x00BF, 0xC0 }, + { 0x00C0, 0xCB }, + { 0x00C1, 0xE7 }, + { 0x00C2, 0xE5 }, + { 0x00C3, 0xCC }, + { 0x00C4, 0x80 }, + { 0x00C5, 0x81 }, + { 0x00C6, 0xAE }, + { 0x00C7, 0x82 }, + { 0x00C8, 0xE9 }, + { 0x00C9, 0x83 }, + { 0x00CA, 0xE6 }, + { 0x00CB, 0xE8 }, + { 0x00CC, 0xED }, + { 0x00CD, 0xEA }, + { 0x00CE, 0xEB }, + { 0x00CF, 0xEC }, + { 0x00D1, 0x84 }, + { 0x00D2, 0xF1 }, + { 0x00D3, 0xEE }, + { 0x00D4, 0xEF }, + { 0x00D5, 0xCD }, + { 0x00D6, 0x85 }, + { 0x00D8, 0xAF }, + { 0x00D9, 0xF4 }, + { 0x00DA, 0xF2 }, + { 0x00DB, 0xF3 }, + { 0x00DC, 0x86 }, + { 0x00DF, 0xA7 }, + { 0x00E0, 0x88 }, + { 0x00E1, 0x87 }, + { 0x00E2, 0x89 }, + { 0x00E3, 0x8B }, + { 0x00E4, 0x8A }, + { 0x00E5, 0x8C }, + { 0x00E6, 0xBE }, + { 0x00E7, 0x8D }, + { 0x00E8, 0x8F }, + { 0x00E9, 0x8E }, + { 0x00EA, 0x90 }, + { 0x00EB, 0x91 }, + { 0x00EC, 0x93 }, + { 0x00ED, 0x92 }, + { 0x00EE, 0x94 }, + { 0x00EF, 0x95 }, + { 0x00F1, 0x96 }, + { 0x00F2, 0x98 }, + { 0x00F3, 0x97 }, + { 0x00F4, 0x99 }, + { 0x00F5, 0x9B }, + { 0x00F6, 0x9A }, + { 0x00F7, 0xD6 }, + { 0x00F8, 0xBF }, + { 0x00F9, 0x9D }, + { 0x00FA, 0x9C }, + { 0x00FB, 0x9E }, + { 0x00FC, 0x9F }, + { 0x00FF, 0xD8 }, + { 0x0131, 0xF5 }, + { 0x0152, 0xCE }, + { 0x0153, 0xCF }, + { 0x0178, 0xD9 }, + { 0x0192, 0xC4 }, + { 0x02C6, 0xF6 }, + { 0x02C7, 0xFF }, + { 0x02D8, 0xF9 }, + { 0x02D9, 0xFA }, + { 0x02DA, 0xFB }, + { 0x02DB, 0xFE }, + { 0x02DC, 0xF7 }, + { 0x02DD, 0xFD }, + { 0x03A9, 0xBD }, + { 0x03C0, 0xB9 }, + { 0x2013, 0xD0 }, + { 0x2014, 0xD1 }, + { 0x2018, 0xD4 }, + { 0x2019, 0xD5 }, + { 0x201A, 0xE2 }, + { 0x201C, 0xD2 }, + { 0x201D, 0xD3 }, + { 0x201E, 0xE3 }, + { 0x2020, 0xA0 }, + { 0x2021, 0xE0 }, + { 0x2022, 0xA5 }, + { 0x2026, 0xC9 }, + { 0x2030, 0xE4 }, + { 0x2039, 0xDC }, + { 0x203A, 0xDD }, + { 0x2044, 0xDA }, + { 0x20AC, 0xDB }, + { 0x2122, 0xAA }, + { 0x2202, 0xB6 }, + { 0x2206, 0xC6 }, + { 0x220F, 0xB8 }, + { 0x2211, 0xB7 }, + { 0x221A, 0xC3 }, + { 0x221E, 0xB0 }, + { 0x222B, 0xBA }, + { 0x2248, 0xC5 }, + { 0x2260, 0xAD }, + { 0x2264, 0xB2 }, + { 0x2265, 0xB3 }, + { 0x25CA, 0xD7 }, + { 0xF8FF, 0xF0 }, + { 0xFB01, 0xDE }, + { 0xFB02, 0xDF }, + }; + auto *c = hb_bsearch (u, mapping, ARRAY_LENGTH (mapping), sizeof (mapping[0]), + _hb_cmp_operator); + return c ? c->macroman : 0; +} struct CmapSubtableFormat0 { @@ -556,6 +698,7 @@ struct CmapSubtableFormat4 TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); if (unlikely (!c->check_range (this, length))) { @@ -742,10 +885,11 @@ struct CmapSubtableLongSegmented unsigned num_glyphs) const { hb_codepoint_t last_end = 0; - for (unsigned i = 0; i < this->groups.len; i++) + unsigned count = this->groups.len; + for (unsigned i = 0; i < count; i++) { - hb_codepoint_t start = this->groups[i].startCharCode; - hb_codepoint_t end = hb_min ((hb_codepoint_t) this->groups[i].endCharCode, + hb_codepoint_t start = this->groups.arrayZ[i].startCharCode; + hb_codepoint_t end = hb_min ((hb_codepoint_t) this->groups.arrayZ[i].endCharCode, (hb_codepoint_t) HB_UNICODE_MAX); if (unlikely (start > end || start < last_end)) { // Range is not in order and is invalid, skip it. @@ -754,7 +898,7 @@ struct CmapSubtableLongSegmented last_end = end; - hb_codepoint_t gid = this->groups[i].glyphID; + hb_codepoint_t gid = this->groups.arrayZ[i].glyphID; if (!gid) { if (T::formatNumber == 13) continue; @@ -767,9 +911,9 @@ struct CmapSubtableLongSegmented mapping->alloc (mapping->get_population () + end - start + 1); + unicodes->add_range (start, end); for (unsigned cp = start; cp <= end; cp++) { - unicodes->add (cp); mapping->set (cp, gid); gid += T::increment; } @@ -1253,6 +1397,9 @@ struct CmapSubtableFormat14 hb_vector_t> obj_indices; for (int i = src_tbl->record.len - 1; i >= 0; i--) { + if (!unicodes->has(src_tbl->record[i].varSelector)) + continue; + hb_pair_t result = src_tbl->record[i].copy (c, unicodes, glyphs_requested, glyph_map, base); if (result.first || result.second) obj_indices.push (result); @@ -1309,6 +1456,7 @@ struct CmapSubtableFormat14 { + hb_iter (record) | hb_filter (hb_bool, &VariationSelectorRecord::nonDefaultUVS) + | hb_filter (unicodes, &VariationSelectorRecord::varSelector) | hb_map (&VariationSelectorRecord::nonDefaultUVS) | hb_map (hb_add (this)) | hb_apply ([=] (const NonDefaultUVS& _) { _.closure_glyphs (unicodes, glyphset); }) @@ -1353,12 +1501,12 @@ struct CmapSubtable hb_codepoint_t *glyph) const { switch (u.format) { - case 0: return u.format0 .get_glyph (codepoint, glyph); - case 4: return u.format4 .get_glyph (codepoint, glyph); - case 6: return u.format6 .get_glyph (codepoint, glyph); - case 10: return u.format10.get_glyph (codepoint, glyph); - case 12: return u.format12.get_glyph (codepoint, glyph); - case 13: return u.format13.get_glyph (codepoint, glyph); + case 0: hb_barrier (); return u.format0 .get_glyph (codepoint, glyph); + case 4: hb_barrier (); return u.format4 .get_glyph (codepoint, glyph); + case 6: hb_barrier (); return u.format6 .get_glyph (codepoint, glyph); + case 10: hb_barrier (); return u.format10.get_glyph (codepoint, glyph); + case 12: hb_barrier (); return u.format12.get_glyph (codepoint, glyph); + case 13: hb_barrier (); return u.format13.get_glyph (codepoint, glyph); case 14: default: return false; } @@ -1366,12 +1514,12 @@ struct CmapSubtable void collect_unicodes (hb_set_t *out, unsigned int num_glyphs = UINT_MAX) const { switch (u.format) { - case 0: u.format0 .collect_unicodes (out); return; - case 4: u.format4 .collect_unicodes (out); return; - case 6: u.format6 .collect_unicodes (out); return; - case 10: u.format10.collect_unicodes (out); return; - case 12: u.format12.collect_unicodes (out, num_glyphs); return; - case 13: u.format13.collect_unicodes (out, num_glyphs); return; + case 0: hb_barrier (); u.format0 .collect_unicodes (out); return; + case 4: hb_barrier (); u.format4 .collect_unicodes (out); return; + case 6: hb_barrier (); u.format6 .collect_unicodes (out); return; + case 10: hb_barrier (); u.format10.collect_unicodes (out); return; + case 12: hb_barrier (); u.format12.collect_unicodes (out, num_glyphs); return; + case 13: hb_barrier (); u.format13.collect_unicodes (out, num_glyphs); return; case 14: default: return; } @@ -1382,12 +1530,12 @@ struct CmapSubtable unsigned num_glyphs = UINT_MAX) const { switch (u.format) { - case 0: u.format0 .collect_mapping (unicodes, mapping); return; - case 4: u.format4 .collect_mapping (unicodes, mapping); return; - case 6: u.format6 .collect_mapping (unicodes, mapping); return; - case 10: u.format10.collect_mapping (unicodes, mapping); return; - case 12: u.format12.collect_mapping (unicodes, mapping, num_glyphs); return; - case 13: u.format13.collect_mapping (unicodes, mapping, num_glyphs); return; + case 0: hb_barrier (); u.format0 .collect_mapping (unicodes, mapping); return; + case 4: hb_barrier (); u.format4 .collect_mapping (unicodes, mapping); return; + case 6: hb_barrier (); u.format6 .collect_mapping (unicodes, mapping); return; + case 10: hb_barrier (); u.format10.collect_mapping (unicodes, mapping); return; + case 12: hb_barrier (); u.format12.collect_mapping (unicodes, mapping, num_glyphs); return; + case 13: hb_barrier (); u.format13.collect_mapping (unicodes, mapping, num_glyphs); return; case 14: default: return; } @@ -1396,12 +1544,12 @@ struct CmapSubtable unsigned get_language () const { switch (u.format) { - case 0: return u.format0 .get_language (); - case 4: return u.format4 .get_language (); - case 6: return u.format6 .get_language (); - case 10: return u.format10.get_language (); - case 12: return u.format12.get_language (); - case 13: return u.format13.get_language (); + case 0: hb_barrier (); return u.format0 .get_language (); + case 4: hb_barrier (); return u.format4 .get_language (); + case 6: hb_barrier (); return u.format6 .get_language (); + case 10: hb_barrier (); return u.format10.get_language (); + case 12: hb_barrier (); return u.format12.get_language (); + case 13: hb_barrier (); return u.format13.get_language (); case 14: default: return 0; } @@ -1416,9 +1564,9 @@ struct CmapSubtable const void *base) { switch (format) { - case 4: return u.format4.serialize (c, it); - case 12: return u.format12.serialize (c, it); - case 14: return u.format14.serialize (c, &plan->unicodes, &plan->glyphs_requested, plan->glyph_map, base); + case 4: hb_barrier (); return u.format4.serialize (c, it); + case 12: hb_barrier (); return u.format12.serialize (c, it); + case 14: hb_barrier (); return u.format14.serialize (c, &plan->unicodes, &plan->glyphs_requested, plan->glyph_map, base); default: return; } } @@ -1427,14 +1575,15 @@ struct CmapSubtable { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { - case 0: return_trace (u.format0 .sanitize (c)); - case 4: return_trace (u.format4 .sanitize (c)); - case 6: return_trace (u.format6 .sanitize (c)); - case 10: return_trace (u.format10.sanitize (c)); - case 12: return_trace (u.format12.sanitize (c)); - case 13: return_trace (u.format13.sanitize (c)); - case 14: return_trace (u.format14.sanitize (c)); + case 0: hb_barrier (); return_trace (u.format0 .sanitize (c)); + case 4: hb_barrier (); return_trace (u.format4 .sanitize (c)); + case 6: hb_barrier (); return_trace (u.format6 .sanitize (c)); + case 10: hb_barrier (); return_trace (u.format10.sanitize (c)); + case 12: hb_barrier (); return_trace (u.format12.sanitize (c)); + case 13: hb_barrier (); return_trace (u.format13.sanitize (c)); + case 14: hb_barrier (); return_trace (u.format14.sanitize (c)); default:return_trace (true); } } @@ -1462,8 +1611,11 @@ struct EncodingRecord int ret; ret = platformID.cmp (other.platformID); if (ret) return ret; - ret = encodingID.cmp (other.encodingID); - if (ret) return ret; + if (other.encodingID != 0xFFFF) + { + ret = encodingID.cmp (other.encodingID); + if (ret) return ret; + } return 0; } @@ -1811,9 +1963,13 @@ struct cmap c->plan)); } - const CmapSubtable *find_best_subtable (bool *symbol = nullptr) const + const CmapSubtable *find_best_subtable (bool *symbol = nullptr, + bool *mac = nullptr, + bool *macroman = nullptr) const { if (symbol) *symbol = false; + if (mac) *mac = false; + if (macroman) *macroman = false; const CmapSubtable *subtable; @@ -1838,6 +1994,20 @@ struct cmap if ((subtable = this->find_subtable (0, 1))) return subtable; if ((subtable = this->find_subtable (0, 0))) return subtable; + /* MacRoman subtable. */ + if ((subtable = this->find_subtable (1, 0))) + { + if (mac) *mac = true; + if (macroman) *macroman = true; + return subtable; + } + /* Any other Mac subtable; we just map ASCII for these. */ + if ((subtable = this->find_subtable (1, 0xFFFF))) + { + if (mac) *mac = true; + return subtable; + } + /* Meh. */ return &Null (CmapSubtable); } @@ -1849,8 +2019,8 @@ struct cmap accelerator_t (hb_face_t *face) { this->table = hb_sanitize_context_t ().reference_table (face); - bool symbol; - this->subtable = table->find_best_subtable (&symbol); + bool symbol, mac, macroman; + this->subtable = table->find_best_subtable (&symbol, &mac, ¯oman); this->subtable_uvs = &Null (CmapSubtableFormat14); { const CmapSubtable *st = table->find_subtable (0, 5); @@ -1859,6 +2029,7 @@ struct cmap } this->get_glyph_data = subtable; +#ifndef HB_NO_CMAP_LEGACY_SUBTABLES if (unlikely (symbol)) { switch ((unsigned) face->table.OS2->get_font_page ()) { @@ -1878,7 +2049,16 @@ struct cmap break; } } + else if (unlikely (macroman)) + { + this->get_glyph_funcZ = get_glyph_from_macroman; + } + else if (unlikely (mac)) + { + this->get_glyph_funcZ = get_glyph_from_ascii; + } else +#endif { switch (subtable->u.format) { /* Accelerate format 4 and format 12. */ @@ -1921,7 +2101,7 @@ struct cmap hb_codepoint_t *glyph, cache_t *cache = nullptr) const { - if (unlikely (!this->get_glyph_funcZ)) return 0; + if (unlikely (!this->get_glyph_funcZ)) return false; return _cached_get (unicode, glyph, cache); } @@ -2003,6 +2183,28 @@ struct cmap return false; } + template + HB_INTERNAL static bool get_glyph_from_ascii (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph) + { + const Type *typed_obj = (const Type *) obj; + return codepoint < 0x80 && typed_obj->get_glyph (codepoint, glyph); + } + + template + HB_INTERNAL static bool get_glyph_from_macroman (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph) + { + if (get_glyph_from_ascii (obj, codepoint, glyph)) + return true; + + const Type *typed_obj = (const Type *) obj; + unsigned c = unicode_to_macroman (codepoint); + return c && typed_obj->get_glyph (c, glyph); + } + private: hb_nonnull_ptr_t subtable; hb_nonnull_ptr_t subtable_uvs; @@ -2032,34 +2234,13 @@ struct cmap return &(this+result.subtable); } - const EncodingRecord *find_encodingrec (unsigned int platform_id, - unsigned int encoding_id) const - { - EncodingRecord key; - key.platformID = platform_id; - key.encodingID = encoding_id; - - return encodingRecord.as_array ().bsearch (key); - } - - bool find_subtable (unsigned format) const - { - auto it = - + hb_iter (encodingRecord) - | hb_map (&EncodingRecord::subtable) - | hb_map (hb_add (this)) - | hb_filter ([&] (const CmapSubtable& _) { return _.u.format == format; }) - ; - - return it.len (); - } - public: bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version == 0) && encodingRecord.sanitize (c, this)); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh index b552dfdd9daed..97825f4d19c75 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh @@ -95,12 +95,18 @@ HB_OT_CORE_TABLE (OT, fvar) HB_OT_CORE_TABLE (OT, avar) HB_OT_CORE_TABLE (OT, cvar) HB_OT_ACCELERATOR (OT, gvar) +#ifndef HB_NO_BEYOND_64K +HB_OT_ACCELERATOR (OT, GVAR) +#endif HB_OT_CORE_TABLE (OT, MVAR) +#ifndef HB_NO_VAR_COMPOSITES +HB_OT_ACCELERATOR (OT, VARC) +#endif #endif /* Legacy kern. */ #ifndef HB_NO_OT_KERN -HB_OT_CORE_TABLE (OT, kern) +HB_OT_ACCELERATOR (OT, kern) #endif /* OpenType shaping. */ @@ -118,9 +124,9 @@ HB_OT_CORE_TABLE (OT, BASE) /* AAT shaping. */ #ifndef HB_NO_AAT -HB_OT_TABLE (AAT, morx) -HB_OT_TABLE (AAT, mort) -HB_OT_TABLE (AAT, kerx) +HB_OT_ACCELERATOR (AAT, morx) +HB_OT_ACCELERATOR (AAT, mort) +HB_OT_ACCELERATOR (AAT, kerx) HB_OT_TABLE (AAT, ankr) HB_OT_TABLE (AAT, trak) HB_OT_TABLE (AAT, ltag) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc index 2243ee0287414..1cf14f3ebc62a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc @@ -41,6 +41,9 @@ #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" +#include "hb-ot-var-varc-table.hh" +#include "hb-aat-layout-kerx-table.hh" +#include "hb-aat-layout-morx-table.hh" void hb_ot_face_t::init0 (hb_face_t *face) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc index deec909b22e79..2a633c7781665 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc @@ -36,13 +36,17 @@ #include "hb-ot-face.hh" #include "hb-outline.hh" +#ifndef HB_NO_AAT +#include "hb-aat-layout-trak-table.hh" +#endif #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-cff2-table.hh" #include "hb-ot-cff1-table.hh" #include "hb-ot-hmtx-table.hh" #include "hb-ot-post-table.hh" -#include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise. +#include "hb-ot-stat-table.hh" +#include "hb-ot-var-varc-table.hh" #include "hb-ot-vorg-table.hh" #include "OT/Color/CBDT/CBDT.hh" #include "OT/Color/COLR/COLR.hh" @@ -72,6 +76,10 @@ struct hb_ot_font_t { const hb_ot_face_t *ot_face; +#ifndef HB_NO_AAT + bool apply_trak; +#endif + #ifndef HB_NO_OT_FONT_CMAP_CACHE hb_ot_font_cmap_cache_t *cmap_cache; #endif @@ -90,6 +98,15 @@ _hb_ot_font_create (hb_font_t *font) ot_font->ot_face = &font->face->table; +#ifndef HB_NO_AAT + /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ +#ifndef HB_NO_STYLE + ot_font->apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); +#else + ot_font->apply_trak = false; +#endif +#endif + #ifndef HB_NO_OT_FONT_CMAP_CACHE // retry: auto *cmap_cache = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face, @@ -199,7 +216,6 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { - const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; @@ -208,12 +224,12 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) const OT::HVAR &HVAR = *hmtx.var_table; - const OT::VariationStore &varStore = &HVAR + HVAR.varStore; - OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr; + const OT::ItemVariationStore &varStore = &HVAR + HVAR.varStore; + OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr; bool use_cache = font->num_coords; #else - OT::VariationStore::cache_t *varStore_cache = nullptr; + OT::ItemVariationStore::cache_t *varStore_cache = nullptr; bool use_cache = false; #endif @@ -277,7 +293,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, } #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - OT::VariationStore::destroy_cache (varStore_cache); + OT::ItemVariationStore::destroy_cache (varStore_cache); #endif if (font->x_strength && !font->embolden_in_place) @@ -291,6 +307,20 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } } + +#ifndef HB_NO_AAT + if (ot_font->apply_trak) + { + hb_position_t tracking = font->face->table.trak->get_h_tracking (font); + first_advance = orig_first_advance; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += tracking; + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } +#endif } #ifndef HB_NO_VERTICAL @@ -313,10 +343,10 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, { #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) const OT::VVAR &VVAR = *vmtx.var_table; - const OT::VariationStore &varStore = &VVAR + VVAR.varStore; - OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; + const OT::ItemVariationStore &varStore = &VVAR + VVAR.varStore; + OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; #else - OT::VariationStore::cache_t *varStore_cache = nullptr; + OT::ItemVariationStore::cache_t *varStore_cache = nullptr; #endif for (unsigned int i = 0; i < count; i++) @@ -327,7 +357,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, } #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - OT::VariationStore::destroy_cache (varStore_cache); + OT::ItemVariationStore::destroy_cache (varStore_cache); #endif } else @@ -355,6 +385,20 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } } + +#ifndef HB_NO_AAT + if (ot_font->apply_trak) + { + hb_position_t tracking = font->face->table.trak->get_v_tracking (font); + first_advance = orig_first_advance; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += tracking; + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } +#endif } #endif @@ -523,6 +567,10 @@ hb_ot_draw_glyph (hb_font_t *font, { // Need draw_session to be destructed before emboldening. hb_draw_session_t draw_session (embolden ? hb_outline_recording_pen_get_funcs () : draw_funcs, embolden ? &outline : draw_data, font->slant_xy); +#ifndef HB_NO_VAR_COMPOSITES + if (!font->face->table.VARC->get_path (font, glyph, draw_session)) +#endif + // Keep the following in synch with VARC::get_path_at() if (!font->face->table.glyf->get_path (font, glyph, draw_session)) #ifndef HB_NO_CFF if (!font->face->table.cff2->get_path (font, glyph, draw_session)) @@ -563,11 +611,11 @@ hb_ot_paint_glyph (hb_font_t *font, if (font->face->table.sbix->paint_glyph (font, glyph, paint_funcs, paint_data)) return; #endif #endif - if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; -#ifndef HB_NO_CFF - if (font->face->table.cff2->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; - if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; -#endif + + // Outline glyph + paint_funcs->push_clip_glyph (paint_data, glyph, font); + paint_funcs->color (paint_data, true, foreground); + paint_funcs->pop_clip (paint_data); } #endif @@ -634,7 +682,9 @@ _hb_ot_get_font_funcs () * hb_ot_font_set_funcs: * @font: #hb_font_t to work upon * - * Sets the font functions to use when working with @font. + * Sets the font functions to use when working with @font to + * the HarfBuzz's native implementation. This is the default + * for fonts newly created. * * Since: 0.9.28 **/ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh index 77e68dbca42ef..918cf32dcb5fc 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh @@ -71,6 +71,7 @@ struct DeviceRecord { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && c->check_range (this, sizeDeviceRecord))); } @@ -94,7 +95,7 @@ struct hdmx bool serialize (hb_serialize_context_t *c, unsigned version, Iterator it, - const hb_vector_t &new_to_old_gid_list, + hb_array_t new_to_old_gid_list, unsigned num_glyphs) { TRACE_SERIALIZE (this); @@ -152,6 +153,7 @@ struct hdmx { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && !hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) && min_size + numRecords * sizeDeviceRecord > numRecords * sizeDeviceRecord && sizeDeviceRecord >= DeviceRecord::min_size && diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh index ab057fcfe4f10..34535e2286d82 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh @@ -103,6 +103,7 @@ struct head { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && version.major == 1 && magicNumber == 0x5F0F3CF5u); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-hhea-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-hhea-table.hh index 37ef8744572d3..5e3be5be525ba 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-hhea-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-hhea-table.hh @@ -50,7 +50,9 @@ struct _hea bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && likely (version.major == 1)); + return_trace (c->check_struct (this) && + hb_barrier () && + likely (version.major == 1)); } public: diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh index 39e1f4830a588..f7b4ca721984c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh @@ -30,6 +30,7 @@ #include "hb-open-type.hh" #include "hb-ot-maxp-table.hh" #include "hb-ot-hhea-table.hh" +#include "hb-ot-os2-table.hh" #include "hb-ot-var-hvar-table.hh" #include "hb-ot-var-mvar-table.hh" #include "hb-ot-metrics.hh" @@ -145,6 +146,29 @@ struct hmtxvmtx table->minTrailingBearing = min_rsb; table->maxExtent = max_extent; } + + if (T::is_horizontal) + { + const auto &OS2 = *c->plan->source->table.OS2; + if (OS2.has_data () && + table->ascender == OS2.sTypoAscender && + table->descender == OS2.sTypoDescender && + table->lineGap == OS2.sTypoLineGap) + { + table->ascender = static_cast (roundf (OS2.sTypoAscender + + MVAR.get_var (HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, + c->plan->normalized_coords.arrayZ, + c->plan->normalized_coords.length))); + table->descender = static_cast (roundf (OS2.sTypoDescender + + MVAR.get_var (HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, + c->plan->normalized_coords.arrayZ, + c->plan->normalized_coords.length))); + table->lineGap = static_cast (roundf (OS2.sTypoLineGap + + MVAR.get_var (HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, + c->plan->normalized_coords.arrayZ, + c->plan->normalized_coords.length))); + } + } } #endif @@ -158,7 +182,7 @@ struct hmtxvmtx hb_requires (hb_is_iterator (Iterator))> void serialize (hb_serialize_context_t *c, Iterator it, - const hb_vector_t new_to_old_gid_list, + hb_array_t new_to_old_gid_list, unsigned num_long_metrics, unsigned total_num_metrics) { @@ -374,7 +398,7 @@ struct hmtxvmtx unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, hb_font_t *font, - VariationStore::cache_t *store_cache = nullptr) const + ItemVariationStore::cache_t *store_cache = nullptr) const { unsigned int advance = get_advance_without_var_unscaled (glyph); @@ -387,7 +411,8 @@ struct hmtxvmtx font->coords, font->num_coords, store_cache)); - return _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx); + unsigned glyf_advance = _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx); + return glyf_advance ? glyf_advance : advance; #else return advance; #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh index 291683369aa35..bc90c345d0556 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh @@ -79,12 +79,23 @@ struct KernSubTableFormat3 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_range (kernValueZ, kernValueCount * sizeof (FWORD) + glyphCount * 2 + leftClassCount * rightClassCount)); } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + set_t set; + if (likely (glyphCount)) + set.add_range (0, glyphCount - 1); + left_set.union_ (set); + right_set.union_ (set); + } + protected: KernSubTableHeader header; @@ -121,7 +132,7 @@ struct KernSubTable { switch (get_type ()) { /* This method hooks up to hb_font_t's get_h_kerning. Only support Format0. */ - case 0: return u.format0.get_kerning (left, right); + case 0: hb_barrier (); return u.format0.get_kerning (left, right); default:return 0; } } @@ -134,22 +145,36 @@ struct KernSubTable switch (subtable_type) { case 0: return_trace (c->dispatch (u.format0)); #ifndef HB_NO_AAT_SHAPE - case 1: return_trace (u.header.apple ? c->dispatch (u.format1, std::forward (ds)...) : c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); #endif case 2: return_trace (c->dispatch (u.format2)); #ifndef HB_NO_AAT_SHAPE - case 3: return_trace (u.header.apple ? c->dispatch (u.format3, std::forward (ds)...) : c->default_return_value ()); + case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); #endif default: return_trace (c->default_return_value ()); } } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + unsigned int subtable_type = get_type (); + switch (subtable_type) { + case 0: u.format0.collect_glyphs (left_set, right_set, num_glyphs); return; + case 1: u.format1.collect_glyphs (left_set, right_set, num_glyphs); return; + case 2: u.format2.collect_glyphs (left_set, right_set, num_glyphs); return; + case 3: u.format3.collect_glyphs (left_set, right_set, num_glyphs); return; + default: return; + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!u.header.sanitize (c) || - u.header.length < u.header.min_size || - !c->check_range (this, u.header.length))) return_trace (false); + if (unlikely (!(u.header.sanitize (c) && + hb_barrier () && + u.header.length >= u.header.min_size && + c->check_range (this, u.header.length)))) return_trace (false); return_trace (dispatch (c)); } @@ -286,9 +311,9 @@ struct kern bool has_state_machine () const { switch (get_type ()) { - case 0: return u.ot.has_state_machine (); + case 0: hb_barrier (); return u.ot.has_state_machine (); #ifndef HB_NO_AAT_SHAPE - case 1: return u.aat.has_state_machine (); + case 1: hb_barrier (); return u.aat.has_state_machine (); #endif default:return false; } @@ -297,9 +322,9 @@ struct kern bool has_cross_stream () const { switch (get_type ()) { - case 0: return u.ot.has_cross_stream (); + case 0: hb_barrier (); return u.ot.has_cross_stream (); #ifndef HB_NO_AAT_SHAPE - case 1: return u.aat.has_cross_stream (); + case 1: hb_barrier (); return u.aat.has_cross_stream (); #endif default:return false; } @@ -308,16 +333,17 @@ struct kern int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const { switch (get_type ()) { - case 0: return u.ot.get_h_kerning (left, right); + case 0: hb_barrier (); return u.ot.get_h_kerning (left, right); #ifndef HB_NO_AAT_SHAPE - case 1: return u.aat.get_h_kerning (left, right); + case 1: hb_barrier (); return u.aat.get_h_kerning (left, right); #endif default:return 0; } } - bool apply (AAT::hb_aat_apply_context_t *c) const - { return dispatch (c); } + bool apply (AAT::hb_aat_apply_context_t *c, + const AAT::kern_accelerator_data_t &accel_data) const + { return dispatch (c, accel_data); } template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const @@ -337,9 +363,45 @@ struct kern { TRACE_SANITIZE (this); if (!u.version32.sanitize (c)) return_trace (false); + hb_barrier (); return_trace (dispatch (c)); } + AAT::kern_accelerator_data_t create_accelerator_data (unsigned num_glyphs) const + { + switch (get_type ()) { + case 0: hb_barrier (); return u.ot.create_accelerator_data (num_glyphs); +#ifndef HB_NO_AAT_SHAPE + case 1: hb_barrier (); return u.aat.create_accelerator_data (num_glyphs); +#endif + default:return AAT::kern_accelerator_data_t (); + } + } + + struct accelerator_t + { + accelerator_t (hb_face_t *face) + { + hb_sanitize_context_t sc; + this->table = sc.reference_table (face); + this->accel_data = this->table->create_accelerator_data (face->get_num_glyphs ()); + } + ~accelerator_t () + { + this->table.destroy (); + } + + hb_blob_t *get_blob () const { return table.get_blob (); } + + bool apply (AAT::hb_aat_apply_context_t *c) const + { + return table->apply (c, accel_data); + } + + hb_blob_ptr_t table; + AAT::kern_accelerator_data_t accel_data; + }; + protected: union { HBUINT32 version32; @@ -353,6 +415,10 @@ struct kern DEFINE_SIZE_UNION (4, version32); }; +struct kern_accelerator_t : kern::accelerator_t { + kern_accelerator_t (hb_face_t *face) : kern::accelerator_t (face) {} +}; + } /* namespace OT */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh index 0e57a6c790994..5a3679e4bfa29 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh @@ -46,6 +46,12 @@ struct BaseCoordFormat1 return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (coordinate) : font->em_scale_x (coordinate); } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + return_trace ((bool) c->serializer->embed (*this)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -67,6 +73,17 @@ struct BaseCoordFormat2 return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (coordinate) : font->em_scale_x (coordinate); } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (c->serializer->check_assign (out->referenceGlyph, + c->plan->glyph_map->get (referenceGlyph), + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -86,7 +103,7 @@ struct BaseCoordFormat2 struct BaseCoordFormat3 { hb_position_t get_coord (hb_font_t *font, - const VariationStore &var_store, + const ItemVariationStore &var_store, hb_direction_t direction) const { const Device &device = this+deviceTable; @@ -96,6 +113,37 @@ struct BaseCoordFormat3 : font->em_scale_x (coordinate) + device.get_x_delta (font, var_store); } + void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const + { + unsigned varidx = (this+deviceTable).get_variation_index (); + varidx_set.add (varidx); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + if (!c->plan->pinned_at_default) + { + unsigned var_idx = (this+deviceTable).get_variation_index (); + if (var_idx != VarIdx::NO_VARIATION) + { + hb_pair_t *v; + if (!c->plan->base_variation_idx_map.has (var_idx, &v)) + return_trace (false); + + if (unlikely (!c->serializer->check_assign (out->coordinate, coordinate + hb_second (*v), + HB_SERIALIZE_ERROR_INT_OVERFLOW))) + return_trace (false); + } + } + return_trace (out->deviceTable.serialize_copy (c->serializer, deviceTable, + this, 0, + hb_serialize_context_t::Head, + &c->plan->base_variation_idx_map)); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -120,25 +168,47 @@ struct BaseCoord bool has_data () const { return u.format; } hb_position_t get_coord (hb_font_t *font, - const VariationStore &var_store, + const ItemVariationStore &var_store, hb_direction_t direction) const { switch (u.format) { - case 1: return u.format1.get_coord (font, direction); - case 2: return u.format2.get_coord (font, direction); - case 3: return u.format3.get_coord (font, var_store, direction); + case 1: hb_barrier (); return u.format1.get_coord (font, direction); + case 2: hb_barrier (); return u.format2.get_coord (font, direction); + case 3: hb_barrier (); return u.format3.get_coord (font, var_store, direction); default:return 0; } } + void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const + { + switch (u.format) { + case 3: hb_barrier (); u.format3.collect_variation_indices (varidx_set); + default:return; + } + } + + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format); + switch (u.format) { + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); + default:return_trace (c->default_return_value ()); + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); if (unlikely (!u.format.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.format) { - case 1: return_trace (u.format1.sanitize (c)); - case 2: return_trace (u.format2.sanitize (c)); - case 3: return_trace (u.format3.sanitize (c)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); + case 3: hb_barrier (); return_trace (u.format3.sanitize (c)); default:return_trace (false); } } @@ -160,12 +230,37 @@ struct FeatMinMaxRecord bool has_data () const { return tag; } + hb_tag_t get_feature_tag () const { return tag; } + void get_min_max (const BaseCoord **min, const BaseCoord **max) const { if (likely (min)) *min = &(this+minCoord); if (likely (max)) *max = &(this+maxCoord); } + void collect_variation_indices (const hb_subset_plan_t* plan, + const void *base, + hb_set_t& varidx_set /* OUT */) const + { + if (!plan->layout_features.has (tag)) + return; + + (base+minCoord).collect_variation_indices (varidx_set); + (base+maxCoord).collect_variation_indices (varidx_set); + } + + bool subset (hb_subset_context_t *c, + const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + if (!(out->minCoord.serialize_subset (c, minCoord, base))) + return_trace (false); + + return_trace (out->maxCoord.serialize_subset (c, maxCoord, base)); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -205,6 +300,39 @@ struct MinMax } } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + (this+minCoord).collect_variation_indices (varidx_set); + (this+maxCoord).collect_variation_indices (varidx_set); + for (const FeatMinMaxRecord& record : featMinMaxRecords) + record.collect_variation_indices (plan, this, varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + if (!(out->minCoord.serialize_subset (c, minCoord, this)) || + !(out->maxCoord.serialize_subset (c, maxCoord, this))) + return_trace (false); + + unsigned len = 0; + for (const FeatMinMaxRecord& _ : featMinMaxRecords) + { + hb_tag_t feature_tag = _.get_feature_tag (); + if (!c->plan->layout_features.has (feature_tag)) + continue; + + if (!_.subset (c, this)) return false; + len++; + } + return_trace (c->serializer->check_assign (out->featMinMaxRecords.len, len, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -239,6 +367,26 @@ struct BaseValues return this+baseCoords[baseline_tag_index]; } + void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const + { + for (const auto& _ : baseCoords) + (this+_).collect_variation_indices (varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + out->defaultIndex = defaultIndex; + + for (const auto& _ : baseCoords) + if (!subset_offset_array (c, out->baseCoords, this) (_)) + return_trace (false); + + return_trace (bool (out->baseCoords)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -267,7 +415,22 @@ struct BaseLangSysRecord bool has_data () const { return baseLangSysTag; } - const MinMax &get_min_max () const { return this+minMax; } + const MinMax &get_min_max (const void* base) const { return base+minMax; } + + void collect_variation_indices (const void* base, + const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { (base+minMax).collect_variation_indices (plan, varidx_set); } + + bool subset (hb_subset_context_t *c, + const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->minMax.serialize_subset (c, minMax, base)); + } bool sanitize (hb_sanitize_context_t *c, const void *base) const { @@ -290,14 +453,43 @@ struct BaseScript const MinMax &get_min_max (hb_tag_t language_tag) const { const BaseLangSysRecord& record = baseLangSysRecords.bsearch (language_tag); - return record.has_data () ? record.get_min_max () : this+defaultMinMax; + return record.has_data () ? record.get_min_max (this) : this+defaultMinMax; } const BaseCoord &get_base_coord (int baseline_tag_index) const { return (this+baseValues).get_base_coord (baseline_tag_index); } bool has_values () const { return baseValues; } - bool has_min_max () const { return defaultMinMax; /* TODO What if only per-language is present? */ } + bool has_min_max () const { return defaultMinMax || baseLangSysRecords; } + + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + (this+baseValues).collect_variation_indices (varidx_set); + (this+defaultMinMax).collect_variation_indices (plan, varidx_set); + + for (const BaseLangSysRecord& _ : baseLangSysRecords) + _.collect_variation_indices (this, plan, varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + if (baseValues && !out->baseValues.serialize_subset (c, baseValues, this)) + return_trace (false); + + if (defaultMinMax && !out->defaultMinMax.serialize_subset (c, defaultMinMax, this)) + return_trace (false); + + for (const auto& _ : baseLangSysRecords) + if (!_.subset (c, this)) return_trace (false); + + return_trace (c->serializer->check_assign (out->baseLangSysRecords.len, baseLangSysRecords.len, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -331,9 +523,31 @@ struct BaseScriptRecord bool has_data () const { return baseScriptTag; } + hb_tag_t get_script_tag () const { return baseScriptTag; } + const BaseScript &get_base_script (const BaseScriptList *list) const { return list+baseScript; } + void collect_variation_indices (const hb_subset_plan_t* plan, + const void* list, + hb_set_t& varidx_set /* OUT */) const + { + if (!plan->layout_scripts.has (baseScriptTag)) + return; + + (list+baseScript).collect_variation_indices (plan, varidx_set); + } + + bool subset (hb_subset_context_t *c, + const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->baseScript.serialize_subset (c, baseScript, base)); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -360,6 +574,33 @@ struct BaseScriptList return record->has_data () ? record->get_base_script (this) : Null (BaseScript); } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + for (const BaseScriptRecord& _ : baseScriptRecords) + _.collect_variation_indices (plan, this, varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + unsigned len = 0; + for (const BaseScriptRecord& _ : baseScriptRecords) + { + hb_tag_t script_tag = _.get_script_tag (); + if (!c->plan->layout_scripts.has (script_tag)) + continue; + + if (!_.subset (c, this)) return false; + len++; + } + return_trace (c->serializer->check_assign (out->baseScriptRecords.len, len, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -421,6 +662,20 @@ struct Axis return true; } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { (this+baseScriptList).collect_variation_indices (plan, varidx_set); } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + out->baseTagList.serialize_copy (c->serializer, baseTagList, this); + return_trace (out->baseScriptList.serialize_subset (c, baseScriptList, this)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -452,8 +707,77 @@ struct BASE const Axis &get_axis (hb_direction_t direction) const { return HB_DIRECTION_IS_VERTICAL (direction) ? this+vAxis : this+hAxis; } - const VariationStore &get_var_store () const - { return version.to_int () < 0x00010001u ? Null (VariationStore) : this+varStore; } + bool has_var_store () const + { return version.to_int () >= 0x00010001u && varStore != 0; } + + const ItemVariationStore &get_var_store () const + { return version.to_int () < 0x00010001u ? Null (ItemVariationStore) : this+varStore; } + + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + (this+hAxis).collect_variation_indices (plan, varidx_set); + (this+vAxis).collect_variation_indices (plan, varidx_set); + } + + bool subset_varstore (hb_subset_context_t *c, + BASE *out /* OUT */) const + { + TRACE_SUBSET (this); + if (!c->serializer->allocate_size> (Offset32To::static_size)) + return_trace (false); + if (!c->plan->normalized_coords) + return_trace (out->varStore.serialize_subset (c, varStore, this, c->plan->base_varstore_inner_maps.as_array ())); + + if (c->plan->all_axes_pinned) + return_trace (true); + + item_variations_t item_vars; + if (!item_vars.instantiate (this+varStore, c->plan, true, true, + c->plan->base_varstore_inner_maps.as_array ())) + return_trace (false); + + if (!out->varStore.serialize_serialize (c->serializer, + item_vars.has_long_word (), + c->plan->axis_tags, + item_vars.get_region_list (), + item_vars.get_vardata_encodings ())) + return_trace (false); + + const hb_map_t &varidx_map = item_vars.get_varidx_map (); + /* base_variation_idx_map in the plan is old_varidx->(varidx, delta) + * mapping, new varidx is generated for subsetting, we need to remap this + * after instancing */ + for (auto _ : c->plan->base_variation_idx_map.iter_ref ()) + { + uint32_t varidx = _.second.first; + uint32_t *new_varidx; + if (varidx_map.has (varidx, &new_varidx)) + _.second.first = *new_varidx; + else + _.second.first = HB_OT_LAYOUT_NO_VARIATIONS_INDEX; + } + return_trace (true); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + out->version = version; + if (has_var_store () && !subset_varstore (c, out)) + return_trace (false); + + if (hAxis && !out->hAxis.serialize_subset (c, hAxis, this)) + return_trace (false); + + if (vAxis && !out->vAxis.serialize_subset (c, vAxis, this)) + return_trace (false); + + return_trace (true); + } bool get_baseline (hb_font_t *font, hb_tag_t baseline_tag, @@ -486,7 +810,7 @@ struct BASE &min_coord, &max_coord)) return false; - const VariationStore &var_store = get_var_store (); + const ItemVariationStore &var_store = get_var_store (); if (likely (min && min_coord)) *min = min_coord->get_coord (font, var_store, direction); if (likely (max && max_coord)) *max = max_coord->get_coord (font, var_store, direction); return true; @@ -496,6 +820,7 @@ struct BASE { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && likely (version.major == 1) && hAxis.sanitize (c, this) && vAxis.sanitize (c, this) && @@ -508,7 +833,7 @@ struct BASE * of BASE table (may be NULL) */ Offset16TovAxis; /* Offset to vertical Axis table, from beginning * of BASE table (may be NULL) */ - Offset32To + Offset32To varStore; /* Offset to the table of Item Variation * Store--from beginning of BASE * header (may be NULL). Introduced diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh index 9216a9a0fe70f..f14675295f620 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh @@ -34,6 +34,7 @@ #include "hb-open-type.hh" #include "hb-set.hh" #include "hb-bimap.hh" +#include "hb-cache.hh" #include "OT/Layout/Common/Coverage.hh" #include "OT/Layout/types.hh" @@ -64,7 +65,7 @@ struct hb_collect_feature_substitutes_with_var_context_t const hb_hashmap_t *axes_location; hb_hashmap_t> *record_cond_idx_map; hb_hashmap_t *feature_substitutes_map; - bool& insert_catch_all_feature_variation_record; + hb_set_t& catch_all_record_feature_idxes; // not stored in subset_plan hb_set_t *feature_indices; @@ -142,6 +143,8 @@ struct hb_subset_layout_context_t : const hb_map_t *feature_index_map; const hb_hashmap_t *feature_substitutes_map; hb_hashmap_t> *feature_record_cond_idx_map; + const hb_set_t *catch_all_record_feature_idxes; + const hb_hashmap_t> *feature_idx_tag_map; unsigned cur_script_index; unsigned cur_feature_var_record_idx; @@ -164,6 +167,8 @@ struct hb_subset_layout_context_t : feature_index_map = &c_->plan->gsub_features; feature_substitutes_map = &c_->plan->gsub_feature_substitutes_map; feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gsub_feature_record_cond_idx_map; + catch_all_record_feature_idxes = &c_->plan->gsub_old_features; + feature_idx_tag_map = &c_->plan->gsub_old_feature_idx_tag_map; } else { @@ -172,6 +177,8 @@ struct hb_subset_layout_context_t : feature_index_map = &c_->plan->gpos_features; feature_substitutes_map = &c_->plan->gpos_feature_substitutes_map; feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gpos_feature_record_cond_idx_map; + catch_all_record_feature_idxes = &c_->plan->gpos_old_features; + feature_idx_tag_map = &c_->plan->gpos_old_feature_idx_tag_map; } } @@ -182,7 +189,7 @@ struct hb_subset_layout_context_t : unsigned lookup_index_count; }; -struct VariationStore; +struct ItemVariationStore; struct hb_collect_variation_indices_context_t : hb_dispatch_context_t { @@ -454,6 +461,7 @@ struct FeatureParamsSize { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); /* This subtable has some "history", if you will. Some earlier versions of * Adobe tools calculated the offset of the FeatureParams subtable from the @@ -639,8 +647,7 @@ struct FeatureParamsCharacterVariants return; unsigned last_name_id = (unsigned) firstParamUILabelNameID + (unsigned) numNamedParameters - 1; - if (last_name_id >= 256 && last_name_id <= 32767) - nameids_to_retain->add_range (firstParamUILabelNameID, last_name_id); + nameids_to_retain->add_range (firstParamUILabelNameID, last_name_id); } bool subset (hb_subset_context_t *c) const @@ -820,6 +827,7 @@ struct Feature TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) return_trace (false); + hb_barrier (); /* Some earlier versions of Adobe tools calculated the offset of the * FeatureParams subtable from the beginning of the FeatureList table! @@ -838,6 +846,7 @@ struct Feature unsigned int orig_offset = featureParams; if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) return_trace (false); + hb_barrier (); if (featureParams == 0 && closure && closure->tag == HB_TAG ('s','i','z','e') && @@ -900,7 +909,8 @@ struct Record { TRACE_SANITIZE (this); const Record_sanitize_closure_t closure = {tag, base}; - return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure)); + return_trace (c->check_struct (this) && + offset.sanitize (c, base, &closure)); } Tag tag; /* 4-byte Tag identifier */ @@ -1371,10 +1381,20 @@ struct Lookup if (lookupFlag & LookupFlag::UseMarkFilteringSet) { - if (unlikely (!c->serializer->extend (out))) return_trace (false); const HBUINT16 &markFilteringSet = StructAfter (subTable); - HBUINT16 &outMarkFilteringSet = StructAfter (out->subTable); - outMarkFilteringSet = markFilteringSet; + hb_codepoint_t *idx; + if (!c->plan->used_mark_sets_map.has (markFilteringSet, &idx)) + { + unsigned new_flag = lookupFlag; + new_flag &= ~LookupFlag::UseMarkFilteringSet; + out->lookupFlag = new_flag; + } + else + { + if (unlikely (!c->serializer->extend (out))) return_trace (false); + HBUINT16 &outMarkFilteringSet = StructAfter (out->subTable); + outMarkFilteringSet = *idx; + } } // Always keep the lookup even if it's empty. The rest of layout subsetting depends on lookup @@ -1391,6 +1411,7 @@ struct Lookup { TRACE_SANITIZE (this); if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false); + hb_barrier (); unsigned subtables = get_subtable_count (); if (unlikely (!c->visit_subtables (subtables))) return_trace (false); @@ -1406,6 +1427,8 @@ struct Lookup if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ())) { + hb_barrier (); + /* The spec says all subtables of an Extension lookup should * have the same type, which shall not be the Extension type * itself (but we already checked for that). @@ -2045,24 +2068,33 @@ struct ClassDef unsigned int get_class (hb_codepoint_t glyph_id) const { switch (u.format) { - case 1: return u.format1.get_class (glyph_id); - case 2: return u.format2.get_class (glyph_id); + case 1: hb_barrier (); return u.format1.get_class (glyph_id); + case 2: hb_barrier (); return u.format2.get_class (glyph_id); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.get_class (glyph_id); - case 4: return u.format4.get_class (glyph_id); + case 3: hb_barrier (); return u.format3.get_class (glyph_id); + case 4: hb_barrier (); return u.format4.get_class (glyph_id); #endif default:return 0; } } + unsigned int get_class (hb_codepoint_t glyph_id, + hb_ot_lookup_cache_t *cache) const + { + unsigned klass; + if (cache && cache->get (glyph_id, &klass)) return klass; + klass = get_class (glyph_id); + if (cache) cache->set (glyph_id, klass); + return klass; + } unsigned get_population () const { switch (u.format) { - case 1: return u.format1.get_population (); - case 2: return u.format2.get_population (); + case 1: hb_barrier (); return u.format1.get_population (); + case 2: hb_barrier (); return u.format2.get_population (); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.get_population (); - case 4: return u.format4.get_population (); + case 3: hb_barrier (); return u.format3.get_population (); + case 4: hb_barrier (); return u.format4.get_population (); #endif default:return NOT_COVERED; } @@ -2124,11 +2156,11 @@ struct ClassDef switch (u.format) { - case 1: return_trace (u.format1.serialize (c, it)); - case 2: return_trace (u.format2.serialize (c, it)); + case 1: hb_barrier (); return_trace (u.format1.serialize (c, it)); + case 2: hb_barrier (); return_trace (u.format2.serialize (c, it)); #ifndef HB_NO_BEYOND_64K - case 3: return_trace (u.format3.serialize (c, it)); - case 4: return_trace (u.format4.serialize (c, it)); + case 3: hb_barrier (); return_trace (u.format3.serialize (c, it)); + case 4: hb_barrier (); return_trace (u.format4.serialize (c, it)); #endif default:return_trace (false); } @@ -2142,11 +2174,11 @@ struct ClassDef { TRACE_SUBSET (this); switch (u.format) { - case 1: return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); - case 2: return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); + case 1: hb_barrier (); return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); + case 2: hb_barrier (); return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); #ifndef HB_NO_BEYOND_64K - case 3: return_trace (u.format3.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); - case 4: return_trace (u.format4.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); + case 3: hb_barrier (); return_trace (u.format3.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); + case 4: hb_barrier (); return_trace (u.format4.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); #endif default:return_trace (false); } @@ -2156,12 +2188,13 @@ struct ClassDef { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { - case 1: return_trace (u.format1.sanitize (c)); - case 2: return_trace (u.format2.sanitize (c)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); #ifndef HB_NO_BEYOND_64K - case 3: return_trace (u.format3.sanitize (c)); - case 4: return_trace (u.format4.sanitize (c)); + case 3: hb_barrier (); return_trace (u.format3.sanitize (c)); + case 4: hb_barrier (); return_trace (u.format4.sanitize (c)); #endif default:return_trace (true); } @@ -2170,11 +2203,11 @@ struct ClassDef unsigned cost () const { switch (u.format) { - case 1: return u.format1.cost (); - case 2: return u.format2.cost (); + case 1: hb_barrier (); return u.format1.cost (); + case 2: hb_barrier (); return u.format2.cost (); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.cost (); - case 4: return u.format4.cost (); + case 3: hb_barrier (); return u.format3.cost (); + case 4: hb_barrier (); return u.format4.cost (); #endif default:return 0u; } @@ -2186,11 +2219,11 @@ struct ClassDef bool collect_coverage (set_t *glyphs) const { switch (u.format) { - case 1: return u.format1.collect_coverage (glyphs); - case 2: return u.format2.collect_coverage (glyphs); + case 1: hb_barrier (); return u.format1.collect_coverage (glyphs); + case 2: hb_barrier (); return u.format2.collect_coverage (glyphs); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.collect_coverage (glyphs); - case 4: return u.format4.collect_coverage (glyphs); + case 3: hb_barrier (); return u.format3.collect_coverage (glyphs); + case 4: hb_barrier (); return u.format4.collect_coverage (glyphs); #endif default:return false; } @@ -2202,11 +2235,11 @@ struct ClassDef bool collect_class (set_t *glyphs, unsigned int klass) const { switch (u.format) { - case 1: return u.format1.collect_class (glyphs, klass); - case 2: return u.format2.collect_class (glyphs, klass); + case 1: hb_barrier (); return u.format1.collect_class (glyphs, klass); + case 2: hb_barrier (); return u.format2.collect_class (glyphs, klass); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.collect_class (glyphs, klass); - case 4: return u.format4.collect_class (glyphs, klass); + case 3: hb_barrier (); return u.format3.collect_class (glyphs, klass); + case 4: hb_barrier (); return u.format4.collect_class (glyphs, klass); #endif default:return false; } @@ -2215,11 +2248,11 @@ struct ClassDef bool intersects (const hb_set_t *glyphs) const { switch (u.format) { - case 1: return u.format1.intersects (glyphs); - case 2: return u.format2.intersects (glyphs); + case 1: hb_barrier (); return u.format1.intersects (glyphs); + case 2: hb_barrier (); return u.format2.intersects (glyphs); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.intersects (glyphs); - case 4: return u.format4.intersects (glyphs); + case 3: hb_barrier (); return u.format3.intersects (glyphs); + case 4: hb_barrier (); return u.format4.intersects (glyphs); #endif default:return false; } @@ -2227,11 +2260,11 @@ struct ClassDef bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { switch (u.format) { - case 1: return u.format1.intersects_class (glyphs, klass); - case 2: return u.format2.intersects_class (glyphs, klass); + case 1: hb_barrier (); return u.format1.intersects_class (glyphs, klass); + case 2: hb_barrier (); return u.format2.intersects_class (glyphs, klass); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.intersects_class (glyphs, klass); - case 4: return u.format4.intersects_class (glyphs, klass); + case 3: hb_barrier (); return u.format3.intersects_class (glyphs, klass); + case 4: hb_barrier (); return u.format4.intersects_class (glyphs, klass); #endif default:return false; } @@ -2240,11 +2273,11 @@ struct ClassDef void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const { switch (u.format) { - case 1: return u.format1.intersected_class_glyphs (glyphs, klass, intersect_glyphs); - case 2: return u.format2.intersected_class_glyphs (glyphs, klass, intersect_glyphs); + case 1: hb_barrier (); return u.format1.intersected_class_glyphs (glyphs, klass, intersect_glyphs); + case 2: hb_barrier (); return u.format2.intersected_class_glyphs (glyphs, klass, intersect_glyphs); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.intersected_class_glyphs (glyphs, klass, intersect_glyphs); - case 4: return u.format4.intersected_class_glyphs (glyphs, klass, intersect_glyphs); + case 3: hb_barrier (); return u.format3.intersected_class_glyphs (glyphs, klass, intersect_glyphs); + case 4: hb_barrier (); return u.format4.intersected_class_glyphs (glyphs, klass, intersect_glyphs); #endif default:return; } @@ -2253,11 +2286,11 @@ struct ClassDef void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const { switch (u.format) { - case 1: return u.format1.intersected_classes (glyphs, intersect_classes); - case 2: return u.format2.intersected_classes (glyphs, intersect_classes); + case 1: hb_barrier (); return u.format1.intersected_classes (glyphs, intersect_classes); + case 2: hb_barrier (); return u.format2.intersected_classes (glyphs, intersect_classes); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.intersected_classes (glyphs, intersect_classes); - case 4: return u.format4.intersected_classes (glyphs, intersect_classes); + case 3: hb_barrier (); return u.format3.intersected_classes (glyphs, intersect_classes); + case 4: hb_barrier (); return u.format4.intersected_classes (glyphs, intersect_classes); #endif default:return; } @@ -2447,6 +2480,8 @@ struct VarRegionAxis int peak = peakCoord.to_int (); if (peak == 0 || coord == peak) return 1.f; + else if (coord == 0) // Faster + return 0.f; int start = startCoord.to_int (), end = endCoord.to_int (); @@ -2470,8 +2505,6 @@ struct VarRegionAxis { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); - /* TODO Handle invalid start/peak/end configs, so we don't - * have to do that at runtime. */ } bool serialize (hb_serialize_context_t *c) const @@ -2487,6 +2520,33 @@ struct VarRegionAxis public: DEFINE_SIZE_STATIC (6); }; +struct SparseVarRegionAxis +{ + float evaluate (const int *coords, unsigned int coord_len) const + { + unsigned i = axisIndex; + int coord = i < coord_len ? coords[i] : 0; + return axis.evaluate (coord); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + bool serialize (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + return_trace (c->embed (this)); + } + + public: + HBUINT16 axisIndex; + VarRegionAxis axis; + public: + DEFINE_SIZE_STATIC (8); +}; #define REGION_CACHE_ITEM_CACHE_INVALID 2.f @@ -2534,7 +2594,9 @@ struct VarRegionList bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && axesZ.sanitize (c, axisCount * regionCount)); + return_trace (c->check_struct (this) && + hb_barrier () && + axesZ.sanitize (c, axisCount * regionCount)); } bool serialize (hb_serialize_context_t *c, @@ -2615,7 +2677,7 @@ struct VarRegionList float max_val = axis_region->endCoord.to_float (); if (def_val != 0.f) - axis_tuples.set (*axis_tag, Triple (min_val, def_val, max_val)); + axis_tuples.set (*axis_tag, Triple ((double) min_val, (double) def_val, (double) max_val)); axis_region++; } return !axis_tuples.in_error (); @@ -2649,6 +2711,65 @@ struct VarRegionList DEFINE_SIZE_ARRAY (4, axesZ); }; +struct SparseVariationRegion : Array16Of +{ + float evaluate (const int *coords, unsigned int coord_len) const + { + float v = 1.f; + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + { + float factor = arrayZ[i].evaluate (coords, coord_len); + if (factor == 0.f) + return 0.; + v *= factor; + } + return v; + } +}; + +struct SparseVarRegionList +{ + using cache_t = float; + + float evaluate (unsigned int region_index, + const int *coords, unsigned int coord_len, + cache_t *cache = nullptr) const + { + if (unlikely (region_index >= regions.len)) + return 0.; + + float *cached_value = nullptr; + if (cache) + { + cached_value = &(cache[region_index]); + if (likely (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID)) + return *cached_value; + } + + const SparseVariationRegion ®ion = this+regions[region_index]; + + float v = region.evaluate (coords, coord_len); + + if (cache) + *cached_value = v; + return v; + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (regions.sanitize (c, this)); + } + + public: + Array16Of> + regions; + public: + DEFINE_SIZE_ARRAY (2, regions); +}; + + struct VarData { unsigned int get_item_count () const @@ -2728,6 +2849,7 @@ struct VarData TRACE_SANITIZE (this); return_trace (c->check_struct (this) && regionIndices.sanitize (c) && + hb_barrier () && wordCount () <= regionIndices.len && c->check_range (get_delta_bytes (), itemCount, @@ -3009,7 +3131,53 @@ struct VarData DEFINE_SIZE_ARRAY (6, regionIndices); }; -struct VariationStore +struct MultiVarData +{ + unsigned int get_size () const + { return min_size + - regionIndices.min_size + regionIndices.get_size () + + StructAfter (regionIndices).get_size (); + } + + void get_delta (unsigned int inner, + const int *coords, unsigned int coord_count, + const SparseVarRegionList ®ions, + hb_array_t out, + SparseVarRegionList::cache_t *cache = nullptr) const + { + auto &deltaSets = StructAfter (regionIndices); + + auto values_iter = deltaSets.fetcher (inner); + unsigned regionCount = regionIndices.len; + for (unsigned regionIndex = 0; regionIndex < regionCount; regionIndex++) + { + float scalar = regions.evaluate (regionIndices.arrayZ[regionIndex], + coords, coord_count, + cache); + values_iter.add_to (out, scalar); + } + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (format.sanitize (c) && + hb_barrier () && + format == 1 && + regionIndices.sanitize (c) && + hb_barrier () && + StructAfter (regionIndices).sanitize (c)); + } + + protected: + HBUINT8 format; // 1 + Array16Of regionIndices; + TupleList deltaSetsX; + public: + DEFINE_SIZE_MIN (8); +}; + +struct ItemVariationStore { friend struct item_variations_t; using cache_t = VarRegionList::cache_t; @@ -3061,7 +3229,7 @@ struct VariationStore return get_delta (outer, inner, coords, coord_count, cache); } float get_delta (unsigned int index, - hb_array_t coords, + hb_array_t coords, VarRegionList::cache_t *cache = nullptr) const { return get_delta (index, @@ -3077,6 +3245,7 @@ struct VariationStore TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && format == 1 && regions.sanitize (c, this) && dataSets.sanitize (c, this)); @@ -3113,7 +3282,7 @@ struct VariationStore } bool serialize (hb_serialize_context_t *c, - const VariationStore *src, + const ItemVariationStore *src, const hb_array_t &inner_maps) { TRACE_SERIALIZE (this); @@ -3169,7 +3338,7 @@ struct VariationStore return_trace (true); } - VariationStore *copy (hb_serialize_context_t *c) const + ItemVariationStore *copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); auto *out = c->start_embed (this); @@ -3180,6 +3349,8 @@ struct VariationStore for (unsigned i = 0; i < count; i++) { hb_inc_bimap_t *map = inner_maps.push (); + if (!c->propagate_error(inner_maps)) + return_trace(nullptr); auto &data = this+dataSets[i]; unsigned itemCount = data.get_item_count (); @@ -3199,7 +3370,7 @@ struct VariationStore return_trace (false); #endif - VariationStore *varstore_prime = c->serializer->start_embed (); + ItemVariationStore *varstore_prime = c->serializer->start_embed (); if (unlikely (!varstore_prime)) return_trace (false); varstore_prime->serialize (c->serializer, this, inner_maps); @@ -3265,8 +3436,370 @@ struct VariationStore DEFINE_SIZE_ARRAY_SIZED (8, dataSets); }; +struct MultiItemVariationStore +{ + using cache_t = SparseVarRegionList::cache_t; + + cache_t *create_cache (hb_array_t static_cache = hb_array_t ()) const + { +#ifdef HB_NO_VAR + return nullptr; +#endif + auto &r = this+regions; + unsigned count = r.regions.len; + + float *cache; + if (count <= static_cache.length) + cache = static_cache.arrayZ; + else + { + cache = (float *) hb_malloc (sizeof (float) * count); + if (unlikely (!cache)) return nullptr; + } + + for (unsigned i = 0; i < count; i++) + cache[i] = REGION_CACHE_ITEM_CACHE_INVALID; + + return cache; + } + + static void destroy_cache (cache_t *cache, + hb_array_t static_cache = hb_array_t ()) + { + if (cache != static_cache.arrayZ) + hb_free (cache); + } + + private: + void get_delta (unsigned int outer, unsigned int inner, + const int *coords, unsigned int coord_count, + hb_array_t out, + VarRegionList::cache_t *cache = nullptr) const + { +#ifdef HB_NO_VAR + return; +#endif + + if (unlikely (outer >= dataSets.len)) + return; + + return (this+dataSets[outer]).get_delta (inner, + coords, coord_count, + this+regions, + out, + cache); + } + + public: + void get_delta (unsigned int index, + const int *coords, unsigned int coord_count, + hb_array_t out, + VarRegionList::cache_t *cache = nullptr) const + { + unsigned int outer = index >> 16; + unsigned int inner = index & 0xFFFF; + get_delta (outer, inner, coords, coord_count, out, cache); + } + void get_delta (unsigned int index, + hb_array_t coords, + hb_array_t out, + VarRegionList::cache_t *cache = nullptr) const + { + return get_delta (index, + coords.arrayZ, coords.length, + out, + cache); + } + + bool sanitize (hb_sanitize_context_t *c) const + { +#ifdef HB_NO_VAR + return true; +#endif + + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + hb_barrier () && + format == 1 && + regions.sanitize (c, this) && + dataSets.sanitize (c, this)); + } + + protected: + HBUINT16 format; // 1 + Offset32To regions; + Array16OfOffset32To dataSets; + public: + DEFINE_SIZE_ARRAY_SIZED (8, dataSets); +}; + #undef REGION_CACHE_ITEM_CACHE_INVALID +template +struct DeltaSetIndexMapFormat01 +{ + friend struct DeltaSetIndexMap; + + unsigned get_size () const + { return min_size + mapCount * get_width (); } + + private: + DeltaSetIndexMapFormat01* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + return_trace (c->embed (this)); + } + + template + bool serialize (hb_serialize_context_t *c, const T &plan) + { + unsigned int width = plan.get_width (); + unsigned int inner_bit_count = plan.get_inner_bit_count (); + const hb_array_t output_map = plan.get_output_map (); + + TRACE_SERIALIZE (this); + if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0)))) + return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); + + entryFormat = ((width-1)<<4)|(inner_bit_count-1); + mapCount = output_map.length; + HBUINT8 *p = c->allocate_size (width * output_map.length); + if (unlikely (!p)) return_trace (false); + for (unsigned int i = 0; i < output_map.length; i++) + { + unsigned int v = output_map.arrayZ[i]; + if (v) + { + unsigned int outer = v >> 16; + unsigned int inner = v & 0xFFFF; + unsigned int u = (outer << inner_bit_count) | inner; + for (unsigned int w = width; w > 0;) + { + p[--w] = u; + u >>= 8; + } + } + p += width; + } + return_trace (true); + } + + uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */ + { + /* If count is zero, pass value unchanged. This takes + * care of direct mapping for advance map. */ + if (!mapCount) + return v; + + if (v >= mapCount) + v = mapCount - 1; + + unsigned int u = 0; + { /* Fetch it. */ + unsigned int w = get_width (); + const HBUINT8 *p = mapDataZ.arrayZ + w * v; + for (; w; w--) + u = (u << 8) + *p++; + } + + { /* Repack it. */ + unsigned int n = get_inner_bit_count (); + unsigned int outer = u >> n; + unsigned int inner = u & ((1 << n) - 1); + u = (outer<<16) | inner; + } + + return u; + } + + unsigned get_map_count () const { return mapCount; } + unsigned get_width () const { return ((entryFormat >> 4) & 3) + 1; } + unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; } + + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + hb_barrier () && + c->check_range (mapDataZ.arrayZ, + mapCount, + get_width ())); + } + + protected: + HBUINT8 format; /* Format identifier--format = 0 */ + HBUINT8 entryFormat; /* A packed field that describes the compressed + * representation of delta-set indices. */ + MapCountT mapCount; /* The number of mapping entries. */ + UnsizedArrayOf + mapDataZ; /* The delta-set index mapping data. */ + + public: + DEFINE_SIZE_ARRAY (2+MapCountT::static_size, mapDataZ); +}; + +struct DeltaSetIndexMap +{ + template + bool serialize (hb_serialize_context_t *c, const T &plan) + { + TRACE_SERIALIZE (this); + unsigned length = plan.get_output_map ().length; + u.format = length <= 0xFFFF ? 0 : 1; + switch (u.format) { + case 0: hb_barrier (); return_trace (u.format0.serialize (c, plan)); + case 1: hb_barrier (); return_trace (u.format1.serialize (c, plan)); + default:return_trace (false); + } + } + + uint32_t map (unsigned v) const + { + switch (u.format) { + case 0: hb_barrier (); return (u.format0.map (v)); + case 1: hb_barrier (); return (u.format1.map (v)); + default:return v; + } + } + + unsigned get_map_count () const + { + switch (u.format) { + case 0: hb_barrier (); return u.format0.get_map_count (); + case 1: hb_barrier (); return u.format1.get_map_count (); + default:return 0; + } + } + + unsigned get_width () const + { + switch (u.format) { + case 0: hb_barrier (); return u.format0.get_width (); + case 1: hb_barrier (); return u.format1.get_width (); + default:return 0; + } + } + + unsigned get_inner_bit_count () const + { + switch (u.format) { + case 0: hb_barrier (); return u.format0.get_inner_bit_count (); + case 1: hb_barrier (); return u.format1.get_inner_bit_count (); + default:return 0; + } + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); + switch (u.format) { + case 0: hb_barrier (); return_trace (u.format0.sanitize (c)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + default:return_trace (true); + } + } + + DeltaSetIndexMap* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + switch (u.format) { + case 0: hb_barrier (); return_trace (reinterpret_cast (u.format0.copy (c))); + case 1: hb_barrier (); return_trace (reinterpret_cast (u.format1.copy (c))); + default:return_trace (nullptr); + } + } + + protected: + union { + HBUINT8 format; /* Format identifier */ + DeltaSetIndexMapFormat01 format0; + DeltaSetIndexMapFormat01 format1; + } u; + public: + DEFINE_SIZE_UNION (1, format); +}; + + +struct ItemVarStoreInstancer +{ + ItemVarStoreInstancer (const ItemVariationStore *varStore_, + const DeltaSetIndexMap *varIdxMap, + hb_array_t coords, + VarRegionList::cache_t *cache = nullptr) : + varStore (varStore_), varIdxMap (varIdxMap), coords (coords), cache (cache) + { + if (!varStore) + varStore = &Null(ItemVariationStore); + } + + operator bool () const { return varStore && bool (coords); } + + float operator[] (uint32_t varIdx) const + { return (*this) (varIdx); } + + float operator() (uint32_t varIdx, unsigned short offset = 0) const + { + if (!coords || varIdx == VarIdx::NO_VARIATION) + return 0.f; + + varIdx += offset; + if (varIdxMap) + varIdx = varIdxMap->map (varIdx); + return varStore->get_delta (varIdx, coords, cache); + } + + const ItemVariationStore *varStore; + const DeltaSetIndexMap *varIdxMap; + hb_array_t coords; + VarRegionList::cache_t *cache; +}; + +struct MultiItemVarStoreInstancer +{ + MultiItemVarStoreInstancer (const MultiItemVariationStore *varStore, + const DeltaSetIndexMap *varIdxMap, + hb_array_t coords, + SparseVarRegionList::cache_t *cache = nullptr) : + varStore (varStore), varIdxMap (varIdxMap), coords (coords), cache (cache) + { + if (!varStore) + varStore = &Null(MultiItemVariationStore); + } + + operator bool () const { return varStore && bool (coords); } + + float operator[] (uint32_t varIdx) const + { + float v = 0; + (*this) (hb_array (&v, 1), varIdx); + return v; + } + + void operator() (hb_array_t out, uint32_t varIdx, unsigned short offset = 0) const + { + if (coords && varIdx != VarIdx::NO_VARIATION) + { + varIdx += offset; + if (varIdxMap) + varIdx = varIdxMap->map (varIdx); + varStore->get_delta (varIdx, coords, out, cache); + } + else + for (unsigned i = 0; i < out.length; i++) + out.arrayZ[i] = 0.f; + } + + const MultiItemVariationStore *varStore; + const DeltaSetIndexMap *varIdxMap; + hb_array_t coords; + SparseVarRegionList::cache_t *cache; +}; + + /* * Feature Variations */ @@ -3278,7 +3811,16 @@ enum Cond_with_Var_flag_t DROP_RECORD_WITH_VAR = 3, }; -struct ConditionFormat1 +struct Condition; + +template +static bool +_hb_recurse_condition_evaluate (const struct Condition &condition, + const int *coords, + unsigned int coord_len, + Instancer *instancer); + +struct ConditionAxisRange { friend struct Condition; @@ -3298,19 +3840,19 @@ struct ConditionFormat1 return_trace (false); const hb_hashmap_t& normalized_axes_location = c->plan->axes_location; - Triple axis_limit{-1.f, 0.f, 1.f}; + Triple axis_limit{-1.0, 0.0, 1.0}; Triple *normalized_limit; if (normalized_axes_location.has (*axis_tag, &normalized_limit)) axis_limit = *normalized_limit; const hb_hashmap_t& axes_triple_distances = c->plan->axes_triple_distances; - TripleDistances axis_triple_distances{1.f, 1.f}; + TripleDistances axis_triple_distances{1.0, 1.0}; TripleDistances *triple_dists; if (axes_triple_distances.has (*axis_tag, &triple_dists)) axis_triple_distances = *triple_dists; - float normalized_min = renormalizeValue (filterRangeMinValue.to_float (), axis_limit, axis_triple_distances, false); - float normalized_max = renormalizeValue (filterRangeMaxValue.to_float (), axis_limit, axis_triple_distances, false); + float normalized_min = renormalizeValue ((double) filterRangeMinValue.to_float (), axis_limit, axis_triple_distances, false); + float normalized_max = renormalizeValue ((double) filterRangeMaxValue.to_float (), axis_limit, axis_triple_distances, false); out->filterRangeMinValue.set_float (normalized_min); out->filterRangeMaxValue.set_float (normalized_max); @@ -3328,10 +3870,14 @@ struct ConditionFormat1 hb_tag_t axis_tag = c->axes_index_tag_map->get (axisIndex); - Triple axis_range (-1.f, 0.f, 1.f); + Triple axis_range (-1.0, 0.0, 1.0); Triple *axis_limit; + bool axis_set_by_user = false; if (c->axes_location->has (axis_tag, &axis_limit)) + { axis_range = *axis_limit; + axis_set_by_user = true; + } float axis_min_val = axis_range.minimum; float axis_default_val = axis_range.middle; @@ -3350,26 +3896,26 @@ struct ConditionFormat1 return DROP_RECORD_WITH_VAR; //condition met and axis pinned, drop the condition - if (c->axes_location->has (axis_tag) && - c->axes_location->get (axis_tag).is_point ()) + if (axis_set_by_user && axis_range.is_point ()) return DROP_COND_WITH_VAR; if (filter_max_val != axis_max_val || filter_min_val != axis_min_val) { // add axisIndex->value into the hashmap so we can check if the record is // unique with variations - int16_t int_filter_max_val = filterRangeMaxValue.to_int (); - int16_t int_filter_min_val = filterRangeMinValue.to_int (); + uint16_t int_filter_max_val = (uint16_t) filterRangeMaxValue.to_int (); + uint16_t int_filter_min_val = (uint16_t) filterRangeMinValue.to_int (); hb_codepoint_t val = (int_filter_max_val << 16) + int_filter_min_val; condition_map->set (axisIndex, val); return KEEP_COND_WITH_VAR; } - return KEEP_RECORD_WITH_VAR; } - bool evaluate (const int *coords, unsigned int coord_len) const + template + bool evaluate (const int *coords, unsigned int coord_len, + Instancer *instancer HB_UNUSED) const { int coord = axisIndex < coord_len ? coords[axisIndex] : 0; return filterRangeMinValue.to_int () <= coord && coord <= filterRangeMaxValue.to_int (); @@ -3390,12 +3936,199 @@ struct ConditionFormat1 DEFINE_SIZE_STATIC (8); }; +struct ConditionValue +{ + friend struct Condition; + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + private: + template + bool evaluate (const int *coords, unsigned int coord_len, + Instancer *instancer) const + { + signed value = defaultValue; + value += (*instancer)[varIdx]; + return value > 0; + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + bool insert_catch_all) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 2 */ + HBINT16 defaultValue; /* Value at default instance. */ + VarIdx varIdx; /* Variation index */ + public: + DEFINE_SIZE_STATIC (8); +}; + +struct ConditionAnd +{ + friend struct Condition; + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + private: + template + bool evaluate (const int *coords, unsigned int coord_len, + Instancer *instancer) const + { + unsigned int count = conditions.len; + for (unsigned int i = 0; i < count; i++) + if (!_hb_recurse_condition_evaluate (this+conditions.arrayZ[i], + coords, coord_len, + instancer)) + return false; + return true; + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + bool insert_catch_all) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (conditions.sanitize (c, this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 3 */ + Array8OfOffset24To conditions; + public: + DEFINE_SIZE_ARRAY (3, conditions); +}; + +struct ConditionOr +{ + friend struct Condition; + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + private: + template + bool evaluate (const int *coords, unsigned int coord_len, + Instancer *instancer) const + { + unsigned int count = conditions.len; + for (unsigned int i = 0; i < count; i++) + if (_hb_recurse_condition_evaluate (this+conditions.arrayZ[i], + coords, coord_len, + instancer)) + return true; + return false; + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + bool insert_catch_all) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (conditions.sanitize (c, this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 4 */ + Array8OfOffset24To conditions; + public: + DEFINE_SIZE_ARRAY (3, conditions); +}; + +struct ConditionNegate +{ + friend struct Condition; + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + private: + template + bool evaluate (const int *coords, unsigned int coord_len, + Instancer *instancer) const + { + return !_hb_recurse_condition_evaluate (this+condition, + coords, coord_len, + instancer); + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + bool insert_catch_all) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (condition.sanitize (c, this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 5 */ + Offset24To condition; + public: + DEFINE_SIZE_STATIC (5); +}; + struct Condition { - bool evaluate (const int *coords, unsigned int coord_len) const + template + bool evaluate (const int *coords, unsigned int coord_len, + Instancer *instancer) const { switch (u.format) { - case 1: return u.format1.evaluate (coords, coord_len); + case 1: hb_barrier (); return u.format1.evaluate (coords, coord_len, instancer); + case 2: hb_barrier (); return u.format2.evaluate (coords, coord_len, instancer); + case 3: hb_barrier (); return u.format3.evaluate (coords, coord_len, instancer); + case 4: hb_barrier (); return u.format4.evaluate (coords, coord_len, instancer); + case 5: hb_barrier (); return u.format5.evaluate (coords, coord_len, instancer); default:return false; } } @@ -3404,7 +4137,8 @@ struct Condition hb_map_t *condition_map /* OUT */) const { switch (u.format) { - case 1: return u.format1.keep_with_variations (c, condition_map); + case 1: hb_barrier (); return u.format1.keep_with_variations (c, condition_map); + // TODO(subset) default: c->apply = false; return KEEP_COND_WITH_VAR; } } @@ -3415,7 +4149,11 @@ struct Condition if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); + case 4: hb_barrier (); return_trace (c->dispatch (u.format4, std::forward (ds)...)); + case 5: hb_barrier (); return_trace (c->dispatch (u.format5, std::forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -3424,8 +4162,13 @@ struct Condition { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { - case 1: return_trace (u.format1.sanitize (c)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); + case 3: hb_barrier (); return_trace (u.format3.sanitize (c)); + case 4: hb_barrier (); return_trace (u.format4.sanitize (c)); + case 5: hb_barrier (); return_trace (u.format5.sanitize (c)); default:return_trace (true); } } @@ -3433,19 +4176,51 @@ struct Condition protected: union { HBUINT16 format; /* Format identifier */ - ConditionFormat1 format1; + ConditionAxisRange format1; + ConditionValue format2; + ConditionAnd format3; + ConditionOr format4; + ConditionNegate format5; } u; public: DEFINE_SIZE_UNION (2, format); }; +template +bool +_hb_recurse_condition_evaluate (const struct Condition &condition, + const int *coords, + unsigned int coord_len, + Instancer *instancer) +{ + return condition.evaluate (coords, coord_len, instancer); +} + +struct ConditionList +{ + const Condition& operator[] (unsigned i) const + { return this+conditions[i]; } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (conditions.sanitize (c, this)); + } + + protected: + Array32OfOffset32To conditions; + public: + DEFINE_SIZE_ARRAY (4, conditions); +}; + struct ConditionSet { - bool evaluate (const int *coords, unsigned int coord_len) const + bool evaluate (const int *coords, unsigned int coord_len, + ItemVarStoreInstancer *instancer) const { unsigned int count = conditions.len; for (unsigned int i = 0; i < count; i++) - if (!(this+conditions.arrayZ[i]).evaluate (coords, coord_len)) + if (!(this+conditions.arrayZ[i]).evaluate (coords, coord_len, instancer)) return false; return true; } @@ -3497,12 +4272,15 @@ struct ConditionSet } bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l) const + hb_subset_layout_context_t *l, + bool insert_catch_all) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + if (insert_catch_all) return_trace (true); + hb_set_t *retained_cond_set = nullptr; if (l->feature_record_cond_idx_map != nullptr) retained_cond_set = l->feature_record_cond_idx_map->get (l->cur_feature_var_record_idx); @@ -3548,27 +4326,51 @@ struct FeatureTableSubstitutionRecord } void collect_feature_substitutes_with_variations (hb_hashmap_t *feature_substitutes_map, + hb_set_t& catch_all_record_feature_idxes, const hb_set_t *feature_indices, const void *base) const { if (feature_indices->has (featureIndex)) + { feature_substitutes_map->set (featureIndex, &(base+feature)); + catch_all_record_feature_idxes.add (featureIndex); + } + } + + bool serialize (hb_subset_layout_context_t *c, + unsigned feature_index, + const Feature *f, const Tag *tag) + { + TRACE_SERIALIZE (this); + hb_serialize_context_t *s = c->subset_context->serializer; + if (unlikely (!s->extend_min (this))) return_trace (false); + + uint32_t *new_feature_idx; + if (!c->feature_index_map->has (feature_index, &new_feature_idx)) + return_trace (false); + + if (!s->check_assign (featureIndex, *new_feature_idx, HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); + + s->push (); + bool ret = f->subset (c->subset_context, c, tag); + if (ret) s->add_link (feature, s->pop_pack ()); + else s->pop_discard (); + + return_trace (ret); } bool subset (hb_subset_layout_context_t *c, const void *base) const { TRACE_SUBSET (this); - if (!c->feature_index_map->has (featureIndex) || - c->feature_substitutes_map->has (featureIndex)) { - // Feature that is being substituted is not being retained, so we don't - // need this. + uint32_t *new_feature_index; + if (!c->feature_index_map->has (featureIndex, &new_feature_index)) return_trace (false); - } auto *out = c->subset_context->serializer->embed (this); if (unlikely (!out)) return_trace (false); - out->featureIndex = c->feature_index_map->get (featureIndex); + out->featureIndex = *new_feature_index; return_trace (out->feature.serialize_subset (c->subset_context, feature, base, c)); } @@ -3600,16 +4402,10 @@ struct FeatureTableSubstitution } void collect_lookups (const hb_set_t *feature_indexes, - const hb_hashmap_t *feature_substitutes_map, hb_set_t *lookup_indexes /* OUT */) const { + hb_iter (substitutions) | hb_filter (feature_indexes, &FeatureTableSubstitutionRecord::featureIndex) - | hb_filter ([feature_substitutes_map] (const FeatureTableSubstitutionRecord& record) - { - if (feature_substitutes_map == nullptr) return true; - return !feature_substitutes_map->has (record.featureIndex); - }) | hb_apply ([this, lookup_indexes] (const FeatureTableSubstitutionRecord& r) { r.collect_lookups (this, lookup_indexes); }) ; @@ -3634,11 +4430,14 @@ struct FeatureTableSubstitution void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const { for (const FeatureTableSubstitutionRecord& record : substitutions) - record.collect_feature_substitutes_with_variations (c->feature_substitutes_map, c->feature_indices, this); + record.collect_feature_substitutes_with_variations (c->feature_substitutes_map, + c->catch_all_record_feature_idxes, + c->feature_indices, this); } bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l) const + hb_subset_layout_context_t *l, + bool insert_catch_all) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); @@ -3647,6 +4446,22 @@ struct FeatureTableSubstitution out->version.major = version.major; out->version.minor = version.minor; + if (insert_catch_all) + { + for (unsigned feature_index : *(l->catch_all_record_feature_idxes)) + { + hb_pair_t *p; + if (!l->feature_idx_tag_map->has (feature_index, &p)) + return_trace (false); + auto *o = out->substitutions.serialize_append (c->serializer); + if (!o->serialize (l, feature_index, + reinterpret_cast (p->first), + reinterpret_cast (p->second))) + return_trace (false); + } + return_trace (true); + } + + substitutions.iter () | hb_apply (subset_record_array (l, &(out->substitutions), this)) ; @@ -3658,6 +4473,7 @@ struct FeatureTableSubstitution { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && substitutions.sanitize (c, this)); } @@ -3676,10 +4492,9 @@ struct FeatureVariationRecord void collect_lookups (const void *base, const hb_set_t *feature_indexes, - const hb_hashmap_t *feature_substitutes_map, hb_set_t *lookup_indexes /* OUT */) const { - return (base+substitutions).collect_lookups (feature_indexes, feature_substitutes_map, lookup_indexes); + return (base+substitutions).collect_lookups (feature_indexes, lookup_indexes); } void closure_features (const void *base, @@ -3705,14 +4520,15 @@ struct FeatureVariationRecord } } - bool subset (hb_subset_layout_context_t *c, const void *base) const + bool subset (hb_subset_layout_context_t *c, const void *base, + bool insert_catch_all = false) const { TRACE_SUBSET (this); auto *out = c->subset_context->serializer->embed (this); if (unlikely (!out)) return_trace (false); - out->conditions.serialize_subset (c->subset_context, conditions, base, c); - out->substitutions.serialize_subset (c->subset_context, substitutions, base, c); + out->conditions.serialize_subset (c->subset_context, conditions, base, c, insert_catch_all); + out->substitutions.serialize_subset (c->subset_context, substitutions, base, c, insert_catch_all); return_trace (true); } @@ -3738,13 +4554,14 @@ struct FeatureVariations static constexpr unsigned NOT_FOUND_INDEX = 0xFFFFFFFFu; bool find_index (const int *coords, unsigned int coord_len, - unsigned int *index) const + unsigned int *index, + ItemVarStoreInstancer *instancer) const { unsigned int count = varRecords.len; for (unsigned int i = 0; i < count; i++) { const FeatureVariationRecord &record = varRecords.arrayZ[i]; - if ((this+record.conditions).evaluate (coords, coord_len)) + if ((this+record.conditions).evaluate (coords, coord_len, instancer)) { *index = i; return true; @@ -3771,9 +4588,8 @@ struct FeatureVariations if (c->universal) break; } - if (c->variation_applied && !c->universal && - !c->record_cond_idx_map->is_empty ()) - c->insert_catch_all_feature_variation_record = true; + if (c->universal || c->record_cond_idx_map->is_empty ()) + c->catch_all_record_feature_idxes.reset (); } FeatureVariations* copy (hb_serialize_context_t *c) const @@ -3783,11 +4599,17 @@ struct FeatureVariations } void collect_lookups (const hb_set_t *feature_indexes, - const hb_hashmap_t *feature_substitutes_map, + const hb_hashmap_t> *feature_record_cond_idx_map, hb_set_t *lookup_indexes /* OUT */) const { - for (const FeatureVariationRecord& r : varRecords) - r.collect_lookups (this, feature_indexes, feature_substitutes_map, lookup_indexes); + unsigned count = varRecords.len; + for (unsigned int i = 0; i < count; i++) + { + if (feature_record_cond_idx_map && + !feature_record_cond_idx_map->has (i)) + continue; + varRecords[i].collect_lookups (this, feature_indexes, lookup_indexes); + } } void closure_features (const hb_map_t *lookup_indexes, @@ -3832,6 +4654,13 @@ struct FeatureVariations l->cur_feature_var_record_idx = i; subset_record_array (l, &(out->varRecords), this) (varRecords[i]); } + + if (out->varRecords.len && !l->catch_all_record_feature_idxes->is_empty ()) + { + bool insert_catch_all_record = true; + subset_record_array (l, &(out->varRecords), this, insert_catch_all_record) (varRecords[0]); + } + return_trace (bool (out->varRecords)); } @@ -3839,6 +4668,7 @@ struct FeatureVariations { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && varRecords.sanitize (c, this)); } @@ -3945,13 +4775,13 @@ struct VariationDevice private: hb_position_t get_x_delta (hb_font_t *font, - const VariationStore &store, - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store, + ItemVariationStore::cache_t *store_cache = nullptr) const { return font->em_scalef_x (get_delta (font, store, store_cache)); } hb_position_t get_y_delta (hb_font_t *font, - const VariationStore &store, - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store, + ItemVariationStore::cache_t *store_cache = nullptr) const { return font->em_scalef_y (get_delta (font, store, store_cache)); } VariationDevice* copy (hb_serialize_context_t *c, @@ -3985,14 +4815,14 @@ struct VariationDevice private: float get_delta (hb_font_t *font, - const VariationStore &store, - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store, + ItemVariationStore::cache_t *store_cache = nullptr) const { - return store.get_delta (varIdx, font->coords, font->num_coords, (VariationStore::cache_t *) store_cache); + return store.get_delta (varIdx, font->coords, font->num_coords, (ItemVariationStore::cache_t *) store_cache); } protected: - VarIdx varIdx; + VarIdx varIdx; /* Variation index */ HBUINT16 deltaFormat; /* Format identifier for this table: 0x0x8000 */ public: DEFINE_SIZE_STATIC (6); @@ -4012,8 +4842,8 @@ struct DeviceHeader struct Device { hb_position_t get_x_delta (hb_font_t *font, - const VariationStore &store=Null (VariationStore), - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store=Null (ItemVariationStore), + ItemVariationStore::cache_t *store_cache = nullptr) const { switch (u.b.format) { @@ -4030,8 +4860,8 @@ struct Device } } hb_position_t get_y_delta (hb_font_t *font, - const VariationStore &store=Null (VariationStore), - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store=Null (ItemVariationStore), + ItemVariationStore::cache_t *store_cache = nullptr) const { switch (u.b.format) { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh index d5b5a488a263a..1a719391b8ef1 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh @@ -406,6 +406,7 @@ struct hb_ot_apply_context_t : void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } + void set_ignore_hidden (bool ignore_hidden_) { ignore_hidden = ignore_hidden_; } void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } void set_mask (hb_mask_t mask_) { mask = mask_; } void set_per_syllable (bool per_syllable_) { per_syllable = per_syllable_; } @@ -451,9 +452,10 @@ struct hb_ot_apply_context_t : if (!c->check_glyph_property (&info, lookup_props)) return SKIP_YES; - if (unlikely (_hb_glyph_info_is_default_ignorable_and_not_hidden (&info) && + if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && - (ignore_zwj || !_hb_glyph_info_is_zwj (&info)))) + (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && + (ignore_hidden || !_hb_glyph_info_is_hidden (&info)))) return SKIP_MAYBE; return SKIP_NO; @@ -464,6 +466,7 @@ struct hb_ot_apply_context_t : hb_mask_t mask = -1; bool ignore_zwnj = false; bool ignore_zwj = false; + bool ignore_hidden = false; bool per_syllable = false; uint8_t syllable = 0; match_func_t match_func = nullptr; @@ -486,6 +489,8 @@ struct hb_ot_apply_context_t : matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && c->auto_zwnj)); /* Ignore ZWJ if we are matching context, or asked to. */ matcher.set_ignore_zwj (context_match || c->auto_zwj); + /* Ignore hidden glyphs (like CGJ) during GPOS. */ + matcher.set_ignore_hidden (c->table_index == 1); matcher.set_mask (context_match ? -1 : c->lookup_mask); /* Per syllable matching is only for GSUB. */ matcher.set_per_syllable (c->table_index == 0 && c->per_syllable); @@ -708,8 +713,9 @@ struct hb_ot_apply_context_t : recurse_func_t recurse_func = nullptr; const GDEF &gdef; const GDEF::accelerator_t &gdef_accel; - const VariationStore &var_store; - VariationStore::cache_t *var_store_cache; + const hb_ot_layout_lookup_accelerator_t *lookup_accel = nullptr; + const ItemVariationStore &var_store; + ItemVariationStore::cache_t *var_store_cache; hb_set_digest_t digest; hb_direction_t direction; @@ -723,7 +729,6 @@ struct hb_ot_apply_context_t : bool auto_zwj = true; bool per_syllable = false; bool random = false; - uint32_t random_state = 1; unsigned new_syllables = (unsigned) -1; signed last_base = -1; // GPOS uses @@ -758,15 +763,17 @@ struct hb_ot_apply_context_t : nullptr #endif ), - digest (buffer_->digest ()), direction (buffer_->props.direction), has_glyph_classes (gdef.has_glyph_classes ()) - { init_iters (); } + { + init_iters (); + buffer->collect_codepoints (digest); + } ~hb_ot_apply_context_t () { #ifndef HB_NO_VAR - VariationStore::destroy_cache (var_store_cache); + ItemVariationStore::destroy_cache (var_store_cache); #endif } @@ -788,8 +795,8 @@ struct hb_ot_apply_context_t : uint32_t random_number () { /* http://www.cplusplus.com/reference/random/minstd_rand/ */ - random_state = random_state * 48271 % 2147483647; - return random_state; + buffer->random_state = buffer->random_state * 48271 % 2147483647; + return buffer->random_state; } bool match_properties_mark (hb_codepoint_t glyph, @@ -895,6 +902,13 @@ struct hb_ot_apply_context_t : } }; +enum class hb_ot_lookup_cache_op_t +{ + CREATE, + ENTER, + LEAVE, + DESTROY, +}; struct hb_accelerate_subtables_context_t : hb_dispatch_context_t @@ -919,19 +933,23 @@ struct hb_accelerate_subtables_context_t : } template - static inline auto cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<1>) HB_RETURN (bool, obj->cache_func (c, enter) ) - template - static inline bool cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<0>) { return false; } + static inline auto cache_func_ (void *p, + hb_ot_lookup_cache_op_t op, + hb_priority<1>) HB_RETURN (void *, T::cache_func (p, op) ) + template + static inline void * cache_func_ (void *p, + hb_ot_lookup_cache_op_t op HB_UNUSED, + hb_priority<0>) { return (void *) false; } template - static inline bool cache_func_to (const void *obj, hb_ot_apply_context_t *c, bool enter) + static inline void * cache_func_to (void *p, + hb_ot_lookup_cache_op_t op) { - const Type *typed_obj = (const Type *) obj; - return cache_func_ (typed_obj, c, enter, hb_prioritize); + return cache_func_ (p, op, hb_prioritize); } #endif typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c); - typedef bool (*hb_cache_func_t) (const void *obj, hb_ot_apply_context_t *c, bool enter); + typedef void * (*hb_cache_func_t) (void *p, hb_ot_lookup_cache_op_t op); struct hb_applicable_t { @@ -968,11 +986,11 @@ struct hb_accelerate_subtables_context_t : } bool cache_enter (hb_ot_apply_context_t *c) const { - return cache_func (obj, c, true); + return (bool) cache_func (c, hb_ot_lookup_cache_op_t::ENTER); } void cache_leave (hb_ot_apply_context_t *c) const { - cache_func (obj, c, false); + cache_func (c, hb_ot_lookup_cache_op_t::LEAVE); } #endif @@ -1255,7 +1273,7 @@ static bool match_input (hb_ot_apply_context_t *c, match_func_t match_func, const void *match_data, unsigned int *end_position, - unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], + unsigned int *match_positions, unsigned int *p_total_component_count = nullptr) { TRACE_APPLY (nullptr); @@ -1379,7 +1397,7 @@ static bool match_input (hb_ot_apply_context_t *c, } static inline bool ligate_input (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph */ - const unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ + const unsigned int *match_positions, /* Including the first glyph */ unsigned int match_end, hb_codepoint_t lig_glyph, unsigned int total_component_count) @@ -1458,6 +1476,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); if (this_comp == 0) this_comp = last_num_components; + assert (components_so_far >= last_num_components); unsigned int new_lig_comp = components_so_far - last_num_components + hb_min (this_comp, last_num_components); _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); @@ -1483,6 +1502,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, unsigned this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]); if (!this_comp) break; + assert (components_so_far >= last_num_components); unsigned new_lig_comp = components_so_far - last_num_components + hb_min (this_comp, last_num_components); _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp); @@ -1538,6 +1558,7 @@ static bool match_lookahead (hb_ot_apply_context_t *c, TRACE_APPLY (nullptr); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; + assert (start_index >= 1); skippy_iter.reset (start_index - 1); skippy_iter.set_match_func (match_func, match_data); skippy_iter.set_glyph_data (lookahead); @@ -1687,7 +1708,7 @@ static inline void recurse_lookups (context_t *c, static inline void apply_lookup (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph */ - unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ + unsigned int *match_positions, /* Including the first glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */ unsigned int match_end) @@ -1695,6 +1716,9 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, hb_buffer_t *buffer = c->buffer; int end; + unsigned int *match_positions_input = match_positions; + unsigned int match_positions_count = count; + /* All positions are distance from beginning of *output* buffer. * Adjust. */ { @@ -1798,6 +1822,27 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, { if (unlikely (delta + count > HB_MAX_CONTEXT_LENGTH)) break; + if (unlikely (delta + count > match_positions_count)) + { + unsigned new_match_positions_count = hb_max (delta + count, hb_max(match_positions_count, 4u) * 1.5); + if (match_positions == match_positions_input) + { + match_positions = (unsigned int *) hb_malloc (new_match_positions_count * sizeof (match_positions[0])); + if (unlikely (!match_positions)) + break; + memcpy (match_positions, match_positions_input, count * sizeof (match_positions[0])); + match_positions_count = new_match_positions_count; + } + else + { + unsigned int *new_match_positions = (unsigned int *) hb_realloc (match_positions, new_match_positions_count * sizeof (match_positions[0])); + if (unlikely (!new_match_positions)) + break; + match_positions = new_match_positions; + match_positions_count = new_match_positions_count; + } + } + } else { @@ -1821,6 +1866,10 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, match_positions[next] += delta; } + if (match_positions != match_positions_input) + hb_free (match_positions); + + assert (end >= 0); (void) buffer->move_to (end); } @@ -1921,8 +1970,18 @@ static bool context_apply_lookup (hb_ot_apply_context_t *c, const LookupRecord lookupRecord[], const ContextApplyLookupContext &lookup_context) { + if (unlikely (inputCount > HB_MAX_CONTEXT_LENGTH)) return false; + unsigned match_positions_stack[4]; + unsigned *match_positions = match_positions_stack; + if (unlikely (inputCount > ARRAY_LENGTH (match_positions_stack))) + { + match_positions = (unsigned *) hb_malloc (hb_max (inputCount, 1u) * sizeof (match_positions[0])); + if (unlikely (!match_positions)) + return false; + } + unsigned match_end = 0; - unsigned match_positions[HB_MAX_CONTEXT_LENGTH]; + bool ret = false; if (match_input (c, inputCount, input, lookup_context.funcs.match, lookup_context.match_data, @@ -1933,13 +1992,18 @@ static bool context_apply_lookup (hb_ot_apply_context_t *c, inputCount, match_positions, lookupCount, lookupRecord, match_end); - return true; + ret = true; } else { c->buffer->unsafe_to_concat (c->buffer->idx, match_end); - return false; + ret = false; } + + if (unlikely (match_positions != match_positions_stack)) + hb_free (match_positions); + + return ret; } template @@ -2051,6 +2115,7 @@ struct Rule { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_range (inputZ.arrayZ, inputZ.item_size * (inputCount ? inputCount - 1 : 0) + LookupRecord::static_size * lookupCount)); @@ -2572,25 +2637,35 @@ struct ContextFormat2_5 unsigned c = (this+classDef).cost () * ruleSet.len; return c >= 4 ? c : 0; } - bool cache_func (hb_ot_apply_context_t *c, bool enter) const + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) { - if (enter) - { - if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) - return false; - auto &info = c->buffer->info; - unsigned count = c->buffer->len; - for (unsigned i = 0; i < count; i++) - info[i].syllable() = 255; - c->new_syllables = 255; - return true; - } - else + switch (op) { - c->new_syllables = (unsigned) -1; - HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); - return true; + case hb_ot_lookup_cache_op_t::CREATE: + return (void *) true; + case hb_ot_lookup_cache_op_t::ENTER: + { + hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; + if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) + return (void *) false; + auto &info = c->buffer->info; + unsigned count = c->buffer->len; + for (unsigned i = 0; i < count; i++) + info[i].syllable() = 255; + c->new_syllables = 255; + return (void *) true; + } + case hb_ot_lookup_cache_op_t::LEAVE: + { + hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; + c->new_syllables = (unsigned) -1; + HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); + return nullptr; + } + case hb_ot_lookup_cache_op_t::DESTROY: + return nullptr; } + return nullptr; } bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } @@ -2599,7 +2674,7 @@ struct ContextFormat2_5 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const ClassDef &class_def = this+classDef; @@ -2785,7 +2860,7 @@ struct ContextFormat3 { TRACE_APPLY (this); unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const LookupRecord *lookupRecord = &StructAfter (coverageZ.as_array (glyphCount)); struct ContextApplyLookupContext lookup_context = { @@ -2826,6 +2901,7 @@ struct ContextFormat3 { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); unsigned int count = glyphCount; if (unlikely (!count)) return_trace (false); /* We want to access coverageZ[0] freely. */ if (unlikely (!c->check_array (coverageZ.arrayZ, count))) return_trace (false); @@ -2858,12 +2934,12 @@ struct Context if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); - case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); - case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K - case 4: return_trace (c->dispatch (u.format4, std::forward (ds)...)); - case 5: return_trace (c->dispatch (u.format5, std::forward (ds)...)); + case 4: hb_barrier (); return_trace (c->dispatch (u.format4, std::forward (ds)...)); + case 5: hb_barrier (); return_trace (c->dispatch (u.format5, std::forward (ds)...)); #endif default:return_trace (c->default_return_value ()); } @@ -3017,9 +3093,20 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, const LookupRecord lookupRecord[], const ChainContextApplyLookupContext &lookup_context) { + if (unlikely (inputCount > HB_MAX_CONTEXT_LENGTH)) return false; + unsigned match_positions_stack[4]; + unsigned *match_positions = match_positions_stack; + if (unlikely (inputCount > ARRAY_LENGTH (match_positions_stack))) + { + match_positions = (unsigned *) hb_malloc (hb_max (inputCount, 1u) * sizeof (match_positions[0])); + if (unlikely (!match_positions)) + return false; + } + + unsigned start_index = c->buffer->out_len; unsigned end_index = c->buffer->idx; unsigned match_end = 0; - unsigned match_positions[HB_MAX_CONTEXT_LENGTH]; + bool ret = true; if (!(match_input (c, inputCount, input, lookup_context.funcs.match[1], lookup_context.match_data[1], @@ -3030,17 +3117,18 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, match_end, &end_index))) { c->buffer->unsafe_to_concat (c->buffer->idx, end_index); - return false; + ret = false; + goto done; } - unsigned start_index = c->buffer->out_len; if (!match_backtrack (c, backtrackCount, backtrack, lookup_context.funcs.match[0], lookup_context.match_data[0], &start_index)) { c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index); - return false; + ret = false; + goto done; } c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index); @@ -3048,7 +3136,12 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, inputCount, match_positions, lookupCount, lookupRecord, match_end); - return true; + done: + + if (unlikely (match_positions != match_positions_stack)) + hb_free (match_positions); + + return ret; } template @@ -3219,10 +3312,13 @@ struct ChainRule TRACE_SANITIZE (this); /* Hyper-optimized sanitized because this is really hot. */ if (unlikely (!backtrack.len.sanitize (c))) return_trace (false); + hb_barrier (); const auto &input = StructAfter (backtrack); if (unlikely (!input.lenP1.sanitize (c))) return_trace (false); + hb_barrier (); const auto &lookahead = StructAfter (input); if (unlikely (!lookahead.len.sanitize (c))) return_trace (false); + hb_barrier (); const auto &lookup = StructAfter (lookahead); return_trace (likely (lookup.sanitize (c))); } @@ -3327,6 +3423,15 @@ struct ChainRuleSet * * Replicated from LigatureSet::apply(). */ + /* If the input skippy has non-auto joiners behavior (as in Indic shapers), + * skip this fast path, as we don't distinguish between input & lookahead + * matching in the fast path. + * + * https://github.com/harfbuzz/harfbuzz/issues/4813 + */ + if (!c->auto_zwnj || !c->auto_zwj) + goto slow; + hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (c->buffer->idx); skippy_iter.set_match_func (match_always, nullptr); @@ -3366,10 +3471,10 @@ struct ChainRuleSet } matched = skippy_iter.next (); if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))) - { + { second = &c->buffer->info[skippy_iter.idx]; unsafe_to2 = skippy_iter.idx + 1; - } + } auto match_input = lookup_context.funcs.match[1]; auto match_lookahead = lookup_context.funcs.match[2]; @@ -3569,7 +3674,7 @@ struct ChainContextFormat1_4 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const ChainRuleSet &rule_set = this+ruleSet[index]; struct ChainContextApplyLookupContext lookup_context = { @@ -3780,28 +3885,37 @@ struct ChainContextFormat2_5 unsigned cache_cost () const { - unsigned c = (this+lookaheadClassDef).cost () * ruleSet.len; - return c >= 4 ? c : 0; + return (this+lookaheadClassDef).cost () * ruleSet.len; } - bool cache_func (hb_ot_apply_context_t *c, bool enter) const + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) { - if (enter) + switch (op) { - if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) - return false; - auto &info = c->buffer->info; - unsigned count = c->buffer->len; - for (unsigned i = 0; i < count; i++) - info[i].syllable() = 255; - c->new_syllables = 255; - return true; - } - else - { - c->new_syllables = (unsigned) -1; - HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); - return true; + case hb_ot_lookup_cache_op_t::CREATE: + return (void *) true; + case hb_ot_lookup_cache_op_t::ENTER: + { + hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; + if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) + return (void *) false; + auto &info = c->buffer->info; + unsigned count = c->buffer->len; + for (unsigned i = 0; i < count; i++) + info[i].syllable() = 255; + c->new_syllables = 255; + return (void *) true; + } + case hb_ot_lookup_cache_op_t::LEAVE: + { + hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; + c->new_syllables = (unsigned) -1; + HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); + return nullptr; + } + case hb_ot_lookup_cache_op_t::DESTROY: + return nullptr; } + return nullptr; } bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } @@ -3810,7 +3924,7 @@ struct ChainContextFormat2_5 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const ClassDef &backtrack_class_def = this+backtrackClassDef; const ClassDef &input_class_def = this+inputClassDef; @@ -4056,7 +4170,7 @@ struct ChainContextFormat3 const auto &input = StructAfter (backtrack); unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const auto &lookahead = StructAfter (input); const auto &lookup = StructAfter (lookahead); @@ -4121,11 +4235,14 @@ struct ChainContextFormat3 { TRACE_SANITIZE (this); if (unlikely (!backtrack.sanitize (c, this))) return_trace (false); + hb_barrier (); const auto &input = StructAfter (backtrack); if (unlikely (!input.sanitize (c, this))) return_trace (false); + hb_barrier (); if (unlikely (!input.len)) return_trace (false); /* To be consistent with Context. */ const auto &lookahead = StructAfter (input); if (unlikely (!lookahead.sanitize (c, this))) return_trace (false); + hb_barrier (); const auto &lookup = StructAfter (lookahead); return_trace (likely (lookup.sanitize (c))); } @@ -4159,12 +4276,12 @@ struct ChainContext if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); - case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); - case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K - case 4: return_trace (c->dispatch (u.format4, std::forward (ds)...)); - case 5: return_trace (c->dispatch (u.format5, std::forward (ds)...)); + case 4: hb_barrier (); return_trace (c->dispatch (u.format4, std::forward (ds)...)); + case 5: hb_barrier (); return_trace (c->dispatch (u.format5, std::forward (ds)...)); #endif default:return_trace (c->default_return_value ()); } @@ -4209,6 +4326,7 @@ struct ExtensionFormat1 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && extensionLookupType != T::SubTable::Extension); } @@ -4247,7 +4365,7 @@ struct Extension unsigned int get_type () const { switch (u.format) { - case 1: return u.format1.get_type (); + case 1: hb_barrier (); return u.format1.get_type (); default:return 0; } } @@ -4255,7 +4373,7 @@ struct Extension const X& get_subtable () const { switch (u.format) { - case 1: return u.format1.template get_subtable (); + case 1: hb_barrier (); return u.format1.template get_subtable (); default:return Null (typename T::SubTable); } } @@ -4267,7 +4385,7 @@ struct Extension typename hb_subset_context_t::return_t dispatch (hb_subset_context_t *c, Ts&&... ds) const { switch (u.format) { - case 1: return u.format1.subset (c); + case 1: hb_barrier (); return u.format1.subset (c); default: return c->default_return_value (); } } @@ -4278,7 +4396,7 @@ struct Extension if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); switch (u.format) { - case 1: return_trace (u.format1.dispatch (c, std::forward (ds)...)); + case 1: hb_barrier (); return_trace (u.format1.dispatch (c, std::forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -4320,10 +4438,21 @@ struct hb_ot_layout_lookup_accelerator_t thiz->digest.init (); for (auto& subtable : hb_iter (thiz->subtables, count)) - thiz->digest.add (subtable.digest); + thiz->digest.union_ (subtable.digest); #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + if (c_accelerate_subtables.cache_user_cost < 4) + c_accelerate_subtables.cache_user_idx = (unsigned) -1; + thiz->cache_user_idx = c_accelerate_subtables.cache_user_idx; + + if (thiz->cache_user_idx != (unsigned) -1) + { + thiz->cache = thiz->subtables[thiz->cache_user_idx].cache_func (nullptr, hb_ot_lookup_cache_op_t::CREATE); + if (!thiz->cache) + thiz->cache_user_idx = (unsigned) -1; + } + for (unsigned i = 0; i < count; i++) if (i != thiz->cache_user_idx) thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func; @@ -4332,6 +4461,17 @@ struct hb_ot_layout_lookup_accelerator_t return thiz; } + void fini () + { +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + if (cache) + { + assert (cache_user_idx != (unsigned) -1); + subtables[cache_user_idx].cache_func (cache, hb_ot_lookup_cache_op_t::DESTROY); + } +#endif + } + bool may_have (hb_codepoint_t g) const { return digest.may_have (g); } @@ -4340,6 +4480,7 @@ struct hb_ot_layout_lookup_accelerator_t #endif bool apply (hb_ot_apply_context_t *c, unsigned subtables_count, bool use_cache) const { + c->lookup_accel = this; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE if (use_cache) { @@ -4379,10 +4520,13 @@ struct hb_ot_layout_lookup_accelerator_t hb_set_digest_t digest; - private: #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + public: + void *cache = nullptr; + private: unsigned cache_user_idx = (unsigned) -1; #endif + private: hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY]; }; @@ -4472,13 +4616,6 @@ struct GSUBGPOSVersion1_2 if (!c->subset_context->serializer->extend_min (&out->featureVars)) return_trace (false); - // TODO(qxliu76): the current implementation doesn't correctly handle feature variations - // that are dropped by instancing when the associated conditions don't trigger. - // Since partial instancing isn't yet supported this isn't an issue yet but will - // need to be fixed for partial instancing. - - - // if all axes are pinned all feature vars are dropped. bool ret = !c->subset_context->plan->all_axes_pinned && out->featureVars.serialize_subset (c->subset_context, featureVars, this, c); @@ -4500,9 +4637,9 @@ struct GSUBGPOS unsigned int get_size () const { switch (u.version.major) { - case 1: return u.version1.get_size (); + case 1: hb_barrier (); return u.version1.get_size (); #ifndef HB_NO_BEYOND_64K - case 2: return u.version2.get_size (); + case 2: hb_barrier (); return u.version2.get_size (); #endif default: return u.version.static_size; } @@ -4513,10 +4650,11 @@ struct GSUBGPOS { TRACE_SANITIZE (this); if (unlikely (!u.version.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.version.major) { - case 1: return_trace (u.version1.sanitize (c)); + case 1: hb_barrier (); return_trace (u.version1.sanitize (c)); #ifndef HB_NO_BEYOND_64K - case 2: return_trace (u.version2.sanitize (c)); + case 2: hb_barrier (); return_trace (u.version2.sanitize (c)); #endif default: return_trace (true); } @@ -4526,9 +4664,9 @@ struct GSUBGPOS bool subset (hb_subset_layout_context_t *c) const { switch (u.version.major) { - case 1: return u.version1.subset (c); + case 1: hb_barrier (); return u.version1.subset (c); #ifndef HB_NO_BEYOND_64K - case 2: return u.version2.subset (c); + case 2: hb_barrier (); return u.version2.subset (c); #endif default: return false; } @@ -4537,9 +4675,9 @@ struct GSUBGPOS const ScriptList &get_script_list () const { switch (u.version.major) { - case 1: return this+u.version1.scriptList; + case 1: hb_barrier (); return this+u.version1.scriptList; #ifndef HB_NO_BEYOND_64K - case 2: return this+u.version2.scriptList; + case 2: hb_barrier (); return this+u.version2.scriptList; #endif default: return Null (ScriptList); } @@ -4547,9 +4685,9 @@ struct GSUBGPOS const FeatureList &get_feature_list () const { switch (u.version.major) { - case 1: return this+u.version1.featureList; + case 1: hb_barrier (); return this+u.version1.featureList; #ifndef HB_NO_BEYOND_64K - case 2: return this+u.version2.featureList; + case 2: hb_barrier (); return this+u.version2.featureList; #endif default: return Null (FeatureList); } @@ -4557,9 +4695,9 @@ struct GSUBGPOS unsigned int get_lookup_count () const { switch (u.version.major) { - case 1: return (this+u.version1.lookupList).len; + case 1: hb_barrier (); return (this+u.version1.lookupList).len; #ifndef HB_NO_BEYOND_64K - case 2: return (this+u.version2.lookupList).len; + case 2: hb_barrier (); return (this+u.version2.lookupList).len; #endif default: return 0; } @@ -4567,9 +4705,9 @@ struct GSUBGPOS const Lookup& get_lookup (unsigned int i) const { switch (u.version.major) { - case 1: return (this+u.version1.lookupList)[i]; + case 1: hb_barrier (); return (this+u.version1.lookupList)[i]; #ifndef HB_NO_BEYOND_64K - case 2: return (this+u.version2.lookupList)[i]; + case 2: hb_barrier (); return (this+u.version2.lookupList)[i]; #endif default: return Null (Lookup); } @@ -4577,9 +4715,9 @@ struct GSUBGPOS const FeatureVariations &get_feature_variations () const { switch (u.version.major) { - case 1: return (u.version.to_int () >= 0x00010001u ? this+u.version1.featureVars : Null (FeatureVariations)); + case 1: hb_barrier (); return (u.version.to_int () >= 0x00010001u && hb_barrier () ? this+u.version1.featureVars : Null (FeatureVariations)); #ifndef HB_NO_BEYOND_64K - case 2: return this+u.version2.featureVars; + case 2: hb_barrier (); return this+u.version2.featureVars; #endif default: return Null (FeatureVariations); } @@ -4613,13 +4751,14 @@ struct GSUBGPOS { return get_feature_list ().find_index (tag, index); } bool find_variations_index (const int *coords, unsigned int num_coords, - unsigned int *index) const + unsigned int *index, + ItemVarStoreInstancer *instancer) const { #ifdef HB_NO_VAR *index = FeatureVariations::NOT_FOUND_INDEX; return false; #endif - return get_feature_variations ().find_index (coords, num_coords, index); + return get_feature_variations ().find_index (coords, num_coords, index, instancer); } const Feature& get_feature_variation (unsigned int feature_index, unsigned int variations_index) const @@ -4638,11 +4777,11 @@ struct GSUBGPOS } void feature_variation_collect_lookups (const hb_set_t *feature_indexes, - const hb_hashmap_t *feature_substitutes_map, + const hb_hashmap_t> *feature_record_cond_idx_map, hb_set_t *lookup_indexes /* OUT */) const { #ifndef HB_NO_VAR - get_feature_variations ().collect_lookups (feature_indexes, feature_substitutes_map, lookup_indexes); + get_feature_variations ().collect_lookups (feature_indexes, feature_record_cond_idx_map, lookup_indexes); #endif } @@ -4772,7 +4911,12 @@ struct GSUBGPOS ~accelerator_t () { for (unsigned int i = 0; i < this->lookup_count; i++) - hb_free (this->accels[i]); + { + auto *accel = this->accels[i].get_relaxed (); + if (accel) + accel->fini (); + hb_free (accel); + } hb_free (this->accels); this->table.destroy (); } @@ -4793,6 +4937,7 @@ struct GSUBGPOS if (unlikely (!accels[lookup_index].cmpexch (nullptr, accel))) { + accel->fini (); hb_free (accel); goto retry; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-jstf-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-jstf-table.hh index 948c88269251e..823520f748340 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-jstf-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-jstf-table.hh @@ -214,6 +214,7 @@ struct JSTF { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && scriptList.sanitize (c, this)); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc index 49465acb75e21..787119dc62b33 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc @@ -87,7 +87,7 @@ using OT::Layout::GPOS; bool hb_ot_layout_has_kerning (hb_face_t *face) { - return face->table.kern->has_data (); + return face->table.kern->table->has_data (); } /** @@ -103,7 +103,7 @@ hb_ot_layout_has_kerning (hb_face_t *face) bool hb_ot_layout_has_machine_kerning (hb_face_t *face) { - return face->table.kern->has_state_machine (); + return face->table.kern->table->has_state_machine (); } /** @@ -123,7 +123,7 @@ hb_ot_layout_has_machine_kerning (hb_face_t *face) bool hb_ot_layout_has_cross_kerning (hb_face_t *face) { - return face->table.kern->has_cross_stream (); + return face->table.kern->table->has_cross_stream (); } void @@ -132,7 +132,7 @@ hb_ot_layout_kern (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer) { hb_blob_t *blob = font->face->table.kern.get_blob (); - const AAT::kern& kern = *blob->as (); + const auto& kern = *font->face->table.kern; AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); @@ -246,6 +246,18 @@ OT::GDEF::is_blocklisted (hb_blob_t *blob, /* sha1sum: c26e41d567ed821bed997e937bc0c41435689e85 Padauk.ttf * "Padauk Regular" "Version 2.5", see https://crbug.com/681813 */ case HB_CODEPOINT_ENCODE3 (1004, 59092, 14836): + /* 88d2006ca084f04af2df1954ed714a8c71e8400f Courier New.ttf from macOS 15 */ + case HB_CODEPOINT_ENCODE3 (588, 5078, 14418): + /* 608e3ebb6dd1aee521cff08eb07d500a2c59df68 Courier New Bold.ttf from macOS 15 */ + case HB_CODEPOINT_ENCODE3 (588, 5078, 14238): + /* d13221044ff054efd78f1cd8631b853c3ce85676 cour.ttf from Windows 10 */ + case HB_CODEPOINT_ENCODE3 (894, 17162, 33960): + /* 68ed4a22d8067fcf1622ac6f6e2f4d3a2e3ec394 courbd.ttf from Windows 10 */ + case HB_CODEPOINT_ENCODE3 (894, 17154, 34472): + /* 4cdb0259c96b7fd7c103821bb8f08f7cc6b211d7 cour.ttf from Windows 8.1 */ + case HB_CODEPOINT_ENCODE3 (816, 7868, 17052): + /* 920483d8a8ed37f7f0afdabbe7f679aece7c75d8 courbd.ttf from Windows 8.1 */ + case HB_CODEPOINT_ENCODE3 (816, 7868, 17138): return true; } return false; @@ -1443,8 +1455,12 @@ hb_ot_layout_table_find_feature_variations (hb_face_t *face, unsigned int *variations_index /* out */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + const OT::GDEF &gdef = *face->table.GDEF->table; - return g.find_variations_index (coords, num_coords, variations_index); + auto instancer = OT::ItemVarStoreInstancer(&gdef.get_var_store(), nullptr, + hb_array (coords, num_coords)); + + return g.find_variations_index (coords, num_coords, variations_index, &instancer); } @@ -1907,9 +1923,10 @@ apply_forward (OT::hb_ot_apply_context_t *c, while (buffer->idx < buffer->len && buffer->successful) { bool applied = false; - if (accel.digest.may_have (buffer->cur().codepoint) && - (buffer->cur().mask & c->lookup_mask) && - c->check_glyph_property (&buffer->cur(), c->lookup_props)) + auto &cur = buffer->cur(); + if (accel.digest.may_have (cur.codepoint) && + (cur.mask & c->lookup_mask) && + c->check_glyph_property (&cur, c->lookup_props)) { applied = accel.apply (c, subtable_count, use_cache); } @@ -1935,9 +1952,10 @@ apply_backward (OT::hb_ot_apply_context_t *c, hb_buffer_t *buffer = c->buffer; do { - if (accel.digest.may_have (buffer->cur().codepoint) && - (buffer->cur().mask & c->lookup_mask) && - c->check_glyph_property (&buffer->cur(), c->lookup_props)) + auto &cur = buffer->cur(); + if (accel.digest.may_have (cur.codepoint) && + (cur.mask & c->lookup_mask) && + c->check_glyph_property (&cur, c->lookup_props)) ret |= accel.apply (c, subtable_count, false); /* The reverse lookup doesn't "advance" cursor (for good reason). */ @@ -2017,7 +2035,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, * (plus some past glyphs). * * Only try applying the lookup if there is any overlap. */ - if (accel->digest.may_have (c.digest)) + if (accel->digest.may_intersect (c.digest)) { c.set_lookup_index (lookup_index); c.set_lookup_mask (lookup.mask, false); @@ -2043,7 +2061,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, if (stage->pause_func (plan, font, buffer)) { /* Refresh working buffer digest since buffer changed. */ - c.digest = buffer->digest (); + buffer->collect_codepoints (c.digest); } } } @@ -2127,7 +2145,7 @@ hb_ot_layout_get_font_extents (hb_font_t *font, hb_tag_t language_tag, hb_font_extents_t *extents) { - hb_position_t min, max; + hb_position_t min = 0, max = 0; if (font->face->table.BASE->get_min_max (font, direction, script_tag, language_tag, HB_TAG_NONE, &min, &max)) { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh index 2d9a184a89339..71074a87401d3 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh @@ -173,12 +173,12 @@ _hb_next_syllable (hb_buffer_t *buffer, unsigned int start) /* Design: * unicode_props() is a two-byte number. The low byte includes: - * - General_Category: 5 bits. + * - Modified General_Category: 5 bits. * - A bit each for: * * Is it Default_Ignorable(); we have a modified Default_Ignorable(). * * Whether it's one of the four Mongolian Free Variation Selectors, * CGJ, or other characters that are hidden but should not be ignored - * like most other Default_Ignorable()s do during matching. + * like most other Default_Ignorable()s do during GSUB matching. * * Whether it's a grapheme continuation. * * The high-byte has different meanings, switched by the Gen-Cat: @@ -186,17 +186,23 @@ _hb_next_syllable (hb_buffer_t *buffer, unsigned int start) * - For Cf: whether it's ZWJ, ZWNJ, or something else. * - For Ws: index of which space character this is, if space fallback * is needed, ie. we don't set this by default, only if asked to. + * + * Above I said "modified" General_Category. This is because we need to + * remember Variation Selectors, and we don't have bits left. So we + * change their Gen_Cat from Mn to Cf, and use a bit of the high byte to + * remember them. */ enum hb_unicode_props_flags_t { UPROPS_MASK_GEN_CAT = 0x001Fu, UPROPS_MASK_IGNORABLE = 0x0020u, - UPROPS_MASK_HIDDEN = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..4, or TAG characters */ + UPROPS_MASK_HIDDEN = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..4, or TAG characters, or CGJ sometimes */ UPROPS_MASK_CONTINUATION=0x0080u, /* If GEN_CAT=FORMAT, top byte masks: */ UPROPS_MASK_Cf_ZWJ = 0x0100u, - UPROPS_MASK_Cf_ZWNJ = 0x0200u + UPROPS_MASK_Cf_ZWNJ = 0x0200u, + UPROPS_MASK_Cf_VS = 0x0400u }; HB_MARK_AS_FLAG_T (hb_unicode_props_flags_t); @@ -229,7 +235,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) /* TAG characters need similar treatment. Fixes: * https://github.com/harfbuzz/harfbuzz/issues/463 */ else if (unlikely (hb_in_range (u, 0xE0020u, 0xE007Fu))) props |= UPROPS_MASK_HIDDEN; - /* COMBINING GRAPHEME JOINER should not be skipped; at least some times. + /* COMBINING GRAPHEME JOINER should not be skipped during GSUB either. * https://github.com/harfbuzz/harfbuzz/issues/554 */ else if (unlikely (u == 0x034Fu)) { @@ -302,6 +308,27 @@ _hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info) (hb_unicode_funcs_t::space_t) (info->unicode_props()>>8) : hb_unicode_funcs_t::NOT_SPACE; } +static inline bool +_hb_glyph_info_is_variation_selector (const hb_glyph_info_t *info) +{ + return _hb_glyph_info_get_general_category (info) == + HB_UNICODE_GENERAL_CATEGORY_FORMAT && + (info->unicode_props() & UPROPS_MASK_Cf_VS); +} +static inline void +_hb_glyph_info_set_variation_selector (hb_glyph_info_t *info, bool customize) +{ + if (customize) + { + _hb_glyph_info_set_general_category (info, HB_UNICODE_GENERAL_CATEGORY_FORMAT); + info->unicode_props() |= UPROPS_MASK_Cf_VS; + } + else + { + // Reset to their original condition + _hb_glyph_info_set_general_category (info, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK); + } +} static inline bool _hb_glyph_info_substituted (const hb_glyph_info_t *info); @@ -311,12 +338,20 @@ _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) return (info->unicode_props() & UPROPS_MASK_IGNORABLE) && !_hb_glyph_info_substituted (info); } +static inline void +_hb_glyph_info_set_default_ignorable (hb_glyph_info_t *info) +{ + info->unicode_props() |= UPROPS_MASK_IGNORABLE; +} +static inline void +_hb_glyph_info_clear_default_ignorable (hb_glyph_info_t *info) +{ + info->unicode_props() &= ~ UPROPS_MASK_IGNORABLE; +} static inline bool -_hb_glyph_info_is_default_ignorable_and_not_hidden (const hb_glyph_info_t *info) +_hb_glyph_info_is_hidden (const hb_glyph_info_t *info) { - return ((info->unicode_props() & (UPROPS_MASK_IGNORABLE|UPROPS_MASK_HIDDEN)) - == UPROPS_MASK_IGNORABLE) && - !_hb_glyph_info_substituted (info); + return info->unicode_props() & UPROPS_MASK_HIDDEN; } static inline void _hb_glyph_info_unhide (hb_glyph_info_t *info) @@ -330,7 +365,7 @@ _hb_glyph_info_set_continuation (hb_glyph_info_t *info) info->unicode_props() |= UPROPS_MASK_CONTINUATION; } static inline void -_hb_glyph_info_reset_continuation (hb_glyph_info_t *info) +_hb_glyph_info_clear_continuation (hb_glyph_info_t *info) { info->unicode_props() &= ~ UPROPS_MASK_CONTINUATION; } @@ -603,8 +638,7 @@ _hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer) } /* Make sure no one directly touches our props... */ -#undef unicode_props0 -#undef unicode_props1 +#undef unicode_props #undef lig_props #undef glyph_props diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc index 261ce43049c67..a0cdfddfa632f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc @@ -390,5 +390,19 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, } } +unsigned int hb_ot_map_t::get_feature_tags (unsigned int start_offset, unsigned int *tag_count, hb_tag_t *tags) const +{ + if (tag_count) + { + auto sub_features = features.as_array ().sub_array (start_offset, tag_count); + if (tags) + { + for (unsigned int i = 0; i < sub_features.length; i++) + tags[i] = sub_features[i].tag; + } + } + + return features.length; +} #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh index 110361552c028..68af9792439fd 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh @@ -166,6 +166,9 @@ struct hb_ot_map_t const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; + HB_INTERNAL unsigned int get_feature_tags (unsigned int start_offset, + unsigned int *tag_count, /* IN/OUT */ + hb_tag_t *tags /* OUT */) const; public: hb_tag_t chosen_script[2]; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh index 63bcd132cf436..c1b2a27b21d6a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh @@ -333,6 +333,7 @@ struct MathKern { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_array (mathValueRecordsZ.arrayZ, 2 * heightCount + 1) && sanitize_math_value_records (c)); } @@ -343,27 +344,20 @@ struct MathKern const MathValueRecord* kernValue = mathValueRecordsZ.arrayZ + heightCount; int sign = font->y_scale < 0 ? -1 : +1; - /* The description of the MathKern table is a ambiguous, but interpreting - * "between the two heights found at those indexes" for 0 < i < len as - * - * correctionHeight[i-1] < correction_height <= correctionHeight[i] - * - * makes the result consistent with the limit cases and we can just use the - * binary search algorithm of std::upper_bound: + /* According to OpenType spec (v1.9), except for the boundary cases, the index + * chosen for kern value should be i such that + * correctionHeight[i-1] <= correction_height < correctionHeight[i] + * We can use the binary search algorithm of std::upper_bound(). Or, we can + * use the internal hb_bsearch_impl. */ - unsigned int i = 0; - unsigned int count = heightCount; - while (count > 0) - { - unsigned int half = count / 2; - hb_position_t height = correctionHeight[i + half].get_y_value (font, this); - if (sign * height < sign * correction_height) - { - i += half + 1; - count -= half + 1; - } else - count = half; - } + unsigned int pos; + auto cmp = +[](const void* key, const void* p, + int sign, hb_font_t* font, const MathKern* mathKern) -> int { + return sign * *(hb_position_t*)key - sign * ((MathValueRecord*)p)->get_y_value(font, mathKern); + }; + unsigned int i = hb_bsearch_impl(&pos, correction_height, correctionHeight, + heightCount, MathValueRecord::static_size, + cmp, sign, font, this) ? pos + 1 : pos; return kernValue[i].get_x_value (font, this); } @@ -984,6 +978,7 @@ struct MathVariants return_trace (c->check_struct (this) && vertGlyphCoverage.sanitize (c, this) && horizGlyphCoverage.sanitize (c, this) && + hb_barrier () && c->check_array (glyphConstruction.arrayZ, vertGlyphCount + horizGlyphCount) && sanitize_offsets (c)); } @@ -1103,6 +1098,7 @@ struct MATH TRACE_SANITIZE (this); return_trace (version.sanitize (c) && likely (version.major == 1) && + hb_barrier () && mathConstants.sanitize (c, this) && mathGlyphInfo.sanitize (c, this) && mathVariants.sanitize (c, this)); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-maxp-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-maxp-table.hh index f7f2e860e4a9f..f6eeda40ed672 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-maxp-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-maxp-table.hh @@ -85,7 +85,7 @@ struct maxp TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); - + hb_barrier (); if (version.major == 1) { const maxpV1Tail &v1 = StructAfter (*this); @@ -103,6 +103,7 @@ struct maxp maxp_prime->numGlyphs = hb_min (c->plan->num_output_glyphs (), 0xFFFFu); if (maxp_prime->version.major == 1) { + hb_barrier (); const maxpV1Tail *src_v1 = &StructAfter (*this); maxpV1Tail *dest_v1 = c->serializer->embed (src_v1); if (unlikely (!dest_v1)) return_trace (false); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-meta-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-meta-table.hh index 1f011882807a0..20c62b83edbe3 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-meta-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-meta-table.hh @@ -51,6 +51,7 @@ struct DataMap { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && dataZ.sanitize (c, base, dataLength))); } @@ -101,6 +102,7 @@ struct meta { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version == 1 && dataMaps.sanitize (c, this))); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh index 30ae335d703f6..24e9c9703531a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh @@ -209,6 +209,23 @@ struct OS2 return ret; } + static unsigned calc_avg_char_width (const hb_hashmap_t>& hmtx_map) + { + unsigned num = 0; + unsigned total_width = 0; + for (const auto& _ : hmtx_map.values_ref ()) + { + unsigned width = _.first; + if (width) + { + total_width += width; + num++; + } + } + + return num ? (unsigned) roundf ((double) total_width / (double) num) : 0; + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -239,17 +256,23 @@ struct OS2 if (os2_prime->version >= 2) { + hb_barrier (); auto *table = & const_cast (os2_prime->v2 ()); HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_X_HEIGHT, sxHeight); HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_CAP_HEIGHT, sCapHeight); } + + unsigned avg_char_width = calc_avg_char_width (c->plan->hmtx_map); + if (!c->serializer->check_assign (os2_prime->xAvgCharWidth, avg_char_width, + HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); } #endif Triple *axis_range; if (c->plan->user_axes_location.has (HB_TAG ('w','g','h','t'), &axis_range)) { - unsigned weight_class = static_cast (roundf (hb_clamp (axis_range->middle, 1.0f, 1000.0f))); + unsigned weight_class = static_cast (roundf (hb_clamp (axis_range->middle, 1.0, 1000.0))); if (os2_prime->usWeightClass != weight_class) os2_prime->usWeightClass = weight_class; } @@ -261,12 +284,12 @@ struct OS2 os2_prime->usWidthClass = width_class; } + os2_prime->usFirstCharIndex = hb_min (0xFFFFu, c->plan->os2_info.min_cmap_codepoint); + os2_prime->usLastCharIndex = hb_min (0xFFFFu, c->plan->os2_info.max_cmap_codepoint); + if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES) return_trace (true); - os2_prime->usFirstCharIndex = hb_min (0xFFFFu, c->plan->unicodes.get_min ()); - os2_prime->usLastCharIndex = hb_min (0xFFFFu, c->plan->unicodes.get_max ()); - _update_unicode_ranges (&c->plan->unicodes, os2_prime->ulUnicodeRange); return_trace (true); @@ -334,6 +357,7 @@ struct OS2 { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); if (unlikely (version >= 1 && !v1X.sanitize (c))) return_trace (false); if (unlikely (version >= 2 && !v2X.sanitize (c))) return_trace (false); if (unlikely (version >= 5 && !v5X.sanitize (c))) return_trace (false); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh index d44233610a695..67d1b6aa713a7 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh @@ -84,9 +84,9 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const old_gid_new_index_map.alloc (num_glyphs); glyph_name_to_new_index.alloc (num_glyphs); - for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++) + for (auto _ : c->plan->new_to_old_gid_list) { - hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid); + hb_codepoint_t old_gid = _.second; unsigned old_index = glyphNameIndex[old_gid]; unsigned new_index; @@ -125,13 +125,22 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const old_gid_new_index_map.set (old_gid, new_index); } + if (old_gid_new_index_map.in_error()) + return_trace (false); + auto index_iter = + hb_range (num_glyphs) - | hb_map (reverse_glyph_map) - | hb_map_retains_sorting ([&](hb_codepoint_t old_gid) + | hb_map_retains_sorting ([&](hb_codepoint_t new_gid) { - unsigned new_index = old_gid_new_index_map.get (old_gid); - return hb_pair_t (old_gid, new_index); + hb_codepoint_t *old_gid; + /* use 0 for retain-gid holes, which refers to the name .notdef, + * as the glyphNameIndex entry for that glyph ID."*/ + unsigned new_index = 0; + if (reverse_glyph_map.has (new_gid, &old_gid)) { + new_index = old_gid_new_index_map.get (*old_gid); + return hb_pair_t (*old_gid, new_index); + } + return hb_pair_t (new_gid, new_index); }) ; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh index d41c86f8bd317..83d310e16a0a1 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh @@ -116,13 +116,16 @@ struct post Triple *axis_range; if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t'), &axis_range)) { - float italic_angle = hb_max (-90.f, hb_min (axis_range->middle, 90.f)); + float italic_angle = hb_max (-90.0, hb_min (axis_range->middle, 90.0)); if (post_prime->italicAngle.to_float () != italic_angle) post_prime->italicAngle.set_float (italic_angle); } if (glyph_names && version.major == 2) + { + hb_barrier (); return_trace (v2X.subset (c)); + } return_trace (true); } @@ -138,6 +141,7 @@ struct post version = table->version.to_int (); if (version != 0x00020000) return; + hb_barrier (); const postV2Tail &v2 = table->v2X; @@ -217,10 +221,16 @@ struct post unsigned int get_glyph_count () const { if (version == 0x00010000) + { + hb_barrier (); return format1_names_length; + } if (version == 0x00020000) + { + hb_barrier (); return glyphNameIndex->len; + } return 0; } @@ -245,13 +255,18 @@ struct post { if (version == 0x00010000) { + hb_barrier (); if (glyph >= format1_names_length) return hb_bytes_t (); return format1_names (glyph); } - if (version != 0x00020000 || glyph >= glyphNameIndex->len) + if (version != 0x00020000) + return hb_bytes_t (); + hb_barrier (); + + if (glyph >= glyphNameIndex->len) return hb_bytes_t (); unsigned int index = glyphNameIndex->arrayZ[glyph]; @@ -284,8 +299,9 @@ struct post { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && (version.to_int () == 0x00010000 || - (version.to_int () == 0x00020000 && v2X.sanitize (c)) || + (version.to_int () == 0x00020000 && hb_barrier () && v2X.sanitize (c)) || version.to_int () == 0x00030000)); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc index b1acc7e7db3c3..cb941bc7fbd22 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc @@ -74,23 +74,6 @@ * Indic shaper may want to disallow recomposing of two matras. */ -static bool -decompose_unicode (const hb_ot_shape_normalize_context_t *c, - hb_codepoint_t ab, - hb_codepoint_t *a, - hb_codepoint_t *b) -{ - return (bool) c->unicode->decompose (ab, a, b); -} - -static bool -compose_unicode (const hb_ot_shape_normalize_context_t *c, - hb_codepoint_t a, - hb_codepoint_t b, - hb_codepoint_t *ab) -{ - return (bool) c->unicode->compose (a, b, ab); -} static inline void set_glyph (hb_glyph_info_t &info, hb_font_t *font) @@ -170,7 +153,7 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor hb_codepoint_t u = buffer->cur().codepoint; hb_codepoint_t glyph = 0; - if (shortest && c->font->get_nominal_glyph (u, &glyph, c->not_found)) + if (shortest && c->font->get_nominal_glyph (u, &glyph, buffer->not_found)) { next_char (buffer, glyph); return; @@ -182,7 +165,7 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor return; } - if (!shortest && c->font->get_nominal_glyph (u, &glyph, c->not_found)) + if (!shortest && c->font->get_nominal_glyph (u, &glyph, buffer->not_found)) { next_char (buffer, glyph); return; @@ -237,6 +220,12 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, /* Just pass on the two characters separately, let GSUB do its magic. */ set_glyph (buffer->cur(), font); (void) buffer->next_glyph (); + + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK; + _hb_glyph_info_set_variation_selector (&buffer->cur(), true); + if (buffer->not_found_variation_selector != HB_CODEPOINT_INVALID) + _hb_glyph_info_clear_default_ignorable (&buffer->cur()); + set_glyph (buffer->cur(), font); (void) buffer->next_glyph (); } @@ -307,15 +296,15 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, mode = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS; } - const hb_ot_shape_normalize_context_t c = { + hb_ot_shape_normalize_context_t c = { plan, buffer, font, buffer->unicode, - buffer->not_found, - plan->shaper->decompose ? plan->shaper->decompose : decompose_unicode, - plan->shaper->compose ? plan->shaper->compose : compose_unicode + plan->shaper->decompose ? plan->shaper->decompose : hb_ot_shape_normalize_context_t::decompose_unicode, + plan->shaper->compose ? plan->shaper->compose : hb_ot_shape_normalize_context_t::compose_unicode }; + c.override_decompose_and_compose (plan->shaper->decompose, plan->shaper->compose); bool always_short_circuit = mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE; bool might_short_circuit = always_short_circuit || diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh index afd62dd40726a..9f17bdbb24326 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh @@ -28,6 +28,7 @@ #define HB_OT_SHAPE_NORMALIZE_HH #include "hb.hh" +#include "hb-unicode.hh" /* buffer var allocations, used during the normalization process */ @@ -52,11 +53,42 @@ HB_INTERNAL void _hb_ot_shape_normalize (const hb_ot_shape_plan_t *shaper, struct hb_ot_shape_normalize_context_t { + static bool + decompose_unicode (const hb_ot_shape_normalize_context_t *c, + hb_codepoint_t ab, + hb_codepoint_t *a, + hb_codepoint_t *b) + { + return (bool) c->unicode->decompose (ab, a, b); + } + + static bool + compose_unicode (const hb_ot_shape_normalize_context_t *c, + hb_codepoint_t a, + hb_codepoint_t b, + hb_codepoint_t *ab) + { + return (bool) c->unicode->compose (a, b, ab); + } + + void + override_decompose_and_compose (bool (*decompose) (const hb_ot_shape_normalize_context_t *c, + hb_codepoint_t ab, + hb_codepoint_t *a, + hb_codepoint_t *b), + bool (*compose) (const hb_ot_shape_normalize_context_t *c, + hb_codepoint_t a, + hb_codepoint_t b, + hb_codepoint_t *ab)) + { + this->decompose = decompose ? decompose : decompose_unicode; + this->compose = compose ? compose : compose_unicode; + } + const hb_ot_shape_plan_t *plan; hb_buffer_t *buffer; hb_font_t *font; hb_unicode_funcs_t *unicode; - const hb_codepoint_t not_found; bool (*decompose) (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t ab, hb_codepoint_t *a, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc index f936ac45f37e1..6265f0eb17d68 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc @@ -46,6 +46,8 @@ #include "hb-set.hh" #include "hb-aat-layout.hh" +#include "hb-ot-stat-table.hh" + static inline bool _hb_codepoint_is_regional_indicator (hb_codepoint_t u) @@ -85,7 +87,7 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac , apply_morx (_hb_apply_morx (face, props)) #endif { - shaper = hb_ot_shaper_categorize (this); + shaper = hb_ot_shaper_categorize (props.script, props.direction, map.chosen_script[0]); script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE; script_fallback_mark_positioning = shaper->fallback_position; @@ -121,10 +123,6 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.kern_mask = plan.map.get_mask (kern_tag); plan.requested_kerning = !!plan.kern_mask; #endif -#ifndef HB_NO_AAT_SHAPE - plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k')); - plan.requested_tracking = !!plan.trak_mask; -#endif bool has_gpos_kern = plan.map.get_feature_index (1, kern_tag) != HB_OT_LAYOUT_NO_FEATURE_INDEX; bool disable_gpos = plan.shaper->gpos_tag && @@ -155,7 +153,7 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, #endif bool has_gpos = !disable_gpos && hb_ot_layout_has_positioning (face); if (false) - ; + {} #ifndef HB_NO_AAT_SHAPE /* Prefer GPOS over kerx if GSUB is present; * https://github.com/harfbuzz/harfbuzz/issues/3008 */ @@ -167,15 +165,16 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, if (!plan.apply_kerx && (!has_gpos_kern || !plan.apply_gpos)) { + if (false) {} #ifndef HB_NO_AAT_SHAPE - if (has_kerx) + else if (has_kerx) plan.apply_kerx = true; - else #endif #ifndef HB_NO_OT_KERN - if (hb_ot_layout_has_kerning (face)) + else if (hb_ot_layout_has_kerning (face)) plan.apply_kern = true; #endif + else {} } plan.apply_fallback_kern = !(plan.apply_gpos || plan.apply_kerx || plan.apply_kern); @@ -206,9 +205,6 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, https://github.com/harfbuzz/harfbuzz/issues/2967. */ if (plan.apply_morx) plan.adjust_mark_positioning_when_zeroing = false; - - /* Currently we always apply trak. */ - plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face); #endif } @@ -273,11 +269,6 @@ hb_ot_shape_plan_t::position (hb_font_t *font, #endif else if (this->apply_fallback_kern) _hb_ot_shape_fallback_kern (this, font, buffer); - -#ifndef HB_NO_AAT_SHAPE - if (this->apply_trak) - hb_aat_layout_track (this, font, buffer); -#endif } @@ -345,13 +336,6 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, /* Random! */ map->enable_feature (HB_TAG ('r','a','n','d'), F_RANDOM, HB_OT_MAP_MAX_VALUE); -#ifndef HB_NO_AAT_SHAPE - /* Tracking. We enable dummy feature here just to allow disabling - * AAT 'trak' table using features. - * https://github.com/harfbuzz/harfbuzz/issues/1303 */ - map->enable_feature (HB_TAG ('t','r','a','k'), F_HAS_FALLBACK); -#endif - map->enable_feature (HB_TAG ('H','a','r','f')); /* Considered required. */ map->enable_feature (HB_TAG ('H','A','R','F')); /* Considered discretionary. */ @@ -836,6 +820,28 @@ hb_ot_zero_width_default_ignorables (const hb_buffer_t *buffer) pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; } +static void +hb_ot_deal_with_variation_selectors (hb_buffer_t *buffer) +{ + if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK) || + buffer->not_found_variation_selector == HB_CODEPOINT_INVALID) + return; + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + + for (unsigned int i = 0; i < count; i++) + { + if (_hb_glyph_info_is_variation_selector (&info[i])) + { + info[i].codepoint = buffer->not_found_variation_selector; + pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; + _hb_glyph_info_set_variation_selector (&info[i], false); + } + } +} + static void hb_ot_hide_default_ignorables (hb_buffer_t *buffer, hb_font_t *font) @@ -965,6 +971,7 @@ hb_ot_substitute_post (const hb_ot_shape_context_t *c) hb_aat_layout_remove_deleted_glyphs (c->buffer); #endif + hb_ot_deal_with_variation_selectors (c->buffer); hb_ot_hide_default_ignorables (c->buffer, c->font); if (c->plan->shaper->postprocess_glyphs && @@ -1253,6 +1260,36 @@ hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, } +/** + * hb_ot_shape_plan_get_feature_tags: + * @shape_plan: A shaping plan + * @start_offset: The index of first feature to retrieve + * @tag_count: (inout): Input = the maximum number of features to return; + * Output = the actual number of features returned (may be zero) + * @tags: (out) (array length=tag_count): The array of enabled feature + * + * Fetches the list of OpenType feature tags enabled for a shaping plan, if possible. + * + * Return value: Total number of feature tagss. + * + * Since: 10.3.0 + */ +unsigned int +hb_ot_shape_plan_get_feature_tags (hb_shape_plan_t *shape_plan, + unsigned int start_offset, + unsigned int *tag_count, /* IN/OUT */ + hb_tag_t *tags /* OUT */) +{ +#ifndef HB_NO_OT_SHAPE + return shape_plan->ot.map.get_feature_tags (start_offset, tag_count, tags); +#else + if (tag_count) + *tag_count = 0; + return 0; +#endif +} + + /* TODO Move this to hb-ot-shape-normalize, make it do decompose, and make it public. */ static void add_char (hb_font_t *font, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.h b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.h index 545e2c3f1b4ce..1732831b1325c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.h @@ -48,6 +48,12 @@ hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, hb_tag_t table_tag, hb_set_t *lookup_indexes /* OUT */); +HB_EXTERN unsigned int +hb_ot_shape_plan_get_feature_tags (hb_shape_plan_t *shape_plan, + unsigned int start_offset, + unsigned int *tag_count, /* IN/OUT */ + hb_tag_t *tags /* OUT */); + HB_END_DECLS #endif /* HB_OT_SHAPE_H */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh index 2fa121ced8137..d5ee82d4c0beb 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh @@ -51,7 +51,8 @@ struct hb_ot_shape_plan_key_t bool equal (const hb_ot_shape_plan_key_t *other) { - return 0 == hb_memcmp (this, other, sizeof (*this)); + return variations_index[0] == other->variations_index[0] && + variations_index[1] == other->variations_index[1]; } }; @@ -79,22 +80,12 @@ struct hb_ot_shape_plan_t #else static constexpr hb_mask_t kern_mask = 0; #endif -#ifndef HB_NO_AAT_SHAPE - hb_mask_t trak_mask; -#else - static constexpr hb_mask_t trak_mask = 0; -#endif #ifndef HB_NO_OT_KERN bool requested_kerning : 1; #else static constexpr bool requested_kerning = false; #endif -#ifndef HB_NO_AAT_SHAPE - bool requested_tracking : 1; -#else - static constexpr bool requested_tracking = false; -#endif #ifndef HB_NO_OT_SHAPE_FRACTIONS bool has_frac : 1; #else @@ -117,11 +108,9 @@ struct hb_ot_shape_plan_t #ifndef HB_NO_AAT_SHAPE bool apply_kerx : 1; bool apply_morx : 1; - bool apply_trak : 1; #else static constexpr bool apply_kerx = false; static constexpr bool apply_morx = false; - static constexpr bool apply_trak = false; #endif void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh index 858a9872726b1..ff0b2acede1d9 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh @@ -355,6 +355,8 @@ arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan) for (unsigned int i = 0; i < fallback_plan->num_lookups; i++) if (fallback_plan->lookup_array[i]) { + if (fallback_plan->accel_array[i]) + fallback_plan->accel_array[i]->fini (); hb_free (fallback_plan->accel_array[i]); if (fallback_plan->free_lookups) hb_free (fallback_plan->lookup_array[i]); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh index a5a7b84af4516..e38686e3ebb78 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-15.1.0.txt - * # Date: 2023-01-05 - * # Scripts-15.1.0.txt - * # Date: 2023-07-28, 16:01:07 GMT + * # ArabicShaping-16.0.0.txt + * # Date: 2024-07-30 + * # Scripts-16.0.0.txt + * # Date: 2024-04-30, 21:48:40 GMT */ #ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh index 8c2504438d969..19bd72d421883 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-15.1.0.txt - * # Date: 2023-01-05 - * # Blocks-15.1.0.txt - * # Date: 2023-07-28, 15:47:20 GMT + * # ArabicShaping-16.0.0.txt + * # Date: 2024-07-30 + * # Blocks-16.0.0.txt + * # Date: 2024-02-02 * UnicodeData.txt does not have a header. */ @@ -136,7 +136,13 @@ static const uint8_t joining_table[] = /* 10D00 */ L,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* 10D20 */ D,D,R,D, -#define joining_offset_0x10f30u 1182 +#define joining_offset_0x10ec2u 1182 + + /* Arabic Extended-C */ + + /* 10EC0 */ R,D,D, + +#define joining_offset_0x10f30u 1185 /* Sogdian */ @@ -155,14 +161,14 @@ static const uint8_t joining_table[] = /* 10FA0 */ D,U,D,D,R,R,R,U,D,R,R,D,D,R,D,D, /* 10FC0 */ U,D,R,R,D,U,U,U,U,R,D,L, -#define joining_offset_0x110bdu 1338 +#define joining_offset_0x110bdu 1341 /* Kaithi */ /* 110A0 */ U,X,X, /* 110C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,U, -#define joining_offset_0x1e900u 1355 +#define joining_offset_0x1e900u 1358 /* Adlam */ @@ -170,7 +176,7 @@ static const uint8_t joining_table[] = /* 1E920 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* 1E940 */ D,D,D,D,X,X,X,X,X,X,X,T, -}; /* Table items: 1431; occupancy: 57% */ +}; /* Table items: 1434; occupancy: 57% */ static unsigned int @@ -198,6 +204,7 @@ joining_type (hb_codepoint_t u) if (hb_in_range (u, 0x10AC0u, 0x10AEFu)) return joining_table[u - 0x10AC0u + joining_offset_0x10ac0u]; if (hb_in_range (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u]; if (hb_in_range (u, 0x10D00u, 0x10D23u)) return joining_table[u - 0x10D00u + joining_offset_0x10d00u]; + if (hb_in_range (u, 0x10EC2u, 0x10EC4u)) return joining_table[u - 0x10EC2u + joining_offset_0x10ec2u]; if (hb_in_range (u, 0x10F30u, 0x10FCBu)) return joining_table[u - 0x10F30u + joining_offset_0x10f30u]; break; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc index 87d76e1a1013a..67db6cb26c421 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc @@ -233,10 +233,7 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) map->enable_feature (HB_TAG('c','a','l','t'), F_MANUAL_ZWJ); /* https://github.com/harfbuzz/harfbuzz/issues/1573 */ if (!map->has_feature (HB_TAG('r','c','l','t'))) - { map->add_gsub_pause (nullptr); - map->enable_feature (HB_TAG('r','c','l','t'), F_MANUAL_ZWJ); - } map->enable_feature (HB_TAG('l','i','g','a'), F_MANUAL_ZWJ); map->enable_feature (HB_TAG('c','l','i','g'), F_MANUAL_ZWJ); @@ -560,9 +557,9 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, DEBUG_MSG (ARABIC, nullptr, "%s stretch at (%u,%u,%u)", step == MEASURE ? "measuring" : "cutting", context, start, end); - DEBUG_MSG (ARABIC, nullptr, "rest of word: count=%u width %d", start - context, w_total); - DEBUG_MSG (ARABIC, nullptr, "fixed tiles: count=%d width=%d", n_fixed, w_fixed); - DEBUG_MSG (ARABIC, nullptr, "repeating tiles: count=%d width=%d", n_repeating, w_repeating); + DEBUG_MSG (ARABIC, nullptr, "rest of word: count=%u width %" PRId32, start - context, w_total); + DEBUG_MSG (ARABIC, nullptr, "fixed tiles: count=%d width=%" PRId32, n_fixed, w_fixed); + DEBUG_MSG (ARABIC, nullptr, "repeating tiles: count=%d width=%" PRId32, n_repeating, w_repeating); /* Number of additional times to repeat each repeating tile. */ int n_copies = 0; @@ -602,7 +599,7 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, if (info[k - 1].arabic_shaping_action() == STCH_REPEATING) repeat += n_copies; - DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %u; j=%u", + DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %" PRIu32 "; j=%u", repeat, info[k - 1].codepoint, j); pos[k - 1].x_advance = 0; for (unsigned int n = 0; n < repeat; n++) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hebrew.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hebrew.cc index bb9950d02d281..0ad1cea953252 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hebrew.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hebrew.cc @@ -78,7 +78,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c, return found; #endif - if (!found && !c->plan->has_gpos_mark) + if (!found && (c->plan && !c->plan->has_gpos_mark)) { /* Special-case Hebrew presentation forms that are excluded from * standard normalization, but wanted for old fonts. */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh index 6a6db44840eae..25e6d85ef8048 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh @@ -68,6 +68,7 @@ enum indic_syllable_type_t { #define indic_syllable_machine_ex_Ra 15u #define indic_syllable_machine_ex_Repha 14u #define indic_syllable_machine_ex_SM 8u +#define indic_syllable_machine_ex_SMPst 57u #define indic_syllable_machine_ex_Symbol 17u #define indic_syllable_machine_ex_V 2u #define indic_syllable_machine_ex_VD 9u @@ -76,251 +77,916 @@ enum indic_syllable_type_t { #define indic_syllable_machine_ex_ZWNJ 5u -#line 80 "hb-ot-shaper-indic-machine.hh" +#line 81 "hb-ot-shaper-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { - 8u, 8u, 4u, 13u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, - 8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, - 8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 8u, 8u, - 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 5u, 13u, 8u, 8u, 1u, 18u, - 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u, - 1u, 15u, 1u, 15u, 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 4u, 13u, - 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 3u, 16u, 3u, 16u, 4u, 16u, - 1u, 15u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, - 1u, 15u, 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 4u, 13u, 5u, 9u, - 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 4u, 13u, 3u, 16u, 3u, 16u, - 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, - 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 3u, 16u, 4u, 13u, 5u, 9u, - 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 4u, 13u, 4u, 13u, 3u, 16u, 3u, 16u, - 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, - 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 3u, 16u, 4u, 13u, 5u, 9u, - 5u, 9u, 3u, 9u, 5u, 9u, 1u, 16u, 3u, 16u, 1u, 16u, 4u, 13u, 5u, 13u, - 5u, 13u, 9u, 9u, 5u, 9u, 1u, 15u, 3u, 9u, 5u, 9u, 5u, 9u, 9u, 9u, + 8u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, + 8u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, 4u, 57u, + 8u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, 8u, 57u, + 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 5u, 57u, 8u, 57u, 1u, 57u, + 3u, 57u, 3u, 57u, 4u, 57u, 1u, 57u, 5u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, + 1u, 57u, 1u, 57u, 1u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 4u, 57u, + 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 4u, 57u, + 1u, 57u, 3u, 57u, 3u, 57u, 4u, 57u, 1u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, + 1u, 57u, 1u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 4u, 57u, 5u, 57u, + 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, 4u, 57u, 3u, 57u, 3u, 57u, + 4u, 57u, 1u, 57u, 3u, 57u, 1u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, 1u, 57u, + 1u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, + 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 4u, 57u, 4u, 57u, 3u, 57u, 3u, 57u, + 4u, 57u, 1u, 57u, 3u, 57u, 1u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, 1u, 57u, + 1u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, + 5u, 57u, 3u, 57u, 5u, 57u, 1u, 57u, 3u, 57u, 1u, 57u, 4u, 57u, 5u, 57u, + 5u, 57u, 9u, 9u, 5u, 9u, 1u, 57u, 3u, 57u, 5u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, 1u, 15u, 0 }; static const char _indic_syllable_machine_key_spans[] = { - 1, 10, 9, 9, 1, 10, 10, 10, - 1, 9, 9, 1, 10, 10, 10, 10, - 1, 9, 9, 1, 10, 10, 10, 1, - 9, 9, 1, 10, 10, 9, 1, 18, - 14, 14, 13, 15, 5, 5, 1, 5, - 15, 15, 15, 11, 10, 9, 9, 10, - 5, 7, 5, 14, 14, 14, 14, 13, - 15, 14, 14, 13, 15, 5, 1, 5, - 15, 15, 11, 10, 9, 9, 10, 5, - 5, 7, 5, 14, 14, 10, 14, 14, - 13, 15, 14, 15, 5, 1, 5, 15, - 15, 11, 10, 9, 9, 14, 10, 5, - 5, 7, 5, 14, 10, 10, 14, 14, - 13, 15, 14, 15, 5, 1, 5, 15, - 15, 11, 10, 9, 9, 14, 10, 5, - 5, 7, 5, 16, 14, 16, 10, 9, - 9, 1, 5, 15, 7, 5, 5, 1, + 50, 54, 53, 53, 1, 54, 54, 54, + 50, 53, 53, 1, 54, 54, 54, 54, + 50, 53, 53, 1, 54, 54, 54, 50, + 53, 53, 1, 54, 54, 53, 50, 57, + 55, 55, 54, 57, 53, 53, 1, 5, + 57, 57, 57, 55, 54, 53, 53, 54, + 53, 55, 53, 55, 55, 55, 55, 54, + 57, 55, 55, 54, 57, 53, 1, 5, + 57, 57, 55, 54, 53, 53, 54, 53, + 53, 55, 53, 55, 55, 54, 55, 55, + 54, 57, 55, 57, 53, 1, 5, 57, + 57, 55, 54, 53, 53, 55, 54, 53, + 53, 55, 53, 55, 54, 54, 55, 55, + 54, 57, 55, 57, 53, 1, 5, 57, + 57, 55, 54, 53, 53, 55, 54, 53, + 53, 55, 53, 57, 55, 57, 54, 53, + 53, 1, 5, 57, 55, 53, 53, 1, 5, 15 }; static const short _indic_syllable_machine_index_offsets[] = { - 0, 2, 13, 23, 33, 35, 46, 57, - 68, 70, 80, 90, 92, 103, 114, 125, - 136, 138, 148, 158, 160, 171, 182, 193, - 195, 205, 215, 217, 228, 239, 249, 251, - 270, 285, 300, 314, 330, 336, 342, 344, - 350, 366, 382, 398, 410, 421, 431, 441, - 452, 458, 466, 472, 487, 502, 517, 532, - 546, 562, 577, 592, 606, 622, 628, 630, - 636, 652, 668, 680, 691, 701, 711, 722, - 728, 734, 742, 748, 763, 778, 789, 804, - 819, 833, 849, 864, 880, 886, 888, 894, - 910, 926, 938, 949, 959, 969, 984, 995, - 1001, 1007, 1015, 1021, 1036, 1047, 1058, 1073, - 1088, 1102, 1118, 1133, 1149, 1155, 1157, 1163, - 1179, 1195, 1207, 1218, 1228, 1238, 1253, 1264, - 1270, 1276, 1284, 1290, 1307, 1322, 1339, 1350, - 1360, 1370, 1372, 1378, 1394, 1402, 1408, 1414, - 1416, 1422 + 0, 51, 106, 160, 214, 216, 271, 326, + 381, 432, 486, 540, 542, 597, 652, 707, + 762, 813, 867, 921, 923, 978, 1033, 1088, + 1139, 1193, 1247, 1249, 1304, 1359, 1413, 1464, + 1522, 1578, 1634, 1689, 1747, 1801, 1855, 1857, + 1863, 1921, 1979, 2037, 2093, 2148, 2202, 2256, + 2311, 2365, 2421, 2475, 2531, 2587, 2643, 2699, + 2754, 2812, 2868, 2924, 2979, 3037, 3091, 3093, + 3099, 3157, 3215, 3271, 3326, 3380, 3434, 3489, + 3543, 3597, 3653, 3707, 3763, 3819, 3874, 3930, + 3986, 4041, 4099, 4155, 4213, 4267, 4269, 4275, + 4333, 4391, 4447, 4502, 4556, 4610, 4666, 4721, + 4775, 4829, 4885, 4939, 4995, 5050, 5105, 5161, + 5217, 5272, 5330, 5386, 5444, 5498, 5500, 5506, + 5564, 5622, 5678, 5733, 5787, 5841, 5897, 5952, + 6006, 6060, 6116, 6170, 6228, 6284, 6342, 6397, + 6451, 6505, 6507, 6513, 6571, 6627, 6681, 6735, + 6737, 6743 }; static const unsigned char _indic_syllable_machine_indicies[] = { - 1, 0, 2, 3, 3, 4, 5, 0, - 0, 0, 0, 4, 0, 3, 3, 4, - 6, 0, 0, 0, 0, 4, 0, 3, - 3, 4, 5, 0, 0, 0, 0, 4, - 0, 4, 0, 7, 3, 3, 4, 5, - 0, 0, 0, 0, 4, 0, 2, 3, - 3, 4, 5, 0, 0, 0, 8, 4, - 0, 10, 11, 11, 12, 13, 9, 9, - 9, 9, 12, 9, 14, 9, 11, 11, - 12, 15, 9, 9, 9, 9, 12, 9, - 11, 11, 12, 13, 9, 9, 9, 9, - 12, 9, 12, 9, 16, 11, 11, 12, - 13, 9, 9, 9, 9, 12, 9, 10, - 11, 11, 12, 13, 9, 9, 9, 17, - 12, 9, 10, 11, 11, 12, 13, 9, - 9, 9, 18, 12, 9, 20, 21, 21, - 22, 23, 19, 19, 19, 24, 22, 19, - 25, 19, 21, 21, 22, 27, 26, 26, - 26, 26, 22, 26, 21, 21, 22, 23, - 19, 19, 19, 19, 22, 19, 22, 26, - 20, 21, 21, 22, 23, 19, 19, 19, - 19, 22, 19, 28, 21, 21, 22, 23, - 19, 19, 19, 19, 22, 19, 30, 31, - 31, 32, 33, 29, 29, 29, 34, 32, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 2, 3, 3, 4, 5, + 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 3, 3, 4, 6, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, + 3, 3, 4, 5, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 4, 0, + 7, 3, 3, 4, 5, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 2, + 3, 3, 4, 5, 0, 0, 0, 8, + 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 10, 11, + 11, 12, 13, 9, 9, 9, 9, 12, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 13, 9, 14, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 14, 9, + 11, 11, 12, 15, 9, 9, 9, 9, + 12, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 15, 9, 11, 11, + 12, 13, 9, 9, 9, 9, 12, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 13, 9, 12, 9, 16, 11, + 11, 12, 13, 9, 9, 9, 9, 12, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 13, 9, 10, 11, 11, + 12, 13, 9, 9, 9, 17, 12, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 13, 9, 10, 11, 11, 12, + 13, 9, 9, 9, 18, 12, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 13, 9, 20, 21, 21, 22, 23, + 19, 19, 19, 24, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 23, 19, 25, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 25, 19, 21, 21, 22, + 27, 26, 26, 26, 26, 22, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 27, 26, 21, 21, 22, 23, 19, + 19, 19, 19, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 23, + 19, 22, 26, 20, 21, 21, 22, 23, + 19, 19, 19, 19, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 23, 19, 28, 21, 21, 22, 23, 19, + 19, 19, 19, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 23, + 19, 30, 31, 31, 32, 33, 29, 29, + 29, 34, 32, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 33, 29, + 35, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 35, 29, 31, 31, 32, 36, 29, - 29, 29, 29, 32, 29, 31, 31, 32, - 33, 29, 29, 29, 29, 32, 29, 32, + 29, 29, 29, 32, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 36, + 29, 31, 31, 32, 33, 29, 29, 29, + 29, 32, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 33, 29, 32, 29, 30, 31, 31, 32, 33, 29, 29, - 29, 29, 32, 29, 37, 31, 31, 32, - 33, 29, 29, 29, 29, 32, 29, 21, + 29, 29, 32, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 33, 29, + 37, 31, 31, 32, 33, 29, 29, 29, + 29, 32, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 33, 29, 21, 21, 22, 38, 0, 0, 0, 0, 22, - 0, 40, 39, 42, 43, 44, 45, 46, - 47, 22, 23, 48, 49, 49, 24, 22, - 50, 51, 52, 53, 54, 41, 56, 57, - 58, 59, 4, 5, 60, 55, 55, 8, - 4, 55, 55, 61, 55, 62, 57, 63, - 63, 4, 5, 60, 55, 55, 55, 4, - 55, 55, 61, 55, 57, 63, 63, 4, - 5, 60, 55, 55, 55, 4, 55, 55, - 61, 55, 42, 55, 55, 55, 64, 65, - 55, 1, 60, 55, 55, 55, 55, 55, - 42, 55, 66, 66, 55, 1, 60, 55, - 60, 55, 55, 67, 60, 55, 60, 55, - 60, 55, 55, 55, 60, 55, 42, 55, - 68, 55, 66, 66, 55, 1, 60, 55, - 55, 55, 55, 55, 42, 55, 42, 55, - 55, 55, 66, 66, 55, 1, 60, 55, - 55, 55, 55, 55, 42, 55, 42, 55, - 55, 55, 66, 65, 55, 1, 60, 55, - 55, 55, 55, 55, 42, 55, 69, 70, - 71, 71, 4, 5, 60, 55, 55, 55, - 4, 55, 70, 71, 71, 4, 5, 60, - 55, 55, 55, 4, 55, 71, 71, 4, - 5, 60, 55, 55, 55, 4, 55, 60, - 55, 55, 67, 60, 55, 55, 55, 4, - 55, 72, 73, 73, 4, 5, 60, 55, - 55, 55, 4, 55, 64, 74, 55, 1, - 60, 55, 64, 55, 66, 66, 55, 1, - 60, 55, 66, 74, 55, 1, 60, 55, - 56, 57, 63, 63, 4, 5, 60, 55, - 55, 55, 4, 55, 55, 61, 55, 56, - 57, 58, 63, 4, 5, 60, 55, 55, - 8, 4, 55, 55, 61, 55, 76, 77, - 78, 79, 12, 13, 80, 75, 75, 18, - 12, 75, 75, 81, 75, 82, 77, 83, - 79, 12, 13, 80, 75, 75, 75, 12, - 75, 75, 81, 75, 77, 83, 79, 12, - 13, 80, 75, 75, 75, 12, 75, 75, - 81, 75, 84, 75, 75, 75, 85, 86, - 75, 14, 80, 75, 75, 75, 75, 75, - 84, 75, 87, 77, 88, 89, 12, 13, - 80, 75, 75, 17, 12, 75, 75, 81, - 75, 90, 77, 83, 83, 12, 13, 80, - 75, 75, 75, 12, 75, 75, 81, 75, - 77, 83, 83, 12, 13, 80, 75, 75, - 75, 12, 75, 75, 81, 75, 84, 75, - 75, 75, 91, 86, 75, 14, 80, 75, - 75, 75, 75, 75, 84, 75, 80, 75, - 75, 92, 80, 75, 80, 75, 80, 75, - 75, 75, 80, 75, 84, 75, 93, 75, - 91, 91, 75, 14, 80, 75, 75, 75, - 75, 75, 84, 75, 84, 75, 75, 75, - 91, 91, 75, 14, 80, 75, 75, 75, - 75, 75, 84, 75, 94, 95, 96, 96, - 12, 13, 80, 75, 75, 75, 12, 75, - 95, 96, 96, 12, 13, 80, 75, 75, - 75, 12, 75, 96, 96, 12, 13, 80, - 75, 75, 75, 12, 75, 80, 75, 75, - 92, 80, 75, 75, 75, 12, 75, 97, - 98, 98, 12, 13, 80, 75, 75, 75, - 12, 75, 85, 99, 75, 14, 80, 75, - 91, 91, 75, 14, 80, 75, 85, 75, - 91, 91, 75, 14, 80, 75, 91, 99, - 75, 14, 80, 75, 87, 77, 83, 83, - 12, 13, 80, 75, 75, 75, 12, 75, - 75, 81, 75, 87, 77, 88, 83, 12, - 13, 80, 75, 75, 17, 12, 75, 75, - 81, 75, 10, 11, 11, 12, 13, 75, - 75, 75, 75, 12, 75, 76, 77, 83, - 79, 12, 13, 80, 75, 75, 75, 12, - 75, 75, 81, 75, 101, 45, 102, 102, - 22, 23, 48, 100, 100, 100, 22, 100, - 100, 52, 100, 45, 102, 102, 22, 23, - 48, 100, 100, 100, 22, 100, 100, 52, - 100, 103, 100, 100, 100, 104, 105, 100, - 25, 48, 100, 100, 100, 100, 100, 103, - 100, 44, 45, 106, 107, 22, 23, 48, - 100, 100, 24, 22, 100, 100, 52, 100, - 103, 100, 100, 100, 108, 105, 100, 25, - 48, 100, 100, 100, 100, 100, 103, 100, - 48, 100, 100, 109, 48, 100, 48, 100, - 48, 100, 100, 100, 48, 100, 103, 100, - 110, 100, 108, 108, 100, 25, 48, 100, - 100, 100, 100, 100, 103, 100, 103, 100, - 100, 100, 108, 108, 100, 25, 48, 100, - 100, 100, 100, 100, 103, 100, 111, 112, - 113, 113, 22, 23, 48, 100, 100, 100, - 22, 100, 112, 113, 113, 22, 23, 48, - 100, 100, 100, 22, 100, 113, 113, 22, - 23, 48, 100, 100, 100, 22, 100, 48, - 100, 100, 109, 48, 100, 100, 100, 22, - 100, 44, 45, 102, 102, 22, 23, 48, - 100, 100, 100, 22, 100, 100, 52, 100, - 114, 115, 115, 22, 23, 48, 100, 100, - 100, 22, 100, 104, 116, 100, 25, 48, - 100, 108, 108, 100, 25, 48, 100, 104, - 100, 108, 108, 100, 25, 48, 100, 108, - 116, 100, 25, 48, 100, 44, 45, 106, - 102, 22, 23, 48, 100, 100, 24, 22, - 100, 100, 52, 100, 20, 21, 21, 22, - 23, 117, 117, 117, 24, 22, 117, 20, - 21, 21, 22, 23, 117, 117, 117, 117, - 22, 117, 119, 120, 121, 122, 32, 33, - 123, 118, 118, 34, 32, 118, 118, 124, - 118, 125, 120, 122, 122, 32, 33, 123, - 118, 118, 118, 32, 118, 118, 124, 118, - 120, 122, 122, 32, 33, 123, 118, 118, - 118, 32, 118, 118, 124, 118, 126, 118, - 118, 118, 127, 128, 118, 35, 123, 118, - 118, 118, 118, 118, 126, 118, 119, 120, - 121, 49, 32, 33, 123, 118, 118, 34, - 32, 118, 118, 124, 118, 126, 118, 118, - 118, 129, 128, 118, 35, 123, 118, 118, - 118, 118, 118, 126, 118, 123, 118, 118, - 130, 123, 118, 123, 118, 123, 118, 118, - 118, 123, 118, 126, 118, 131, 118, 129, - 129, 118, 35, 123, 118, 118, 118, 118, - 118, 126, 118, 126, 118, 118, 118, 129, - 129, 118, 35, 123, 118, 118, 118, 118, - 118, 126, 118, 132, 133, 134, 134, 32, - 33, 123, 118, 118, 118, 32, 118, 133, - 134, 134, 32, 33, 123, 118, 118, 118, - 32, 118, 134, 134, 32, 33, 123, 118, - 118, 118, 32, 118, 123, 118, 118, 130, - 123, 118, 118, 118, 32, 118, 119, 120, - 122, 122, 32, 33, 123, 118, 118, 118, - 32, 118, 118, 124, 118, 135, 136, 136, - 32, 33, 123, 118, 118, 118, 32, 118, - 127, 137, 118, 35, 123, 118, 129, 129, - 118, 35, 123, 118, 127, 118, 129, 129, - 118, 35, 123, 118, 129, 137, 118, 35, - 123, 118, 42, 43, 44, 45, 106, 102, - 22, 23, 48, 49, 49, 24, 22, 100, - 42, 52, 100, 56, 138, 58, 59, 4, - 5, 60, 55, 55, 8, 4, 55, 55, - 61, 55, 42, 43, 44, 45, 139, 140, - 22, 141, 142, 55, 49, 24, 22, 55, - 42, 52, 55, 20, 143, 143, 22, 141, - 60, 55, 55, 24, 22, 55, 60, 55, - 55, 67, 60, 55, 55, 55, 22, 55, - 142, 55, 55, 144, 142, 55, 55, 55, - 22, 55, 142, 55, 142, 55, 55, 55, - 142, 55, 42, 55, 68, 20, 143, 143, - 22, 141, 60, 55, 55, 55, 22, 55, - 42, 55, 146, 145, 147, 147, 145, 40, - 148, 145, 147, 147, 145, 40, 148, 145, - 148, 145, 145, 149, 148, 145, 148, 145, - 148, 145, 145, 145, 148, 145, 42, 117, - 117, 117, 117, 117, 117, 117, 117, 49, - 117, 117, 117, 117, 42, 117, 0 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 38, 0, 40, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 40, 39, + 42, 43, 44, 45, 46, 47, 22, 23, + 48, 49, 49, 24, 22, 50, 51, 52, + 53, 54, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 55, 41, 57, 58, 59, 60, 4, 5, + 61, 56, 56, 8, 4, 56, 56, 62, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 5, 56, 63, 58, 64, 64, 4, 5, + 61, 56, 56, 56, 4, 56, 56, 62, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 5, 56, 58, 64, 64, 4, 5, 61, + 56, 56, 56, 4, 56, 56, 62, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 5, + 56, 42, 56, 56, 56, 65, 66, 56, + 1, 61, 56, 56, 56, 56, 56, 42, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 1, 56, 67, 67, 56, 1, 61, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 1, + 56, 61, 56, 56, 68, 61, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 68, 56, 61, + 56, 61, 56, 56, 56, 61, 56, 42, + 56, 69, 56, 67, 67, 56, 1, 61, + 56, 56, 56, 56, 56, 42, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 1, + 56, 42, 56, 56, 56, 67, 67, 56, + 1, 61, 56, 56, 56, 56, 56, 42, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 1, 56, 42, 56, 56, 56, 67, + 66, 56, 1, 61, 56, 56, 56, 56, + 56, 42, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 1, 56, 70, 71, 72, + 72, 4, 5, 61, 56, 56, 56, 4, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 5, 56, 71, 72, 72, + 4, 5, 61, 56, 56, 56, 4, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 5, 56, 72, 72, 4, 5, + 61, 56, 56, 56, 4, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 5, 56, 61, 56, 56, 68, 61, 56, + 56, 56, 4, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 68, 56, + 73, 74, 74, 4, 5, 61, 56, 56, + 56, 4, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 5, 56, 65, + 75, 56, 1, 61, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 1, 56, 65, 56, 67, + 67, 56, 1, 61, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 1, 56, 67, 75, 56, + 1, 61, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 1, 56, 57, 58, 64, 64, 4, + 5, 61, 56, 56, 56, 4, 56, 56, + 62, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 5, 56, 57, 58, 59, 64, 4, + 5, 61, 56, 56, 8, 4, 56, 56, + 62, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 5, 56, 77, 78, 79, 80, 12, + 13, 81, 76, 76, 18, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 83, 78, 84, 80, 12, + 13, 81, 76, 76, 76, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 78, 84, 80, 12, 13, + 81, 76, 76, 76, 12, 76, 76, 82, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 13, 76, 85, 76, 76, 76, 86, 87, + 76, 14, 81, 76, 76, 76, 76, 76, + 85, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 14, 76, 88, 78, 89, 90, + 12, 13, 81, 76, 76, 17, 12, 76, + 76, 82, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 13, 76, 91, 78, 84, 84, + 12, 13, 81, 76, 76, 76, 12, 76, + 76, 82, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 13, 76, 78, 84, 84, 12, + 13, 81, 76, 76, 76, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 85, 76, 76, 76, 92, + 87, 76, 14, 81, 76, 76, 76, 76, + 76, 85, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 14, 76, 81, 76, 76, + 93, 81, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 93, 76, 81, 76, 81, 76, 76, + 76, 81, 76, 85, 76, 94, 76, 92, + 92, 76, 14, 81, 76, 76, 76, 76, + 76, 85, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 14, 76, 85, 76, 76, + 76, 92, 92, 76, 14, 81, 76, 76, + 76, 76, 76, 85, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 14, 76, 95, + 96, 97, 97, 12, 13, 81, 76, 76, + 76, 12, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 13, 76, 96, + 97, 97, 12, 13, 81, 76, 76, 76, + 12, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 13, 76, 97, 97, + 12, 13, 81, 76, 76, 76, 12, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 13, 76, 81, 76, 76, 93, + 81, 76, 76, 76, 12, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 93, 76, 98, 99, 99, 12, 13, 81, + 76, 76, 76, 12, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 13, + 76, 86, 100, 76, 14, 81, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 14, 76, 92, + 92, 76, 14, 81, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 14, 76, 86, 76, 92, + 92, 76, 14, 81, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 14, 76, 92, 100, 76, + 14, 81, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 14, 76, 88, 78, 84, 84, 12, + 13, 81, 76, 76, 76, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 88, 78, 89, 84, 12, + 13, 81, 76, 76, 17, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 10, 11, 11, 12, 13, + 76, 76, 76, 76, 12, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 13, 76, 77, 78, 84, 80, 12, 13, + 81, 76, 76, 76, 12, 76, 76, 82, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 13, 76, 102, 45, 103, 103, 22, 23, + 48, 101, 101, 101, 22, 101, 101, 52, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 23, 101, 45, 103, 103, 22, 23, 48, + 101, 101, 101, 22, 101, 101, 52, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 23, + 101, 104, 101, 101, 101, 105, 106, 101, + 25, 48, 101, 101, 101, 101, 101, 104, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 25, 101, 44, 45, 107, 108, 22, + 23, 48, 101, 101, 24, 22, 101, 101, + 52, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 23, 101, 104, 101, 101, 101, 109, + 106, 101, 25, 48, 101, 101, 101, 101, + 101, 104, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 25, 101, 48, 101, 101, + 110, 48, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 110, 101, 48, 101, 48, 101, 101, + 101, 48, 101, 104, 101, 111, 101, 109, + 109, 101, 25, 48, 101, 101, 101, 101, + 101, 104, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 25, 101, 104, 101, 101, + 101, 109, 109, 101, 25, 48, 101, 101, + 101, 101, 101, 104, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 25, 101, 112, + 113, 114, 114, 22, 23, 48, 101, 101, + 101, 22, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 23, 101, 113, + 114, 114, 22, 23, 48, 101, 101, 101, + 22, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 23, 101, 114, 114, + 22, 23, 48, 101, 101, 101, 22, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 23, 101, 48, 26, 26, 110, + 48, 26, 26, 26, 22, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 110, 26, 44, 45, 103, 103, 22, 23, + 48, 101, 101, 101, 22, 101, 101, 52, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 23, 101, 115, 116, 116, 22, 23, 48, + 101, 101, 101, 22, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 23, + 101, 105, 117, 101, 25, 48, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 25, 101, 109, + 109, 101, 25, 48, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 25, 101, 105, 101, 109, + 109, 101, 25, 48, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 25, 101, 109, 117, 101, + 25, 48, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 25, 101, 44, 45, 107, 103, 22, + 23, 48, 101, 101, 24, 22, 101, 101, + 52, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 23, 101, 20, 21, 21, 22, 23, + 118, 118, 118, 24, 22, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 23, 118, 20, 21, 21, 22, 23, 118, + 118, 118, 118, 22, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 23, + 118, 120, 121, 122, 123, 32, 33, 124, + 119, 119, 34, 32, 119, 119, 125, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 33, + 119, 126, 121, 123, 123, 32, 33, 124, + 119, 119, 119, 32, 119, 119, 125, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 33, + 119, 121, 123, 123, 32, 33, 124, 119, + 119, 119, 32, 119, 119, 125, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 33, 119, + 127, 119, 119, 119, 128, 129, 119, 35, + 124, 119, 119, 119, 119, 119, 127, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 35, 119, 120, 121, 122, 49, 32, 33, + 124, 119, 119, 34, 32, 119, 119, 125, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 33, 119, 127, 119, 119, 119, 130, 129, + 119, 35, 124, 119, 119, 119, 119, 119, + 127, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 35, 119, 124, 119, 119, 131, + 124, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 131, 119, 124, 119, 124, 119, 119, 119, + 124, 119, 127, 119, 132, 119, 130, 130, + 119, 35, 124, 119, 119, 119, 119, 119, + 127, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 35, 119, 127, 119, 119, 119, + 130, 130, 119, 35, 124, 119, 119, 119, + 119, 119, 127, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 35, 119, 133, 134, + 135, 135, 32, 33, 124, 119, 119, 119, + 32, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 33, 119, 134, 135, + 135, 32, 33, 124, 119, 119, 119, 32, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 33, 119, 135, 135, 32, + 33, 124, 119, 119, 119, 32, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 33, 119, 124, 119, 119, 131, 124, + 119, 119, 119, 32, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 131, + 119, 120, 121, 123, 123, 32, 33, 124, + 119, 119, 119, 32, 119, 119, 125, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 33, + 119, 136, 137, 137, 32, 33, 124, 119, + 119, 119, 32, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 33, 119, + 128, 138, 119, 35, 124, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 35, 119, 130, 130, + 119, 35, 124, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 35, 119, 128, 119, 130, 130, + 119, 35, 124, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 35, 119, 130, 138, 119, 35, + 124, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 35, 119, 42, 43, 44, 45, 107, 103, + 22, 23, 48, 49, 49, 24, 22, 101, + 42, 52, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 23, 101, 57, 139, 59, 60, + 4, 5, 61, 56, 56, 8, 4, 56, + 56, 62, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 5, 56, 42, 43, 44, 45, + 140, 141, 22, 142, 143, 56, 49, 24, + 22, 56, 42, 52, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 142, 56, 20, 144, + 144, 22, 142, 61, 56, 56, 24, 22, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 142, 56, 61, 56, 56, + 68, 61, 56, 56, 56, 22, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 68, 56, 143, 56, 56, 145, 143, + 56, 56, 56, 22, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 145, + 56, 143, 56, 143, 56, 56, 56, 143, + 56, 42, 56, 69, 20, 144, 144, 22, + 142, 61, 56, 56, 56, 22, 56, 42, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 142, 56, 147, 146, 148, 148, 146, + 40, 149, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 40, 146, 148, 148, 146, 40, 149, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 40, + 146, 149, 146, 146, 150, 149, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 150, 146, 149, + 146, 149, 146, 146, 146, 149, 146, 42, + 118, 118, 118, 118, 118, 118, 118, 118, + 49, 118, 118, 118, 118, 42, 118, 0 }; static const unsigned char _indic_syllable_machine_trans_targs[] = { @@ -330,41 +996,41 @@ static const unsigned char _indic_syllable_machine_trans_targs[] = { 93, 84, 31, 19, 98, 31, 107, 24, 113, 116, 117, 108, 26, 122, 127, 31, 134, 31, 32, 53, 79, 81, 100, 101, - 85, 102, 123, 124, 94, 132, 137, 31, - 33, 35, 6, 52, 38, 47, 34, 1, - 36, 40, 0, 39, 41, 44, 45, 3, - 48, 5, 49, 31, 54, 56, 14, 77, - 62, 70, 55, 7, 57, 72, 64, 58, - 13, 76, 59, 8, 63, 65, 67, 68, - 10, 71, 12, 73, 31, 80, 20, 82, - 96, 87, 15, 99, 16, 86, 88, 90, - 91, 18, 95, 21, 97, 31, 31, 103, - 105, 22, 27, 109, 118, 104, 106, 120, - 111, 23, 110, 112, 114, 115, 25, 119, - 28, 121, 125, 126, 131, 128, 129, 29, - 130, 31, 133, 30, 135, 136 + 85, 102, 123, 124, 94, 132, 137, 92, + 31, 33, 35, 6, 52, 38, 47, 34, + 1, 36, 40, 0, 39, 41, 44, 45, + 3, 48, 5, 49, 31, 54, 56, 14, + 77, 62, 70, 55, 7, 57, 72, 64, + 58, 13, 76, 59, 8, 63, 65, 67, + 68, 10, 71, 12, 73, 31, 80, 20, + 82, 96, 87, 15, 99, 16, 86, 88, + 90, 91, 18, 95, 21, 97, 31, 31, + 103, 105, 22, 27, 109, 118, 104, 106, + 120, 111, 23, 110, 112, 114, 115, 25, + 119, 28, 121, 125, 126, 131, 128, 129, + 29, 130, 31, 133, 30, 135, 136 }; static const char _indic_syllable_machine_trans_actions[] = { 1, 0, 2, 0, 2, 0, 0, 2, 2, 3, 2, 0, 2, 0, 0, 0, - 2, 2, 2, 4, 2, 0, 5, 0, + 2, 2, 2, 4, 2, 0, 5, 5, 5, 0, 6, 0, 2, 7, 2, 0, 2, 0, 2, 0, 0, 2, 0, 8, 0, 11, 2, 2, 5, 0, 12, 12, 0, 2, 5, 2, 5, 2, 0, 13, - 2, 0, 0, 2, 0, 2, 2, 0, - 2, 2, 0, 0, 2, 2, 2, 0, - 0, 0, 2, 14, 2, 0, 0, 2, - 0, 2, 2, 0, 2, 2, 2, 2, + 14, 2, 0, 0, 2, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 2, - 0, 0, 0, 2, 15, 5, 0, 5, - 2, 2, 0, 5, 0, 0, 2, 5, - 5, 0, 0, 0, 2, 16, 17, 2, - 0, 0, 0, 0, 2, 2, 2, 2, - 2, 0, 0, 2, 2, 2, 0, 0, - 0, 2, 0, 18, 18, 0, 0, 0, - 0, 19, 2, 0, 0, 0 + 0, 0, 0, 2, 15, 2, 0, 0, + 2, 0, 2, 2, 0, 2, 2, 2, + 2, 0, 2, 2, 0, 0, 2, 2, + 2, 0, 0, 0, 2, 16, 5, 0, + 5, 2, 2, 0, 5, 0, 0, 2, + 5, 5, 0, 0, 0, 2, 17, 18, + 2, 0, 0, 0, 0, 2, 2, 2, + 2, 2, 0, 0, 2, 2, 2, 0, + 0, 0, 2, 0, 19, 19, 0, 0, + 0, 0, 20, 2, 0, 0, 0 }; static const char _indic_syllable_machine_to_state_actions[] = { @@ -414,20 +1080,20 @@ static const short _indic_syllable_machine_eof_trans[] = { 10, 10, 10, 10, 10, 10, 10, 20, 20, 27, 20, 27, 20, 20, 30, 30, 30, 30, 30, 30, 30, 1, 40, 0, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 76, 76, 76, - 76, 76, 76, 76, 76, 76, 76, 76, - 76, 76, 76, 76, 76, 76, 76, 76, - 76, 76, 76, 76, 76, 76, 76, 101, - 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 118, 118, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 101, 56, 56, 56, 56, - 56, 56, 56, 56, 146, 146, 146, 146, - 146, 118 + 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 27, 102, 102, 102, + 102, 102, 102, 102, 119, 119, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 102, 57, 57, 57, 57, + 57, 57, 57, 57, 147, 147, 147, 147, + 147, 119 }; static const int indic_syllable_machine_start = 31; @@ -441,7 +1107,7 @@ static const int indic_syllable_machine_en_main = 31; -#line 118 "hb-ot-shaper-indic-machine.rl" +#line 121 "hb-ot-shaper-indic-machine.rl" #define found_syllable(syllable_type) \ @@ -460,7 +1126,7 @@ find_syllables_indic (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 464 "hb-ot-shaper-indic-machine.hh" +#line 1130 "hb-ot-shaper-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -468,7 +1134,7 @@ find_syllables_indic (hb_buffer_t *buffer) act = 0; } -#line 138 "hb-ot-shaper-indic-machine.rl" +#line 141 "hb-ot-shaper-indic-machine.rl" p = 0; @@ -476,7 +1142,7 @@ find_syllables_indic (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 480 "hb-ot-shaper-indic-machine.hh" +#line 1146 "hb-ot-shaper-indic-machine.hh" { int _slen; int _trans; @@ -490,7 +1156,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 494 "hb-ot-shaper-indic-machine.hh" +#line 1160 "hb-ot-shaper-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -513,51 +1179,51 @@ _eof_trans: {te = p+1;} break; case 11: -#line 114 "hb-ot-shaper-indic-machine.rl" +#line 117 "hb-ot-shaper-indic-machine.rl" {te = p+1;{ found_syllable (indic_non_indic_cluster); }} break; - case 13: -#line 109 "hb-ot-shaper-indic-machine.rl" + case 14: +#line 111 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_consonant_syllable); }} break; - case 14: -#line 110 "hb-ot-shaper-indic-machine.rl" + case 15: +#line 112 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_vowel_syllable); }} break; - case 17: -#line 111 "hb-ot-shaper-indic-machine.rl" + case 18: +#line 113 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_standalone_cluster); }} break; - case 19: -#line 112 "hb-ot-shaper-indic-machine.rl" + case 20: +#line 114 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_symbol_cluster); }} break; - case 15: -#line 113 "hb-ot-shaper-indic-machine.rl" + case 16: +#line 116 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; - case 16: -#line 114 "hb-ot-shaper-indic-machine.rl" + case 17: +#line 117 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_non_indic_cluster); }} break; case 1: -#line 109 "hb-ot-shaper-indic-machine.rl" +#line 111 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }} break; case 3: -#line 110 "hb-ot-shaper-indic-machine.rl" +#line 112 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }} break; case 7: -#line 111 "hb-ot-shaper-indic-machine.rl" +#line 113 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }} break; case 8: -#line 112 "hb-ot-shaper-indic-machine.rl" +#line 114 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }} break; case 4: -#line 113 "hb-ot-shaper-indic-machine.rl" +#line 116 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; case 6: @@ -567,33 +1233,42 @@ _eof_trans: {{p = ((te))-1;} found_syllable (indic_consonant_syllable); } break; case 5: - {{p = ((te))-1;} found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } + {{p = ((te))-1;} found_syllable (indic_non_indic_cluster); } break; case 6: + {{p = ((te))-1;} found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } + break; + case 7: {{p = ((te))-1;} found_syllable (indic_non_indic_cluster); } break; } } break; - case 18: + case 19: #line 1 "NONE" {te = p+1;} -#line 109 "hb-ot-shaper-indic-machine.rl" +#line 111 "hb-ot-shaper-indic-machine.rl" {act = 1;} break; - case 5: + case 13: #line 1 "NONE" {te = p+1;} -#line 113 "hb-ot-shaper-indic-machine.rl" +#line 115 "hb-ot-shaper-indic-machine.rl" {act = 5;} break; - case 12: + case 5: #line 1 "NONE" {te = p+1;} -#line 114 "hb-ot-shaper-indic-machine.rl" +#line 116 "hb-ot-shaper-indic-machine.rl" {act = 6;} break; -#line 597 "hb-ot-shaper-indic-machine.hh" + case 12: +#line 1 "NONE" + {te = p+1;} +#line 117 "hb-ot-shaper-indic-machine.rl" + {act = 7;} + break; +#line 1272 "hb-ot-shaper-indic-machine.hh" } _again: @@ -602,7 +1277,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 606 "hb-ot-shaper-indic-machine.hh" +#line 1281 "hb-ot-shaper-indic-machine.hh" } if ( ++p != pe ) @@ -618,7 +1293,7 @@ _again: } -#line 146 "hb-ot-shaper-indic-machine.rl" +#line 149 "hb-ot-shaper-indic-machine.rl" } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc index d9899a633c189..b87c530853bf7 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc @@ -6,12 +6,12 @@ * * on files with these headers: * - * # IndicSyllabicCategory-15.1.0.txt - * # Date: 2023-01-05 - * # IndicPositionalCategory-15.1.0.txt - * # Date: 2023-01-05 - * # Blocks-15.1.0.txt - * # Date: 2023-07-28, 15:47:20 GMT + * # IndicSyllabicCategory-16.0.0.txt + * # Date: 2024-04-30, 21:48:21 GMT + * # IndicPositionalCategory-16.0.0.txt + * # Date: 2024-04-30, 21:48:21 GMT + * # Blocks-16.0.0.txt + * # Date: 2024-02-02 */ #include "hb.hh" @@ -48,6 +48,7 @@ #define OT_CM I_Cat(CM) #define OT_Symbol I_Cat(Symbol) #define OT_CS I_Cat(CS) +#define OT_SMPst I_Cat(SMPst) /* khmer */ #define OT_VAbv K_Cat(VAbv) #define OT_VBlw K_Cat(VBlw) @@ -89,12 +90,13 @@ static_assert (OT_VPst == M_Cat(VPst), ""); #define _OT_MW OT_MW /* 2 chars; MW */ #define _OT_MY OT_MY /* 3 chars; MY */ #define _OT_N OT_N /* 17 chars; N */ -#define _OT_GB OT_PLACEHOLDER /* 165 chars; PLACEHOLDER */ +#define _OT_GB OT_PLACEHOLDER /* 185 chars; PLACEHOLDER */ #define _OT_PT OT_PT /* 8 chars; PT */ #define _OT_R OT_Ra /* 14 chars; Ra */ #define _OT_Rf OT_Repha /* 1 chars; Repha */ #define _OT_Rt OT_Robatic /* 3 chars; Robatic */ -#define _OT_SM OT_SM /* 56 chars; SM */ +#define _OT_SM OT_SM /* 50 chars; SM */ +#define _OT_SP OT_SMPst /* 6 chars; SMPst */ #define _OT_S OT_Symbol /* 22 chars; Symbol */ #define _OT_V OT_V /* 172 chars; V */ #define _OT_VA OT_VAbv /* 18 chars; VAbv */ @@ -112,7 +114,7 @@ static_assert (OT_VPst == M_Cat(VPst), ""); #define _POS_A POS_AFTER_MAIN /* 3 chars; AFTER_MAIN */ #define _POS_AP POS_AFTER_POST /* 50 chars; AFTER_POST */ #define _POS_AS POS_AFTER_SUB /* 51 chars; AFTER_SUB */ -#define _POS_C POS_BASE_C /* 833 chars; BASE_C */ +#define _POS_C POS_BASE_C /* 853 chars; BASE_C */ #define _POS_BS POS_BEFORE_SUB /* 25 chars; BEFORE_SUB */ #define _POS_B POS_BELOW_C /* 13 chars; BELOW_C */ #define _POS_X POS_END /* 71 chars; END */ @@ -145,7 +147,7 @@ static const uint16_t indic_table[] = { /* Latin-1 Supplement */ - /* 00B0 */ _(X,X), _(X,X),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X), _(X,X), + /* 00B0 */ _(X,X), _(X,X),_(SP,SM),_(SP,SM), _(X,X), _(X,X), _(X,X), _(X,X), /* 00B8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), /* 00C0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), /* 00C8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), @@ -398,9 +400,9 @@ static const uint16_t indic_table[] = { /* Superscripts and Subscripts */ - /* 2070 */ _(X,X), _(X,X), _(X,X), _(X,X),_(SM,SM), _(X,X), _(X,X), _(X,X), + /* 2070 */ _(X,X), _(X,X), _(X,X), _(X,X),_(SP,SM), _(X,X), _(X,X), _(X,X), /* 2078 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 2080 */ _(X,X), _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X), + /* 2080 */ _(X,X), _(X,X),_(SP,SM),_(SP,SM),_(SP,SM), _(X,X), _(X,X), _(X,X), #define indic_offset_0x25f8u 1592 @@ -458,7 +460,16 @@ static const uint16_t indic_table[] = { /* 11338 */ _(X,X), _(X,X), _(X,X), _(N,X), _(N,X), _(X,X), _(X,X), _(X,X), -}; /* Table items: 1728; occupancy: 71% */ +#define indic_offset_0x116d0u 1728 + + + /* Myanmar Extended-C */ + + /* 116D0 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 116D8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 116E0 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), + +}; /* Table items: 1752; occupancy: 71% */ uint16_t hb_indic_get_categories (hb_codepoint_t u) @@ -498,6 +509,7 @@ hb_indic_get_categories (hb_codepoint_t u) case 0x11u: if (hb_in_range (u, 0x11300u, 0x11307u)) return indic_table[u - 0x11300u + indic_offset_0x11300u]; if (hb_in_range (u, 0x11338u, 0x1133Fu)) return indic_table[u - 0x11338u + indic_offset_0x11338u]; + if (hb_in_range (u, 0x116D0u, 0x116E7u)) return indic_table[u - 0x116D0u + indic_offset_0x116d0u]; break; default: @@ -530,6 +542,7 @@ hb_indic_get_categories (hb_codepoint_t u) #undef _OT_Rf #undef _OT_Rt #undef _OT_SM +#undef _OT_SP #undef _OT_S #undef _OT_V #undef _OT_VA diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh index 3dcf61b938f37..64eb761b4ea95 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh @@ -68,6 +68,7 @@ enum myanmar_syllable_type_t { #define myanmar_syllable_machine_ex_PT 39u #define myanmar_syllable_machine_ex_Ra 15u #define myanmar_syllable_machine_ex_SM 8u +#define myanmar_syllable_machine_ex_SMPst 57u #define myanmar_syllable_machine_ex_VAbv 20u #define myanmar_syllable_machine_ex_VBlw 21u #define myanmar_syllable_machine_ex_VPre 22u @@ -77,35 +78,35 @@ enum myanmar_syllable_type_t { #define myanmar_syllable_machine_ex_ZWNJ 5u -#line 81 "hb-ot-shaper-myanmar-machine.hh" +#line 82 "hb-ot-shaper-myanmar-machine.hh" static const unsigned char _myanmar_syllable_machine_trans_keys[] = { - 1u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u, - 5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 39u, 3u, 39u, - 3u, 40u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 41u, - 3u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u, - 5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 41u, 3u, 39u, - 3u, 39u, 3u, 40u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 39u, 3u, 41u, 3u, 41u, - 3u, 41u, 3u, 41u, 3u, 41u, 3u, 41u, 3u, 41u, 1u, 41u, 1u, 15u, 0 + 1u, 57u, 3u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 3u, 57u, 5u, 57u, 1u, 15u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 5u, 57u, 1u, 15u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 3u, 57u, 1u, 57u, 1u, 15u, 0 }; static const char _myanmar_syllable_machine_key_spans[] = { - 41, 39, 35, 4, 39, 37, 37, 35, - 35, 37, 37, 39, 35, 15, 37, 37, - 38, 37, 39, 39, 37, 39, 39, 39, - 39, 39, 35, 4, 39, 37, 37, 35, - 35, 37, 37, 39, 35, 15, 39, 37, - 37, 38, 37, 39, 39, 37, 39, 39, - 39, 39, 39, 39, 39, 41, 15 + 57, 55, 53, 53, 55, 53, 55, 55, + 55, 55, 55, 53, 15, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 53, 53, 55, 53, 55, 55, 55, + 55, 55, 53, 15, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 57, 15 }; static const short _myanmar_syllable_machine_index_offsets[] = { - 0, 42, 82, 118, 123, 163, 201, 239, - 275, 311, 349, 387, 427, 463, 479, 517, - 555, 594, 632, 672, 712, 750, 790, 830, - 870, 910, 950, 986, 991, 1031, 1069, 1107, - 1143, 1179, 1217, 1255, 1295, 1331, 1347, 1387, - 1425, 1463, 1502, 1540, 1580, 1620, 1658, 1698, - 1738, 1778, 1818, 1858, 1898, 1938, 1980 + 0, 58, 114, 168, 222, 278, 332, 388, + 444, 500, 556, 612, 666, 682, 738, 794, + 850, 906, 962, 1018, 1074, 1130, 1186, 1242, + 1298, 1354, 1408, 1462, 1518, 1572, 1628, 1684, + 1740, 1796, 1852, 1906, 1922, 1978, 2034, 2090, + 2146, 2202, 2258, 2314, 2370, 2426, 2482, 2538, + 2594, 2650, 2706, 2762, 2820 }; static const char _myanmar_syllable_machine_indicies[] = { @@ -114,273 +115,378 @@ static const char _myanmar_syllable_machine_indicies[] = { 0, 8, 0, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 15, 16, 17, 18, 19, - 20, 0, 22, 23, 24, 24, 21, 25, - 26, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 27, 28, 29, 30, 21, - 21, 21, 21, 21, 21, 21, 21, 31, - 21, 21, 32, 33, 34, 35, 36, 37, - 38, 21, 24, 24, 21, 25, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 30, 21, 21, 21, - 21, 21, 21, 21, 21, 39, 21, 21, - 21, 21, 21, 21, 36, 21, 24, 24, - 21, 25, 21, 22, 21, 24, 24, 21, - 25, 26, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 40, 21, 21, 30, - 21, 21, 21, 21, 21, 21, 21, 21, - 41, 21, 21, 42, 21, 21, 21, 36, - 21, 41, 21, 22, 21, 24, 24, 21, - 25, 26, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 30, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 36, - 21, 43, 21, 24, 24, 21, 25, 36, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 44, 21, - 21, 21, 21, 21, 21, 36, 21, 24, - 24, 21, 25, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 44, 21, 21, 21, 21, 21, - 21, 36, 21, 24, 24, 21, 25, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 36, 21, 22, - 21, 24, 24, 21, 25, 26, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 40, 21, 21, 30, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 36, 21, 22, 21, 24, - 24, 21, 25, 26, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 40, 21, - 21, 30, 21, 21, 21, 21, 21, 21, - 21, 21, 41, 21, 21, 21, 21, 21, - 21, 36, 21, 22, 21, 24, 24, 21, - 25, 26, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 40, 21, 21, 30, - 21, 21, 21, 21, 21, 21, 21, 21, - 41, 21, 21, 21, 21, 21, 21, 36, - 21, 41, 21, 24, 24, 21, 25, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 30, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 36, 21, 1, - 1, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 1, 21, 22, - 21, 24, 24, 21, 25, 26, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 27, 28, 21, 30, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 36, 21, 22, 21, 24, - 24, 21, 25, 26, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 28, - 21, 30, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 36, 21, 22, 21, 24, 24, 21, - 25, 26, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 27, 28, 29, 30, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 36, - 45, 21, 22, 21, 24, 24, 21, 25, - 26, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 27, 28, 29, 30, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 36, 21, - 22, 21, 24, 24, 21, 25, 26, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 27, 28, 29, 30, 21, 21, 21, - 21, 21, 21, 21, 21, 31, 21, 21, - 32, 33, 34, 35, 36, 21, 38, 21, - 22, 21, 24, 24, 21, 25, 26, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 27, 28, 29, 30, 21, 21, 21, - 21, 21, 21, 21, 21, 45, 21, 21, - 21, 21, 21, 21, 36, 21, 38, 21, - 22, 21, 24, 24, 21, 25, 26, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 27, 28, 29, 30, 21, 21, 21, - 21, 21, 21, 21, 21, 45, 21, 21, - 21, 21, 21, 21, 36, 21, 22, 21, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 32, 21, - 34, 21, 36, 21, 38, 21, 22, 21, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 45, 21, 21, 32, 21, - 21, 21, 36, 21, 38, 21, 22, 21, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 46, 21, 21, 32, 33, - 34, 21, 36, 21, 38, 21, 22, 21, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 32, 33, - 34, 21, 36, 21, 38, 21, 22, 23, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 31, 21, 21, 32, 33, - 34, 35, 36, 21, 38, 21, 48, 48, + 20, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 23, 24, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 32, + 22, 22, 33, 34, 35, 36, 37, 38, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 25, 25, 22, 26, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 31, 22, 22, 22, + 22, 22, 22, 22, 22, 40, 22, 22, + 22, 22, 22, 22, 37, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 26, 22, + 25, 25, 22, 26, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 37, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 26, 22, 41, 22, + 25, 25, 22, 26, 37, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 26, 22, 22, 22, 22, + 22, 22, 37, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 26, 22, 25, 25, + 22, 26, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 26, 22, 22, 22, 22, 22, 22, + 37, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 42, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 43, 22, 22, 44, 22, 22, 22, + 37, 22, 43, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 37, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 42, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 37, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 42, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 43, 22, 22, 22, 22, 22, 22, + 37, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 42, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 43, 22, 22, 22, 22, 22, 22, + 37, 22, 43, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 25, 25, 22, 26, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 1, 1, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 1, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 22, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 29, 22, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 45, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 32, + 22, 22, 33, 34, 35, 36, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 45, + 22, 22, 22, 22, 22, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 45, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 33, 22, 35, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 45, + 22, 22, 33, 22, 22, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 46, + 22, 22, 33, 34, 35, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 33, 34, 35, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 24, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 32, + 22, 22, 33, 34, 35, 36, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 48, 48, 47, 5, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 12, 47, 47, 47, + 47, 47, 47, 47, 47, 49, 47, 47, + 47, 47, 47, 47, 18, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 5, 47, + 48, 48, 50, 5, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 18, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 5, 50, 51, 47, + 48, 48, 47, 5, 18, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 5, 47, 47, 47, 47, + 47, 47, 18, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 5, 47, 48, 48, 47, 5, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 5, 47, 47, 47, 47, 47, 47, + 18, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 52, 47, 47, + 12, 47, 47, 47, 47, 47, 47, 47, + 47, 53, 47, 47, 54, 47, 47, 47, + 18, 47, 53, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 12, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 18, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 52, 47, 47, + 12, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 18, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 52, 47, 47, + 12, 47, 47, 47, 47, 47, 47, 47, + 47, 53, 47, 47, 47, 47, 47, 47, + 18, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 52, 47, 47, 12, 47, 47, 47, 47, 47, 47, 47, - 47, 49, 47, 47, 47, 47, 47, 47, - 18, 47, 48, 48, 47, 5, 47, 2, - 47, 48, 48, 47, 5, 6, 47, 47, + 47, 53, 47, 47, 47, 47, 47, 47, + 18, 47, 53, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 50, 47, 47, 12, 47, 47, 47, 47, - 47, 47, 47, 47, 51, 47, 47, 52, - 47, 47, 47, 18, 47, 51, 47, 2, - 47, 48, 48, 47, 5, 6, 47, 47, + 47, 47, 5, 47, 48, 48, 47, 5, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 12, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 18, 47, 53, 47, 48, - 48, 47, 5, 18, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 54, 47, 47, 47, 47, 47, - 47, 18, 47, 48, 48, 47, 5, 47, + 5, 47, 55, 55, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 55, 47, 2, 3, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, + 47, 47, 47, 47, 47, 47, 47, 13, + 47, 47, 14, 15, 16, 17, 18, 19, + 20, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 54, 47, - 47, 47, 47, 47, 47, 18, 47, 48, - 48, 47, 5, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 47, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 18, 47, 2, 47, 48, 48, 47, - 5, 6, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 50, 47, 47, 12, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 10, 47, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 18, - 47, 2, 47, 48, 48, 47, 5, 6, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 50, 47, 47, 12, 47, 47, - 47, 47, 47, 47, 47, 47, 51, 47, - 47, 47, 47, 47, 47, 18, 47, 2, - 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 50, 47, 47, 12, 47, 47, 47, 47, - 47, 47, 47, 47, 51, 47, 47, 47, - 47, 47, 47, 18, 47, 51, 47, 48, - 48, 47, 5, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 12, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 18, 56, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 18, 47, 55, 55, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 55, 47, 2, 3, 48, 48, 47, - 5, 6, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 9, 10, 11, 12, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 13, 47, 47, 14, 15, 16, 17, 18, - 19, 20, 47, 2, 47, 48, 48, 47, - 5, 6, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 9, 10, 47, 12, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 18, - 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 10, 47, 12, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, + 47, 47, 47, 47, 47, 47, 47, 13, + 47, 47, 14, 15, 16, 17, 18, 47, + 20, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 18, 47, 2, - 47, 48, 48, 47, 5, 6, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, + 47, 47, 47, 47, 47, 47, 47, 56, + 47, 47, 47, 47, 47, 47, 18, 47, + 20, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 9, 10, 11, 12, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, + 47, 47, 47, 47, 47, 47, 47, 56, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 18, 56, 47, 2, 47, - 48, 48, 47, 5, 6, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 9, - 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 18, 47, 2, 47, 48, 48, - 47, 5, 6, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 9, 10, 11, - 12, 47, 47, 47, 47, 47, 47, 47, - 47, 13, 47, 47, 14, 15, 16, 17, - 18, 47, 20, 47, 2, 47, 48, 48, - 47, 5, 6, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 9, 10, 11, - 12, 47, 47, 47, 47, 47, 47, 47, - 47, 56, 47, 47, 47, 47, 47, 47, - 18, 47, 20, 47, 2, 47, 48, 48, - 47, 5, 6, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 9, 10, 11, - 12, 47, 47, 47, 47, 47, 47, 47, - 47, 56, 47, 47, 47, 47, 47, 47, - 18, 47, 2, 47, 48, 48, 47, 5, + 5, 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 14, 47, 16, 47, 18, 47, - 20, 47, 2, 47, 48, 48, 47, 5, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 56, 47, 47, 14, 47, 47, 47, 18, 47, - 20, 47, 2, 47, 48, 48, 47, 5, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 57, 47, 47, 14, 15, 16, 47, 18, 47, - 20, 47, 2, 47, 48, 48, 47, 5, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 14, 15, 16, 47, 18, 47, - 20, 47, 2, 3, 48, 48, 47, 5, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 2, 3, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 13, 47, 47, 14, 15, 16, 17, 18, 47, - 20, 47, 22, 23, 24, 24, 21, 25, - 26, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 27, 28, 29, 30, 21, - 21, 21, 21, 21, 21, 21, 21, 58, - 21, 21, 32, 33, 34, 35, 36, 37, - 38, 21, 22, 59, 24, 24, 21, 25, - 26, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 27, 28, 29, 30, 21, - 21, 21, 21, 21, 21, 21, 21, 31, - 21, 21, 32, 33, 34, 35, 36, 21, - 38, 21, 1, 1, 2, 3, 48, 48, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 23, 24, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 58, + 22, 22, 33, 34, 35, 36, 37, 38, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 59, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 32, + 22, 22, 33, 34, 35, 36, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 1, 1, 2, 3, 48, 48, 47, 5, 6, 1, 1, 47, 47, 47, 1, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 13, 47, 47, 14, 15, 16, 17, - 18, 19, 20, 47, 1, 1, 60, 60, + 18, 19, 20, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 1, 1, 60, 60, 60, 60, 60, 60, 60, 1, 1, 60, 60, 60, 1, 60, 0 }; static const char _myanmar_syllable_machine_trans_targs[] = { - 0, 1, 26, 37, 0, 27, 29, 51, - 54, 39, 40, 41, 28, 43, 44, 46, - 47, 48, 30, 50, 45, 0, 2, 13, - 0, 3, 5, 14, 15, 16, 4, 18, - 19, 21, 22, 23, 6, 25, 20, 12, - 9, 10, 11, 7, 8, 17, 24, 0, - 0, 36, 33, 34, 35, 31, 32, 38, - 42, 49, 52, 53, 0 + 0, 1, 25, 35, 0, 26, 30, 49, + 52, 37, 38, 39, 29, 41, 42, 44, + 45, 46, 27, 48, 43, 26, 0, 2, + 12, 0, 3, 7, 13, 14, 15, 6, + 17, 18, 20, 21, 22, 4, 24, 19, + 11, 5, 8, 9, 10, 16, 23, 0, + 0, 34, 0, 28, 31, 32, 33, 36, + 40, 47, 50, 51, 0 }; static const char _myanmar_syllable_machine_trans_actions[] = { - 3, 0, 0, 0, 4, 0, 0, 0, + 3, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 0, 0, - 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 6, 7, 0, + 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, - 8, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9 + 0, 0, 0, 0, 0, 0, 0, 9, + 10, 0, 11, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 12 }; static const char _myanmar_syllable_machine_to_state_actions[] = { @@ -390,7 +496,7 @@ static const char _myanmar_syllable_machine_to_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0 }; static const char _myanmar_syllable_machine_from_state_actions[] = { @@ -400,17 +506,17 @@ static const char _myanmar_syllable_machine_from_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0 }; static const short _myanmar_syllable_machine_eof_trans[] = { - 0, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 48, 48, 48, 48, 48, 48, + 0, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 48, 51, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 22, 22, 48, 61 + 48, 23, 23, 48, 61 }; static const int myanmar_syllable_machine_start = 0; @@ -424,7 +530,7 @@ static const int myanmar_syllable_machine_en_main = 0; -#line 117 "hb-ot-shaper-myanmar-machine.rl" +#line 118 "hb-ot-shaper-myanmar-machine.rl" #define found_syllable(syllable_type) \ @@ -443,7 +549,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 447 "hb-ot-shaper-myanmar-machine.hh" +#line 553 "hb-ot-shaper-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -451,7 +557,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) act = 0; } -#line 137 "hb-ot-shaper-myanmar-machine.rl" +#line 138 "hb-ot-shaper-myanmar-machine.rl" p = 0; @@ -459,7 +565,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 463 "hb-ot-shaper-myanmar-machine.hh" +#line 569 "hb-ot-shaper-myanmar-machine.hh" { int _slen; int _trans; @@ -473,7 +579,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 477 "hb-ot-shaper-myanmar-machine.hh" +#line 583 "hb-ot-shaper-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -491,35 +597,59 @@ _eof_trans: goto _again; switch ( _myanmar_syllable_machine_trans_actions[_trans] ) { - case 6: -#line 110 "hb-ot-shaper-myanmar-machine.rl" + case 8: +#line 111 "hb-ot-shaper-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_consonant_syllable); }} break; case 4: -#line 111 "hb-ot-shaper-myanmar-machine.rl" +#line 112 "hb-ot-shaper-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} break; - case 8: -#line 112 "hb-ot-shaper-myanmar-machine.rl" + case 10: +#line 113 "hb-ot-shaper-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; case 3: -#line 113 "hb-ot-shaper-myanmar-machine.rl" +#line 114 "hb-ot-shaper-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} break; - case 5: -#line 110 "hb-ot-shaper-myanmar-machine.rl" - {te = p;p--;{ found_syllable (myanmar_consonant_syllable); }} - break; case 7: -#line 112 "hb-ot-shaper-myanmar-machine.rl" - {te = p;p--;{ found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} +#line 111 "hb-ot-shaper-myanmar-machine.rl" + {te = p;p--;{ found_syllable (myanmar_consonant_syllable); }} break; case 9: #line 113 "hb-ot-shaper-myanmar-machine.rl" + {te = p;p--;{ found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} + break; + case 12: +#line 114 "hb-ot-shaper-myanmar-machine.rl" {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }} break; -#line 523 "hb-ot-shaper-myanmar-machine.hh" + case 11: +#line 1 "NONE" + { switch( act ) { + case 2: + {{p = ((te))-1;} found_syllable (myanmar_non_myanmar_cluster); } + break; + case 3: + {{p = ((te))-1;} found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } + break; + } + } + break; + case 6: +#line 1 "NONE" + {te = p+1;} +#line 112 "hb-ot-shaper-myanmar-machine.rl" + {act = 2;} + break; + case 5: +#line 1 "NONE" + {te = p+1;} +#line 113 "hb-ot-shaper-myanmar-machine.rl" + {act = 3;} + break; +#line 653 "hb-ot-shaper-myanmar-machine.hh" } _again: @@ -528,7 +658,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 532 "hb-ot-shaper-myanmar-machine.hh" +#line 662 "hb-ot-shaper-myanmar-machine.hh" } if ( ++p != pe ) @@ -544,7 +674,7 @@ _again: } -#line 145 "hb-ot-shaper-myanmar-machine.rl" +#line 146 "hb-ot-shaper-myanmar-machine.rl" } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh index 47b0e6bbdcc35..46f66f7d2858a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh @@ -81,6 +81,7 @@ enum use_syllable_type_t { #define use_syllable_machine_ex_N 4u #define use_syllable_machine_ex_O 0u #define use_syllable_machine_ex_R 18u +#define use_syllable_machine_ex_RK 56u #define use_syllable_machine_ex_SB 51u #define use_syllable_machine_ex_SE 52u #define use_syllable_machine_ex_SMAbv 41u @@ -99,62 +100,62 @@ enum use_syllable_type_t { #define use_syllable_machine_ex_ZWNJ 14u -#line 103 "hb-ot-shaper-use-machine.hh" +#line 104 "hb-ot-shaper-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { - 49u, 51u, 0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, + 49u, 51u, 0u, 56u, 11u, 56u, 11u, 56u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, - 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 48u, 14u, 42u, 14u, 42u, 11u, 53u, + 12u, 53u, 12u, 53u, 11u, 56u, 1u, 14u, 1u, 48u, 14u, 42u, 14u, 42u, 11u, 56u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, - 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, - 1u, 14u, 1u, 48u, 13u, 14u, 4u, 14u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, - 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, - 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, - 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 14u, 1u, 48u, - 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, - 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, - 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, - 1u, 14u, 1u, 48u, 4u, 14u, 13u, 14u, 1u, 53u, 14u, 42u, 14u, 42u, 1u, 5u, - 14u, 55u, 14u, 51u, 14u, 52u, 14u, 54u, 11u, 53u, 0 + 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 56u, 1u, 14u, + 1u, 14u, 1u, 48u, 14u, 14u, 13u, 14u, 4u, 14u, 11u, 56u, 11u, 56u, 1u, 53u, + 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, + 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, + 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 56u, 1u, 14u, 1u, 14u, + 1u, 48u, 14u, 14u, 11u, 56u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, + 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, + 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, + 12u, 53u, 11u, 56u, 1u, 14u, 1u, 48u, 4u, 14u, 13u, 14u, 1u, 56u, 14u, 42u, + 14u, 42u, 1u, 5u, 14u, 55u, 14u, 51u, 14u, 52u, 14u, 54u, 11u, 56u, 0 }; static const char _use_syllable_machine_key_spans[] = { - 3, 54, 43, 43, 53, 35, 34, 34, + 3, 57, 46, 46, 53, 35, 34, 34, 34, 33, 33, 1, 35, 35, 35, 14, 35, 40, 40, 40, 40, 42, 40, 42, - 42, 42, 43, 14, 48, 29, 29, 43, + 42, 42, 46, 14, 48, 29, 29, 46, 53, 35, 34, 34, 34, 33, 33, 1, 35, 35, 35, 14, 35, 40, 40, 40, - 40, 42, 40, 42, 42, 42, 43, 14, - 14, 48, 2, 11, 43, 43, 53, 35, - 34, 34, 34, 33, 33, 1, 35, 35, - 35, 14, 35, 40, 40, 40, 40, 42, - 40, 42, 42, 42, 43, 14, 14, 48, - 43, 53, 35, 34, 34, 34, 33, 33, - 1, 35, 35, 35, 14, 35, 40, 40, - 40, 40, 42, 40, 42, 42, 42, 43, - 14, 48, 11, 2, 53, 29, 29, 5, - 42, 38, 39, 41, 43 + 40, 42, 40, 42, 42, 42, 46, 14, + 14, 48, 1, 2, 11, 46, 46, 53, + 35, 34, 34, 34, 33, 33, 1, 35, + 35, 35, 14, 35, 40, 40, 40, 40, + 42, 40, 42, 42, 42, 46, 14, 14, + 48, 1, 46, 53, 35, 34, 34, 34, + 33, 33, 1, 35, 35, 35, 14, 35, + 40, 40, 40, 40, 42, 40, 42, 42, + 42, 46, 14, 48, 11, 2, 56, 29, + 29, 5, 42, 38, 39, 41, 46 }; static const short _use_syllable_machine_index_offsets[] = { - 0, 4, 59, 103, 147, 201, 237, 272, - 307, 342, 376, 410, 412, 448, 484, 520, - 535, 571, 612, 653, 694, 735, 778, 819, - 862, 905, 948, 992, 1007, 1056, 1086, 1116, - 1160, 1214, 1250, 1285, 1320, 1355, 1389, 1423, - 1425, 1461, 1497, 1533, 1548, 1584, 1625, 1666, - 1707, 1748, 1791, 1832, 1875, 1918, 1961, 2005, - 2020, 2035, 2084, 2087, 2099, 2143, 2187, 2241, - 2277, 2312, 2347, 2382, 2416, 2450, 2452, 2488, - 2524, 2560, 2575, 2611, 2652, 2693, 2734, 2775, - 2818, 2859, 2902, 2945, 2988, 3032, 3047, 3062, - 3111, 3155, 3209, 3245, 3280, 3315, 3350, 3384, - 3418, 3420, 3456, 3492, 3528, 3543, 3579, 3620, - 3661, 3702, 3743, 3786, 3827, 3870, 3913, 3956, - 4000, 4015, 4064, 4076, 4079, 4133, 4163, 4193, - 4199, 4242, 4281, 4321, 4363 + 0, 4, 62, 109, 156, 210, 246, 281, + 316, 351, 385, 419, 421, 457, 493, 529, + 544, 580, 621, 662, 703, 744, 787, 828, + 871, 914, 957, 1004, 1019, 1068, 1098, 1128, + 1175, 1229, 1265, 1300, 1335, 1370, 1404, 1438, + 1440, 1476, 1512, 1548, 1563, 1599, 1640, 1681, + 1722, 1763, 1806, 1847, 1890, 1933, 1976, 2023, + 2038, 2053, 2102, 2104, 2107, 2119, 2166, 2213, + 2267, 2303, 2338, 2373, 2408, 2442, 2476, 2478, + 2514, 2550, 2586, 2601, 2637, 2678, 2719, 2760, + 2801, 2844, 2885, 2928, 2971, 3014, 3061, 3076, + 3091, 3140, 3142, 3189, 3243, 3279, 3314, 3349, + 3384, 3418, 3452, 3454, 3490, 3526, 3562, 3577, + 3613, 3654, 3695, 3736, 3777, 3820, 3861, 3904, + 3947, 3990, 4037, 4052, 4101, 4113, 4116, 4173, + 4203, 4233, 4239, 4282, 4321, 4361, 4403 }; static const unsigned char _use_syllable_machine_indicies[] = { @@ -165,571 +166,578 @@ static const unsigned char _use_syllable_machine_indicies[] = { 19, 20, 21, 8, 22, 23, 24, 25, 5, 26, 27, 28, 5, 29, 30, 31, 32, 33, 34, 35, 32, 1, 5, 36, - 5, 37, 5, 39, 40, 38, 41, 38, - 38, 38, 38, 38, 38, 38, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 39, - 51, 52, 53, 54, 38, 55, 56, 57, - 38, 58, 59, 38, 60, 61, 62, 63, - 60, 38, 38, 38, 38, 64, 38, 39, - 40, 38, 41, 38, 38, 38, 38, 38, - 38, 38, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 39, 51, 52, 53, 54, - 38, 55, 56, 57, 38, 38, 38, 38, - 60, 61, 62, 63, 60, 38, 38, 38, - 38, 64, 38, 39, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 38, 43, 44, 45, 46, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 55, - 56, 57, 38, 38, 38, 38, 38, 61, - 62, 63, 65, 38, 38, 38, 38, 43, - 38, 41, 38, 38, 38, 38, 38, 38, - 38, 38, 43, 44, 45, 46, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 55, 56, 57, 38, 38, 38, 38, 38, - 61, 62, 63, 65, 38, 41, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 44, - 45, 46, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 61, 62, 63, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 45, 46, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 61, - 62, 63, 38, 41, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 46, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 61, 62, 63, 38, 41, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 61, 62, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 62, 38, 41, 38, 41, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 44, 45, - 46, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 55, 56, 57, 38, 38, - 38, 38, 38, 61, 62, 63, 65, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 44, 45, 46, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 56, 57, 38, 38, 38, 38, 38, 61, - 62, 63, 65, 38, 41, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 44, 45, - 46, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 57, 38, 38, - 38, 38, 38, 61, 62, 63, 65, 38, - 66, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 41, 38, 41, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 44, 45, 46, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 61, 62, - 63, 65, 38, 41, 38, 38, 38, 38, - 38, 38, 38, 42, 43, 44, 45, 46, - 38, 38, 38, 38, 38, 38, 52, 53, - 54, 38, 55, 56, 57, 38, 38, 38, - 38, 38, 61, 62, 63, 65, 38, 38, - 38, 38, 43, 38, 41, 38, 38, 38, - 38, 38, 38, 38, 38, 43, 44, 45, - 46, 38, 38, 38, 38, 38, 38, 52, - 53, 54, 38, 55, 56, 57, 38, 38, - 38, 38, 38, 61, 62, 63, 65, 38, - 38, 38, 38, 43, 38, 41, 38, 38, - 38, 38, 38, 38, 38, 38, 43, 44, - 45, 46, 38, 38, 38, 38, 38, 38, - 38, 53, 54, 38, 55, 56, 57, 38, - 38, 38, 38, 38, 61, 62, 63, 65, - 38, 38, 38, 38, 43, 38, 41, 38, - 38, 38, 38, 38, 38, 38, 38, 43, - 44, 45, 46, 38, 38, 38, 38, 38, - 38, 38, 38, 54, 38, 55, 56, 57, - 38, 38, 38, 38, 38, 61, 62, 63, - 65, 38, 38, 38, 38, 43, 38, 67, - 38, 41, 38, 38, 38, 38, 38, 38, - 38, 42, 43, 44, 45, 46, 38, 48, - 49, 38, 38, 38, 52, 53, 54, 38, - 55, 56, 57, 38, 38, 38, 38, 38, - 61, 62, 63, 65, 38, 38, 38, 38, - 43, 38, 41, 38, 38, 38, 38, 38, - 38, 38, 38, 43, 44, 45, 46, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 55, 56, 57, 38, 38, 38, 38, - 38, 61, 62, 63, 65, 38, 38, 38, - 38, 43, 38, 67, 38, 41, 38, 38, - 38, 38, 38, 38, 38, 42, 43, 44, - 45, 46, 38, 38, 49, 38, 38, 38, - 52, 53, 54, 38, 55, 56, 57, 38, - 38, 38, 38, 38, 61, 62, 63, 65, - 38, 38, 38, 38, 43, 38, 67, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 42, 43, 44, 45, 46, 38, 38, 38, - 38, 38, 38, 52, 53, 54, 38, 55, - 56, 57, 38, 38, 38, 38, 38, 61, - 62, 63, 65, 38, 38, 38, 38, 43, - 38, 67, 38, 41, 38, 38, 38, 38, - 38, 38, 38, 42, 43, 44, 45, 46, - 47, 48, 49, 38, 38, 38, 52, 53, - 54, 38, 55, 56, 57, 38, 38, 38, - 38, 38, 61, 62, 63, 65, 38, 38, - 38, 38, 43, 38, 39, 40, 38, 41, - 38, 38, 38, 38, 38, 38, 38, 42, + 5, 37, 5, 5, 38, 5, 40, 41, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 40, 52, 53, 54, 55, 39, + 56, 57, 58, 39, 59, 60, 39, 61, + 62, 63, 64, 61, 39, 39, 39, 39, + 65, 39, 39, 64, 39, 40, 41, 39, + 42, 39, 39, 39, 39, 39, 39, 39, 43, 44, 45, 46, 47, 48, 49, 50, - 38, 51, 52, 53, 54, 38, 55, 56, - 57, 38, 38, 38, 38, 60, 61, 62, - 63, 60, 38, 38, 38, 38, 64, 38, - 39, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 41, 38, 39, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 41, 38, 38, 38, - 38, 38, 38, 38, 38, 43, 44, 45, - 46, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 55, 56, 57, 38, 38, - 38, 38, 38, 61, 62, 63, 65, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 58, 59, 38, 41, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 59, 38, 4, 69, 68, 70, - 68, 68, 68, 68, 68, 68, 68, 71, - 72, 73, 74, 75, 76, 77, 78, 79, - 4, 80, 81, 82, 83, 68, 84, 85, - 86, 68, 68, 68, 68, 87, 88, 89, - 90, 91, 68, 68, 68, 68, 92, 68, - 4, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 68, 72, 73, - 74, 75, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 84, 85, 86, 68, - 68, 68, 68, 68, 88, 89, 90, 93, - 68, 68, 68, 68, 72, 68, 70, 68, - 68, 68, 68, 68, 68, 68, 68, 72, - 73, 74, 75, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 84, 85, 86, - 68, 68, 68, 68, 68, 88, 89, 90, - 93, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 73, 74, 75, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 88, 89, 90, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 74, 75, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 88, 89, 90, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 75, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 88, - 89, 90, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 88, 89, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 89, 68, 70, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 73, 74, 75, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 84, 85, 86, 68, 68, 68, 68, 68, - 88, 89, 90, 93, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 73, - 74, 75, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 85, 86, 68, - 68, 68, 68, 68, 88, 89, 90, 93, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 73, 74, 75, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 86, 68, 68, 68, 68, 68, - 88, 89, 90, 93, 68, 95, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 96, 94, 70, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 73, 74, - 75, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 88, 89, 90, 93, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 71, 72, 73, 74, 75, 68, 68, 68, - 68, 68, 68, 81, 82, 83, 68, 84, - 85, 86, 68, 68, 68, 68, 68, 88, - 89, 90, 93, 68, 68, 68, 68, 72, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 68, 72, 73, 74, 75, 68, 68, - 68, 68, 68, 68, 81, 82, 83, 68, - 84, 85, 86, 68, 68, 68, 68, 68, - 88, 89, 90, 93, 68, 68, 68, 68, - 72, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 68, 72, 73, 74, 75, 68, - 68, 68, 68, 68, 68, 68, 82, 83, - 68, 84, 85, 86, 68, 68, 68, 68, - 68, 88, 89, 90, 93, 68, 68, 68, - 68, 72, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 68, 72, 73, 74, 75, - 68, 68, 68, 68, 68, 68, 68, 68, - 83, 68, 84, 85, 86, 68, 68, 68, - 68, 68, 88, 89, 90, 93, 68, 68, - 68, 68, 72, 68, 97, 68, 70, 68, - 68, 68, 68, 68, 68, 68, 71, 72, - 73, 74, 75, 68, 77, 78, 68, 68, - 68, 81, 82, 83, 68, 84, 85, 86, - 68, 68, 68, 68, 68, 88, 89, 90, - 93, 68, 68, 68, 68, 72, 68, 70, - 68, 68, 68, 68, 68, 68, 68, 68, - 72, 73, 74, 75, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 84, 85, - 86, 68, 68, 68, 68, 68, 88, 89, - 90, 93, 68, 68, 68, 68, 72, 68, - 97, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 71, 72, 73, 74, 75, 68, - 68, 78, 68, 68, 68, 81, 82, 83, - 68, 84, 85, 86, 68, 68, 68, 68, - 68, 88, 89, 90, 93, 68, 68, 68, - 68, 72, 68, 97, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 71, 72, 73, - 74, 75, 68, 68, 68, 68, 68, 68, - 81, 82, 83, 68, 84, 85, 86, 68, - 68, 68, 68, 68, 88, 89, 90, 93, - 68, 68, 68, 68, 72, 68, 97, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 71, 72, 73, 74, 75, 76, 77, 78, - 68, 68, 68, 81, 82, 83, 68, 84, - 85, 86, 68, 68, 68, 68, 68, 88, - 89, 90, 93, 68, 68, 68, 68, 72, - 68, 4, 69, 68, 70, 68, 68, 68, - 68, 68, 68, 68, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 68, 80, 81, - 82, 83, 68, 84, 85, 86, 68, 68, - 68, 68, 87, 88, 89, 90, 91, 68, - 68, 68, 68, 92, 68, 4, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 99, 98, 4, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, - 94, 96, 94, 4, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 72, 73, 74, 75, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 84, - 85, 86, 68, 68, 68, 68, 68, 88, - 89, 90, 93, 68, 101, 102, 100, 6, - 103, 103, 103, 103, 103, 103, 103, 103, - 103, 104, 103, 105, 106, 68, 70, 68, - 68, 68, 68, 68, 68, 68, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 105, - 116, 117, 118, 119, 68, 120, 121, 122, - 68, 58, 59, 68, 123, 124, 125, 126, - 127, 68, 68, 68, 68, 128, 68, 105, - 106, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 105, 116, 117, 118, 119, - 68, 120, 121, 122, 68, 68, 68, 68, - 123, 124, 125, 126, 127, 68, 68, 68, - 68, 128, 68, 105, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 108, 109, 110, 111, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 120, - 121, 122, 68, 68, 68, 68, 68, 124, - 125, 126, 129, 68, 68, 68, 68, 108, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 68, 108, 109, 110, 111, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 120, 121, 122, 68, 68, 68, 68, 68, - 124, 125, 126, 129, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 109, - 110, 111, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 124, 125, 126, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 110, 111, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 124, - 125, 126, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 111, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 124, 125, 126, 68, 70, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 124, 125, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 125, 68, 70, 68, 70, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 109, 110, - 111, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 120, 121, 122, 68, 68, - 68, 68, 68, 124, 125, 126, 129, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 109, 110, 111, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 121, 122, 68, 68, 68, 68, 68, 124, - 125, 126, 129, 68, 70, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 109, 110, - 111, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 122, 68, 68, - 68, 68, 68, 124, 125, 126, 129, 68, - 130, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 96, 94, 70, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 109, 110, 111, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 124, 125, - 126, 129, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 107, 108, 109, 110, 111, - 68, 68, 68, 68, 68, 68, 117, 118, - 119, 68, 120, 121, 122, 68, 68, 68, - 68, 68, 124, 125, 126, 129, 68, 68, - 68, 68, 108, 68, 70, 68, 68, 68, - 68, 68, 68, 68, 68, 108, 109, 110, - 111, 68, 68, 68, 68, 68, 68, 117, - 118, 119, 68, 120, 121, 122, 68, 68, - 68, 68, 68, 124, 125, 126, 129, 68, - 68, 68, 68, 108, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 68, 108, 109, - 110, 111, 68, 68, 68, 68, 68, 68, - 68, 118, 119, 68, 120, 121, 122, 68, - 68, 68, 68, 68, 124, 125, 126, 129, - 68, 68, 68, 68, 108, 68, 70, 68, - 68, 68, 68, 68, 68, 68, 68, 108, - 109, 110, 111, 68, 68, 68, 68, 68, - 68, 68, 68, 119, 68, 120, 121, 122, - 68, 68, 68, 68, 68, 124, 125, 126, - 129, 68, 68, 68, 68, 108, 68, 131, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 107, 108, 109, 110, 111, 68, 113, - 114, 68, 68, 68, 117, 118, 119, 68, - 120, 121, 122, 68, 68, 68, 68, 68, - 124, 125, 126, 129, 68, 68, 68, 68, - 108, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 68, 108, 109, 110, 111, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 120, 121, 122, 68, 68, 68, 68, - 68, 124, 125, 126, 129, 68, 68, 68, - 68, 108, 68, 131, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 107, 108, 109, - 110, 111, 68, 68, 114, 68, 68, 68, - 117, 118, 119, 68, 120, 121, 122, 68, - 68, 68, 68, 68, 124, 125, 126, 129, - 68, 68, 68, 68, 108, 68, 131, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 107, 108, 109, 110, 111, 68, 68, 68, - 68, 68, 68, 117, 118, 119, 68, 120, - 121, 122, 68, 68, 68, 68, 68, 124, - 125, 126, 129, 68, 68, 68, 68, 108, - 68, 131, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 107, 108, 109, 110, 111, - 112, 113, 114, 68, 68, 68, 117, 118, - 119, 68, 120, 121, 122, 68, 68, 68, - 68, 68, 124, 125, 126, 129, 68, 68, - 68, 68, 108, 68, 105, 106, 68, 70, - 68, 68, 68, 68, 68, 68, 68, 107, - 108, 109, 110, 111, 112, 113, 114, 115, - 68, 116, 117, 118, 119, 68, 120, 121, - 122, 68, 68, 68, 68, 123, 124, 125, - 126, 127, 68, 68, 68, 68, 128, 68, - 105, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 99, 98, 105, - 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 96, 94, 105, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 68, 108, 109, 110, 111, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 120, 121, 122, 68, 68, 68, - 68, 68, 124, 125, 126, 129, 68, 8, - 9, 132, 11, 132, 132, 132, 132, 132, - 132, 132, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 8, 22, 23, 24, 25, - 132, 26, 27, 28, 132, 132, 132, 132, - 32, 33, 34, 35, 32, 132, 132, 132, - 132, 37, 132, 8, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 11, 132, 132, 132, 132, 132, 132, 132, - 132, 14, 15, 16, 17, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 26, - 27, 28, 132, 132, 132, 132, 132, 33, - 34, 35, 133, 132, 132, 132, 132, 14, - 132, 11, 132, 132, 132, 132, 132, 132, - 132, 132, 14, 15, 16, 17, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 26, 27, 28, 132, 132, 132, 132, 132, - 33, 34, 35, 133, 132, 11, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 15, - 16, 17, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 33, 34, 35, 132, - 11, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 16, 17, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 33, - 34, 35, 132, 11, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 17, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 33, 34, 35, 132, 11, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 33, 34, 132, - 11, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 34, 132, 11, 132, 11, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 15, 16, - 17, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 26, 27, 28, 132, 132, - 132, 132, 132, 33, 34, 35, 133, 132, - 11, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 15, 16, 17, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 27, 28, 132, 132, 132, 132, 132, 33, - 34, 35, 133, 132, 11, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 15, 16, - 17, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 28, 132, 132, - 132, 132, 132, 33, 34, 35, 133, 132, - 134, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 11, 132, 11, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 15, 16, 17, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 33, 34, - 35, 133, 132, 11, 132, 132, 132, 132, - 132, 132, 132, 13, 14, 15, 16, 17, - 132, 132, 132, 132, 132, 132, 23, 24, - 25, 132, 26, 27, 28, 132, 132, 132, - 132, 132, 33, 34, 35, 133, 132, 132, - 132, 132, 14, 132, 11, 132, 132, 132, - 132, 132, 132, 132, 132, 14, 15, 16, - 17, 132, 132, 132, 132, 132, 132, 23, - 24, 25, 132, 26, 27, 28, 132, 132, - 132, 132, 132, 33, 34, 35, 133, 132, - 132, 132, 132, 14, 132, 11, 132, 132, - 132, 132, 132, 132, 132, 132, 14, 15, - 16, 17, 132, 132, 132, 132, 132, 132, - 132, 24, 25, 132, 26, 27, 28, 132, - 132, 132, 132, 132, 33, 34, 35, 133, - 132, 132, 132, 132, 14, 132, 11, 132, - 132, 132, 132, 132, 132, 132, 132, 14, - 15, 16, 17, 132, 132, 132, 132, 132, - 132, 132, 132, 25, 132, 26, 27, 28, - 132, 132, 132, 132, 132, 33, 34, 35, - 133, 132, 132, 132, 132, 14, 132, 135, - 132, 11, 132, 132, 132, 132, 132, 132, - 132, 13, 14, 15, 16, 17, 132, 19, - 20, 132, 132, 132, 23, 24, 25, 132, - 26, 27, 28, 132, 132, 132, 132, 132, - 33, 34, 35, 133, 132, 132, 132, 132, - 14, 132, 11, 132, 132, 132, 132, 132, - 132, 132, 132, 14, 15, 16, 17, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 26, 27, 28, 132, 132, 132, 132, - 132, 33, 34, 35, 133, 132, 132, 132, - 132, 14, 132, 135, 132, 11, 132, 132, - 132, 132, 132, 132, 132, 13, 14, 15, - 16, 17, 132, 132, 20, 132, 132, 132, - 23, 24, 25, 132, 26, 27, 28, 132, - 132, 132, 132, 132, 33, 34, 35, 133, - 132, 132, 132, 132, 14, 132, 135, 132, - 11, 132, 132, 132, 132, 132, 132, 132, - 13, 14, 15, 16, 17, 132, 132, 132, - 132, 132, 132, 23, 24, 25, 132, 26, - 27, 28, 132, 132, 132, 132, 132, 33, - 34, 35, 133, 132, 132, 132, 132, 14, - 132, 135, 132, 11, 132, 132, 132, 132, - 132, 132, 132, 13, 14, 15, 16, 17, - 18, 19, 20, 132, 132, 132, 23, 24, - 25, 132, 26, 27, 28, 132, 132, 132, - 132, 132, 33, 34, 35, 133, 132, 132, - 132, 132, 14, 132, 8, 9, 132, 11, - 132, 132, 132, 132, 132, 132, 132, 13, - 14, 15, 16, 17, 18, 19, 20, 21, - 132, 22, 23, 24, 25, 132, 26, 27, - 28, 132, 132, 132, 132, 32, 33, 34, - 35, 32, 132, 132, 132, 132, 37, 132, - 8, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 11, 132, 8, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 11, 132, 132, 132, - 132, 132, 132, 132, 132, 14, 15, 16, - 17, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 26, 27, 28, 132, 132, - 132, 132, 132, 33, 34, 35, 133, 132, - 136, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 11, 132, 10, 11, 132, 4, - 132, 132, 132, 4, 132, 132, 132, 132, - 132, 8, 9, 10, 11, 132, 132, 132, - 132, 132, 132, 132, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 8, 22, 23, - 24, 25, 132, 26, 27, 28, 132, 29, - 30, 132, 32, 33, 34, 35, 32, 132, - 132, 132, 132, 37, 132, 11, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 29, 30, 132, 11, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 30, - 132, 4, 137, 137, 137, 4, 137, 139, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 140, 138, 141, 138, 141, - 142, 138, 139, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 1, 140, 140, - 138, 139, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 140, 138, 141, - 138, 139, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 140, 138, 141, - 138, 141, 138, 39, 40, 38, 41, 38, - 38, 38, 38, 38, 38, 38, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 39, - 51, 52, 53, 54, 38, 55, 56, 57, - 38, 58, 59, 38, 60, 61, 62, 63, - 60, 1, 38, 2, 38, 64, 38, 0 + 51, 40, 52, 53, 54, 55, 39, 56, + 57, 58, 39, 39, 39, 39, 61, 62, + 63, 64, 61, 39, 39, 39, 39, 65, + 39, 39, 64, 39, 40, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 39, 44, 45, 46, 47, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 56, 57, 58, 39, 39, 39, 39, 39, + 62, 63, 64, 66, 39, 39, 39, 39, + 44, 39, 42, 39, 39, 39, 39, 39, + 39, 39, 39, 44, 45, 46, 47, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 56, 57, 58, 39, 39, 39, 39, + 39, 62, 63, 64, 66, 39, 42, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 45, 46, 47, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 62, 63, 64, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 46, 47, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 62, 63, 64, 39, 42, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 47, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 62, 63, 64, 39, 42, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 62, 63, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 63, 39, 42, 39, 42, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 45, + 46, 47, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 56, 57, 58, 39, + 39, 39, 39, 39, 62, 63, 64, 66, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 45, 46, 47, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 57, 58, 39, 39, 39, 39, 39, + 62, 63, 64, 66, 39, 42, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 45, + 46, 47, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 58, 39, + 39, 39, 39, 39, 62, 63, 64, 66, + 39, 67, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 42, 39, + 42, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 45, 46, 47, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 62, + 63, 64, 66, 39, 42, 39, 39, 39, + 39, 39, 39, 39, 43, 44, 45, 46, + 47, 39, 39, 39, 39, 39, 39, 53, + 54, 55, 39, 56, 57, 58, 39, 39, + 39, 39, 39, 62, 63, 64, 66, 39, + 39, 39, 39, 44, 39, 42, 39, 39, + 39, 39, 39, 39, 39, 39, 44, 45, + 46, 47, 39, 39, 39, 39, 39, 39, + 53, 54, 55, 39, 56, 57, 58, 39, + 39, 39, 39, 39, 62, 63, 64, 66, + 39, 39, 39, 39, 44, 39, 42, 39, + 39, 39, 39, 39, 39, 39, 39, 44, + 45, 46, 47, 39, 39, 39, 39, 39, + 39, 39, 54, 55, 39, 56, 57, 58, + 39, 39, 39, 39, 39, 62, 63, 64, + 66, 39, 39, 39, 39, 44, 39, 42, + 39, 39, 39, 39, 39, 39, 39, 39, + 44, 45, 46, 47, 39, 39, 39, 39, + 39, 39, 39, 39, 55, 39, 56, 57, + 58, 39, 39, 39, 39, 39, 62, 63, + 64, 66, 39, 39, 39, 39, 44, 39, + 68, 39, 42, 39, 39, 39, 39, 39, + 39, 39, 43, 44, 45, 46, 47, 39, + 49, 50, 39, 39, 39, 53, 54, 55, + 39, 56, 57, 58, 39, 39, 39, 39, + 39, 62, 63, 64, 66, 39, 39, 39, + 39, 44, 39, 42, 39, 39, 39, 39, + 39, 39, 39, 39, 44, 45, 46, 47, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 56, 57, 58, 39, 39, 39, + 39, 39, 62, 63, 64, 66, 39, 39, + 39, 39, 44, 39, 68, 39, 42, 39, + 39, 39, 39, 39, 39, 39, 43, 44, + 45, 46, 47, 39, 39, 50, 39, 39, + 39, 53, 54, 55, 39, 56, 57, 58, + 39, 39, 39, 39, 39, 62, 63, 64, + 66, 39, 39, 39, 39, 44, 39, 68, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 43, 44, 45, 46, 47, 39, 39, + 39, 39, 39, 39, 53, 54, 55, 39, + 56, 57, 58, 39, 39, 39, 39, 39, + 62, 63, 64, 66, 39, 39, 39, 39, + 44, 39, 68, 39, 42, 39, 39, 39, + 39, 39, 39, 39, 43, 44, 45, 46, + 47, 48, 49, 50, 39, 39, 39, 53, + 54, 55, 39, 56, 57, 58, 39, 39, + 39, 39, 39, 62, 63, 64, 66, 39, + 39, 39, 39, 44, 39, 40, 41, 39, + 42, 39, 39, 39, 39, 39, 39, 39, + 43, 44, 45, 46, 47, 48, 49, 50, + 51, 39, 52, 53, 54, 55, 39, 56, + 57, 58, 39, 39, 39, 39, 61, 62, + 63, 64, 61, 39, 39, 39, 39, 65, + 39, 39, 64, 39, 40, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 42, 39, 40, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 42, 39, 39, 39, 39, 39, 39, 39, + 39, 44, 45, 46, 47, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 56, + 57, 58, 39, 39, 39, 39, 39, 62, + 63, 64, 66, 39, 42, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 59, + 60, 39, 42, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 60, 39, + 4, 70, 69, 71, 69, 69, 69, 69, + 69, 69, 69, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 4, 81, 82, 83, + 84, 69, 85, 86, 87, 69, 69, 69, + 69, 88, 89, 90, 91, 92, 69, 69, + 69, 69, 93, 69, 69, 94, 69, 4, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 73, 74, 75, + 76, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 85, 86, 87, 69, 69, + 69, 69, 69, 89, 90, 91, 95, 69, + 69, 69, 69, 73, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 69, 73, 74, + 75, 76, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 85, 86, 87, 69, + 69, 69, 69, 69, 89, 90, 91, 95, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 74, 75, 76, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 89, 90, 91, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 75, + 76, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 89, 90, 91, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 76, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 89, 90, + 91, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 89, 90, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 90, 69, 71, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 74, 75, 76, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 85, + 86, 87, 69, 69, 69, 69, 69, 89, + 90, 91, 95, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 74, 75, + 76, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 86, 87, 69, 69, + 69, 69, 69, 89, 90, 91, 95, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 74, 75, 76, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 87, 69, 69, 69, 69, 69, 89, + 90, 91, 95, 69, 97, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 98, 96, 71, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 74, 75, 76, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 89, 90, 91, 95, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 72, + 73, 74, 75, 76, 69, 69, 69, 69, + 69, 69, 82, 83, 84, 69, 85, 86, + 87, 69, 69, 69, 69, 69, 89, 90, + 91, 95, 69, 69, 69, 69, 73, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 73, 74, 75, 76, 69, 69, 69, + 69, 69, 69, 82, 83, 84, 69, 85, + 86, 87, 69, 69, 69, 69, 69, 89, + 90, 91, 95, 69, 69, 69, 69, 73, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 69, 73, 74, 75, 76, 69, 69, + 69, 69, 69, 69, 69, 83, 84, 69, + 85, 86, 87, 69, 69, 69, 69, 69, + 89, 90, 91, 95, 69, 69, 69, 69, + 73, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 73, 74, 75, 76, 69, + 69, 69, 69, 69, 69, 69, 69, 84, + 69, 85, 86, 87, 69, 69, 69, 69, + 69, 89, 90, 91, 95, 69, 69, 69, + 69, 73, 69, 99, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 72, 73, 74, + 75, 76, 69, 78, 79, 69, 69, 69, + 82, 83, 84, 69, 85, 86, 87, 69, + 69, 69, 69, 69, 89, 90, 91, 95, + 69, 69, 69, 69, 73, 69, 71, 69, + 69, 69, 69, 69, 69, 69, 69, 73, + 74, 75, 76, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 85, 86, 87, + 69, 69, 69, 69, 69, 89, 90, 91, + 95, 69, 69, 69, 69, 73, 69, 99, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 72, 73, 74, 75, 76, 69, 69, + 79, 69, 69, 69, 82, 83, 84, 69, + 85, 86, 87, 69, 69, 69, 69, 69, + 89, 90, 91, 95, 69, 69, 69, 69, + 73, 69, 99, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 72, 73, 74, 75, + 76, 69, 69, 69, 69, 69, 69, 82, + 83, 84, 69, 85, 86, 87, 69, 69, + 69, 69, 69, 89, 90, 91, 95, 69, + 69, 69, 69, 73, 69, 99, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 72, + 73, 74, 75, 76, 77, 78, 79, 69, + 69, 69, 82, 83, 84, 69, 85, 86, + 87, 69, 69, 69, 69, 69, 89, 90, + 91, 95, 69, 69, 69, 69, 73, 69, + 4, 70, 69, 71, 69, 69, 69, 69, + 69, 69, 69, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 69, 81, 82, 83, + 84, 69, 85, 86, 87, 69, 69, 69, + 69, 88, 89, 90, 91, 92, 69, 69, + 69, 69, 93, 69, 69, 94, 69, 4, + 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 101, 100, 4, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 98, 96, 4, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 73, 74, 75, 76, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 85, 86, 87, 69, 69, 69, 69, + 69, 89, 90, 91, 95, 69, 101, 100, + 103, 104, 102, 6, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 106, 105, 107, + 108, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 107, 118, 119, 120, 121, + 69, 122, 123, 124, 69, 59, 60, 69, + 125, 126, 127, 128, 129, 69, 69, 69, + 69, 130, 69, 69, 131, 69, 107, 108, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 107, 118, 119, 120, 121, 69, + 122, 123, 124, 69, 69, 69, 69, 125, + 126, 127, 128, 129, 69, 69, 69, 69, + 130, 69, 69, 131, 69, 107, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 110, 111, 112, 113, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 122, 123, 124, 69, 69, 69, 69, + 69, 126, 127, 128, 132, 69, 69, 69, + 69, 110, 69, 71, 69, 69, 69, 69, + 69, 69, 69, 69, 110, 111, 112, 113, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 122, 123, 124, 69, 69, 69, + 69, 69, 126, 127, 128, 132, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 111, 112, 113, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 126, 127, + 128, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 112, 113, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 126, 127, 128, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 113, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 126, 127, 128, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 126, + 127, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 127, 69, 71, 69, 71, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 111, 112, 113, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 122, 123, 124, + 69, 69, 69, 69, 69, 126, 127, 128, + 132, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 111, 112, 113, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 123, 124, 69, 69, 69, 69, + 69, 126, 127, 128, 132, 69, 71, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 111, 112, 113, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 124, + 69, 69, 69, 69, 69, 126, 127, 128, + 132, 69, 133, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 98, + 96, 71, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 111, 112, 113, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 126, 127, 128, 132, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 109, 110, 111, + 112, 113, 69, 69, 69, 69, 69, 69, + 119, 120, 121, 69, 122, 123, 124, 69, + 69, 69, 69, 69, 126, 127, 128, 132, + 69, 69, 69, 69, 110, 69, 71, 69, + 69, 69, 69, 69, 69, 69, 69, 110, + 111, 112, 113, 69, 69, 69, 69, 69, + 69, 119, 120, 121, 69, 122, 123, 124, + 69, 69, 69, 69, 69, 126, 127, 128, + 132, 69, 69, 69, 69, 110, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 69, + 110, 111, 112, 113, 69, 69, 69, 69, + 69, 69, 69, 120, 121, 69, 122, 123, + 124, 69, 69, 69, 69, 69, 126, 127, + 128, 132, 69, 69, 69, 69, 110, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 110, 111, 112, 113, 69, 69, 69, + 69, 69, 69, 69, 69, 121, 69, 122, + 123, 124, 69, 69, 69, 69, 69, 126, + 127, 128, 132, 69, 69, 69, 69, 110, + 69, 134, 69, 71, 69, 69, 69, 69, + 69, 69, 69, 109, 110, 111, 112, 113, + 69, 115, 116, 69, 69, 69, 119, 120, + 121, 69, 122, 123, 124, 69, 69, 69, + 69, 69, 126, 127, 128, 132, 69, 69, + 69, 69, 110, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 110, 111, 112, + 113, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 122, 123, 124, 69, 69, + 69, 69, 69, 126, 127, 128, 132, 69, + 69, 69, 69, 110, 69, 134, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 109, + 110, 111, 112, 113, 69, 69, 116, 69, + 69, 69, 119, 120, 121, 69, 122, 123, + 124, 69, 69, 69, 69, 69, 126, 127, + 128, 132, 69, 69, 69, 69, 110, 69, + 134, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 109, 110, 111, 112, 113, 69, + 69, 69, 69, 69, 69, 119, 120, 121, + 69, 122, 123, 124, 69, 69, 69, 69, + 69, 126, 127, 128, 132, 69, 69, 69, + 69, 110, 69, 134, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 109, 110, 111, + 112, 113, 114, 115, 116, 69, 69, 69, + 119, 120, 121, 69, 122, 123, 124, 69, + 69, 69, 69, 69, 126, 127, 128, 132, + 69, 69, 69, 69, 110, 69, 107, 108, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 69, 118, 119, 120, 121, 69, + 122, 123, 124, 69, 69, 69, 69, 125, + 126, 127, 128, 129, 69, 69, 69, 69, + 130, 69, 69, 131, 69, 107, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 101, 100, 107, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 98, 96, 107, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 110, 111, 112, 113, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 122, + 123, 124, 69, 69, 69, 69, 69, 126, + 127, 128, 132, 69, 101, 100, 8, 9, + 135, 11, 135, 135, 135, 135, 135, 135, + 135, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 8, 22, 23, 24, 25, 135, + 26, 27, 28, 135, 135, 135, 135, 32, + 33, 34, 38, 32, 135, 135, 135, 135, + 37, 135, 135, 38, 135, 8, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 135, 14, 15, 16, 17, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 26, 27, 28, 135, 135, 135, 135, + 135, 33, 34, 38, 136, 135, 135, 135, + 135, 14, 135, 11, 135, 135, 135, 135, + 135, 135, 135, 135, 14, 15, 16, 17, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 26, 27, 28, 135, 135, 135, + 135, 135, 33, 34, 38, 136, 135, 11, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 15, 16, 17, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 33, 34, + 38, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 16, 17, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 33, 34, 38, 135, 11, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 17, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 33, 34, 38, 135, + 11, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 33, + 34, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 34, 135, 11, 137, 11, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 15, 16, 17, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 26, 27, 28, + 135, 135, 135, 135, 135, 33, 34, 38, + 136, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 15, 16, 17, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 27, 28, 135, 135, 135, 135, + 135, 33, 34, 38, 136, 135, 11, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 15, 16, 17, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 28, + 135, 135, 135, 135, 135, 33, 34, 38, + 136, 135, 138, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 11, + 135, 11, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 15, 16, 17, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 33, 34, 38, 136, 135, 11, 135, 135, + 135, 135, 135, 135, 135, 13, 14, 15, + 16, 17, 135, 135, 135, 135, 135, 135, + 23, 24, 25, 135, 26, 27, 28, 135, + 135, 135, 135, 135, 33, 34, 38, 136, + 135, 135, 135, 135, 14, 135, 11, 135, + 135, 135, 135, 135, 135, 135, 135, 14, + 15, 16, 17, 135, 135, 135, 135, 135, + 135, 23, 24, 25, 135, 26, 27, 28, + 135, 135, 135, 135, 135, 33, 34, 38, + 136, 135, 135, 135, 135, 14, 135, 11, + 135, 135, 135, 135, 135, 135, 135, 135, + 14, 15, 16, 17, 135, 135, 135, 135, + 135, 135, 135, 24, 25, 135, 26, 27, + 28, 135, 135, 135, 135, 135, 33, 34, + 38, 136, 135, 135, 135, 135, 14, 135, + 11, 135, 135, 135, 135, 135, 135, 135, + 135, 14, 15, 16, 17, 135, 135, 135, + 135, 135, 135, 135, 135, 25, 135, 26, + 27, 28, 135, 135, 135, 135, 135, 33, + 34, 38, 136, 135, 135, 135, 135, 14, + 135, 139, 135, 11, 135, 135, 135, 135, + 135, 135, 135, 13, 14, 15, 16, 17, + 135, 19, 20, 135, 135, 135, 23, 24, + 25, 135, 26, 27, 28, 135, 135, 135, + 135, 135, 33, 34, 38, 136, 135, 135, + 135, 135, 14, 135, 11, 135, 135, 135, + 135, 135, 135, 135, 135, 14, 15, 16, + 17, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 26, 27, 28, 135, 135, + 135, 135, 135, 33, 34, 38, 136, 135, + 135, 135, 135, 14, 135, 139, 135, 11, + 135, 135, 135, 135, 135, 135, 135, 13, + 14, 15, 16, 17, 135, 135, 20, 135, + 135, 135, 23, 24, 25, 135, 26, 27, + 28, 135, 135, 135, 135, 135, 33, 34, + 38, 136, 135, 135, 135, 135, 14, 135, + 139, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 13, 14, 15, 16, 17, 135, + 135, 135, 135, 135, 135, 23, 24, 25, + 135, 26, 27, 28, 135, 135, 135, 135, + 135, 33, 34, 38, 136, 135, 135, 135, + 135, 14, 135, 139, 135, 11, 135, 135, + 135, 135, 135, 135, 135, 13, 14, 15, + 16, 17, 18, 19, 20, 135, 135, 135, + 23, 24, 25, 135, 26, 27, 28, 135, + 135, 135, 135, 135, 33, 34, 38, 136, + 135, 135, 135, 135, 14, 135, 8, 9, + 135, 11, 135, 135, 135, 135, 135, 135, + 135, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 135, 22, 23, 24, 25, 135, + 26, 27, 28, 135, 135, 135, 135, 32, + 33, 34, 38, 32, 135, 135, 135, 135, + 37, 135, 135, 38, 135, 8, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 11, 135, 8, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 11, 135, 135, 135, 135, 135, 135, + 135, 135, 14, 15, 16, 17, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 26, 27, 28, 135, 135, 135, 135, 135, + 33, 34, 38, 136, 135, 140, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 11, + 135, 10, 11, 135, 4, 135, 135, 135, + 4, 135, 135, 135, 135, 135, 8, 9, + 10, 11, 135, 135, 135, 135, 135, 135, + 135, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 8, 22, 23, 24, 25, 135, + 26, 27, 28, 135, 29, 30, 135, 32, + 33, 34, 38, 32, 135, 135, 135, 135, + 37, 135, 135, 38, 135, 11, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 29, 30, 135, 11, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 30, + 135, 4, 141, 141, 141, 4, 141, 143, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 144, 142, 145, 142, 145, + 146, 142, 143, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 1, 144, 144, + 142, 143, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 144, 142, 145, + 142, 143, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 144, 142, 145, + 142, 145, 142, 40, 41, 39, 42, 39, + 39, 39, 39, 39, 39, 39, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 40, + 52, 53, 54, 55, 39, 56, 57, 58, + 39, 59, 60, 39, 61, 62, 63, 64, + 61, 1, 39, 2, 39, 65, 39, 39, + 64, 39, 0 }; static const char _use_syllable_machine_trans_targs[] = { - 1, 120, 0, 2, 31, 1, 58, 60, - 88, 89, 114, 1, 116, 102, 90, 91, - 92, 93, 106, 108, 109, 110, 111, 103, - 104, 105, 97, 98, 99, 117, 118, 119, - 112, 94, 95, 96, 124, 113, 1, 3, - 4, 1, 17, 5, 6, 7, 8, 21, - 23, 24, 25, 26, 18, 19, 20, 12, - 13, 14, 29, 30, 27, 9, 10, 11, - 28, 15, 16, 22, 1, 32, 1, 45, - 33, 34, 35, 36, 49, 51, 52, 53, - 54, 46, 47, 48, 40, 41, 42, 55, - 37, 38, 39, 56, 57, 43, 1, 44, - 1, 50, 1, 1, 1, 59, 1, 1, - 1, 61, 62, 75, 63, 64, 65, 66, - 79, 81, 82, 83, 84, 76, 77, 78, - 70, 71, 72, 85, 67, 68, 69, 86, - 87, 73, 74, 80, 1, 100, 101, 107, - 115, 1, 1, 1, 121, 122, 123 + 1, 122, 0, 2, 31, 1, 59, 61, + 90, 91, 116, 1, 118, 104, 92, 93, + 94, 95, 108, 110, 111, 112, 113, 105, + 106, 107, 99, 100, 101, 119, 120, 121, + 114, 96, 97, 98, 126, 115, 98, 1, + 3, 4, 1, 17, 5, 6, 7, 8, + 21, 23, 24, 25, 26, 18, 19, 20, + 12, 13, 14, 29, 30, 27, 9, 10, + 11, 28, 15, 16, 22, 1, 32, 1, + 45, 33, 34, 35, 36, 49, 51, 52, + 53, 54, 46, 47, 48, 40, 41, 42, + 55, 37, 38, 39, 56, 57, 58, 43, + 1, 44, 1, 50, 1, 1, 1, 60, + 1, 1, 1, 62, 63, 76, 64, 65, + 66, 67, 80, 82, 83, 84, 85, 77, + 78, 79, 71, 72, 73, 86, 68, 69, + 70, 87, 88, 89, 74, 75, 81, 1, + 102, 1, 103, 109, 117, 1, 1, 1, + 123, 124, 125 }; static const char _use_syllable_machine_trans_actions[] = { @@ -737,20 +745,21 @@ static const char _use_syllable_machine_trans_actions[] = { 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 0, 7, 0, - 0, 8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 7, 0, 8, 9, + 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 10, 0, + 0, 0, 0, 0, 0, 11, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 11, 0, - 12, 0, 13, 14, 15, 0, 16, 17, - 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 14, 0, 15, 16, 17, 0, + 18, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19, 0, 0, 0, - 0, 20, 21, 22, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 21, + 0, 22, 0, 0, 0, 23, 24, 25, + 0, 0, 0 }; static const char _use_syllable_machine_to_state_actions[] = { @@ -769,7 +778,7 @@ static const char _use_syllable_machine_to_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }; static const char _use_syllable_machine_from_state_actions[] = { @@ -788,26 +797,26 @@ static const char _use_syllable_machine_from_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }; static const short _use_syllable_machine_eof_trans[] = { - 1, 0, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 95, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 99, - 95, 69, 101, 104, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 95, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 99, 95, 69, - 133, 133, 133, 133, 133, 133, 133, 133, - 133, 133, 133, 133, 133, 133, 133, 133, - 133, 133, 133, 133, 133, 133, 133, 133, - 133, 133, 133, 133, 133, 133, 133, 138, - 139, 139, 139, 139, 39 + 1, 0, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 97, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 101, + 97, 70, 101, 103, 106, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 97, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 101, 97, + 70, 101, 136, 136, 136, 136, 136, 136, + 136, 136, 138, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 142, 143, 143, 143, 143, 40 }; static const int use_syllable_machine_start = 1; @@ -821,7 +830,7 @@ static const int use_syllable_machine_en_main = 1; -#line 184 "hb-ot-shaper-use-machine.rl" +#line 186 "hb-ot-shaper-use-machine.rl" #define found_syllable(syllable_type) \ @@ -920,7 +929,7 @@ find_syllables_use (hb_buffer_t *buffer) unsigned int act HB_UNUSED; int cs; -#line 924 "hb-ot-shaper-use-machine.hh" +#line 933 "hb-ot-shaper-use-machine.hh" { cs = use_syllable_machine_start; ts = 0; @@ -928,12 +937,12 @@ find_syllables_use (hb_buffer_t *buffer) act = 0; } -#line 284 "hb-ot-shaper-use-machine.rl" +#line 286 "hb-ot-shaper-use-machine.rl" unsigned int syllable_serial = 1; -#line 937 "hb-ot-shaper-use-machine.hh" +#line 946 "hb-ot-shaper-use-machine.hh" { int _slen; int _trans; @@ -947,7 +956,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 951 "hb-ot-shaper-use-machine.hh" +#line 960 "hb-ot-shaper-use-machine.hh" } _keys = _use_syllable_machine_trans_keys + (cs<<1); @@ -965,87 +974,111 @@ _eof_trans: goto _again; switch ( _use_syllable_machine_trans_actions[_trans] ) { - case 6: + case 7: #line 1 "NONE" {te = p+1;} break; - case 14: -#line 172 "hb-ot-shaper-use-machine.rl" + case 16: +#line 173 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_virama_terminated_cluster); }} break; - case 12: -#line 173 "hb-ot-shaper-use-machine.rl" + case 14: +#line 174 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_sakot_terminated_cluster); }} break; - case 10: -#line 174 "hb-ot-shaper-use-machine.rl" + case 12: +#line 175 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_standard_cluster); }} break; - case 18: -#line 175 "hb-ot-shaper-use-machine.rl" + case 20: +#line 176 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_number_joiner_terminated_cluster); }} break; - case 16: -#line 176 "hb-ot-shaper-use-machine.rl" + case 18: +#line 177 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_numeral_cluster); }} break; - case 8: -#line 177 "hb-ot-shaper-use-machine.rl" + case 10: +#line 178 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_symbol_cluster); }} break; - case 22: -#line 178 "hb-ot-shaper-use-machine.rl" + case 25: +#line 179 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_hieroglyph_cluster); }} break; case 5: -#line 179 "hb-ot-shaper-use-machine.rl" +#line 181 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; case 4: -#line 180 "hb-ot-shaper-use-machine.rl" +#line 182 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_non_cluster); }} break; - case 13: -#line 172 "hb-ot-shaper-use-machine.rl" + case 15: +#line 173 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_virama_terminated_cluster); }} break; - case 11: -#line 173 "hb-ot-shaper-use-machine.rl" + case 13: +#line 174 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }} break; - case 9: -#line 174 "hb-ot-shaper-use-machine.rl" + case 11: +#line 175 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_standard_cluster); }} break; - case 17: -#line 175 "hb-ot-shaper-use-machine.rl" + case 19: +#line 176 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }} break; - case 15: -#line 176 "hb-ot-shaper-use-machine.rl" + case 17: +#line 177 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_numeral_cluster); }} break; - case 7: -#line 177 "hb-ot-shaper-use-machine.rl" + case 9: +#line 178 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_symbol_cluster); }} break; - case 21: -#line 178 "hb-ot-shaper-use-machine.rl" + case 24: +#line 179 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }} break; - case 19: -#line 179 "hb-ot-shaper-use-machine.rl" + case 21: +#line 181 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; - case 20: -#line 180 "hb-ot-shaper-use-machine.rl" + case 23: +#line 182 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_non_cluster); }} break; case 1: -#line 177 "hb-ot-shaper-use-machine.rl" +#line 178 "hb-ot-shaper-use-machine.rl" {{p = ((te))-1;}{ found_syllable (use_symbol_cluster); }} break; -#line 1049 "hb-ot-shaper-use-machine.hh" + case 22: +#line 1 "NONE" + { switch( act ) { + case 8: + {{p = ((te))-1;} found_syllable (use_non_cluster); } + break; + case 9: + {{p = ((te))-1;} found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } + break; + } + } + break; + case 6: +#line 1 "NONE" + {te = p+1;} +#line 180 "hb-ot-shaper-use-machine.rl" + {act = 8;} + break; + case 8: +#line 1 "NONE" + {te = p+1;} +#line 181 "hb-ot-shaper-use-machine.rl" + {act = 9;} + break; +#line 1082 "hb-ot-shaper-use-machine.hh" } _again: @@ -1054,7 +1087,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 1058 "hb-ot-shaper-use-machine.hh" +#line 1091 "hb-ot-shaper-use-machine.hh" } if ( ++p != pe ) @@ -1070,7 +1103,7 @@ _again: } -#line 289 "hb-ot-shaper-use-machine.rl" +#line 291 "hb-ot-shaper-use-machine.rl" } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh index 491b2f940e1da..d3c49949aa8c6 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh @@ -6,18 +6,18 @@ * * on files with these headers: * - * # IndicSyllabicCategory-15.1.0.txt - * # Date: 2023-01-05 - * # IndicPositionalCategory-15.1.0.txt - * # Date: 2023-01-05 - * # ArabicShaping-15.1.0.txt - * # Date: 2023-01-05 - * # DerivedCoreProperties-15.1.0.txt - * # Date: 2023-08-07, 15:21:24 GMT - * # Blocks-15.1.0.txt - * # Date: 2023-07-28, 15:47:20 GMT - * # Scripts-15.1.0.txt - * # Date: 2023-07-28, 16:01:07 GMT + * # IndicSyllabicCategory-16.0.0.txt + * # Date: 2024-04-30, 21:48:21 GMT + * # IndicPositionalCategory-16.0.0.txt + * # Date: 2024-04-30, 21:48:21 GMT + * # ArabicShaping-16.0.0.txt + * # Date: 2024-07-30 + * # DerivedCoreProperties-16.0.0.txt + * # Date: 2024-05-31, 18:09:32 GMT + * # Blocks-16.0.0.txt + * # Date: 2024-02-02 + * # Scripts-16.0.0.txt + * # Date: 2024-04-30, 21:48:40 GMT * # Override values For Indic_Syllabic_Category * # Not derivable * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 @@ -27,6 +27,7 @@ * # Updated for Unicode 14.0 by Andrew Glass 2021-09-25 * # Updated for Unicode 15.0 by Andrew Glass 2022-09-16 * # Updated for Unicode 15.1 by Andrew Glass 2023-09-14 + * # Updated for Unicode 16.0 by Andrew Glass 2024-09-11 * # Override values For Indic_Positional_Category * # Not derivable * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 @@ -38,6 +39,7 @@ * # Updated for Unicode 14.0 by Andrew Glass 2021-09-28 * # Updated for Unicode 15.0 by Andrew Glass 2022-09-16 * # Updated for Unicode 15.1 by Andrew Glass 2023-09-14 + * # Updated for Unicode 16.0 by Andrew Glass 2024-09-11 * UnicodeData.txt does not have a header. */ @@ -65,6 +67,7 @@ #define N USE(N) /* BASE_NUM */ #define O USE(O) /* OTHER */ #define R USE(R) /* REPHA */ +#define RK USE(RK) /* REORDERING_KILLER */ #define SB USE(SB) /* HIEROGLYPH_SEGMENT_BEGIN */ #define SE USE(SE) /* HIEROGLYPH_SEGMENT_END */ #define SUB USE(SUB) /* CONS_SUB */ @@ -99,16 +102,16 @@ #ifndef HB_OPTIMIZE_SIZE static const uint8_t -hb_use_u8[3187] = +hb_use_u8[3345] = { - 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 51, 57, 58, 179, 195, 61, + 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 57, 58, 59, 195, 211, 62, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 14, 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 4, 2, 2, + 15, 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 4, 2, 2, 5, 6, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 2, 2, 17, 18, 19, 20, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 33, 2, 2, 2, @@ -121,24 +124,26 @@ hb_use_u8[3187] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 47, 48, 2, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 51, 2, 2, 2, - 2, 2, 2, 2, 2, 52, 53, 2, 54, 2, 2, 55, 2, 2, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 2, 66, 67, 2, 68, 69, 70, 71, - 2, 72, 2, 73, 74, 75, 76, 2, 2, 77, 78, 79, 80, 2, 81, 82, - 2, 83, 83, 83, 83, 83, 83, 83, 83, 84, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 52, 53, 2, 54, 2, 2, 55, 56, 2, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 2, 70, 71, 72, 73, + 2, 74, 2, 75, 76, 77, 78, 2, 2, 79, 80, 81, 82, 2, 83, 84, + 2, 85, 85, 85, 85, 85, 85, 85, 85, 86, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 87, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 89, 90, 2, 2, 2, 91, 2, 2, 2, 92, + 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 94, 94, 94, 95, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 85, 86, 2, 2, 2, 2, 2, 2, 2, 87, - 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 89, 89, 89, 90, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 97, 2, 2, 2, 2, 2, + 2, 2, 2, 98, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 91, 92, 2, 2, 2, 2, 2, - 2, 2, 2, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 94, 2, 2, 95, 2, 2, 2, 96, 2, 2, 2, 2, 2, - 2, 2, 2, 97, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 98, 98, 99, 100, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 2, 2, 2, 99, 2, 2, 100, 2, 2, 2, 101, 2, 102, 2, 2, 2, + 2, 2, 2, 103, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 104, 104, 105, 106, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -167,7 +172,7 @@ hb_use_u8[3187] = 0, 0, 0, 27, 31, 2, 9, 0, 0, 10, 29, 30, 2, 2, 2, 9, 2, 2, 2, 30, 2, 2, 0, 17, 45, 0, 0, 35, 47, 0, 0, 0, 9, 50, 51, 0, 0, 0, 0, 0, 0, 11, 29, 2, 2, 2, 2, 9, - 2, 2, 2, 2, 2, 2, 52, 53, 23, 23, 19, 31, 48, 33, 48, 34, + 2, 2, 2, 2, 2, 2, 52, 53, 23, 19, 20, 31, 48, 33, 48, 34, 54, 0, 0, 0, 35, 0, 0, 0, 30, 12, 29, 30, 2, 2, 2, 2, 2, 2, 2, 2, 9, 0, 2, 2, 2, 2, 30, 2, 2, 2, 2, 30, 0, 2, 2, 2, 9, 0, 55, 0, 35, 23, 22, 31, 31, 18, 48, 48, @@ -195,9 +200,9 @@ hb_use_u8[3187] = 0, 2, 2, 100, 101, 102, 103, 61, 63, 104, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 105, 46, 40, 11, 106, 74, 2, 2, 2, 2, 2, 2, 2, 107, 22, 20, 20, 22, 48, 48, 22, 108, 2, 2, 2, 9, - 0, 0, 0, 0, 0, 0, 109, 110, 111, 111, 111, 0, 0, 0, 0, 0, - 0, 106, 74, 2, 2, 2, 2, 2, 2, 60, 61, 59, 25, 22, 112, 61, - 2, 2, 2, 2, 107, 22, 23, 45, 45, 102, 14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 109, 110, 110, 110, 110, 0, 0, 0, 0, 0, + 0, 106, 74, 2, 2, 2, 2, 2, 2, 60, 61, 59, 25, 22, 111, 61, + 2, 2, 2, 2, 107, 22, 23, 45, 45, 102, 112, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 113, 102, 102, 102, 114, 115, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, 2, 11, 46, 116, 116, 116, 11, 116, 116, 15, 116, 116, 116, 26, 0, 40, 0, 0, 0, 117, 51, 11, 5, 0, @@ -226,6 +231,7 @@ hb_use_u8[3187] = 146, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, 2, 0, 14, 37, 0, 147, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, 9, 2, 2, 11, 41, 0, 0, 0, + 0, 2, 2, 2, 0, 27, 22, 22, 30, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, 0, 2, 2, 2, 116, 116, 116, 116, 116, 148, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0, 0, 9, 2, 2, 9, 2, 2, 2, 2, 30, 2, 9, 0, 30, 2, 0, @@ -244,39 +250,45 @@ hb_use_u8[3187] = 0, 11, 11, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 58, 17, 23, 16, 23, 47, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 0, 2, 2, 23, 0, 11, 11, 11, 46, 0, 11, 11, 46, 0, 0, 0, 0, - 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 126, 15, 17, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 0, 0, 163, 164, 0, 0, 0, 0, 0, 0, - 0, 18, 19, 20, 20, 66, 99, 25, 160, 11, 165, 9, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 2, 65, 25, 20, 20, 0, 48, 48, 11, - 166, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, - 0, 23, 19, 20, 20, 21, 16, 82, 166, 38, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 10, 167, 25, 20, 22, 22, 165, 9, 0, 0, - 0, 2, 2, 2, 2, 2, 9, 43, 136, 23, 22, 20, 76, 21, 22, 0, - 0, 2, 2, 2, 9, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 18, - 19, 20, 21, 22, 105, 166, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, - 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 168, - 169, 170, 171, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, - 2, 65, 25, 20, 20, 0, 22, 23, 29, 108, 0, 33, 0, 0, 0, 0, - 0, 52, 20, 22, 22, 22, 140, 2, 2, 2, 172, 173, 11, 15, 174, 72, - 175, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, - 2, 2, 2, 158, 158, 158, 176, 176, 176, 176, 176, 176, 15, 177, 0, 30, - 0, 22, 20, 20, 31, 22, 22, 11, 166, 0, 61, 61, 61, 61, 61, 61, - 61, 66, 21, 82, 46, 0, 0, 0, 0, 2, 2, 2, 9, 2, 30, 2, - 2, 52, 22, 22, 31, 0, 38, 22, 27, 11, 159, 178, 174, 0, 0, 0, - 0, 2, 2, 2, 30, 9, 2, 2, 2, 2, 2, 2, 2, 2, 23, 23, - 47, 22, 35, 82, 68, 0, 0, 0, 0, 2, 179, 66, 47, 0, 0, 0, - 0, 11, 180, 2, 2, 2, 2, 2, 2, 2, 2, 23, 22, 20, 31, 0, - 48, 16, 143, 0, 0, 0, 0, 0, 0, 181, 181, 181, 181, 181, 181, 181, - 181, 182, 182, 182, 183, 184, 182, 181, 181, 185, 181, 181, 186, 187, 187, 187, - 187, 187, 187, 187, 0, 0, 0, 0, 0, 11, 11, 11, 46, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 9, 0, 58, 188, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, - 40, 116, 26, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, - 0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 58, - 37, 0, 6, 120, 120, 120, 121, 0, 0, 11, 11, 11, 49, 2, 2, 2, - 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, - 46, 2, 2, 2, 2, 2, 2, 11, 11, 2, 2, 2, 2, 2, 2, 22, - 22, 2, 2, 44, 44, 44, 92, 0, 0, O, O, O, GB, B, B, O, + 0, 2, 2, 2, 2, 2, 30, 0, 9, 2, 2, 2, 30, 45, 59, 20, + 20, 31, 33, 32, 32, 25, 163, 29, 164, 165, 37, 0, 0, 0, 0, 0, + 0, 12, 26, 0, 0, 0, 0, 0, 0, 2, 2, 65, 25, 20, 20, 20, + 22, 23, 126, 15, 17, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, + 166, 167, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 20, 66, 99, 25, + 160, 11, 168, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 65, 25, 20, 20, 0, 48, 48, 11, 169, 37, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 20, 0, 23, 19, 20, 20, 21, 16, 82, + 169, 38, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 10, 170, + 25, 20, 22, 22, 168, 9, 0, 0, 0, 2, 2, 2, 2, 2, 9, 43, + 136, 23, 22, 20, 76, 21, 22, 0, 0, 2, 2, 2, 9, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 18, 19, 20, 21, 22, 105, 169, 37, 0, + 0, 2, 2, 2, 9, 30, 0, 2, 2, 2, 2, 30, 9, 2, 2, 2, + 2, 23, 23, 18, 32, 33, 12, 171, 165, 172, 173, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 0, 2, 2, 2, 65, 25, 20, 20, 0, 22, 23, + 29, 108, 0, 33, 0, 0, 0, 0, 0, 52, 20, 22, 22, 22, 140, 2, + 2, 2, 174, 175, 11, 15, 176, 61, 177, 0, 0, 1, 147, 0, 0, 0, + 0, 52, 20, 22, 16, 19, 20, 2, 2, 2, 2, 158, 158, 158, 178, 178, + 178, 178, 178, 178, 15, 179, 0, 30, 0, 22, 20, 20, 31, 22, 22, 11, + 169, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, + 0, 2, 2, 2, 9, 2, 30, 2, 2, 52, 22, 22, 31, 0, 38, 22, + 27, 11, 159, 180, 181, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, + 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0, + 0, 2, 182, 66, 47, 0, 0, 0, 0, 11, 183, 2, 2, 2, 2, 2, + 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 143, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 156, 0, 0, 184, 184, 184, 184, 184, 184, 184, + 184, 185, 185, 185, 186, 187, 185, 184, 184, 188, 184, 184, 189, 190, 190, 190, + 190, 190, 190, 190, 0, 0, 0, 0, 0, 184, 184, 184, 184, 184, 191, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 192, 193, + 194, 11, 11, 11, 46, 0, 0, 0, 0, 29, 74, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 65, 47, 0, 2, 2, 2, 2, 2, 9, 0, + 58, 195, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 0, 0, 0, 40, 116, 26, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 120, 120, 120, 121, 0, + 0, 11, 11, 11, 49, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 2, 2, 2, 2, 2, 11, + 11, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, + 20, 2, 2, 44, 44, 44, 92, 0, 0, O, O, O, GB, B, B, O, SB, O, SE, GB, O, O, WJ,FMPst,FMPst, O, CGJ, B, O, B,VMAbv,VMAbv, VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, VPst,VMBlw, O, O, @@ -290,20 +302,21 @@ hb_use_u8[3187] = FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB, CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, - VPst, H, B, O,SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst, IS, VBlw, FAbv,VMPre,VMPre,FMAbv, + VPst, H, B, O,SMAbv,SMAbv,SMAbv, VPst, IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv, CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B, CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, - IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,FMAbv, - B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, VPst, IS, R, MPst, R, MPst, - CMBlw, B,FMBlw, VBlw,VMAbv, R, MBlw, MBlw, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, GB, - VAbv, R,VMPst, G, G, J, J, J, SB, SE, J, HR, G, G, HM, HM, - HM, O, VBlw, + IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, + O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, + VPst, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, + IS, VBlw, IS, R, MBlw, GB, VAbv, R,VMPst, G, G, J, J, J, SB, SE, + J, HR, G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, + VBlw, }; static const uint16_t -hb_use_u16[808] = +hb_use_u16[856] = { 0, 0, 1, 2, 0, 3, 0, 3, 0, 0, 4, 5, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, @@ -332,28 +345,31 @@ hb_use_u16[808] = 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0,166,166,167, 34,168, 0, 0, 0, 0, 169,170, 10,171, 95, 0, 0, 0, 0, 0, 0, 0, 70, 10,172, 0, - 10,173,174, 0, 0, 0, 0, 0, 10, 10,175, 2, 0, 0, 0, 0, - 10, 10,176,173, 0, 0, 0, 0, 0, 0, 0, 10,177,178, 0, 10, - 179, 0, 0,180,181, 0, 0, 0,182, 10, 10,183,184,185,186,187, - 188, 10, 10,189,190, 0, 0, 0,191, 10,192,193,194, 10, 10,195, - 188, 10, 10,196,197,106,198,103, 10, 34,199,200,201, 0, 0, 0, - 202,203, 95, 10, 10,204,205, 2,206, 21, 22,207,208,209,210,211, - 10, 10, 10,212,213,214,215, 0,198, 10, 10,216,217, 2, 0, 0, - 10, 10,218,219,220,221, 0, 0, 10, 10, 10,222,223, 2, 0, 0, - 10, 10,224,225, 2, 0, 0, 0, 10,226,227,104,228, 0, 0, 0, - 10, 10,229,230, 0, 0, 0, 0,231,232, 10,233,234, 2, 0, 0, - 0, 0,235, 10, 10,236,237, 0,238, 10, 10,239,240,241, 10, 10, - 242,243, 0, 0, 0, 0, 0, 0, 22, 10,218,244, 8, 10, 71, 19, - 10,245, 74,246, 0, 0, 0, 0,247, 10, 10,248,249, 2,250, 10, - 251,252, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,253, - 254, 49, 10,255,256, 2, 0, 0,257,257,257,257,257,257,257,257, - 257,257,257,258,259,260, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 10, 10, 10,261, 0, 0, 0, 0, 10, 10, 10, 10,262,263,264,264, - 265,266, 0, 0, 0, 0,267, 0, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10,268, 0, 0, 10, 10, 10, 10, 10, 10,106, 71, - 95,269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,270, - 10, 10, 71,271,272, 0, 0, 0, 0, 10,273, 0, 10, 10,274, 2, - 0, 0, 0, 0, 0, 10,275, 2, 10, 10, 10, 10,276, 2, 0, 0, + 10,173,174, 0, 0, 0, 0, 0, 10, 10,175, 2, 9, 10,176, 10, + 177, 0, 0, 0, 0, 0, 0, 0, 10, 10,178,173, 0, 0, 0, 0, + 0, 0, 0, 10,179,180, 0, 10,181, 0, 0,182,183, 0, 0, 0, + 184, 10, 10,185,186,187,188,189,190, 10, 10,191,192, 0, 0, 0, + 193, 10,194,195,196, 10, 10,197,190, 10, 10,198,199,106,200,103, + 10, 34,201,202,203, 0, 0, 0,204,205, 95, 10, 10,206,207, 2, + 208, 21, 22,209,210,211,212,213,214, 10, 10,215,216,217,218, 0, + 10, 10, 10,219,220,221,222, 0,200, 10, 10,223,224, 2, 0, 0, + 10, 10,225,226,227,228, 0, 0, 10, 10, 10,229,230, 2, 0, 0, + 10, 10,231,232, 2, 10,141, 0, 10,233,234,104,235, 0, 0, 0, + 10, 10,236,237, 0, 0, 0, 0,238,239, 10,240,241, 2, 0, 0, + 0, 0,242, 10, 10,243,244, 0,245, 10, 10,246,247,248, 10, 10, + 249,250, 0, 0, 0, 0, 0, 0, 22, 10,225,251, 8, 10, 71, 19, + 10,252, 74,253, 0, 0, 0, 0,254, 10, 10,255,256, 2,257, 10, + 258,259, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,260, + 261, 49, 10,262,263,264, 0, 0,265,265,265,265,265,265,265,265, + 265,265,265,266,267,268,265,265,265,265,265,265,265,265,265,269, + 10,270,271, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 10, 10, 10,272, 0, 0, 0, 0, 0, 0, 0, 0,273, 10,274, 2, + 10, 10, 10, 10,275,276,277,277,278,279, 0, 0, 0, 0,280, 0, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,177, 0,281, + 10, 10, 10, 10, 10, 10,106, 71, 95,282, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,283, 10, 10, 71,284,285, 0, 0, 0, + 0, 10,286, 0, 10, 10,287, 2, 0, 0, 0, 0, 0, 10,288, 2, + 0, 0, 0, 0, 0, 10,289,106, 10, 10, 10, 10,290, 2, 0, 0, 130,130,130,130,130,130,130,130,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,130, }; @@ -366,23 +382,23 @@ hb_use_b4 (const uint8_t* a, unsigned i) static inline uint_fast8_t hb_use_get_category (unsigned u) { - return u<921600u?hb_use_u8[2809+(((hb_use_u8[593+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; + return u<921600u?hb_use_u8[2953+(((hb_use_u8[625+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; } #else static const uint8_t -hb_use_u8[3483] = +hb_use_u8[3657] = { - 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 51, 57, 58, 179, 195, 61, + 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 57, 58, 59, 195, 211, 62, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 14, 0, 1, 1, 2, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 1, + 15, 0, 1, 1, 2, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 1, 11, 12, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 17, 18, 19, 1, 1, 20, 1, 1, 1, 1, 21, 1, 22, 1, 1, 1, 1, 1, 23, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -390,14 +406,15 @@ hb_use_u8[3483] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 30, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 32, 33, 1, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 1, 48, 49, 50, - 51, 52, 52, 52, 52, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 54, 55, 1, 1, 1, - 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 57, 58, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 59, 1, 1, - 1, 1, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 61, 62, 1, 63, 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, - 1, 65, 66, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 0, 1, 2, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 51, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 56, 57, 1, 58, 1, + 59, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 60, 61, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 1, + 1, 1, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 64, 65, 1, 66, 67, 1, 1, 1, 68, 1, 1, 1, 1, 1, + 1, 69, 70, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 0, 1, 2, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 9, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, @@ -414,23 +431,25 @@ hb_use_u8[3483] = 122, 0, 0, 0, 0, 0, 0, 56, 123, 124, 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 127, 128, 129, 0, 0, 130, 131, 132, 0, 0, 0, 51, 133, 0, 0, 0, 0, 134, 135, 0, - 0, 56, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 137, 0, - 0, 0, 101, 138, 101, 139, 140, 141, 0, 142, 143, 144, 145, 146, 147, 148, - 0, 149, 150, 151, 152, 146, 153, 154, 155, 156, 157, 158, 0, 159, 160, 161, - 162, 163, 164, 165, 166, 0, 0, 0, 0, 56, 167, 168, 169, 170, 171, 172, - 0, 0, 0, 0, 0, 56, 173, 174, 0, 56, 175, 176, 0, 56, 177, 67, - 0, 178, 179, 180, 0, 0, 0, 0, 0, 56, 181, 0, 0, 0, 0, 0, - 0, 182, 183, 184, 0, 0, 185, 186, 187, 188, 189, 190, 56, 191, 0, 0, - 0, 192, 193, 194, 195, 196, 197, 0, 0, 198, 199, 200, 201, 202, 67, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 203, 204, 205, 206, 0, 0, 0, 0, - 0, 207, 207, 207, 207, 207, 207, 207, 207, 207, 208, 209, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 67, 0, 56, 210, 0, 0, 0, 0, 0, - 0, 56, 56, 211, 212, 213, 0, 0, 214, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 215, 0, 56, 56, 56, 216, 217, 0, 0, - 0, 0, 0, 0, 218, 0, 0, 0, 0, 56, 219, 220, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 101, 221, 56, 222, 0, 0, 0, 0, 0, 0, 101, - 223, 56, 56, 224, 0, 0, 0, 0, 0, 225, 225, 225, 225, 225, 225, 225, - 225, 226, 226, 226, 226, 226, 226, 226, 227, 0, 0, 0, 0, 0, 0, 0, + 0, 56, 136, 7, 137, 138, 0, 0, 0, 0, 0, 0, 0, 56, 139, 0, + 0, 0, 101, 140, 101, 141, 142, 143, 0, 144, 145, 146, 147, 148, 149, 150, + 0, 151, 152, 153, 154, 148, 155, 156, 157, 158, 159, 160, 0, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 56, 173, 174, 175, 176, 177, 178, + 0, 0, 0, 0, 0, 56, 179, 180, 0, 56, 181, 182, 0, 56, 183, 184, + 185, 186, 187, 188, 0, 0, 0, 0, 0, 56, 189, 0, 0, 0, 0, 0, + 0, 190, 191, 192, 0, 0, 193, 194, 195, 196, 197, 198, 56, 199, 0, 0, + 0, 200, 201, 202, 203, 204, 205, 0, 0, 206, 207, 208, 209, 210, 67, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 211, 212, 213, 214, 0, 0, 0, 0, + 0, 215, 215, 215, 215, 215, 215, 215, 215, 215, 216, 217, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 215, 218, 219, 220, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 67, 0, 56, 221, 0, 0, 0, 0, 0, + 0, 0, 0, 222, 223, 0, 0, 0, 0, 56, 56, 224, 225, 226, 0, 0, + 227, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 228, + 229, 56, 56, 56, 230, 231, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, + 0, 56, 233, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 235, 56, + 236, 0, 0, 0, 0, 0, 0, 101, 237, 0, 0, 0, 0, 0, 0, 101, + 238, 56, 56, 239, 0, 0, 0, 0, 0, 240, 240, 240, 240, 240, 240, 240, + 240, 241, 241, 241, 241, 241, 241, 241, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, @@ -460,7 +479,7 @@ hb_use_u8[3483] = 0, 10, 29, 30, 2, 2, 2, 9, 2, 2, 2, 30, 2, 2, 0, 17, 45, 0, 0, 35, 47, 0, 0, 0, 9, 50, 51, 0, 0, 0, 0, 0, 0, 11, 29, 2, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 52, 53, - 23, 23, 19, 31, 48, 33, 48, 34, 54, 0, 0, 0, 35, 0, 0, 0, + 23, 19, 20, 31, 48, 33, 48, 34, 54, 0, 0, 0, 35, 0, 0, 0, 30, 12, 29, 30, 2, 2, 2, 2, 2, 2, 2, 2, 9, 0, 2, 2, 2, 2, 30, 2, 2, 2, 2, 30, 0, 2, 2, 2, 9, 0, 55, 0, 35, 23, 22, 31, 31, 18, 48, 48, 25, 0, 23, 0, 0, 0, 0, 0, @@ -488,9 +507,9 @@ hb_use_u8[3483] = 63, 104, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 105, 46, 40, 11, 106, 74, 2, 2, 2, 2, 2, 2, 2, 107, 22, 20, 20, 22, 48, 48, 22, 108, 2, 2, 2, 9, 0, 0, 0, 0, 0, 0, 109, 110, - 111, 111, 111, 0, 0, 0, 0, 0, 0, 106, 74, 2, 2, 2, 2, 2, - 2, 60, 61, 59, 25, 22, 112, 61, 2, 2, 2, 2, 107, 22, 23, 45, - 45, 102, 14, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 113, + 110, 110, 110, 0, 0, 0, 0, 0, 0, 106, 74, 2, 2, 2, 2, 2, + 2, 60, 61, 59, 25, 22, 111, 61, 2, 2, 2, 2, 107, 22, 23, 45, + 45, 102, 112, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 113, 102, 102, 102, 114, 115, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, 2, 11, 46, 116, 116, 116, 11, 116, 116, 15, 116, 116, 116, 26, 0, 40, 0, 0, 0, 117, 51, 11, 5, 0, 0, 0, 0, 0, 0, 0, 118, 0, @@ -518,7 +537,8 @@ hb_use_u8[3483] = 0, 128, 20, 27, 31, 0, 0, 145, 146, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, 2, 0, 14, 37, 0, 147, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, - 9, 2, 2, 11, 41, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, + 9, 2, 2, 11, 41, 0, 0, 0, 0, 2, 2, 2, 0, 27, 22, 22, + 30, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, 0, 2, 2, 2, 116, 116, 116, 116, 116, 148, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0, 0, 9, 2, 2, 9, 2, 2, 2, 2, 30, 2, 9, 0, 30, 2, 0, 0, 149, 150, 151, 2, 2, 2, 2, @@ -536,39 +556,45 @@ hb_use_u8[3483] = 10, 18, 19, 21, 22, 162, 31, 0, 0, 11, 11, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 58, 17, 23, 16, 23, 47, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 0, 2, 2, 23, 0, 11, 11, 11, 46, - 0, 11, 11, 46, 0, 0, 0, 0, 0, 2, 2, 65, 25, 20, 20, 20, - 22, 23, 126, 15, 17, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, - 163, 164, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 20, 66, 99, 25, - 160, 11, 165, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 65, 25, 20, 20, 0, 48, 48, 11, 166, 37, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 2, 20, 0, 23, 19, 20, 20, 21, 16, 82, - 166, 38, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 10, 167, - 25, 20, 22, 22, 165, 9, 0, 0, 0, 2, 2, 2, 2, 2, 9, 43, - 136, 23, 22, 20, 76, 21, 22, 0, 0, 2, 2, 2, 9, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 18, 19, 20, 21, 22, 105, 166, 37, 0, - 0, 2, 2, 2, 9, 30, 0, 2, 2, 2, 2, 30, 9, 2, 2, 2, - 2, 23, 23, 18, 32, 33, 12, 168, 169, 170, 171, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 0, 2, 2, 2, 65, 25, 20, 20, 0, 22, 23, - 29, 108, 0, 33, 0, 0, 0, 0, 0, 52, 20, 22, 22, 22, 140, 2, - 2, 2, 172, 173, 11, 15, 174, 72, 175, 0, 0, 1, 147, 0, 0, 0, - 0, 52, 20, 22, 16, 19, 20, 2, 2, 2, 2, 158, 158, 158, 176, 176, - 176, 176, 176, 176, 15, 177, 0, 30, 0, 22, 20, 20, 31, 22, 22, 11, - 166, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, - 0, 2, 2, 2, 9, 2, 30, 2, 2, 52, 22, 22, 31, 0, 38, 22, - 27, 11, 159, 178, 174, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, - 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0, - 0, 2, 179, 66, 47, 0, 0, 0, 0, 11, 180, 2, 2, 2, 2, 2, - 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 143, 0, 0, 0, 0, 0, - 0, 181, 181, 181, 181, 181, 181, 181, 181, 182, 182, 182, 183, 184, 182, 181, - 181, 185, 181, 181, 186, 187, 187, 187, 187, 187, 187, 187, 0, 0, 0, 0, - 0, 11, 11, 11, 46, 0, 0, 0, 0, 2, 2, 2, 2, 2, 9, 0, - 58, 188, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 0, 0, 0, 40, 116, 26, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 120, 120, 120, 121, 0, - 0, 11, 11, 11, 49, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 2, 2, 2, 2, 2, 11, - 11, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 44, 44, 44, 92, 0, + 0, 11, 11, 46, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 30, 0, + 9, 2, 2, 2, 30, 45, 59, 20, 20, 31, 33, 32, 32, 25, 163, 29, + 164, 165, 37, 0, 0, 0, 0, 0, 0, 12, 26, 0, 0, 0, 0, 0, + 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 126, 15, 17, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 0, 166, 167, 0, 0, 0, 0, 0, 0, + 0, 18, 19, 20, 20, 66, 99, 25, 160, 11, 168, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 65, 25, 20, 20, 0, 48, 48, 11, + 169, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, + 0, 23, 19, 20, 20, 21, 16, 82, 169, 38, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 10, 170, 25, 20, 22, 22, 168, 9, 0, 0, + 0, 2, 2, 2, 2, 2, 9, 43, 136, 23, 22, 20, 76, 21, 22, 0, + 0, 2, 2, 2, 9, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 18, + 19, 20, 21, 22, 105, 169, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, + 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 171, + 165, 172, 173, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, + 2, 65, 25, 20, 20, 0, 22, 23, 29, 108, 0, 33, 0, 0, 0, 0, + 0, 52, 20, 22, 22, 22, 140, 2, 2, 2, 174, 175, 11, 15, 176, 61, + 177, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, + 2, 2, 2, 158, 158, 158, 178, 178, 178, 178, 178, 178, 15, 179, 0, 30, + 0, 22, 20, 20, 31, 22, 22, 11, 169, 0, 61, 61, 61, 61, 61, 61, + 61, 66, 21, 82, 46, 0, 0, 0, 0, 2, 2, 2, 9, 2, 30, 2, + 2, 52, 22, 22, 31, 0, 38, 22, 27, 11, 159, 180, 181, 0, 0, 0, + 0, 2, 2, 2, 30, 9, 2, 2, 2, 2, 2, 2, 2, 2, 23, 23, + 47, 22, 35, 82, 68, 0, 0, 0, 0, 2, 182, 66, 47, 0, 0, 0, + 0, 11, 183, 2, 2, 2, 2, 2, 2, 2, 2, 23, 22, 20, 31, 0, + 48, 16, 143, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 156, 0, + 0, 184, 184, 184, 184, 184, 184, 184, 184, 185, 185, 185, 186, 187, 185, 184, + 184, 188, 184, 184, 189, 190, 190, 190, 190, 190, 190, 190, 0, 0, 0, 0, + 0, 184, 184, 184, 184, 184, 191, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 22, 22, 22, 22, 22, 22, 192, 193, 194, 11, 11, 11, 46, 0, 0, 0, + 0, 29, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 65, 47, + 0, 2, 2, 2, 2, 2, 9, 0, 58, 195, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, + 40, 116, 26, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, 2, 2, 2, 0, 58, + 37, 0, 6, 120, 120, 120, 121, 0, 0, 11, 11, 11, 49, 2, 2, 2, + 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, + 46, 2, 2, 2, 2, 2, 2, 11, 11, 2, 2, 2, 2, 2, 2, 22, + 22, 2, 2, 2, 2, 2, 2, 2, 20, 2, 2, 44, 44, 44, 92, 0, 0, O, O, O, GB, B, B, O, SB, O, SE, GB, O, O, WJ,FMPst, FMPst, O, CGJ, B, O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv, VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, @@ -582,20 +608,21 @@ hb_use_u8[3483] = VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS, FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, - SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,SMAbv,SMBlw,SMAbv,SMAbv, - SMAbv, VPst, IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, + SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,SMAbv,SMAbv,SMAbv, VPst, + IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, H, MPst, VPst, H,VMAbv, VAbv, VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R, R,CMBlw, - VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, - VAbv,VMAbv, VPst, IS, R, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, R, MBlw, MBlw, - GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, GB, VAbv, R,VMPst, G, G, J, J, J, - SB, SE, J, HR, G, G, HM, HM, HM, O, VBlw, + VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, + CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, VPst, MPst, R, MPst,CMBlw, B,FMBlw, VBlw, + VMAbv, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, R, MBlw, GB, VAbv, R, + VMPst, G, G, J, J, J, SB, SE, J, HR, G, G, HM, HM, HM, G, + O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, }; static const uint16_t -hb_use_u16[456] = +hb_use_u16[486] = { 0, 0, 1, 2, 0, 3, 4, 5, 0, 6, 7, 0, 8, 0, 9, 10, 11, 12, 10, 13, 14, 10, 10, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -614,18 +641,20 @@ hb_use_u16[456] = 148,149,150, 10, 10,151,152, 2,153, 99,154,155,156, 2, 10,157, 10,158,159, 0,160,161,162, 2,163, 0, 0,164, 0,165, 0,166, 166,167, 34,168,169,170, 10,171, 95, 0,172, 0, 10,173,174, 0, - 175, 2,176,173,177,178,179, 0, 0,180,181, 0,182, 10, 10,183, - 184,185,186,187,188, 10, 10,189,190, 0,191, 10,192,193,194, 10, - 10,195, 10,196,197,106,198,103, 10, 34,199,200,201, 0,202,203, - 95, 10, 10,204,205, 2,206, 21, 22,207,208,209,210,211, 10,212, - 213,214,215, 0,198, 10, 10,216,217, 2,218,219,220,221, 10,222, - 223, 2,224,225, 10,226,227,104,228, 0,229,230,231,232, 10,233, - 234, 2,235, 10, 10,236,237, 0,238, 10, 10,239,240,241,242,243, - 22, 10,218,244, 8, 10, 71, 19, 10,245, 74,246,247, 10, 10,248, - 249, 2,250, 10,251,252, 10,253,254, 49, 10,255,256, 2,257,257, - 257,258,259,260, 10,261,262,263,264,264,265,266,267, 0, 10,268, - 106, 71, 95,269, 0,270, 71,271,272, 0,273, 0,274, 2,275, 2, - 276, 2,130,130,163,163,163,130, + 175, 2,176, 10,177, 0,178,173,179,180,181, 0, 0,182,183, 0, + 184, 10, 10,185,186,187,188,189,190, 10, 10,191,192, 0,193, 10, + 194,195,196, 10, 10,197, 10,198,199,106,200,103, 10, 34,201,202, + 203, 0,204,205, 95, 10, 10,206,207, 2,208, 21, 22,209,210,211, + 212,213,214, 10, 10,215,216,217,218, 0, 10,219,220,221,222, 0, + 200, 10, 10,223,224, 2,225,226,227,228, 10,229,230, 2,231,232, + 2, 10,141, 0, 10,233,234,104,235, 0,236,237,238,239, 10,240, + 241, 2,242, 10, 10,243,244, 0,245, 10, 10,246,247,248,249,250, + 22, 10,225,251, 8, 10, 71, 19, 10,252, 74,253,254, 10, 10,255, + 256, 2,257, 10,258,259, 10,260,261, 49, 10,262,263,264,265,265, + 265,266,267,268,265,269, 10,270,271, 2, 10,272,273, 10,274, 2, + 275,276,277,277,278,279,280, 0, 10,177, 0,281,106, 71, 95,282, + 0,283, 71,284,285, 0,286, 0,287, 2,288, 2,289,106,290, 2, + 130,130,163,163,163,130, }; static inline unsigned @@ -636,7 +665,7 @@ hb_use_b4 (const uint8_t* a, unsigned i) static inline uint_fast8_t hb_use_get_category (unsigned u) { - return u<921600u?hb_use_u8[3105+(((hb_use_u8[889+(((hb_use_u16[((hb_use_u8[353+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; + return u<921600u?hb_use_u8[3265+(((hb_use_u8[937+(((hb_use_u16[((hb_use_u8[369+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; } #endif @@ -656,6 +685,7 @@ hb_use_get_category (unsigned u) #undef N #undef O #undef R +#undef RK #undef SB #undef SE #undef SUB diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc index 35693254ec075..4a112e1c28973 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc @@ -10,8 +10,8 @@ * # Date: 2015-03-12, 21:17:00 GMT [AG] * # Date: 2019-11-08, 23:22:00 GMT [AG] * - * # Scripts-15.1.0.txt - * # Date: 2023-07-28, 16:01:07 GMT + * # Scripts-16.0.0.txt + * # Date: 2024-04-30, 21:48:40 GMT */ #include "hb.hh" @@ -24,7 +24,7 @@ static void _output_dotted_circle (hb_buffer_t *buffer) { (void) buffer->output_glyph (0x25CCu); - _hb_glyph_info_reset_continuation (&buffer->prev()); + _hb_glyph_info_clear_continuation (&buffer->prev()); } static void diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh index 39a04ec2348e6..48cd5296ffd05 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh @@ -174,9 +174,11 @@ HB_OT_SHAPERS_IMPLEMENT_SHAPERS static inline const hb_ot_shaper_t * -hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner) +hb_ot_shaper_categorize (hb_script_t script, + hb_direction_t direction, + hb_tag_t gsub_script) { - switch ((hb_tag_t) planner->props.script) + switch ((hb_tag_t) script) { default: return &_hb_ot_shaper_default; @@ -192,9 +194,8 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner) * This is because we do fallback shaping for Arabic script (and not others). * But note that Arabic shaping is applicable only to horizontal layout; for * vertical text, just use the generic shaper instead. */ - if ((planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT || - planner->props.script == HB_SCRIPT_ARABIC) && - HB_DIRECTION_IS_HORIZONTAL(planner->props.direction)) + if ((gsub_script != HB_OT_TAG_DEFAULT_SCRIPT || script == HB_SCRIPT_ARABIC) && + HB_DIRECTION_IS_HORIZONTAL (direction)) return &_hb_ot_shaper_arabic; else return &_hb_ot_shaper_default; @@ -235,10 +236,10 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner) * Otherwise, use the specific shaper. * * If it's indy3 tag, send to USE. */ - if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') || - planner->map.chosen_script[0] == HB_TAG ('l','a','t','n')) + if (gsub_script == HB_TAG ('D','F','L','T') || + gsub_script == HB_TAG ('l','a','t','n')) return &_hb_ot_shaper_default; - else if ((planner->map.chosen_script[0] & 0x000000FF) == '3') + else if ((gsub_script & 0x000000FF) == '3') return &_hb_ot_shaper_use; else return &_hb_ot_shaper_indic; @@ -254,9 +255,9 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner) * If designer designed for 'mymr' tag, also send to default * shaper. That's tag used from before Myanmar shaping spec * was developed. The shaping spec uses 'mym2' tag. */ - if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') || - planner->map.chosen_script[0] == HB_TAG ('l','a','t','n') || - planner->map.chosen_script[0] == HB_TAG ('m','y','m','r')) + if (gsub_script == HB_TAG ('D','F','L','T') || + gsub_script == HB_TAG ('l','a','t','n') || + gsub_script == HB_TAG ('m','y','m','r')) return &_hb_ot_shaper_default; else return &_hb_ot_shaper_myanmar; @@ -386,13 +387,22 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_KAWI: case HB_SCRIPT_NAG_MUNDARI: + /* Unicode-16.0 additions */ + case HB_SCRIPT_GARAY: + case HB_SCRIPT_GURUNG_KHEMA: + case HB_SCRIPT_KIRAT_RAI: + case HB_SCRIPT_OL_ONAL: + case HB_SCRIPT_SUNUWAR: + case HB_SCRIPT_TODHRI: + case HB_SCRIPT_TULU_TIGALARI: + /* If the designer designed the font for the 'DFLT' script, * (or we ended up arbitrarily pick 'latn'), use the default shaper. * Otherwise, use the specific shaper. * Note that for some simple scripts, there may not be *any* * GSUB/GPOS needed, so there may be no scripts found! */ - if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') || - planner->map.chosen_script[0] == HB_TAG ('l','a','t','n')) + if (gsub_script == HB_TAG ('D','F','L','T') || + gsub_script == HB_TAG ('l','a','t','n')) return &_hb_ot_shaper_default; else return &_hb_ot_shaper_use; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh index 7f6b52d797754..10165f57b7556 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh @@ -63,8 +63,9 @@ static bool axis_value_is_outside_axis_range (hb_tag_t axis_tag, float axis_valu if (!user_axes_location->has (axis_tag)) return false; + double axis_value_double = static_cast(axis_value); Triple axis_range = user_axes_location->get (axis_tag); - return (axis_value < axis_range.minimum || axis_value > axis_range.maximum); + return (axis_value_double < axis_range.minimum || axis_value_double > axis_range.maximum); } struct StatAxisRecord @@ -327,6 +328,7 @@ struct AxisValueFormat4 { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && axisValues.sanitize (c, axisCount))); } @@ -348,15 +350,15 @@ struct AxisValueFormat4 struct AxisValue { - bool get_value (unsigned int axis_index) const + float get_value (unsigned int axis_index) const { switch (u.format) { - case 1: return u.format1.get_value (); - case 2: return u.format2.get_value (); - case 3: return u.format3.get_value (); - case 4: return u.format4.get_axis_record (axis_index).get_value (); - default:return 0; + case 1: hb_barrier (); return u.format1.get_value (); + case 2: hb_barrier (); return u.format2.get_value (); + case 3: hb_barrier (); return u.format3.get_value (); + case 4: hb_barrier (); return u.format4.get_axis_record (axis_index).get_value (); + default:return 0.f; } } @@ -364,9 +366,9 @@ struct AxisValue { switch (u.format) { - case 1: return u.format1.get_axis_index (); - case 2: return u.format2.get_axis_index (); - case 3: return u.format3.get_axis_index (); + case 1: hb_barrier (); return u.format1.get_axis_index (); + case 2: hb_barrier (); return u.format2.get_axis_index (); + case 3: hb_barrier (); return u.format3.get_axis_index (); /* case 4: Makes more sense for variable fonts which are handled by fvar in hb-style */ default:return -1; } @@ -376,10 +378,10 @@ struct AxisValue { switch (u.format) { - case 1: return u.format1.get_value_name_id (); - case 2: return u.format2.get_value_name_id (); - case 3: return u.format3.get_value_name_id (); - case 4: return u.format4.get_value_name_id (); + case 1: hb_barrier (); return u.format1.get_value_name_id (); + case 2: hb_barrier (); return u.format2.get_value_name_id (); + case 3: hb_barrier (); return u.format3.get_value_name_id (); + case 4: hb_barrier (); return u.format4.get_value_name_id (); default:return HB_OT_NAME_ID_INVALID; } } @@ -390,10 +392,10 @@ struct AxisValue if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); - case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); - case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); - case 4: return_trace (c->dispatch (u.format4, std::forward (ds)...)); + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); + case 4: hb_barrier (); return_trace (c->dispatch (u.format4, std::forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -403,10 +405,10 @@ struct AxisValue { switch (u.format) { - case 1: return u.format1.keep_axis_value (axis_records, user_axes_location); - case 2: return u.format2.keep_axis_value (axis_records, user_axes_location); - case 3: return u.format3.keep_axis_value (axis_records, user_axes_location); - case 4: return u.format4.keep_axis_value (axis_records, user_axes_location); + case 1: hb_barrier (); return u.format1.keep_axis_value (axis_records, user_axes_location); + case 2: hb_barrier (); return u.format2.keep_axis_value (axis_records, user_axes_location); + case 3: hb_barrier (); return u.format3.keep_axis_value (axis_records, user_axes_location); + case 4: hb_barrier (); return u.format4.keep_axis_value (axis_records, user_axes_location); default:return false; } } @@ -416,13 +418,14 @@ struct AxisValue TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (u.format) { - case 1: return_trace (u.format1.sanitize (c)); - case 2: return_trace (u.format2.sanitize (c)); - case 3: return_trace (u.format3.sanitize (c)); - case 4: return_trace (u.format4.sanitize (c)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); + case 3: hb_barrier (); return_trace (u.format3.sanitize (c)); + case 4: hb_barrier (); return_trace (u.format4.sanitize (c)); default:return_trace (true); } } @@ -483,7 +486,7 @@ struct STAT hb_array_t> axis_values = get_axis_value_offsets (); for (unsigned int i = 0; i < axis_values.length; i++) { - const AxisValue& axis_value = this+axis_values[i]; + const AxisValue& axis_value = this+offsetToAxisValueOffsets+axis_values[i]; if (axis_value.get_axis_index () == axis_index) { if (value) @@ -560,6 +563,7 @@ struct STAT { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && version.minor > 0 && designAxesOffset.sanitize (c, this, designAxisCount) && diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh index 8ee42e638e021..50ddf5f696725 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh @@ -6,8 +6,8 @@ * * on files with these headers: * - * - * File-Date: 2023-08-02 + * + * File-Date: 2025-01-21 */ #ifndef HB_OT_TAG_TABLE_HH @@ -26,12 +26,12 @@ static const LangTag ot_languages2[] = { {HB_TAG('a','y',' ',' '), HB_TAG('A','Y','M',' ')}, /* Aymara [macrolanguage] */ {HB_TAG('a','z',' ',' '), HB_TAG('A','Z','E',' ')}, /* Azerbaijani [macrolanguage] */ {HB_TAG('b','a',' ',' '), HB_TAG('B','S','H',' ')}, /* Bashkir */ - {HB_TAG('b','e',' ',' '), HB_TAG('B','E','L',' ')}, /* Belarusian -> Belarussian */ + {HB_TAG('b','e',' ',' '), HB_TAG('B','E','L',' ')}, /* Belarusian */ {HB_TAG('b','g',' ',' '), HB_TAG('B','G','R',' ')}, /* Bulgarian */ {HB_TAG('b','i',' ',' '), HB_TAG('B','I','S',' ')}, /* Bislama */ {HB_TAG('b','i',' ',' '), HB_TAG('C','P','P',' ')}, /* Bislama -> Creoles */ {HB_TAG('b','m',' ',' '), HB_TAG('B','M','B',' ')}, /* Bambara (Bamanankan) */ - {HB_TAG('b','n',' ',' '), HB_TAG('B','E','N',' ')}, /* Bengali */ + {HB_TAG('b','n',' ',' '), HB_TAG('B','E','N',' ')}, /* Bangla */ {HB_TAG('b','o',' ',' '), HB_TAG('T','I','B',' ')}, /* Tibetan */ {HB_TAG('b','r',' ',' '), HB_TAG('B','R','E',' ')}, /* Breton */ {HB_TAG('b','s',' ',' '), HB_TAG('B','O','S',' ')}, /* Bosnian */ @@ -64,7 +64,8 @@ static const LangTag ot_languages2[] = { {HB_TAG('f','r',' ',' '), HB_TAG('F','R','A',' ')}, /* French */ {HB_TAG('f','y',' ',' '), HB_TAG('F','R','I',' ')}, /* Western Frisian -> Frisian */ {HB_TAG('g','a',' ',' '), HB_TAG('I','R','I',' ')}, /* Irish */ - {HB_TAG('g','d',' ',' '), HB_TAG('G','A','E',' ')}, /* Scottish Gaelic (Gaelic) */ + {HB_TAG('g','a',' ',' '), HB_TAG('I','R','T',' ')}, /* Irish -> Irish Traditional */ + {HB_TAG('g','d',' ',' '), HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */ {HB_TAG('g','l',' ',' '), HB_TAG('G','A','L',' ')}, /* Galician */ {HB_TAG('g','n',' ',' '), HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */ {HB_TAG('g','u',' ',' '), HB_TAG('G','U','J',' ')}, /* Gujarati */ @@ -153,7 +154,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('o','c',' ',' '), HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */ {HB_TAG('o','j',' ',' '), HB_TAG('O','J','B',' ')}, /* Ojibwa [macrolanguage] -> Ojibway */ {HB_TAG('o','m',' ',' '), HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */ - {HB_TAG('o','r',' ',' '), HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) [macrolanguage] */ + {HB_TAG('o','r',' ',' '), HB_TAG('O','R','I',' ')}, /* Odia [macrolanguage] */ {HB_TAG('o','s',' ',' '), HB_TAG('O','S','S',' ')}, /* Ossetian */ {HB_TAG('p','a',' ',' '), HB_TAG('P','A','N',' ')}, /* Punjabi */ {HB_TAG('p','i',' ',' '), HB_TAG('P','A','L',' ')}, /* Pali */ @@ -166,7 +167,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('r','o',' ',' '), HB_TAG('R','O','M',' ')}, /* Romanian */ {HB_TAG('r','u',' ',' '), HB_TAG('R','U','S',' ')}, /* Russian */ {HB_TAG('r','w',' ',' '), HB_TAG('R','U','A',' ')}, /* Kinyarwanda */ - {HB_TAG('s','a',' ',' '), HB_TAG('S','A','N',' ')}, /* Sanskrit */ + {HB_TAG('s','a',' ',' '), HB_TAG('S','A','N',' ')}, /* Sanskrit [macrolanguage] */ {HB_TAG('s','c',' ',' '), HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */ {HB_TAG('s','d',' ',' '), HB_TAG('S','N','D',' ')}, /* Sindhi */ {HB_TAG('s','e',' ',' '), HB_TAG('N','S','M',' ')}, /* Northern Sami */ @@ -223,6 +224,7 @@ static const LangTag ot_languages2[] = { static const LangTag ot_languages3[] = { {HB_TAG('a','a','e',' '), HB_TAG('S','Q','I',' ')}, /* Arbëreshë Albanian -> Albanian */ {HB_TAG('a','a','o',' '), HB_TAG('A','R','A',' ')}, /* Algerian Saharan Arabic -> Arabic */ +/*{HB_TAG('a','a','q',' '), HB_TAG('A','A','Q',' ')},*/ /* Eastern Abnaki -> Eastern Abenaki */ {HB_TAG('a','a','t',' '), HB_TAG('S','Q','I',' ')}, /* Arvanitika Albanian -> Albanian */ {HB_TAG('a','b','a',' '), HB_TAG_NONE }, /* Abé != Abaza */ {HB_TAG('a','b','h',' '), HB_TAG('A','R','A',' ')}, /* Tajiki Arabic -> Arabic */ @@ -238,6 +240,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('a','c','r',' '), HB_TAG('M','Y','N',' ')}, /* Achi -> Mayan */ {HB_TAG('a','c','w',' '), HB_TAG('A','R','A',' ')}, /* Hijazi Arabic -> Arabic */ {HB_TAG('a','c','x',' '), HB_TAG('A','R','A',' ')}, /* Omani Arabic -> Arabic */ + {HB_TAG('a','c','y',' '), HB_TAG('A','C','Y',' ')}, /* Cypriot Arabic */ {HB_TAG('a','c','y',' '), HB_TAG('A','R','A',' ')}, /* Cypriot Arabic -> Arabic */ {HB_TAG('a','d','a',' '), HB_TAG('D','N','G',' ')}, /* Adangme -> Dangme */ {HB_TAG('a','d','f',' '), HB_TAG('A','R','A',' ')}, /* Dhofari Arabic -> Arabic */ @@ -288,6 +291,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('a','s','t',' '), HB_TAG('A','S','T',' ')},*/ /* Asturian */ /*{HB_TAG('a','t','h',' '), HB_TAG('A','T','H',' ')},*/ /* Athapascan [collection] -> Athapaskan */ {HB_TAG('a','t','j',' '), HB_TAG('R','C','R',' ')}, /* Atikamekw -> R-Cree */ +/*{HB_TAG('a','t','s',' '), HB_TAG('A','T','S',' ')},*/ /* Gros Ventre (Atsina) */ {HB_TAG('a','t','v',' '), HB_TAG('A','L','T',' ')}, /* Northern Altai -> Altai */ {HB_TAG('a','u','j',' '), HB_TAG('B','B','R',' ')}, /* Awjilah -> Berber */ {HB_TAG('a','u','z',' '), HB_TAG('A','R','A',' ')}, /* Uzbeki Arabic -> Arabic */ @@ -326,6 +330,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('b','c','l',' '), HB_TAG('B','I','K',' ')}, /* Central Bikol -> Bikol */ {HB_TAG('b','c','q',' '), HB_TAG('B','C','H',' ')}, /* Bench */ {HB_TAG('b','c','r',' '), HB_TAG('A','T','H',' ')}, /* Babine -> Athapaskan */ +/*{HB_TAG('b','d','c',' '), HB_TAG('B','D','C',' ')},*/ /* Emberá-Baudó */ /*{HB_TAG('b','d','y',' '), HB_TAG('B','D','Y',' ')},*/ /* Bandjalang */ {HB_TAG('b','e','a',' '), HB_TAG('A','T','H',' ')}, /* Beaver -> Athapaskan */ {HB_TAG('b','e','b',' '), HB_TAG('B','T','I',' ')}, /* Bebele -> Beti */ @@ -421,6 +426,8 @@ static const LangTag ot_languages3[] = { {HB_TAG('c','a','f',' '), HB_TAG('A','T','H',' ')}, /* Southern Carrier -> Athapaskan */ {HB_TAG('c','a','k',' '), HB_TAG('C','A','K',' ')}, /* Kaqchikel */ {HB_TAG('c','a','k',' '), HB_TAG('M','Y','N',' ')}, /* Kaqchikel -> Mayan */ +/*{HB_TAG('c','a','y',' '), HB_TAG('C','A','Y',' ')},*/ /* Cayuga */ +/*{HB_TAG('c','b','g',' '), HB_TAG('C','B','G',' ')},*/ /* Chimila */ {HB_TAG('c','b','k',' '), HB_TAG('C','B','K',' ')}, /* Chavacano -> Zamboanga Chavacano */ {HB_TAG('c','b','k',' '), HB_TAG('C','P','P',' ')}, /* Chavacano -> Creoles */ {HB_TAG('c','b','l',' '), HB_TAG('Q','I','N',' ')}, /* Bualkhaw Chin -> Chin */ @@ -465,7 +472,9 @@ static const LangTag ot_languages3[] = { {HB_TAG('c','l','d',' '), HB_TAG('S','Y','R',' ')}, /* Chaldean Neo-Aramaic -> Syriac */ {HB_TAG('c','l','e',' '), HB_TAG('C','C','H','N')}, /* Lealao Chinantec -> Chinantec */ {HB_TAG('c','l','j',' '), HB_TAG('Q','I','N',' ')}, /* Laitu Chin -> Chin */ + {HB_TAG('c','l','s',' '), HB_TAG('S','A','N',' ')}, /* Classical Sanskrit -> Sanskrit */ {HB_TAG('c','l','t',' '), HB_TAG('Q','I','N',' ')}, /* Lautu Chin -> Chin */ +/*{HB_TAG('c','m','i',' '), HB_TAG('C','M','I',' ')},*/ /* Emberá-Chamí */ {HB_TAG('c','m','n',' '), HB_TAG('Z','H','S',' ')}, /* Mandarin Chinese -> Chinese, Simplified */ {HB_TAG('c','m','r',' '), HB_TAG('Q','I','N',' ')}, /* Mro-Khimi Chin -> Chin */ {HB_TAG('c','n','b',' '), HB_TAG('Q','I','N',' ')}, /* Chinbon Chin -> Chin */ @@ -479,6 +488,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('c','n','w',' '), HB_TAG('Q','I','N',' ')}, /* Ngawn Chin -> Chin */ {HB_TAG('c','o','a',' '), HB_TAG('M','L','Y',' ')}, /* Cocos Islands Malay -> Malay */ {HB_TAG('c','o','b',' '), HB_TAG('M','Y','N',' ')}, /* Chicomuceltec -> Mayan */ +/*{HB_TAG('c','o','o',' '), HB_TAG('C','O','O',' ')},*/ /* Comox */ /*{HB_TAG('c','o','p',' '), HB_TAG('C','O','P',' ')},*/ /* Coptic */ {HB_TAG('c','o','q',' '), HB_TAG('A','T','H',' ')}, /* Coquille -> Athapaskan */ {HB_TAG('c','p','a',' '), HB_TAG('C','C','H','N')}, /* Palantla Chinantec -> Chinantec */ @@ -528,6 +538,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('c','t','g',' '), HB_TAG('C','T','G',' ')},*/ /* Chittagonian */ {HB_TAG('c','t','h',' '), HB_TAG('Q','I','N',' ')}, /* Thaiphum Chin -> Chin */ {HB_TAG('c','t','l',' '), HB_TAG('C','C','H','N')}, /* Tlacoatzintepec Chinantec -> Chinantec */ +/*{HB_TAG('c','t','o',' '), HB_TAG('C','T','O',' ')},*/ /* Emberá-Catío */ {HB_TAG('c','t','s',' '), HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol -> Bikol */ /*{HB_TAG('c','t','t',' '), HB_TAG('C','T','T',' ')},*/ /* Wayanad Chetti */ {HB_TAG('c','t','u',' '), HB_TAG('M','Y','N',' ')}, /* Chol -> Mayan */ @@ -551,7 +562,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('d','e','p',' '), HB_TAG('C','P','P',' ')}, /* Pidgin Delaware -> Creoles */ {HB_TAG('d','g','o',' '), HB_TAG('D','G','O',' ')}, /* Dogri (individual language) */ {HB_TAG('d','g','o',' '), HB_TAG('D','G','R',' ')}, /* Dogri (macrolanguage) */ - {HB_TAG('d','g','r',' '), HB_TAG('A','T','H',' ')}, /* Dogrib -> Athapaskan */ + {HB_TAG('d','g','r',' '), HB_TAG('A','T','H',' ')}, /* Tlicho -> Athapaskan */ {HB_TAG('d','h','d',' '), HB_TAG('M','A','W',' ')}, /* Dhundari -> Marwari */ /*{HB_TAG('d','h','g',' '), HB_TAG('D','H','G',' ')},*/ /* Dhangu */ {HB_TAG('d','h','v',' '), HB_TAG_NONE }, /* Dehu != Divehi (Dhivehi, Maldivian) (deprecated) */ @@ -590,6 +601,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('e','k','y',' '), HB_TAG('K','R','N',' ')}, /* Eastern Kayah -> Karen */ {HB_TAG('e','m','k',' '), HB_TAG('E','M','K',' ')}, /* Eastern Maninkakan */ {HB_TAG('e','m','k',' '), HB_TAG('M','N','K',' ')}, /* Eastern Maninkakan -> Maninka */ +/*{HB_TAG('e','m','p',' '), HB_TAG('E','M','P',' ')},*/ /* Northern Emberá */ {HB_TAG('e','m','y',' '), HB_TAG('M','Y','N',' ')}, /* Epigraphic Mayan -> Mayan */ {HB_TAG('e','n','b',' '), HB_TAG('K','A','L',' ')}, /* Markweeta -> Kalenjin */ {HB_TAG('e','n','f',' '), HB_TAG('F','N','E',' ')}, /* Forest Enets */ @@ -637,7 +649,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('g','a','a',' '), HB_TAG('G','A','D',' ')}, /* Ga */ {HB_TAG('g','a','c',' '), HB_TAG('C','P','P',' ')}, /* Mixed Great Andamanese -> Creoles */ {HB_TAG('g','a','d',' '), HB_TAG_NONE }, /* Gaddang != Ga */ - {HB_TAG('g','a','e',' '), HB_TAG_NONE }, /* Guarequena != Scottish Gaelic (Gaelic) */ + {HB_TAG('g','a','e',' '), HB_TAG_NONE }, /* Guarequena != Scottish Gaelic */ /*{HB_TAG('g','a','g',' '), HB_TAG('G','A','G',' ')},*/ /* Gagauz */ {HB_TAG('g','a','l',' '), HB_TAG_NONE }, /* Galolen != Galician */ {HB_TAG('g','a','n',' '), HB_TAG('Z','H','S',' ')}, /* Gan Chinese -> Chinese, Simplified */ @@ -654,6 +666,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('g','e','z',' '), HB_TAG('G','E','Z',' ')},*/ /* Geez */ {HB_TAG('g','g','o',' '), HB_TAG('G','O','N',' ')}, /* Southern Gondi (retired code) -> Gondi */ {HB_TAG('g','h','a',' '), HB_TAG('B','B','R',' ')}, /* Ghadamès -> Berber */ + {HB_TAG('g','h','c',' '), HB_TAG('I','R','T',' ')}, /* Hiberno-Scottish Gaelic -> Irish Traditional */ {HB_TAG('g','h','k',' '), HB_TAG('K','R','N',' ')}, /* Geko Karen -> Karen */ {HB_TAG('g','h','o',' '), HB_TAG('B','B','R',' ')}, /* Ghomara -> Berber */ {HB_TAG('g','i','b',' '), HB_TAG('C','P','P',' ')}, /* Gibanawa -> Creoles */ @@ -732,6 +745,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('h','n','d',' '), HB_TAG('H','N','D',' ')},*/ /* Southern Hindko -> Hindko */ {HB_TAG('h','n','e',' '), HB_TAG('C','H','H',' ')}, /* Chhattisgarhi -> Chattisgarhi */ {HB_TAG('h','n','j',' '), HB_TAG('H','M','N',' ')}, /* Hmong Njua -> Hmong */ + {HB_TAG('h','n','m',' '), HB_TAG('Z','H','S',' ')}, /* Hainanese -> Chinese, Simplified */ {HB_TAG('h','n','o',' '), HB_TAG('H','N','D',' ')}, /* Northern Hindko -> Hindko */ {HB_TAG('h','o','c',' '), HB_TAG('H','O',' ',' ')}, /* Ho */ {HB_TAG('h','o','i',' '), HB_TAG('A','T','H',' ')}, /* Holikachuk -> Athapaskan */ @@ -743,6 +757,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('h','s','n',' '), HB_TAG('Z','H','S',' ')}, /* Xiang Chinese -> Chinese, Simplified */ {HB_TAG('h','u','j',' '), HB_TAG('H','M','N',' ')}, /* Northern Guiyang Hmong -> Hmong */ {HB_TAG('h','u','p',' '), HB_TAG('A','T','H',' ')}, /* Hupa -> Athapaskan */ +/*{HB_TAG('h','u','r',' '), HB_TAG('H','U','R',' ')},*/ /* Halkomelem */ {HB_TAG('h','u','s',' '), HB_TAG('M','Y','N',' ')}, /* Huastec -> Mayan */ {HB_TAG('h','w','c',' '), HB_TAG('C','P','P',' ')}, /* Hawai'i Creole English -> Creoles */ {HB_TAG('h','y','w',' '), HB_TAG('H','Y','E',' ')}, /* Western Armenian -> Armenian */ @@ -780,6 +795,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('j','b','n',' '), HB_TAG('B','B','R',' ')}, /* Nafusi -> Berber */ /*{HB_TAG('j','b','o',' '), HB_TAG('J','B','O',' ')},*/ /* Lojban */ /*{HB_TAG('j','c','t',' '), HB_TAG('J','C','T',' ')},*/ /* Krymchak */ +/*{HB_TAG('j','d','t',' '), HB_TAG('J','D','T',' ')},*/ /* Judeo-Tat */ {HB_TAG('j','g','o',' '), HB_TAG('B','M','L',' ')}, /* Ngomba -> Bamileke */ {HB_TAG('j','i','i',' '), HB_TAG_NONE }, /* Jiiddu != Yiddish */ {HB_TAG('j','k','m',' '), HB_TAG('K','R','N',' ')}, /* Mobwa Karen -> Karen */ @@ -794,6 +810,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','a','m',' '), HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */ {HB_TAG('k','a','r',' '), HB_TAG('K','R','N',' ')}, /* Karen [collection] */ /*{HB_TAG('k','a','w',' '), HB_TAG('K','A','W',' ')},*/ /* Kawi (Old Javanese) */ +/*{HB_TAG('k','b','c',' '), HB_TAG('K','B','C',' ')},*/ /* Kadiwéu */ {HB_TAG('k','b','d',' '), HB_TAG('K','A','B',' ')}, /* Kabardian */ {HB_TAG('k','b','y',' '), HB_TAG('K','N','R',' ')}, /* Manga Kanuri -> Kanuri */ {HB_TAG('k','c','a',' '), HB_TAG('K','H','K',' ')}, /* Khanty -> Khanty-Kazim */ @@ -814,6 +831,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','f','x',' '), HB_TAG('K','U','L',' ')}, /* Kullu Pahari -> Kulvi */ {HB_TAG('k','f','y',' '), HB_TAG('K','M','N',' ')}, /* Kumaoni */ {HB_TAG('k','g','e',' '), HB_TAG_NONE }, /* Komering != Khutsuri Georgian */ +/*{HB_TAG('k','g','f',' '), HB_TAG('K','G','F',' ')},*/ /* Kube */ {HB_TAG('k','h','a',' '), HB_TAG('K','S','I',' ')}, /* Khasi */ {HB_TAG('k','h','b',' '), HB_TAG('X','B','D',' ')}, /* Lü */ {HB_TAG('k','h','k',' '), HB_TAG('M','N','G',' ')}, /* Halh Mongolian -> Mongolian */ @@ -829,6 +847,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','j','b',' '), HB_TAG('M','Y','N',' ')}, /* Q'anjob'al -> Mayan */ /*{HB_TAG('k','j','d',' '), HB_TAG('K','J','D',' ')},*/ /* Southern Kiwai */ {HB_TAG('k','j','h',' '), HB_TAG('K','H','A',' ')}, /* Khakas -> Khakass */ +/*{HB_TAG('k','j','j',' '), HB_TAG('K','J','J',' ')},*/ /* Khinalugh -> Khinalug */ {HB_TAG('k','j','p',' '), HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen -> Eastern Pwo Karen */ {HB_TAG('k','j','p',' '), HB_TAG('K','R','N',' ')}, /* Pwo Eastern Karen -> Karen */ {HB_TAG('k','j','t',' '), HB_TAG('K','R','N',' ')}, /* Phrae Pwo Karen -> Karen */ @@ -838,6 +857,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','l','m',' '), HB_TAG_NONE }, /* Migum != Kalmyk */ {HB_TAG('k','l','n',' '), HB_TAG('K','A','L',' ')}, /* Kalenjin [macrolanguage] */ {HB_TAG('k','m','b',' '), HB_TAG('M','B','N',' ')}, /* Kimbundu -> Mbundu */ +/*{HB_TAG('k','m','g',' '), HB_TAG('K','M','G',' ')},*/ /* Kâte */ {HB_TAG('k','m','n',' '), HB_TAG_NONE }, /* Awtuw != Kumaoni */ {HB_TAG('k','m','o',' '), HB_TAG_NONE }, /* Kwoma != Komo */ {HB_TAG('k','m','r',' '), HB_TAG('K','U','R',' ')}, /* Northern Kurdish -> Kurdish */ @@ -881,6 +901,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','s','i',' '), HB_TAG_NONE }, /* Krisa != Khasi */ {HB_TAG('k','s','m',' '), HB_TAG_NONE }, /* Kumba != Kildin Sami */ {HB_TAG('k','s','s',' '), HB_TAG('K','I','S',' ')}, /* Southern Kisi -> Kisii */ +/*{HB_TAG('k','s','u',' '), HB_TAG('K','S','U',' ')},*/ /* Khamyang */ {HB_TAG('k','s','w',' '), HB_TAG('K','S','W',' ')}, /* S’gaw Karen */ {HB_TAG('k','s','w',' '), HB_TAG('K','R','N',' ')}, /* S'gaw Karen -> Karen */ {HB_TAG('k','t','b',' '), HB_TAG('K','E','B',' ')}, /* Kambaata -> Kebena */ @@ -894,6 +915,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','u','y',' '), HB_TAG_NONE }, /* Kuuku-Ya'u != Kuy */ {HB_TAG('k','v','b',' '), HB_TAG('M','L','Y',' ')}, /* Kubu -> Malay */ {HB_TAG('k','v','l',' '), HB_TAG('K','R','N',' ')}, /* Kayaw -> Karen */ + {HB_TAG('k','v','q',' '), HB_TAG('K','V','Q',' ')}, /* Geba Karen */ {HB_TAG('k','v','q',' '), HB_TAG('K','R','N',' ')}, /* Geba Karen -> Karen */ {HB_TAG('k','v','r',' '), HB_TAG('M','L','Y',' ')}, /* Kerinci -> Malay */ {HB_TAG('k','v','t',' '), HB_TAG('K','R','N',' ')}, /* Lahta Karen -> Karen */ @@ -930,6 +952,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('l','i','j',' '), HB_TAG('L','I','J',' ')},*/ /* Ligurian */ {HB_TAG('l','i','r',' '), HB_TAG('C','P','P',' ')}, /* Liberian English -> Creoles */ /*{HB_TAG('l','i','s',' '), HB_TAG('L','I','S',' ')},*/ /* Lisu */ +/*{HB_TAG('l','i','v',' '), HB_TAG('L','I','V',' ')},*/ /* Liv */ {HB_TAG('l','i','w',' '), HB_TAG('M','L','Y',' ')}, /* Col -> Malay */ {HB_TAG('l','i','y',' '), HB_TAG('B','A','D','0')}, /* Banda-Bambari -> Banda */ /*{HB_TAG('l','j','p',' '), HB_TAG('L','J','P',' ')},*/ /* Lampung Api -> Lampung */ @@ -959,9 +982,11 @@ static const LangTag ot_languages3[] = { {HB_TAG('l','t','o',' '), HB_TAG('L','U','H',' ')}, /* Tsotso -> Luyia */ {HB_TAG('l','t','s',' '), HB_TAG('L','U','H',' ')}, /* Tachoni -> Luyia */ /*{HB_TAG('l','u','a',' '), HB_TAG('L','U','A',' ')},*/ /* Luba-Lulua */ + {HB_TAG('l','u','h',' '), HB_TAG('Z','H','S',' ')}, /* Leizhou Chinese -> Chinese, Simplified */ /*{HB_TAG('l','u','o',' '), HB_TAG('L','U','O',' ')},*/ /* Luo (Kenya and Tanzania) */ {HB_TAG('l','u','s',' '), HB_TAG('M','I','Z',' ')}, /* Lushai -> Mizo */ {HB_TAG('l','u','s',' '), HB_TAG('Q','I','N',' ')}, /* Lushai -> Chin */ +/*{HB_TAG('l','u','t',' '), HB_TAG('L','U','T',' ')},*/ /* Lushootseed */ {HB_TAG('l','u','y',' '), HB_TAG('L','U','H',' ')}, /* Luyia [macrolanguage] */ {HB_TAG('l','u','z',' '), HB_TAG('L','R','C',' ')}, /* Southern Luri -> Luri */ {HB_TAG('l','v','i',' '), HB_TAG_NONE }, /* Lavi != Latvian */ @@ -995,12 +1020,14 @@ static const LangTag ot_languages3[] = { {HB_TAG('m','e','n',' '), HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */ {HB_TAG('m','e','o',' '), HB_TAG('M','L','Y',' ')}, /* Kedah Malay -> Malay */ /*{HB_TAG('m','e','r',' '), HB_TAG('M','E','R',' ')},*/ /* Meru */ +/*{HB_TAG('m','e','v',' '), HB_TAG('M','E','V',' ')},*/ /* Mano */ {HB_TAG('m','f','a',' '), HB_TAG('M','F','A',' ')}, /* Pattani Malay */ {HB_TAG('m','f','a',' '), HB_TAG('M','L','Y',' ')}, /* Pattani Malay -> Malay */ {HB_TAG('m','f','b',' '), HB_TAG('M','L','Y',' ')}, /* Bangka -> Malay */ {HB_TAG('m','f','e',' '), HB_TAG('M','F','E',' ')}, /* Morisyen */ {HB_TAG('m','f','e',' '), HB_TAG('C','P','P',' ')}, /* Morisyen -> Creoles */ {HB_TAG('m','f','p',' '), HB_TAG('C','P','P',' ')}, /* Makassar Malay -> Creoles */ + {HB_TAG('m','g','a',' '), HB_TAG('S','G','A',' ')}, /* Middle Irish (900-1200) -> Old Irish */ {HB_TAG('m','h','c',' '), HB_TAG('M','Y','N',' ')}, /* Mocho -> Mayan */ {HB_TAG('m','h','r',' '), HB_TAG('L','M','A',' ')}, /* Eastern Mari -> Low Mari */ {HB_TAG('m','h','v',' '), HB_TAG('A','R','K',' ')}, /* Arakanese (retired code) -> Rakhine */ @@ -1126,6 +1153,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('n','o','d',' '), HB_TAG('N','T','A',' ')}, /* Northern Thai -> Northern Tai */ /*{HB_TAG('n','o','e',' '), HB_TAG('N','O','E',' ')},*/ /* Nimadi */ /*{HB_TAG('n','o','g',' '), HB_TAG('N','O','G',' ')},*/ /* Nogai */ +/*{HB_TAG('n','o','p',' '), HB_TAG('N','O','P',' ')},*/ /* Numanggang */ /*{HB_TAG('n','o','v',' '), HB_TAG('N','O','V',' ')},*/ /* Novial */ {HB_TAG('n','p','i',' '), HB_TAG('N','E','P',' ')}, /* Nepali */ {HB_TAG('n','p','l',' '), HB_TAG('N','A','H',' ')}, /* Southeastern Puebla Nahuatl -> Nahuatl */ @@ -1136,6 +1164,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('n','s','u',' '), HB_TAG('N','A','H',' ')}, /* Sierra Negra Nahuatl -> Nahuatl */ {HB_TAG('n','t','o',' '), HB_TAG_NONE }, /* Ntomba != Esperanto */ {HB_TAG('n','u','e',' '), HB_TAG('B','A','D','0')}, /* Ngundu -> Banda */ +/*{HB_TAG('n','u','k',' '), HB_TAG('N','U','K',' ')},*/ /* Nuu-chah-nulth */ {HB_TAG('n','u','u',' '), HB_TAG('B','A','D','0')}, /* Ngbundu -> Banda */ {HB_TAG('n','u','z',' '), HB_TAG('N','A','H',' ')}, /* Tlamacazapa Nahuatl -> Nahuatl */ {HB_TAG('n','w','e',' '), HB_TAG('B','M','L',' ')}, /* Ngwe -> Bamileke */ @@ -1153,6 +1182,8 @@ static const LangTag ot_languages3[] = { {HB_TAG('o','k','i',' '), HB_TAG('K','A','L',' ')}, /* Okiek -> Kalenjin */ {HB_TAG('o','k','m',' '), HB_TAG('K','O','H',' ')}, /* Middle Korean (10th-16th cent.) -> Korean Old Hangul */ {HB_TAG('o','k','r',' '), HB_TAG('I','J','O',' ')}, /* Kirike -> Ijo */ +/*{HB_TAG('o','n','e',' '), HB_TAG('O','N','E',' ')},*/ /* Oneida */ +/*{HB_TAG('o','n','o',' '), HB_TAG('O','N','O',' ')},*/ /* Onondaga */ {HB_TAG('o','n','x',' '), HB_TAG('C','P','P',' ')}, /* Onin Based Pidgin -> Creoles */ {HB_TAG('o','o','r',' '), HB_TAG('C','P','P',' ')}, /* Oorlams -> Creoles */ {HB_TAG('o','r','c',' '), HB_TAG('O','R','O',' ')}, /* Orma -> Oromo */ @@ -1160,7 +1191,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('o','r','o',' '), HB_TAG_NONE }, /* Orokolo != Oromo */ {HB_TAG('o','r','r',' '), HB_TAG('I','J','O',' ')}, /* Oruma -> Ijo */ {HB_TAG('o','r','s',' '), HB_TAG('M','L','Y',' ')}, /* Orang Seletar -> Malay */ - {HB_TAG('o','r','y',' '), HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) */ + {HB_TAG('o','r','y',' '), HB_TAG('O','R','I',' ')}, /* Odia */ {HB_TAG('o','t','w',' '), HB_TAG('O','J','B',' ')}, /* Ottawa -> Ojibway */ {HB_TAG('o','u','a',' '), HB_TAG('B','B','R',' ')}, /* Tagargrent -> Berber */ {HB_TAG('p','a','a',' '), HB_TAG_NONE }, /* Papuan [collection] != Palestinian Aramaic */ @@ -1193,7 +1224,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('p','i','s',' '), HB_TAG('C','P','P',' ')}, /* Pijin -> Creoles */ {HB_TAG('p','k','h',' '), HB_TAG('Q','I','N',' ')}, /* Pankhu -> Chin */ {HB_TAG('p','k','o',' '), HB_TAG('K','A','L',' ')}, /* Pökoot -> Kalenjin */ - {HB_TAG('p','l','g',' '), HB_TAG_NONE }, /* Pilagá != Palaung */ + {HB_TAG('p','l','g',' '), HB_TAG('P','L','G','0')}, /* Pilagá */ {HB_TAG('p','l','k',' '), HB_TAG_NONE }, /* Kohistani Shina != Polish */ {HB_TAG('p','l','l',' '), HB_TAG('P','L','G',' ')}, /* Shwe Palaung -> Palaung */ {HB_TAG('p','l','n',' '), HB_TAG('C','P','P',' ')}, /* Palenquero -> Creoles */ @@ -1353,6 +1384,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('s','d','h',' '), HB_TAG('K','U','R',' ')}, /* Southern Kurdish -> Kurdish */ {HB_TAG('s','d','n',' '), HB_TAG('S','R','D',' ')}, /* Gallurese Sardinian -> Sardinian */ {HB_TAG('s','d','s',' '), HB_TAG('B','B','R',' ')}, /* Sened -> Berber */ +/*{HB_TAG('s','e','e',' '), HB_TAG('S','E','E',' ')},*/ /* Seneca */ {HB_TAG('s','e','h',' '), HB_TAG('S','N','A',' ')}, /* Sena */ {HB_TAG('s','e','k',' '), HB_TAG('A','T','H',' ')}, /* Sekani -> Athapaskan */ /*{HB_TAG('s','e','l',' '), HB_TAG('S','E','L',' ')},*/ /* Selkup */ @@ -1374,9 +1406,13 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('s','i','d',' '), HB_TAG('S','I','D',' ')},*/ /* Sidamo */ {HB_TAG('s','i','g',' '), HB_TAG_NONE }, /* Paasaal != Silte Gurage */ {HB_TAG('s','i','z',' '), HB_TAG('B','B','R',' ')}, /* Siwi -> Berber */ +/*{HB_TAG('s','j','a',' '), HB_TAG('S','J','A',' ')},*/ /* Epena */ + {HB_TAG('s','j','c',' '), HB_TAG('Z','H','S',' ')}, /* Shaojiang Chinese -> Chinese, Simplified */ {HB_TAG('s','j','d',' '), HB_TAG('K','S','M',' ')}, /* Kildin Sami */ +/*{HB_TAG('s','j','e',' '), HB_TAG('S','J','E',' ')},*/ /* Pite Sami */ {HB_TAG('s','j','o',' '), HB_TAG('S','I','B',' ')}, /* Xibe -> Sibe */ {HB_TAG('s','j','s',' '), HB_TAG('B','B','R',' ')}, /* Senhaja De Srair -> Berber */ +/*{HB_TAG('s','j','u',' '), HB_TAG('S','J','U',' ')},*/ /* Ume Sami */ {HB_TAG('s','k','g',' '), HB_TAG('M','L','G',' ')}, /* Sakalava Malagasy -> Malagasy */ {HB_TAG('s','k','r',' '), HB_TAG('S','R','K',' ')}, /* Saraiki */ {HB_TAG('s','k','s',' '), HB_TAG_NONE }, /* Maia != Skolt Sami */ @@ -1395,7 +1431,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('s','n','k',' '), HB_TAG('S','N','K',' ')},*/ /* Soninke */ {HB_TAG('s','o','g',' '), HB_TAG_NONE }, /* Sogdian != Sodo Gurage */ /*{HB_TAG('s','o','p',' '), HB_TAG('S','O','P',' ')},*/ /* Songe */ - {HB_TAG('s','p','v',' '), HB_TAG('O','R','I',' ')}, /* Sambalpuri -> Odia (formerly Oriya) */ + {HB_TAG('s','p','v',' '), HB_TAG('O','R','I',' ')}, /* Sambalpuri -> Odia */ {HB_TAG('s','p','y',' '), HB_TAG('K','A','L',' ')}, /* Sabaot -> Kalenjin */ {HB_TAG('s','r','b',' '), HB_TAG_NONE }, /* Sora != Serbian */ {HB_TAG('s','r','c',' '), HB_TAG('S','R','D',' ')}, /* Logudorese Sardinian -> Sardinian */ @@ -1410,6 +1446,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('s','s','m',' '), HB_TAG_NONE }, /* Semnam != Southern Sami */ {HB_TAG('s','t','a',' '), HB_TAG('C','P','P',' ')}, /* Settla -> Creoles */ /*{HB_TAG('s','t','q',' '), HB_TAG('S','T','Q',' ')},*/ /* Saterfriesisch -> Saterland Frisian */ +/*{HB_TAG('s','t','r',' '), HB_TAG('S','T','R',' ')},*/ /* Straits Salish */ {HB_TAG('s','t','v',' '), HB_TAG('S','I','G',' ')}, /* Silt'e -> Silte Gurage */ /*{HB_TAG('s','u','k',' '), HB_TAG('S','U','K',' ')},*/ /* Sukuma */ {HB_TAG('s','u','q',' '), HB_TAG('S','U','R',' ')}, /* Suri */ @@ -1431,10 +1468,12 @@ static const LangTag ot_languages3[] = { {HB_TAG('t','a','a',' '), HB_TAG('A','T','H',' ')}, /* Lower Tanana -> Athapaskan */ /*{HB_TAG('t','a','b',' '), HB_TAG('T','A','B',' ')},*/ /* Tabassaran -> Tabasaran */ {HB_TAG('t','a','j',' '), HB_TAG_NONE }, /* Eastern Tamang != Tajiki */ + {HB_TAG('t','a','q',' '), HB_TAG('T','A','Q',' ')}, /* Tamasheq */ {HB_TAG('t','a','q',' '), HB_TAG('T','M','H',' ')}, /* Tamasheq -> Tamashek */ {HB_TAG('t','a','q',' '), HB_TAG('B','B','R',' ')}, /* Tamasheq -> Berber */ {HB_TAG('t','a','s',' '), HB_TAG('C','P','P',' ')}, /* Tay Boi -> Creoles */ {HB_TAG('t','a','u',' '), HB_TAG('A','T','H',' ')}, /* Upper Tanana -> Athapaskan */ +/*{HB_TAG('t','b','v',' '), HB_TAG('T','B','V',' ')},*/ /* Tobo */ {HB_TAG('t','c','b',' '), HB_TAG('A','T','H',' ')}, /* Tanacross -> Athapaskan */ {HB_TAG('t','c','e',' '), HB_TAG('A','T','H',' ')}, /* Southern Tutchone -> Athapaskan */ {HB_TAG('t','c','h',' '), HB_TAG('C','P','P',' ')}, /* Turks And Caicos Creole English -> Creoles */ @@ -1442,6 +1481,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('t','c','s',' '), HB_TAG('C','P','P',' ')}, /* Torres Strait Creole -> Creoles */ {HB_TAG('t','c','y',' '), HB_TAG('T','U','L',' ')}, /* Tulu */ {HB_TAG('t','c','z',' '), HB_TAG('Q','I','N',' ')}, /* Thado Chin -> Chin */ +/*{HB_TAG('t','d','c',' '), HB_TAG('T','D','C',' ')},*/ /* Emberá-Tadó */ /*{HB_TAG('t','d','d',' '), HB_TAG('T','D','D',' ')},*/ /* Tai Nüa -> Dehong Dai */ {HB_TAG('t','d','x',' '), HB_TAG('M','L','G',' ')}, /* Tandroy-Mahafaly Malagasy -> Malagasy */ {HB_TAG('t','e','c',' '), HB_TAG('K','A','L',' ')}, /* Terik -> Kalenjin */ @@ -1455,9 +1495,12 @@ static const LangTag ot_languages3[] = { {HB_TAG('t','g','r',' '), HB_TAG_NONE }, /* Tareng != Tigre */ {HB_TAG('t','g','x',' '), HB_TAG('A','T','H',' ')}, /* Tagish -> Athapaskan */ {HB_TAG('t','g','y',' '), HB_TAG_NONE }, /* Togoyo != Tigrinya */ +/*{HB_TAG('t','h','p',' '), HB_TAG('T','H','P',' ')},*/ /* Thompson */ {HB_TAG('t','h','t',' '), HB_TAG('A','T','H',' ')}, /* Tahltan -> Athapaskan */ + {HB_TAG('t','h','v',' '), HB_TAG('T','H','V',' ')}, /* Tahaggart Tamahaq */ {HB_TAG('t','h','v',' '), HB_TAG('T','M','H',' ')}, /* Tahaggart Tamahaq -> Tamashek */ {HB_TAG('t','h','v',' '), HB_TAG('B','B','R',' ')}, /* Tahaggart Tamahaq -> Berber */ + {HB_TAG('t','h','z',' '), HB_TAG('T','H','Z',' ')}, /* Tayart Tamajeq */ {HB_TAG('t','h','z',' '), HB_TAG('T','M','H',' ')}, /* Tayart Tamajeq -> Tamashek */ {HB_TAG('t','h','z',' '), HB_TAG('B','B','R',' ')}, /* Tayart Tamajeq -> Berber */ {HB_TAG('t','i','a',' '), HB_TAG('B','B','R',' ')}, /* Tidikelt Tamazight -> Berber */ @@ -1468,6 +1511,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('t','k','g',' '), HB_TAG('M','L','G',' ')}, /* Tesaka Malagasy -> Malagasy */ {HB_TAG('t','k','m',' '), HB_TAG_NONE }, /* Takelma != Turkmen */ /*{HB_TAG('t','l','i',' '), HB_TAG('T','L','I',' ')},*/ /* Tlingit */ +/*{HB_TAG('t','l','y',' '), HB_TAG('T','L','Y',' ')},*/ /* Talysh */ {HB_TAG('t','m','g',' '), HB_TAG('C','P','P',' ')}, /* Ternateño -> Creoles */ {HB_TAG('t','m','h',' '), HB_TAG('T','M','H',' ')}, /* Tamashek [macrolanguage] */ {HB_TAG('t','m','h',' '), HB_TAG('B','B','R',' ')}, /* Tamashek [macrolanguage] -> Berber */ @@ -1493,11 +1537,13 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('t','s','j',' '), HB_TAG('T','S','J',' ')},*/ /* Tshangla */ {HB_TAG('t','t','c',' '), HB_TAG('M','Y','N',' ')}, /* Tektiteko -> Mayan */ {HB_TAG('t','t','m',' '), HB_TAG('A','T','H',' ')}, /* Northern Tutchone -> Athapaskan */ + {HB_TAG('t','t','q',' '), HB_TAG('T','T','Q',' ')}, /* Tawallammat Tamajaq */ {HB_TAG('t','t','q',' '), HB_TAG('T','M','H',' ')}, /* Tawallammat Tamajaq -> Tamashek */ {HB_TAG('t','t','q',' '), HB_TAG('B','B','R',' ')}, /* Tawallammat Tamajaq -> Berber */ {HB_TAG('t','u','a',' '), HB_TAG_NONE }, /* Wiarumus != Turoyo Aramaic */ {HB_TAG('t','u','l',' '), HB_TAG_NONE }, /* Tula != Tulu */ /*{HB_TAG('t','u','m',' '), HB_TAG('T','U','M',' ')},*/ /* Tumbuka */ +/*{HB_TAG('t','u','s',' '), HB_TAG('T','U','S',' ')},*/ /* Tuscarora */ {HB_TAG('t','u','u',' '), HB_TAG('A','T','H',' ')}, /* Tututni -> Athapaskan */ {HB_TAG('t','u','v',' '), HB_TAG_NONE }, /* Turkana != Tuvin */ {HB_TAG('t','u','y',' '), HB_TAG('K','A','L',' ')}, /* Tugen -> Kalenjin */ @@ -1514,6 +1560,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('t','z','o',' '), HB_TAG('T','Z','O',' ')}, /* Tzotzil */ {HB_TAG('t','z','o',' '), HB_TAG('M','Y','N',' ')}, /* Tzotzil -> Mayan */ {HB_TAG('u','b','l',' '), HB_TAG('B','I','K',' ')}, /* Buhi'non Bikol -> Bikol */ +/*{HB_TAG('u','d','i',' '), HB_TAG('U','D','I',' ')},*/ /* Udi */ /*{HB_TAG('u','d','m',' '), HB_TAG('U','D','M',' ')},*/ /* Udmurt */ {HB_TAG('u','k','i',' '), HB_TAG('K','U','I',' ')}, /* Kui (India) */ {HB_TAG('u','l','n',' '), HB_TAG('C','P','P',' ')}, /* Unserdeutsch -> Creoles */ @@ -1532,13 +1579,17 @@ static const LangTag ot_languages3[] = { {HB_TAG('v','k','t',' '), HB_TAG('M','L','Y',' ')}, /* Tenggarong Kutai Malay -> Malay */ {HB_TAG('v','l','s',' '), HB_TAG('F','L','E',' ')}, /* Vlaams -> Dutch (Flemish) */ {HB_TAG('v','m','w',' '), HB_TAG('M','A','K',' ')}, /* Makhuwa */ -/*{HB_TAG('v','r','o',' '), HB_TAG('V','R','O',' ')},*/ /* Võro */ + {HB_TAG('v','r','o',' '), HB_TAG('V','R','O',' ')}, /* Võro */ + {HB_TAG('v','r','o',' '), HB_TAG('E','T','I',' ')}, /* Võro -> Estonian */ + {HB_TAG('v','s','n',' '), HB_TAG('S','A','N',' ')}, /* Vedic Sanskrit -> Sanskrit */ {HB_TAG('w','a','g',' '), HB_TAG_NONE }, /* Wa'ema != Wagdi */ /*{HB_TAG('w','a','r',' '), HB_TAG('W','A','R',' ')},*/ /* Waray (Philippines) -> Waray-Waray */ +/*{HB_TAG('w','b','l',' '), HB_TAG('W','B','L',' ')},*/ /* Wakhi */ {HB_TAG('w','b','m',' '), HB_TAG('W','A',' ',' ')}, /* Wa */ {HB_TAG('w','b','r',' '), HB_TAG('W','A','G',' ')}, /* Wagdi */ {HB_TAG('w','b','r',' '), HB_TAG('R','A','J',' ')}, /* Wagdi -> Rajasthani */ /*{HB_TAG('w','c','i',' '), HB_TAG('W','C','I',' ')},*/ /* Waci Gbe */ +/*{HB_TAG('w','d','t',' '), HB_TAG('W','D','T',' ')},*/ /* Wendat */ {HB_TAG('w','e','a',' '), HB_TAG('K','R','N',' ')}, /* Wewaw -> Karen */ {HB_TAG('w','e','s',' '), HB_TAG('C','P','P',' ')}, /* Cameroon Pidgin -> Creoles */ {HB_TAG('w','e','u',' '), HB_TAG('Q','I','N',' ')}, /* Rawngtu Chin -> Chin */ @@ -1550,6 +1601,9 @@ static const LangTag ot_languages3[] = { {HB_TAG('w','s','g',' '), HB_TAG('G','O','N',' ')}, /* Adilabad Gondi -> Gondi */ /*{HB_TAG('w','t','m',' '), HB_TAG('W','T','M',' ')},*/ /* Mewati */ {HB_TAG('w','u','u',' '), HB_TAG('Z','H','S',' ')}, /* Wu Chinese -> Chinese, Simplified */ + {HB_TAG('w','y','a',' '), HB_TAG('W','D','T',' ')}, /* Wyandot (retired code) -> Wendat */ + {HB_TAG('w','y','a',' '), HB_TAG('W','Y','N',' ')}, /* Wyandot (retired code) */ +/*{HB_TAG('w','y','n',' '), HB_TAG('W','Y','N',' ')},*/ /* Wyandot */ {HB_TAG('x','a','l',' '), HB_TAG('K','L','M',' ')}, /* Kalmyk */ {HB_TAG('x','a','l',' '), HB_TAG('T','O','D',' ')}, /* Kalmyk -> Todo */ {HB_TAG('x','a','n',' '), HB_TAG('S','E','K',' ')}, /* Xamtanga -> Sekota */ @@ -1582,7 +1636,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('y','b','a',' '), HB_TAG_NONE }, /* Yala != Yoruba */ {HB_TAG('y','b','b',' '), HB_TAG('B','M','L',' ')}, /* Yemba -> Bamileke */ {HB_TAG('y','b','d',' '), HB_TAG('A','R','K',' ')}, /* Yangbye (retired code) -> Rakhine */ - {HB_TAG('y','c','r',' '), HB_TAG_NONE }, /* Yilan Creole != Y-Cree */ + {HB_TAG('y','c','r',' '), HB_TAG('C','P','P',' ')}, /* Yilan Creole -> Creoles */ {HB_TAG('y','d','d',' '), HB_TAG('J','I','I',' ')}, /* Eastern Yiddish -> Yiddish */ /*{HB_TAG('y','g','p',' '), HB_TAG('Y','G','P',' ')},*/ /* Gepo */ {HB_TAG('y','i','h',' '), HB_TAG('J','I','I',' ')}, /* Western Yiddish -> Yiddish */ @@ -1591,6 +1645,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('y','o','s',' '), HB_TAG('Q','I','N',' ')}, /* Yos (retired code) -> Chin */ {HB_TAG('y','u','a',' '), HB_TAG('M','Y','N',' ')}, /* Yucateco -> Mayan */ {HB_TAG('y','u','e',' '), HB_TAG('Z','H','H',' ')}, /* Yue Chinese -> Chinese, Traditional, Hong Kong SAR */ +/*{HB_TAG('y','u','f',' '), HB_TAG('Y','U','F',' ')},*/ /* Havasupai-Walapai-Yavapai */ /*{HB_TAG('y','w','q',' '), HB_TAG('Y','W','Q',' ')},*/ /* Wuding-Luquan Yi */ {HB_TAG('z','c','h',' '), HB_TAG('Z','H','A',' ')}, /* Central Hongshuihe Zhuang -> Zhuang */ {HB_TAG('z','d','j',' '), HB_TAG('C','M','R',' ')}, /* Ngazidja Comorian -> Comorian */ @@ -2335,6 +2390,26 @@ out: *count = i; return true; } + if (lang_matches (&lang_str[1], limit, "nm-hant-hk", 10)) + { + /* Hainanese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "nm-hant-mo", 10)) + { + /* Hainanese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } if (lang_matches (&lang_str[1], limit, "sn-hant-hk", 10)) { /* Xiang Chinese; Han (Traditional variant); Hong Kong */ @@ -2369,6 +2444,20 @@ out: *count = 1; return true; } + if (lang_matches (&lang_str[1], limit, "nm-hans", 7)) + { + /* Hainanese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "nm-hant", 7)) + { + /* Hainanese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } if (lang_matches (&lang_str[1], limit, "sn-hans", 7)) { /* Xiang Chinese; Han (Simplified variant) */ @@ -2413,6 +2502,36 @@ out: *count = 1; return true; } + if (0 == strncmp (&lang_str[1], "nm-", 3) + && subtag_matches (lang_str, limit, "-hk", 3)) + { + /* Hainanese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "nm-", 3) + && subtag_matches (lang_str, limit, "-mo", 3)) + { + /* Hainanese; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strncmp (&lang_str[1], "nm-", 3) + && subtag_matches (lang_str, limit, "-tw", 3)) + { + /* Hainanese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } if (0 == strncmp (&lang_str[1], "sn-", 3) && subtag_matches (lang_str, limit, "-hk", 3)) { @@ -2474,6 +2593,40 @@ out: } break; case 'l': + if (lang_matches (&lang_str[1], limit, "uh-hant-hk", 10)) + { + /* Leizhou Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "uh-hant-mo", 10)) + { + /* Leizhou Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (lang_matches (&lang_str[1], limit, "uh-hans", 7)) + { + /* Leizhou Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "uh-hant", 7)) + { + /* Leizhou Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } if (lang_matches (&lang_str[1], limit, "zh-hans", 7)) { /* Literary Chinese; Han (Simplified variant) */ @@ -2481,6 +2634,36 @@ out: *count = 1; return true; } + if (0 == strncmp (&lang_str[1], "uh-", 3) + && subtag_matches (lang_str, limit, "-hk", 3)) + { + /* Leizhou Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "uh-", 3) + && subtag_matches (lang_str, limit, "-mo", 3)) + { + /* Leizhou Chinese; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strncmp (&lang_str[1], "uh-", 3) + && subtag_matches (lang_str, limit, "-tw", 3)) + { + /* Leizhou Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } break; case 'm': if (lang_matches (&lang_str[1], limit, "np-hant-hk", 10)) @@ -2652,6 +2835,72 @@ out: return true; } break; + case 's': + if (lang_matches (&lang_str[1], limit, "jc-hant-hk", 10)) + { + /* Shaojiang Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "jc-hant-mo", 10)) + { + /* Shaojiang Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (lang_matches (&lang_str[1], limit, "jc-hans", 7)) + { + /* Shaojiang Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "jc-hant", 7)) + { + /* Shaojiang Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "jc-", 3) + && subtag_matches (lang_str, limit, "-hk", 3)) + { + /* Shaojiang Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "jc-", 3) + && subtag_matches (lang_str, limit, "-mo", 3)) + { + /* Shaojiang Chinese; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strncmp (&lang_str[1], "jc-", 3) + && subtag_matches (lang_str, limit, "-tw", 3)) + { + /* Shaojiang Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } + break; case 'w': if (lang_matches (&lang_str[1], limit, "uu-hant-hk", 10)) { @@ -2816,9 +3065,10 @@ out: * @tag: A language tag. * * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to - * many language tags) and the best tag is not the alphabetically first, or if - * the best tag consists of multiple subtags, or if the best tag does not appear - * in #ot_languages. + * many language tags) and the best tag is not the first (sorted alphabetically, + * with two-letter tags having priority over all three-letter tags), or if the + * best tag consists of multiple subtags, or if the best tag does not appear in + * #ot_languages2 or #ot_languages3. * * Return value: The #hb_language_t corresponding to the BCP 47 language tag, * or #HB_LANGUAGE_INVALID if @tag is not ambiguous. @@ -2832,8 +3082,6 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("alt", -1); /* Southern Altai */ case HB_TAG('A','P','P','H'): /* Phonetic transcription—Americanist conventions */ return hb_language_from_string ("und-fonnapa", -1); /* Undetermined; North American Phonetic Alphabet */ - case HB_TAG('A','R','A',' '): /* Arabic */ - return hb_language_from_string ("ar", -1); /* Arabic [macrolanguage] */ case HB_TAG('A','R','K',' '): /* Rakhine */ return hb_language_from_string ("rki", -1); /* Rakhine */ case HB_TAG('A','T','H',' '): /* Athapaskan */ @@ -2854,12 +3102,6 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("din", -1); /* Dinka [macrolanguage] */ case HB_TAG('D','R','I',' '): /* Dari */ return hb_language_from_string ("prs", -1); /* Dari */ - case HB_TAG('D','Z','N',' '): /* Dzongkha */ - return hb_language_from_string ("dz", -1); /* Dzongkha */ - case HB_TAG('E','T','I',' '): /* Estonian */ - return hb_language_from_string ("et", -1); /* Estonian [macrolanguage] */ - case HB_TAG('F','A','R',' '): /* Persian */ - return hb_language_from_string ("fa", -1); /* Persian [macrolanguage] */ case HB_TAG('G','O','N',' '): /* Gondi */ return hb_language_from_string ("gon", -1); /* Gondi [macrolanguage] */ case HB_TAG('H','M','A',' '): /* High Mari */ @@ -2874,50 +3116,34 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("iba", -1); /* Iban */ case HB_TAG('I','J','O',' '): /* Ijo */ return hb_language_from_string ("ijo", -1); /* Ijo [collection] */ - case HB_TAG('I','N','U',' '): /* Inuktitut */ - return hb_language_from_string ("iu", -1); /* Inuktitut [macrolanguage] */ - case HB_TAG('I','P','K',' '): /* Inupiat */ - return hb_language_from_string ("ik", -1); /* Inupiaq [macrolanguage] */ case HB_TAG('I','P','P','H'): /* Phonetic transcription—IPA conventions */ return hb_language_from_string ("und-fonipa", -1); /* Undetermined; International Phonetic Alphabet */ case HB_TAG('I','R','T',' '): /* Irish Traditional */ - return hb_language_from_string ("ga-Latg", -1); /* Irish; Latin (Gaelic variant) */ + return hb_language_from_string ("ghc", -1); /* Hiberno-Scottish Gaelic */ case HB_TAG('J','I','I',' '): /* Yiddish */ return hb_language_from_string ("yi", -1); /* Yiddish [macrolanguage] */ case HB_TAG('K','A','L',' '): /* Kalenjin */ return hb_language_from_string ("kln", -1); /* Kalenjin [macrolanguage] */ case HB_TAG('K','G','E',' '): /* Khutsuri Georgian */ return hb_language_from_string ("und-Geok", -1); /* Undetermined; Khutsuri (Asomtavruli and Nuskhuri) */ - case HB_TAG('K','N','R',' '): /* Kanuri */ - return hb_language_from_string ("kr", -1); /* Kanuri [macrolanguage] */ case HB_TAG('K','O','H',' '): /* Korean Old Hangul */ return hb_language_from_string ("okm", -1); /* Middle Korean (10th-16th cent.) */ case HB_TAG('K','O','K',' '): /* Konkani */ return hb_language_from_string ("kok", -1); /* Konkani [macrolanguage] */ - case HB_TAG('K','O','M',' '): /* Komi */ - return hb_language_from_string ("kv", -1); /* Komi [macrolanguage] */ case HB_TAG('K','P','L',' '): /* Kpelle */ return hb_language_from_string ("kpe", -1); /* Kpelle [macrolanguage] */ case HB_TAG('K','R','N',' '): /* Karen */ return hb_language_from_string ("kar", -1); /* Karen [collection] */ case HB_TAG('K','U','I',' '): /* Kui */ return hb_language_from_string ("uki", -1); /* Kui (India) */ - case HB_TAG('K','U','R',' '): /* Kurdish */ - return hb_language_from_string ("ku", -1); /* Kurdish [macrolanguage] */ case HB_TAG('L','M','A',' '): /* Low Mari */ return hb_language_from_string ("mhr", -1); /* Eastern Mari */ case HB_TAG('L','U','H',' '): /* Luyia */ return hb_language_from_string ("luy", -1); /* Luyia [macrolanguage] */ - case HB_TAG('L','V','I',' '): /* Latvian */ - return hb_language_from_string ("lv", -1); /* Latvian [macrolanguage] */ case HB_TAG('M','A','W',' '): /* Marwari */ return hb_language_from_string ("mwr", -1); /* Marwari [macrolanguage] */ - case HB_TAG('M','L','G',' '): /* Malagasy */ - return hb_language_from_string ("mg", -1); /* Malagasy [macrolanguage] */ case HB_TAG('M','L','Y',' '): /* Malay */ return hb_language_from_string ("ms", -1); /* Malay [macrolanguage] */ - case HB_TAG('M','N','G',' '): /* Mongolian */ - return hb_language_from_string ("mn", -1); /* Mongolian [macrolanguage] */ case HB_TAG('M','N','K',' '): /* Maninka */ return hb_language_from_string ("man", -1); /* Mandingo [macrolanguage] */ case HB_TAG('M','O','L',' '): /* Moldavian */ @@ -2928,26 +3154,16 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("myn", -1); /* Mayan [collection] */ case HB_TAG('N','A','H',' '): /* Nahuatl */ return hb_language_from_string ("nah", -1); /* Nahuatl [collection] */ - case HB_TAG('N','E','P',' '): /* Nepali */ - return hb_language_from_string ("ne", -1); /* Nepali [macrolanguage] */ case HB_TAG('N','I','S',' '): /* Nisi */ return hb_language_from_string ("njz", -1); /* Nyishi */ case HB_TAG('N','O','R',' '): /* Norwegian */ return hb_language_from_string ("no", -1); /* Norwegian [macrolanguage] */ - case HB_TAG('O','J','B',' '): /* Ojibway */ - return hb_language_from_string ("oj", -1); /* Ojibwa [macrolanguage] */ - case HB_TAG('O','R','O',' '): /* Oromo */ - return hb_language_from_string ("om", -1); /* Oromo [macrolanguage] */ - case HB_TAG('P','A','S',' '): /* Pashto */ - return hb_language_from_string ("ps", -1); /* Pashto [macrolanguage] */ case HB_TAG('P','G','R',' '): /* Polytonic Greek */ return hb_language_from_string ("el-polyton", -1); /* Modern Greek (1453-); Polytonic Greek */ case HB_TAG('P','R','O',' '): /* Provençal / Old Provençal */ return hb_language_from_string ("pro", -1); /* Old Provençal (to 1500) */ case HB_TAG('Q','U','H',' '): /* Quechua (Bolivia) */ return hb_language_from_string ("quh", -1); /* South Bolivian Quechua */ - case HB_TAG('Q','U','Z',' '): /* Quechua */ - return hb_language_from_string ("qu", -1); /* Quechua [macrolanguage] */ case HB_TAG('Q','V','I',' '): /* Quechua (Ecuador) */ return hb_language_from_string ("qvi", -1); /* Imbabura Highland Quichua */ case HB_TAG('Q','W','H',' '): /* Quechua (Peru) */ @@ -2958,8 +3174,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("ro", -1); /* Romanian */ case HB_TAG('R','O','Y',' '): /* Romany */ return hb_language_from_string ("rom", -1); /* Romany [macrolanguage] */ - case HB_TAG('S','Q','I',' '): /* Albanian */ - return hb_language_from_string ("sq", -1); /* Albanian [macrolanguage] */ + case HB_TAG('S','G','A',' '): /* Old Irish */ + return hb_language_from_string ("sga", -1); /* Old Irish (to 900) */ case HB_TAG('S','R','B',' '): /* Serbian */ return hb_language_from_string ("sr", -1); /* Serbian */ case HB_TAG('S','X','T',' '): /* Sutu */ @@ -2976,6 +3192,10 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("tmh", -1); /* Tamashek [macrolanguage] */ case HB_TAG('T','O','D',' '): /* Todo */ return hb_language_from_string ("xwo", -1); /* Written Oirat */ + case HB_TAG('W','D','T',' '): /* Wendat */ + return hb_language_from_string ("wdt", -1); /* Wendat */ + case HB_TAG('W','Y','N',' '): /* Wyandot */ + return hb_language_from_string ("wyn", -1); /* Wyandot */ case HB_TAG('Z','H','H',' '): /* Chinese, Traditional, Hong Kong SAR */ return hb_language_from_string ("zh-HK", -1); /* Chinese [macrolanguage]; Hong Kong */ case HB_TAG('Z','H','S',' '): /* Chinese, Simplified */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc index 9f0ae3b4dc198..3cdb703203b38 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc @@ -547,7 +547,7 @@ hb_ot_tag_to_language (hb_tag_t tag) buf[3] = '-'; str += 4; } - snprintf (str, 16, "x-hbot-%08x", tag); + snprintf (str, 16, "x-hbot-%08" PRIx32, tag); return hb_language_from_string (&*buf, -1); } } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh index 0aaf68adb0b14..e26687c34ed18 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh @@ -57,7 +57,7 @@ struct avarV2Tail protected: Offset32To varIdxMap; /* Offset from the beginning of 'avar' table. */ - Offset32To varStore; /* Offset from the beginning of 'avar' table. */ + Offset32To varStore; /* Offset from the beginning of 'avar' table. */ public: DEFINE_SIZE_STATIC (8); @@ -80,7 +80,7 @@ struct AxisValueMap bool is_outside_axis_range (const Triple& axis_range) const { - float from_coord = coords[0].to_float (); + double from_coord = (double) coords[0].to_float (); return !axis_range.contains (from_coord); } @@ -100,8 +100,8 @@ struct AxisValueMap float from_coord = coords[0].to_float (); float to_coord = coords[1].to_float (); - from_coord = renormalizeValue (from_coord, unmapped_range, triple_distances); - to_coord = renormalizeValue (to_coord, axis_range, triple_distances); + from_coord = renormalizeValue ((double) from_coord, unmapped_range, triple_distances); + to_coord = renormalizeValue ((double) to_coord, axis_range, triple_distances); coords[0].set_float (from_coord); coords[1].set_float (to_coord); @@ -197,7 +197,7 @@ struct SegmentMaps : Array16Of unmapped_val.set_int (unmap (val.to_int ())); float unmapped_max = unmapped_val.to_float (); - return Triple{unmapped_min, unmapped_middle, unmapped_max}; + return Triple{(double) unmapped_min, (double) unmapped_middle, (double) unmapped_max}; } bool subset (hb_subset_context_t *c, hb_tag_t axis_tag) const @@ -230,7 +230,7 @@ struct SegmentMaps : Array16Of * duplicates here */ if (mapping.must_include ()) continue; - value_mappings.push (std::move (mapping)); + value_mappings.push (mapping); } AxisValueMap m; @@ -273,6 +273,7 @@ struct avar { TRACE_SANITIZE (this); if (!(version.sanitize (c) && + hb_barrier () && (version.major == 1 #ifndef HB_NO_AVAR2 || version.major == 2 @@ -293,6 +294,7 @@ struct avar #ifndef HB_NO_AVAR2 if (version.major < 2) return_trace (true); + hb_barrier (); const auto &v2 = * (const avarV2Tail *) map; if (unlikely (!v2.sanitize (c, this))) @@ -316,6 +318,7 @@ struct avar #ifndef HB_NO_AVAR2 if (version.major < 2) return; + hb_barrier (); for (; count < axisCount; count++) map = &StructAfter (*map); @@ -340,7 +343,7 @@ struct avar for (unsigned i = 0; i < coords_length; i++) coords[i] = out[i]; - OT::VariationStore::destroy_cache (var_store_cache); + OT::ItemVariationStore::destroy_cache (var_store_cache); #endif } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh index 271250f91c38d..72deddef213d8 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh @@ -28,215 +28,11 @@ #include "hb-ot-layout-common.hh" #include "hb-priority-queue.hh" +#include "hb-subset-instancer-iup.hh" namespace OT { -template -struct DeltaSetIndexMapFormat01 -{ - friend struct DeltaSetIndexMap; - - unsigned get_size () const - { return min_size + mapCount * get_width (); } - - private: - DeltaSetIndexMapFormat01* copy (hb_serialize_context_t *c) const - { - TRACE_SERIALIZE (this); - return_trace (c->embed (this)); - } - - template - bool serialize (hb_serialize_context_t *c, const T &plan) - { - unsigned int width = plan.get_width (); - unsigned int inner_bit_count = plan.get_inner_bit_count (); - const hb_array_t output_map = plan.get_output_map (); - - TRACE_SERIALIZE (this); - if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0)))) - return_trace (false); - if (unlikely (!c->extend_min (this))) return_trace (false); - - entryFormat = ((width-1)<<4)|(inner_bit_count-1); - mapCount = output_map.length; - HBUINT8 *p = c->allocate_size (width * output_map.length); - if (unlikely (!p)) return_trace (false); - for (unsigned int i = 0; i < output_map.length; i++) - { - unsigned int v = output_map.arrayZ[i]; - if (v) - { - unsigned int outer = v >> 16; - unsigned int inner = v & 0xFFFF; - unsigned int u = (outer << inner_bit_count) | inner; - for (unsigned int w = width; w > 0;) - { - p[--w] = u; - u >>= 8; - } - } - p += width; - } - return_trace (true); - } - - uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */ - { - /* If count is zero, pass value unchanged. This takes - * care of direct mapping for advance map. */ - if (!mapCount) - return v; - - if (v >= mapCount) - v = mapCount - 1; - - unsigned int u = 0; - { /* Fetch it. */ - unsigned int w = get_width (); - const HBUINT8 *p = mapDataZ.arrayZ + w * v; - for (; w; w--) - u = (u << 8) + *p++; - } - - { /* Repack it. */ - unsigned int n = get_inner_bit_count (); - unsigned int outer = u >> n; - unsigned int inner = u & ((1 << n) - 1); - u = (outer<<16) | inner; - } - - return u; - } - - unsigned get_map_count () const { return mapCount; } - unsigned get_width () const { return ((entryFormat >> 4) & 3) + 1; } - unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; } - - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - c->check_range (mapDataZ.arrayZ, - mapCount, - get_width ())); - } - - protected: - HBUINT8 format; /* Format identifier--format = 0 */ - HBUINT8 entryFormat; /* A packed field that describes the compressed - * representation of delta-set indices. */ - MapCountT mapCount; /* The number of mapping entries. */ - UnsizedArrayOf - mapDataZ; /* The delta-set index mapping data. */ - - public: - DEFINE_SIZE_ARRAY (2+MapCountT::static_size, mapDataZ); -}; - -struct DeltaSetIndexMap -{ - template - bool serialize (hb_serialize_context_t *c, const T &plan) - { - TRACE_SERIALIZE (this); - unsigned length = plan.get_output_map ().length; - u.format = length <= 0xFFFF ? 0 : 1; - switch (u.format) { - case 0: return_trace (u.format0.serialize (c, plan)); - case 1: return_trace (u.format1.serialize (c, plan)); - default:return_trace (false); - } - } - - uint32_t map (unsigned v) const - { - switch (u.format) { - case 0: return (u.format0.map (v)); - case 1: return (u.format1.map (v)); - default:return v; - } - } - - unsigned get_map_count () const - { - switch (u.format) { - case 0: return u.format0.get_map_count (); - case 1: return u.format1.get_map_count (); - default:return 0; - } - } - - unsigned get_width () const - { - switch (u.format) { - case 0: return u.format0.get_width (); - case 1: return u.format1.get_width (); - default:return 0; - } - } - - unsigned get_inner_bit_count () const - { - switch (u.format) { - case 0: return u.format0.get_inner_bit_count (); - case 1: return u.format1.get_inner_bit_count (); - default:return 0; - } - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); - switch (u.format) { - case 0: return_trace (u.format0.sanitize (c)); - case 1: return_trace (u.format1.sanitize (c)); - default:return_trace (true); - } - } - - DeltaSetIndexMap* copy (hb_serialize_context_t *c) const - { - TRACE_SERIALIZE (this); - switch (u.format) { - case 0: return_trace (reinterpret_cast (u.format0.copy (c))); - case 1: return_trace (reinterpret_cast (u.format1.copy (c))); - default:return_trace (nullptr); - } - } - - protected: - union { - HBUINT8 format; /* Format identifier */ - DeltaSetIndexMapFormat01 format0; - DeltaSetIndexMapFormat01 format1; - } u; - public: - DEFINE_SIZE_UNION (1, format); -}; - - -struct VarStoreInstancer -{ - VarStoreInstancer (const VariationStore *varStore, - const DeltaSetIndexMap *varIdxMap, - hb_array_t coords) : - varStore (varStore), varIdxMap (varIdxMap), coords (coords) {} - - operator bool () const { return varStore && bool (coords); } - - /* according to the spec, if colr table has varStore but does not have - * varIdxMap, then an implicit identity mapping is used */ - float operator() (uint32_t varIdx, unsigned short offset = 0) const - { return coords ? varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords) : 0; } - - const VariationStore *varStore; - const DeltaSetIndexMap *varIdxMap; - hb_array_t coords; -}; /* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */ struct TupleVariationHeader @@ -296,15 +92,15 @@ struct TupleVariationHeader start = hb_min (peak, 0.f); end = hb_max (peak, 0.f); } - axis_tuples.set (*axis_tag, Triple (start, peak, end)); + axis_tuples.set (*axis_tag, Triple ((double) start, (double) peak, (double) end)); } return true; } - float calculate_scalar (hb_array_t coords, unsigned int coord_count, - const hb_array_t shared_tuples, - const hb_vector_t> *shared_tuple_active_idx = nullptr) const + double calculate_scalar (hb_array_t coords, unsigned int coord_count, + const hb_array_t shared_tuples, + const hb_vector_t> *shared_tuple_active_idx = nullptr) const { const F2DOT14 *peak_tuple; @@ -318,13 +114,13 @@ struct TupleVariationHeader { unsigned int index = get_index (); if (unlikely ((index + 1) * coord_count > shared_tuples.length)) - return 0.f; + return 0.0; peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count).arrayZ; if (shared_tuple_active_idx) { if (unlikely (index >= shared_tuple_active_idx->length)) - return 0.f; + return 0.0; auto _ = (*shared_tuple_active_idx).arrayZ[index]; if (_.second != -1) { @@ -349,7 +145,7 @@ struct TupleVariationHeader end_tuple = get_end_tuple (coord_count).arrayZ; } - float scalar = 1.f; + double scalar = 1.0; for (unsigned int i = start_idx; i < end_idx; i += step) { int peak = peak_tuple[i].to_int (); @@ -364,15 +160,15 @@ struct TupleVariationHeader int end = end_tuple[i].to_int (); if (unlikely (start > peak || peak > end || (start < 0 && end > 0 && peak))) continue; - if (v < start || v > end) return 0.f; + if (v < start || v > end) return 0.0; if (v < peak) - { if (peak != start) scalar *= (float) (v - start) / (peak - start); } + { if (peak != start) scalar *= (double) (v - start) / (peak - start); } else - { if (peak != end) scalar *= (float) (end - v) / (end - peak); } + { if (peak != end) scalar *= (double) (end - v) / (end - peak); } } - else if (!v || v < hb_min (0, peak) || v > hb_max (0, peak)) return 0.f; + else if (!v || v < hb_min (0, peak) || v > hb_max (0, peak)) return 0.0; else - scalar *= (float) v / peak; + scalar *= (double) v / peak; } return scalar; } @@ -425,15 +221,10 @@ struct TupleVariationHeader DEFINE_SIZE_MIN (4); }; -enum packed_delta_flag_t -{ - DELTAS_ARE_ZERO = 0x80, - DELTAS_ARE_WORDS = 0x40, - DELTA_RUN_COUNT_MASK = 0x3F -}; - struct tuple_delta_t { + static constexpr bool realloc_move = true; // Watch out when adding new members! + public: hb_hashmap_t axis_tuples; @@ -447,8 +238,8 @@ struct tuple_delta_t /* compiled data: header and deltas * compiled point data is saved in a hashmap within tuple_variations_t cause * some point sets might be reused by different tuple variations */ - hb_vector_t compiled_tuple_header; - hb_vector_t compiled_deltas; + hb_vector_t compiled_tuple_header; + hb_vector_t compiled_deltas; /* compiled peak coords, empty for non-gvar tuples */ hb_vector_t compiled_peak_coords; @@ -456,7 +247,7 @@ struct tuple_delta_t tuple_delta_t () = default; tuple_delta_t (const tuple_delta_t& o) = default; - friend void swap (tuple_delta_t& a, tuple_delta_t& b) + friend void swap (tuple_delta_t& a, tuple_delta_t& b) noexcept { hb_swap (a.axis_tuples, b.axis_tuples); hb_swap (a.indices, b.indices); @@ -467,10 +258,10 @@ struct tuple_delta_t hb_swap (a.compiled_peak_coords, b.compiled_peak_coords); } - tuple_delta_t (tuple_delta_t&& o) : tuple_delta_t () + tuple_delta_t (tuple_delta_t&& o) noexcept : tuple_delta_t () { hb_swap (*this, o); } - tuple_delta_t& operator = (tuple_delta_t&& o) + tuple_delta_t& operator = (tuple_delta_t&& o) noexcept { hb_swap (*this, o); return *this; @@ -514,14 +305,19 @@ struct tuple_delta_t return *this; unsigned num = indices.length; - for (unsigned i = 0; i < num; i++) - { - if (!indices.arrayZ[i]) continue; - - deltas_x[i] *= scalar; - if (deltas_y) + if (deltas_y) + for (unsigned i = 0; i < num; i++) + { + if (!indices.arrayZ[i]) continue; + deltas_x[i] *= scalar; deltas_y[i] *= scalar; - } + } + else + for (unsigned i = 0; i < num; i++) + { + if (!indices.arrayZ[i]) continue; + deltas_x[i] *= scalar; + } return *this; } @@ -536,18 +332,18 @@ struct tuple_delta_t return out; } - if ((tent->minimum < 0.f && tent->maximum > 0.f) || + if ((tent->minimum < 0.0 && tent->maximum > 0.0) || !(tent->minimum <= tent->middle && tent->middle <= tent->maximum)) return out; - if (tent->middle == 0.f) + if (tent->middle == 0.0) { out.push (*this); return out; } - result_t solutions = rebase_tent (*tent, axis_limit, axis_triple_distances); - for (auto t : solutions) + rebase_tent_result_t solutions = rebase_tent (*tent, axis_limit, axis_triple_distances); + for (auto &t : solutions) { tuple_delta_t new_var = *this; if (t.second == Triple ()) @@ -600,7 +396,9 @@ struct tuple_delta_t const hb_map_t& axes_old_index_tag_map, const hb_hashmap_t*, unsigned>* shared_tuples_idx_map) { - if (!compiled_deltas) return false; + /* compiled_deltas could be empty after iup delta optimization, we can skip + * compiling this tuple and return true */ + if (!compiled_deltas) return true; unsigned cur_axis_count = axes_index_map.get_population (); /* allocate enough memory: 1 peak + 2 intermediate coords + fixed header size */ @@ -714,37 +512,42 @@ struct tuple_delta_t } bool compile_deltas () + { return compile_deltas (indices, deltas_x, deltas_y, compiled_deltas); } + + static bool compile_deltas (hb_array_t point_indices, + hb_array_t x_deltas, + hb_array_t y_deltas, + hb_vector_t &compiled_deltas /* OUT */) { hb_vector_t rounded_deltas; - if (unlikely (!rounded_deltas.alloc (indices.length))) + if (unlikely (!rounded_deltas.alloc (point_indices.length))) return false; - for (unsigned i = 0; i < indices.length; i++) + for (unsigned i = 0; i < point_indices.length; i++) { - if (!indices[i]) continue; - int rounded_delta = (int) roundf (deltas_x[i]); + if (!point_indices[i]) continue; + int rounded_delta = (int) roundf (x_deltas.arrayZ[i]); rounded_deltas.push (rounded_delta); } - if (!rounded_deltas) return false; - /* allocate enough memories 3 * num_deltas */ - unsigned alloc_len = 3 * rounded_deltas.length; - if (deltas_y) + if (!rounded_deltas) return true; + /* allocate enough memories 5 * num_deltas */ + unsigned alloc_len = 5 * rounded_deltas.length; + if (y_deltas) alloc_len *= 2; if (unlikely (!compiled_deltas.resize (alloc_len))) return false; - unsigned i = 0; - unsigned encoded_len = encode_delta_run (i, compiled_deltas.as_array (), rounded_deltas); + unsigned encoded_len = compile_deltas (compiled_deltas, rounded_deltas); - if (deltas_y) + if (y_deltas) { - /* reuse the rounded_deltas vector, check that deltas_y have the same num of deltas as deltas_x */ + /* reuse the rounded_deltas vector, check that y_deltas have the same num of deltas as x_deltas */ unsigned j = 0; - for (unsigned idx = 0; idx < indices.length; idx++) + for (unsigned idx = 0; idx < point_indices.length; idx++) { - if (!indices[idx]) continue; - int rounded_delta = (int) roundf (deltas_y[idx]); + if (!point_indices[idx]) continue; + int rounded_delta = (int) roundf (y_deltas.arrayZ[idx]); if (j >= rounded_deltas.length) return false; @@ -752,174 +555,15 @@ struct tuple_delta_t } if (j != rounded_deltas.length) return false; - /* reset i because we reuse rounded_deltas for deltas_y */ - i = 0; - encoded_len += encode_delta_run (i, compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas); + encoded_len += compile_deltas (compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas); } return compiled_deltas.resize (encoded_len); } - unsigned encode_delta_run (unsigned& i, - hb_array_t encoded_bytes, - const hb_vector_t& deltas) const - { - unsigned num_deltas = deltas.length; - unsigned encoded_len = 0; - while (i < num_deltas) - { - int val = deltas[i]; - if (val == 0) - encoded_len += encode_delta_run_as_zeroes (i, encoded_bytes.sub_array (encoded_len), deltas); - else if (val >= -128 && val <= 127) - encoded_len += encode_delta_run_as_bytes (i, encoded_bytes.sub_array (encoded_len), deltas); - else - encoded_len += encode_delta_run_as_words (i, encoded_bytes.sub_array (encoded_len), deltas); - } - return encoded_len; - } - - unsigned encode_delta_run_as_zeroes (unsigned& i, - hb_array_t encoded_bytes, - const hb_vector_t& deltas) const - { - unsigned num_deltas = deltas.length; - unsigned run_length = 0; - auto it = encoded_bytes.iter (); - unsigned encoded_len = 0; - while (i < num_deltas && deltas[i] == 0) - { - i++; - run_length++; - } - - while (run_length >= 64) - { - *it++ = char (DELTAS_ARE_ZERO | 63); - run_length -= 64; - encoded_len++; - } - - if (run_length) - { - *it++ = char (DELTAS_ARE_ZERO | (run_length - 1)); - encoded_len++; - } - return encoded_len; - } - - unsigned encode_delta_run_as_bytes (unsigned &i, - hb_array_t encoded_bytes, - const hb_vector_t& deltas) const - { - unsigned start = i; - unsigned num_deltas = deltas.length; - while (i < num_deltas) - { - int val = deltas[i]; - if (val > 127 || val < -128) - break; - - /* from fonttools: if there're 2 or more zeros in a sequence, - * it is better to start a new run to save bytes. */ - if (val == 0 && i + 1 < num_deltas && deltas[i+1] == 0) - break; - - i++; - } - unsigned run_length = i - start; - - unsigned encoded_len = 0; - auto it = encoded_bytes.iter (); - - while (run_length >= 64) - { - *it++ = 63; - encoded_len++; - - for (unsigned j = 0; j < 64; j++) - { - *it++ = static_cast (deltas[start + j]); - encoded_len++; - } - - start += 64; - run_length -= 64; - } - - if (run_length) - { - *it++ = run_length - 1; - encoded_len++; - - while (start < i) - { - *it++ = static_cast (deltas[start++]); - encoded_len++; - } - } - - return encoded_len; - } - - unsigned encode_delta_run_as_words (unsigned &i, - hb_array_t encoded_bytes, - const hb_vector_t& deltas) const + static unsigned compile_deltas (hb_array_t encoded_bytes, + hb_array_t deltas) { - unsigned start = i; - unsigned num_deltas = deltas.length; - while (i < num_deltas) - { - int val = deltas[i]; - - /* start a new run for a single zero value*/ - if (val == 0) break; - - /* from fonttools: continue word-encoded run if there's only one - * single value in the range [-128, 127] because it is more compact. - * Only start a new run when there're 2 continuous such values. */ - if (val >= -128 && val <= 127 && - i + 1 < num_deltas && - deltas[i+1] >= -128 && deltas[i+1] <= 127) - break; - - i++; - } - - unsigned run_length = i - start; - auto it = encoded_bytes.iter (); - unsigned encoded_len = 0; - while (run_length >= 64) - { - *it++ = (DELTAS_ARE_WORDS | 63); - encoded_len++; - - for (unsigned j = 0; j < 64; j++) - { - int16_t delta_val = deltas[start + j]; - *it++ = static_cast (delta_val >> 8); - *it++ = static_cast (delta_val & 0xFF); - - encoded_len += 2; - } - - start += 64; - run_length -= 64; - } - - if (run_length) - { - *it++ = (DELTAS_ARE_WORDS | (run_length - 1)); - encoded_len++; - while (start < i) - { - int16_t delta_val = deltas[start++]; - *it++ = static_cast (delta_val >> 8); - *it++ = static_cast (delta_val & 0xFF); - - encoded_len += 2; - } - } - return encoded_len; + return TupleValues::compile (deltas, encoded_bytes); } bool calc_inferred_deltas (const contour_point_vector_t& orig_points) @@ -982,10 +626,14 @@ struct tuple_delta_t { i = next_index (i, start_point, end_point); if (i == next) break; - deltas_x.arrayZ[i] = infer_delta (orig_points.arrayZ[i].x, orig_points.arrayZ[prev].x, orig_points.arrayZ[next].x, - deltas_x.arrayZ[prev], deltas_x.arrayZ[next]); - deltas_y.arrayZ[i] = infer_delta (orig_points.arrayZ[i].y, orig_points.arrayZ[prev].y, orig_points.arrayZ[next].y, - deltas_y.arrayZ[prev], deltas_y.arrayZ[next]); + deltas_x.arrayZ[i] = infer_delta ((double) orig_points.arrayZ[i].x, + (double) orig_points.arrayZ[prev].x, + (double) orig_points.arrayZ[next].x, + (double) deltas_x.arrayZ[prev], (double) deltas_x.arrayZ[next]); + deltas_y.arrayZ[i] = infer_delta ((double) orig_points.arrayZ[i].y, + (double) orig_points.arrayZ[prev].y, + (double) orig_points.arrayZ[next].y, + (double) deltas_y.arrayZ[prev], (double) deltas_y.arrayZ[next]); inferred_idxes.add (i); if (--unref_count == 0) goto no_more_gaps; } @@ -1002,8 +650,8 @@ struct tuple_delta_t { if (!inferred_idxes.has (i)) { - deltas_x.arrayZ[i] = 0.f; - deltas_y.arrayZ[i] = 0.f; + deltas_x.arrayZ[i] = 0.0; + deltas_y.arrayZ[i] = 0.0; } indices[i] = true; } @@ -1011,16 +659,181 @@ struct tuple_delta_t return true; } - static float infer_delta (float target_val, float prev_val, float next_val, float prev_delta, float next_delta) + bool optimize (const contour_point_vector_t& contour_points, + bool is_composite, + double tolerance = 0.5 + 1e-10) + { + unsigned count = contour_points.length; + if (deltas_x.length != count || + deltas_y.length != count) + return false; + + hb_vector_t opt_indices; + hb_vector_t rounded_x_deltas, rounded_y_deltas; + + if (unlikely (!rounded_x_deltas.alloc (count) || + !rounded_y_deltas.alloc (count))) + return false; + + for (unsigned i = 0; i < count; i++) + { + int rounded_x_delta = (int) roundf (deltas_x.arrayZ[i]); + int rounded_y_delta = (int) roundf (deltas_y.arrayZ[i]); + rounded_x_deltas.push (rounded_x_delta); + rounded_y_deltas.push (rounded_y_delta); + } + + if (!iup_delta_optimize (contour_points, rounded_x_deltas, rounded_y_deltas, opt_indices, tolerance)) + return false; + + unsigned ref_count = 0; + for (bool ref_flag : opt_indices) + ref_count += ref_flag; + + if (ref_count == count) return true; + + hb_vector_t opt_deltas_x, opt_deltas_y; + bool is_comp_glyph_wo_deltas = (is_composite && ref_count == 0); + if (is_comp_glyph_wo_deltas) + { + if (unlikely (!opt_deltas_x.resize (count) || + !opt_deltas_y.resize (count))) + return false; + + opt_indices.arrayZ[0] = true; + for (unsigned i = 1; i < count; i++) + opt_indices.arrayZ[i] = false; + } + + hb_vector_t opt_point_data; + if (!compile_point_set (opt_indices, opt_point_data)) + return false; + hb_vector_t opt_deltas_data; + if (!compile_deltas (opt_indices, + is_comp_glyph_wo_deltas ? opt_deltas_x : deltas_x, + is_comp_glyph_wo_deltas ? opt_deltas_y : deltas_y, + opt_deltas_data)) + return false; + + hb_vector_t point_data; + if (!compile_point_set (indices, point_data)) + return false; + hb_vector_t deltas_data; + if (!compile_deltas (indices, deltas_x, deltas_y, deltas_data)) + return false; + + if (opt_point_data.length + opt_deltas_data.length < point_data.length + deltas_data.length) + { + indices.fini (); + indices = std::move (opt_indices); + + if (is_comp_glyph_wo_deltas) + { + deltas_x.fini (); + deltas_x = std::move (opt_deltas_x); + + deltas_y.fini (); + deltas_y = std::move (opt_deltas_y); + } + } + return !indices.in_error () && !deltas_x.in_error () && !deltas_y.in_error (); + } + + static bool compile_point_set (const hb_vector_t &point_indices, + hb_vector_t& compiled_points /* OUT */) + { + unsigned num_points = 0; + for (bool i : point_indices) + if (i) num_points++; + + /* when iup optimization is enabled, num of referenced points could be 0 */ + if (!num_points) return true; + + unsigned indices_length = point_indices.length; + /* If the points set consists of all points in the glyph, it's encoded with a + * single zero byte */ + if (num_points == indices_length) + return compiled_points.resize (1); + + /* allocate enough memories: 2 bytes for count + 3 bytes for each point */ + unsigned num_bytes = 2 + 3 *num_points; + if (unlikely (!compiled_points.resize (num_bytes, false))) + return false; + + unsigned pos = 0; + /* binary data starts with the total number of reference points */ + if (num_points < 0x80) + compiled_points.arrayZ[pos++] = num_points; + else + { + compiled_points.arrayZ[pos++] = ((num_points >> 8) | 0x80); + compiled_points.arrayZ[pos++] = num_points & 0xFF; + } + + const unsigned max_run_length = 0x7F; + unsigned i = 0; + unsigned last_value = 0; + unsigned num_encoded = 0; + while (i < indices_length && num_encoded < num_points) + { + unsigned run_length = 0; + unsigned header_pos = pos; + compiled_points.arrayZ[pos++] = 0; + + bool use_byte_encoding = false; + bool new_run = true; + while (i < indices_length && num_encoded < num_points && + run_length <= max_run_length) + { + // find out next referenced point index + while (i < indices_length && !point_indices[i]) + i++; + + if (i >= indices_length) break; + + unsigned cur_value = i; + unsigned delta = cur_value - last_value; + + if (new_run) + { + use_byte_encoding = (delta <= 0xFF); + new_run = false; + } + + if (use_byte_encoding && delta > 0xFF) + break; + + if (use_byte_encoding) + compiled_points.arrayZ[pos++] = delta; + else + { + compiled_points.arrayZ[pos++] = delta >> 8; + compiled_points.arrayZ[pos++] = delta & 0xFF; + } + i++; + last_value = cur_value; + run_length++; + num_encoded++; + } + + if (use_byte_encoding) + compiled_points.arrayZ[header_pos] = run_length - 1; + else + compiled_points.arrayZ[header_pos] = (run_length - 1) | 0x80; + } + return compiled_points.resize (pos, false); + } + + static double infer_delta (double target_val, double prev_val, double next_val, double prev_delta, double next_delta) { if (prev_val == next_val) - return (prev_delta == next_delta) ? prev_delta : 0.f; + return (prev_delta == next_delta) ? prev_delta : 0.0; else if (target_val <= hb_min (prev_val, next_val)) return (prev_val < next_val) ? prev_delta : next_delta; else if (target_val >= hb_max (prev_val, next_val)) return (prev_val > next_val) ? prev_delta : next_delta; - float r = (target_val - prev_val) / (next_val - prev_val); + double r = (target_val - prev_val) / (next_val - prev_val); return prev_delta + r * (next_delta - prev_delta); } @@ -1028,6 +841,7 @@ struct tuple_delta_t { return (i >= end) ? start : (i + 1); } }; +template struct TupleVariationData { bool sanitize (hb_sanitize_context_t *c) const @@ -1062,19 +876,22 @@ struct TupleVariationData private: /* referenced point set->compiled point data map */ - hb_hashmap_t*, hb_bytes_t> point_data_map; + hb_hashmap_t*, hb_vector_t> point_data_map; /* referenced point set-> count map, used in finding shared points */ hb_hashmap_t*, unsigned> point_set_count_map; /* empty for non-gvar tuples. - * shared_points_bytes is just a copy of some value in the point_data_map, + * shared_points_bytes is a pointer to some value in the point_data_map, * which will be freed during map destruction. Save it for serialization, so * no need to do find_shared_points () again */ - hb_bytes_t shared_points_bytes; + hb_vector_t *shared_points_bytes = nullptr; - /* total compiled byte size as TupleVariationData format, initialized to its - * min_size: 4 */ - unsigned compiled_byte_size = 4; + /* total compiled byte size as TupleVariationData format, initialized to 0 */ + unsigned compiled_byte_size = 0; + bool needs_padding = false; + + /* for gvar iup delta optimization: whether this is a composite glyph */ + bool is_composite = false; public: tuple_variations_t () = default; @@ -1082,21 +899,18 @@ struct TupleVariationData tuple_variations_t& operator=(const tuple_variations_t&) = delete; tuple_variations_t (tuple_variations_t&&) = default; tuple_variations_t& operator=(tuple_variations_t&&) = default; - ~tuple_variations_t () { fini (); } - void fini () - { - for (auto _ : point_data_map.values ()) - _.fini (); - - point_set_count_map.fini (); - tuple_vars.fini (); - } + ~tuple_variations_t () = default; explicit operator bool () const { return bool (tuple_vars); } unsigned get_var_count () const { - unsigned count = tuple_vars.length; - if (shared_points_bytes.length) + unsigned count = 0; + /* when iup delta opt is enabled, compiled_deltas could be empty and we + * should skip this tuple */ + for (auto& tuple: tuple_vars) + if (tuple.compiled_deltas) count++; + + if (shared_points_bytes && shared_points_bytes->length) count |= TupleVarCount::SharedPointNumbers; return count; } @@ -1110,26 +924,27 @@ struct TupleVariationData bool is_gvar, const hb_map_t *axes_old_index_tag_map, const hb_vector_t &shared_indices, - const hb_array_t shared_tuples) + const hb_array_t shared_tuples, + bool is_composite_glyph) { do { const HBUINT8 *p = iterator.get_serialized_data (); unsigned int length = iterator.current_tuple->get_data_size (); if (unlikely (!iterator.var_data_bytes.check_range (p, length))) - { fini (); return false; } + return false; hb_hashmap_t axis_tuples; if (!iterator.current_tuple->unpack_axis_tuples (iterator.get_axis_count (), shared_tuples, axes_old_index_tag_map, axis_tuples) || axis_tuples.is_empty ()) - { fini (); return false; } + return false; hb_vector_t private_indices; bool has_private_points = iterator.current_tuple->has_private_points (); const HBUINT8 *end = p + length; if (has_private_points && - !TupleVariationData::unpack_points (p, private_indices, end)) - { fini (); return false; } + !TupleVariationData::decompile_points (p, private_indices, end)) + return false; const hb_vector_t &indices = has_private_points ? private_indices : shared_indices; bool apply_to_all = (indices.length == 0); @@ -1138,43 +953,46 @@ struct TupleVariationData hb_vector_t deltas_x; if (unlikely (!deltas_x.resize (num_deltas, false) || - !TupleVariationData::unpack_deltas (p, deltas_x, end))) - { fini (); return false; } + !TupleVariationData::decompile_deltas (p, deltas_x, end))) + return false; hb_vector_t deltas_y; if (is_gvar) { if (unlikely (!deltas_y.resize (num_deltas, false) || - !TupleVariationData::unpack_deltas (p, deltas_y, end))) - { fini (); return false; } + !TupleVariationData::decompile_deltas (p, deltas_y, end))) + return false; } tuple_delta_t var; var.axis_tuples = std::move (axis_tuples); if (unlikely (!var.indices.resize (point_count) || !var.deltas_x.resize (point_count, false))) - { fini (); return false; } + return false; if (is_gvar && unlikely (!var.deltas_y.resize (point_count, false))) - { fini (); return false; } + return false; for (unsigned i = 0; i < num_deltas; i++) { unsigned idx = apply_to_all ? i : indices[i]; if (idx >= point_count) continue; var.indices[idx] = true; - var.deltas_x[idx] = static_cast (deltas_x[i]); + var.deltas_x[idx] = deltas_x[i]; if (is_gvar) - var.deltas_y[idx] = static_cast (deltas_y[i]); + var.deltas_y[idx] = deltas_y[i]; } tuple_vars.push (std::move (var)); } while (iterator.move_to_next ()); + + is_composite = is_composite_glyph; return true; } bool create_from_item_var_data (const VarData &var_data, const hb_vector_t>& regions, const hb_map_t& axes_old_index_tag_map, + unsigned& item_count, const hb_inc_bimap_t* inner_map = nullptr) { /* NULL offset, to keep original varidx valid, just return */ @@ -1184,7 +1002,8 @@ struct TupleVariationData unsigned num_regions = var_data.get_region_index_count (); if (!tuple_vars.alloc (num_regions)) return false; - unsigned item_count = inner_map ? inner_map->get_population () : var_data.get_item_count (); + item_count = inner_map ? inner_map->get_population () : var_data.get_item_count (); + if (!item_count) return true; unsigned row_size = var_data.get_row_size (); const HBUINT8 *delta_bytes = var_data.get_delta_bytes (); @@ -1237,7 +1056,7 @@ struct TupleVariationData Triple *axis_limit; if (!normalized_axes_location.has (axis_tag, &axis_limit)) return false; - TripleDistances axis_triple_distances{1.f, 1.f}; + TripleDistances axis_triple_distances{1.0, 1.0}; if (axes_triple_distances.has (axis_tag)) axis_triple_distances = axes_triple_distances.get (axis_tag); @@ -1250,7 +1069,7 @@ struct TupleVariationData unsigned new_len = new_vars.length + out.length; if (unlikely (!new_vars.alloc (new_len, false))) - { fini (); return false;} + return false; for (unsigned i = 0; i < out.length; i++) new_vars.push (std::move (out[i])); @@ -1261,8 +1080,9 @@ struct TupleVariationData return true; } - /* merge tuple variations with overlapping tents */ - void merge_tuple_variations () + /* merge tuple variations with overlapping tents, if iup delta optimization + * is enabled, add default deltas to contour_points */ + bool merge_tuple_variations (contour_point_vector_t* contour_points = nullptr) { hb_vector_t new_vars; hb_hashmap_t*, unsigned> m; @@ -1270,7 +1090,15 @@ struct TupleVariationData for (const tuple_delta_t& var : tuple_vars) { /* if all axes are pinned, drop the tuple variation */ - if (var.axis_tuples.is_empty ()) continue; + if (var.axis_tuples.is_empty ()) + { + /* if iup_delta_optimize is enabled, add deltas to contour coords */ + if (contour_points && !contour_points->add_deltas (var.deltas_x, + var.deltas_y, + var.indices)) + return false; + continue; + } unsigned *idx; if (m.has (&(var.axis_tuples), &idx)) @@ -1280,98 +1108,14 @@ struct TupleVariationData else { new_vars.push (var); - m.set (&(var.axis_tuples), i); + if (!m.set (&(var.axis_tuples), i)) + return false; i++; } } tuple_vars.fini (); tuple_vars = std::move (new_vars); - } - - hb_bytes_t compile_point_set (const hb_vector_t &point_indices) - { - unsigned num_points = 0; - for (bool i : point_indices) - if (i) num_points++; - - unsigned indices_length = point_indices.length; - /* If the points set consists of all points in the glyph, it's encoded with a - * single zero byte */ - if (num_points == indices_length) - { - char *p = (char *) hb_calloc (1, sizeof (char)); - if (unlikely (!p)) return hb_bytes_t (); - - return hb_bytes_t (p, 1); - } - - /* allocate enough memories: 2 bytes for count + 3 bytes for each point */ - unsigned num_bytes = 2 + 3 *num_points; - char *p = (char *) hb_calloc (num_bytes, sizeof (char)); - if (unlikely (!p)) return hb_bytes_t (); - - unsigned pos = 0; - /* binary data starts with the total number of reference points */ - if (num_points < 0x80) - p[pos++] = num_points; - else - { - p[pos++] = ((num_points >> 8) | 0x80); - p[pos++] = num_points & 0xFF; - } - - const unsigned max_run_length = 0x7F; - unsigned i = 0; - unsigned last_value = 0; - unsigned num_encoded = 0; - while (i < indices_length && num_encoded < num_points) - { - unsigned run_length = 0; - unsigned header_pos = pos; - p[pos++] = 0; - - bool use_byte_encoding = false; - bool new_run = true; - while (i < indices_length && num_encoded < num_points && - run_length <= max_run_length) - { - // find out next referenced point index - while (i < indices_length && !point_indices[i]) - i++; - - if (i >= indices_length) break; - - unsigned cur_value = i; - unsigned delta = cur_value - last_value; - - if (new_run) - { - use_byte_encoding = (delta <= 0xFF); - new_run = false; - } - - if (use_byte_encoding && delta > 0xFF) - break; - - if (use_byte_encoding) - p[pos++] = delta; - else - { - p[pos++] = delta >> 8; - p[pos++] = delta & 0xFF; - } - i++; - last_value = cur_value; - run_length++; - num_encoded++; - } - - if (use_byte_encoding) - p[header_pos] = run_length - 1; - else - p[header_pos] = (run_length - 1) | 0x80; - } - return hb_bytes_t (p, pos); + return true; } /* compile all point set and store byte data in a point_set->hb_bytes_t hashmap, @@ -1391,11 +1135,11 @@ struct TupleVariationData continue; } - hb_bytes_t compiled_data = compile_point_set (*points_set); - if (unlikely (compiled_data == hb_bytes_t ())) + hb_vector_t compiled_point_data; + if (!tuple_delta_t::compile_point_set (*points_set, compiled_point_data)) return false; - if (!point_data_map.set (points_set, compiled_data) || + if (!point_data_map.set (points_set, std::move (compiled_point_data)) || !point_set_count_map.set (points_set, 1)) return false; } @@ -1403,31 +1147,33 @@ struct TupleVariationData } /* find shared points set which saves most bytes */ - hb_bytes_t find_shared_points () + void find_shared_points () { unsigned max_saved_bytes = 0; - hb_bytes_t res{}; - for (const auto& _ : point_data_map.iter ()) + for (const auto& _ : point_data_map.iter_ref ()) { const hb_vector_t* points_set = _.first; unsigned data_length = _.second.length; + if (!data_length) continue; unsigned *count; if (unlikely (!point_set_count_map.has (points_set, &count) || *count <= 1)) - return hb_bytes_t (); + { + shared_points_bytes = nullptr; + return; + } unsigned saved_bytes = data_length * ((*count) -1); if (saved_bytes > max_saved_bytes) { max_saved_bytes = saved_bytes; - res = _.second; + shared_points_bytes = &(_.second); } } - return res; } - bool calc_inferred_deltas (contour_point_vector_t& contour_points) + bool calc_inferred_deltas (const contour_point_vector_t& contour_points) { for (tuple_delta_t& var : tuple_vars) if (!var.calc_inferred_deltas (contour_points)) @@ -1436,10 +1182,21 @@ struct TupleVariationData return true; } + bool iup_optimize (const contour_point_vector_t& contour_points) + { + for (tuple_delta_t& var : tuple_vars) + { + if (!var.optimize (contour_points, is_composite)) + return false; + } + return true; + } + public: bool instantiate (const hb_hashmap_t& normalized_axes_location, const hb_hashmap_t& axes_triple_distances, - contour_point_vector_t* contour_points = nullptr) + contour_point_vector_t* contour_points = nullptr, + bool optimize = false) { if (!tuple_vars) return true; if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances)) @@ -1449,41 +1206,70 @@ struct TupleVariationData if (!calc_inferred_deltas (*contour_points)) return false; - merge_tuple_variations (); + /* if iup delta opt is on, contour_points can't be null */ + if (optimize && !contour_points) + return false; + + if (!merge_tuple_variations (optimize ? contour_points : nullptr)) + return false; + + if (optimize && !iup_optimize (*contour_points)) return false; return !tuple_vars.in_error (); } bool compile_bytes (const hb_map_t& axes_index_map, const hb_map_t& axes_old_index_tag_map, bool use_shared_points, + bool is_gvar = false, const hb_hashmap_t*, unsigned>* shared_tuples_idx_map = nullptr) { + // return true for empty glyph + if (!tuple_vars) + return true; + // compile points set and store data in hashmap if (!compile_all_point_sets ()) return false; + /* total compiled byte size as TupleVariationData format, initialized to its + * min_size: 4 */ + compiled_byte_size += 4; + if (use_shared_points) { - shared_points_bytes = find_shared_points (); - compiled_byte_size += shared_points_bytes.length; + find_shared_points (); + if (shared_points_bytes) + compiled_byte_size += shared_points_bytes->length; } // compile delta and tuple var header for each tuple variation for (auto& tuple: tuple_vars) { const hb_vector_t* points_set = &(tuple.indices); - hb_bytes_t *points_data; + hb_vector_t *points_data; if (unlikely (!point_data_map.has (points_set, &points_data))) return false; + /* when iup optimization is enabled, num of referenced points could be 0 + * and thus the compiled points bytes is empty, we should skip compiling + * this tuple */ + if (!points_data->length) + continue; if (!tuple.compile_deltas ()) return false; - unsigned points_data_length = (*points_data != shared_points_bytes) ? points_data->length : 0; + unsigned points_data_length = (points_data != shared_points_bytes) ? points_data->length : 0; if (!tuple.compile_tuple_var_header (axes_index_map, points_data_length, axes_old_index_tag_map, shared_tuples_idx_map)) return false; compiled_byte_size += tuple.compiled_tuple_header.length + points_data_length + tuple.compiled_deltas.length; } + + if (is_gvar && (compiled_byte_size % 2)) + { + needs_padding = true; + compiled_byte_size += 1; + } + return true; } @@ -1502,25 +1288,31 @@ struct TupleVariationData bool serialize_var_data (hb_serialize_context_t *c, bool is_gvar) const { TRACE_SERIALIZE (this); - if (is_gvar) - shared_points_bytes.copy (c); + if (is_gvar && shared_points_bytes) + { + hb_ubytes_t s (shared_points_bytes->arrayZ, shared_points_bytes->length); + s.copy (c); + } for (const auto& tuple: tuple_vars) { const hb_vector_t* points_set = &(tuple.indices); - hb_bytes_t *point_data; + hb_vector_t *point_data; if (!point_data_map.has (points_set, &point_data)) return_trace (false); - if (!is_gvar || *point_data != shared_points_bytes) - point_data->copy (c); + if (!is_gvar || point_data != shared_points_bytes) + { + hb_ubytes_t s (point_data->arrayZ, point_data->length); + s.copy (c); + } tuple.compiled_deltas.as_array ().copy (c); if (c->in_error ()) return_trace (false); } /* padding for gvar */ - if (is_gvar && (compiled_byte_size % 2)) + if (is_gvar && needs_padding) { HBUINT8 pad; pad = 0; @@ -1551,7 +1343,7 @@ struct TupleVariationData { const HBUINT8 *base = &(table_base+var_data->data); const HBUINT8 *p = base; - if (!unpack_points (p, shared_indices, (const HBUINT8 *) (var_data_bytes.arrayZ + var_data_bytes.length))) return false; + if (!decompile_points (p, shared_indices, (const HBUINT8 *) (var_data_bytes.arrayZ + var_data_bytes.length))) return false; data_offset = p - base; } return true; @@ -1601,9 +1393,9 @@ struct TupleVariationData bool has_shared_point_numbers () const { return tupleVarCount.has_shared_point_numbers (); } - static bool unpack_points (const HBUINT8 *&p /* IN/OUT */, - hb_vector_t &points /* OUT */, - const HBUINT8 *end) + static bool decompile_points (const HBUINT8 *&p /* IN/OUT */, + hb_vector_t &points /* OUT */, + const HBUINT8 *end) { enum packed_point_flag_t { @@ -1653,43 +1445,13 @@ struct TupleVariationData return true; } - static bool unpack_deltas (const HBUINT8 *&p /* IN/OUT */, - hb_vector_t &deltas /* IN/OUT */, - const HBUINT8 *end) + template + static bool decompile_deltas (const HBUINT8 *&p /* IN/OUT */, + hb_vector_t &deltas /* IN/OUT */, + const HBUINT8 *end, + bool consume_all = false) { - unsigned i = 0; - unsigned count = deltas.length; - while (i < count) - { - if (unlikely (p + 1 > end)) return false; - unsigned control = *p++; - unsigned run_count = (control & DELTA_RUN_COUNT_MASK) + 1; - unsigned stop = i + run_count; - if (unlikely (stop > count)) return false; - if (control & DELTAS_ARE_ZERO) - { - for (; i < stop; i++) - deltas.arrayZ[i] = 0; - } - else if (control & DELTAS_ARE_WORDS) - { - if (unlikely (p + run_count * HBUINT16::static_size > end)) return false; - for (; i < stop; i++) - { - deltas.arrayZ[i] = * (const HBINT16 *) p; - p += HBUINT16::static_size; - } - } - else - { - if (unlikely (p + run_count > end)) return false; - for (; i < stop; i++) - { - deltas.arrayZ[i] = * (const HBINT8 *) p++; - } - } - } - return true; + return TupleValues::decompile (p, deltas, end, consume_all); } bool has_data () const { return tupleVarCount; } @@ -1700,13 +1462,15 @@ struct TupleVariationData const hb_map_t *axes_old_index_tag_map, const hb_vector_t &shared_indices, const hb_array_t shared_tuples, - tuple_variations_t& tuple_variations /* OUT */) const + tuple_variations_t& tuple_variations, /* OUT */ + bool is_composite_glyph = false) const { return tuple_variations.create_from_tuple_var_data (iterator, tupleVarCount, point_count, is_gvar, axes_old_index_tag_map, shared_indices, - shared_tuples); + shared_tuples, + is_composite_glyph); } bool serialize (hb_serialize_context_t *c, @@ -1758,15 +1522,16 @@ struct TupleVariationData * low 12 bits are the number of tuple variation tables * for this glyph. The number of tuple variation tables * can be any number between 1 and 4095. */ - Offset16To + OffsetTo data; /* Offset from the start of the base table * to the serialized data. */ /* TupleVariationHeader tupleVariationHeaders[] *//* Array of tuple variation headers. */ public: - DEFINE_SIZE_MIN (4); + DEFINE_SIZE_MIN (2 + OffType::static_size); }; -using tuple_variations_t = TupleVariationData::tuple_variations_t; +// TODO: Move tuple_variations_t to outside of TupleVariationData +using tuple_variations_t = TupleVariationData::tuple_variations_t; struct item_variations_t { using region_t = const hb_hashmap_t*; @@ -1775,6 +1540,14 @@ struct item_variations_t * have the same num of deltas (rows) */ hb_vector_t vars; + /* num of retained rows for each subtable, there're 2 cases when var_data is empty: + * 1. retained item_count is zero + * 2. regions is empty and item_count is non-zero. + * when converting to tuples, both will be dropped because the tuple is empty, + * however, we need to retain 2. as all-zero rows to keep original varidx + * valid, so we need a way to remember the num of rows for each subtable */ + hb_vector_t var_data_num_rows; + /* original region list, decompiled from item varstore, used when rebuilding * region list after instantiation */ hb_vector_t> orig_region_list; @@ -1812,7 +1585,7 @@ struct item_variations_t const hb_map_t& get_varidx_map () const { return varidx_map; } - bool instantiate (const VariationStore& varStore, + bool instantiate (const ItemVariationStore& varStore, const hb_subset_plan_t *plan, bool optimize=true, bool use_no_variation_idx=true, @@ -1826,7 +1599,7 @@ struct item_variations_t } /* keep below APIs public only for unit test: test-item-varstore */ - bool create_from_item_varstore (const VariationStore& varStore, + bool create_from_item_varstore (const ItemVariationStore& varStore, const hb_map_t& axes_old_index_tag_map, const hb_array_t inner_maps = hb_array_t ()) { @@ -1836,22 +1609,26 @@ struct item_variations_t unsigned num_var_data = varStore.get_sub_table_count (); if (inner_maps && inner_maps.length != num_var_data) return false; - if (!vars.alloc (num_var_data)) return false; + if (!vars.alloc (num_var_data) || + !var_data_num_rows.alloc (num_var_data)) return false; for (unsigned i = 0; i < num_var_data; i++) { if (inner_maps && !inner_maps.arrayZ[i].get_population ()) continue; tuple_variations_t var_data_tuples; + unsigned item_count = 0; if (!var_data_tuples.create_from_item_var_data (varStore.get_sub_table (i), orig_region_list, axes_old_index_tag_map, + item_count, inner_maps ? &(inner_maps.arrayZ[i]) : nullptr)) return false; + var_data_num_rows.push (item_count); vars.push (std::move (var_data_tuples)); } - return !vars.in_error (); + return !vars.in_error () && !var_data_num_rows.in_error () && vars.length == var_data_num_rows.length; } bool instantiate_tuple_vars (const hb_hashmap_t& normalized_axes_location, @@ -1904,7 +1681,9 @@ struct item_variations_t } } - if (!all_regions || !all_unique_regions) return false; + /* regions are empty means no variation data, return true */ + if (!all_regions || !all_unique_regions) return true; + if (!region_list.alloc (all_regions.get_population ())) return false; @@ -1969,16 +1748,13 @@ struct item_variations_t bool as_item_varstore (bool optimize=true, bool use_no_variation_idx=true) { - if (!region_list) return false; + /* return true if no variation data */ + if (!region_list) return true; unsigned num_cols = region_list.length; /* pre-alloc a 2D vector for all sub_table's VarData rows */ unsigned total_rows = 0; - for (unsigned major = 0; major < vars.length; major++) - { - const tuple_variations_t& tuples = vars[major]; - /* all tuples in each sub_table should have same num of deltas(num rows) */ - total_rows += tuples.tuple_vars[0].deltas_x.length; - } + for (unsigned major = 0; major < var_data_num_rows.length; major++) + total_rows += var_data_num_rows[major]; if (!delta_rows.resize (total_rows)) return false; /* init all rows to [0]*num_cols */ @@ -1998,7 +1774,7 @@ struct item_variations_t /* deltas are stored in tuples(column based), convert them back into items * (row based) delta */ const tuple_variations_t& tuples = vars[major]; - unsigned num_rows = tuples.tuple_vars[0].deltas_x.length; + unsigned num_rows = var_data_num_rows[major]; for (const tuple_delta_t& tuple: tuples.tuple_vars) { if (tuple.deltas_x.length != num_rows) @@ -2223,6 +1999,7 @@ struct item_variations_t } }; + } /* namespace OT */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh index a44a8e99998b1..3dc4ebaebd821 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh @@ -45,11 +45,12 @@ struct cvar { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - version.sanitize (c) && likely (version.major == 1) && + hb_barrier () && + likely (version.major == 1) && tupleVariationData.sanitize (c)); } - const TupleVariationData* get_tuple_var_data (void) const + const TupleVariationData<>* get_tuple_var_data (void) const { return &tupleVariationData; } bool decompile_tuple_variations (unsigned axis_count, @@ -57,12 +58,12 @@ struct cvar hb_blob_t *blob, bool is_gvar, const hb_map_t *axes_old_index_tag_map, - TupleVariationData::tuple_variations_t& tuple_variations /* OUT */) const + TupleVariationData<>::tuple_variations_t& tuple_variations /* OUT */) const { hb_vector_t shared_indices; - TupleVariationData::tuple_iterator_t iterator; + TupleVariationData<>::tuple_iterator_t iterator; hb_bytes_t var_data_bytes = blob->as_bytes ().sub_array (4); - if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, this, + if (!TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, this, shared_indices, &iterator)) return false; @@ -76,16 +77,16 @@ struct cvar static bool calculate_cvt_deltas (unsigned axis_count, hb_array_t coords, unsigned num_cvt_item, - const TupleVariationData *tuple_var_data, + const TupleVariationData<> *tuple_var_data, const void *base, hb_vector_t& cvt_deltas /* OUT */) { if (!coords) return true; hb_vector_t shared_indices; - TupleVariationData::tuple_iterator_t iterator; + TupleVariationData<>::tuple_iterator_t iterator; unsigned var_data_length = tuple_var_data->get_size (axis_count); hb_bytes_t var_data_bytes = hb_bytes_t (reinterpret_cast (tuple_var_data), var_data_length); - if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, base, + if (!TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, base, shared_indices, &iterator)) return true; /* isn't applied at all */ @@ -106,14 +107,14 @@ struct cvar bool has_private_points = iterator.current_tuple->has_private_points (); if (has_private_points && - !TupleVariationData::unpack_points (p, private_indices, end)) + !TupleVariationData<>::decompile_points (p, private_indices, end)) return false; const hb_vector_t &indices = has_private_points ? private_indices : shared_indices; bool apply_to_all = (indices.length == 0); unsigned num_deltas = apply_to_all ? num_cvt_item : indices.length; if (unlikely (!unpacked_deltas.resize (num_deltas, false))) return false; - if (unlikely (!TupleVariationData::unpack_deltas (p, unpacked_deltas, end))) return false; + if (unlikely (!TupleVariationData<>::decompile_deltas (p, unpacked_deltas, end))) return false; for (unsigned int i = 0; i < num_deltas; i++) { @@ -128,7 +129,7 @@ struct cvar } bool serialize (hb_serialize_context_t *c, - TupleVariationData::tuple_variations_t& tuple_variations) const + TupleVariationData<>::tuple_variations_t& tuple_variations) const { TRACE_SERIALIZE (this); if (!tuple_variations) return_trace (false); @@ -143,7 +144,7 @@ struct cvar if (c->plan->all_axes_pinned) return_trace (false); - OT::TupleVariationData::tuple_variations_t tuple_variations; + OT::TupleVariationData<>::tuple_variations_t tuple_variations; unsigned axis_count = c->plan->axes_old_index_tag_map.get_population (); const hb_tag_t cvt = HB_TAG('c','v','t',' '); @@ -168,7 +169,7 @@ struct cvar } static bool add_cvt_and_apply_deltas (hb_subset_plan_t *plan, - const TupleVariationData *tuple_var_data, + const TupleVariationData<> *tuple_var_data, const void *base) { const hb_tag_t cvt = HB_TAG('c','v','t',' '); @@ -208,7 +209,7 @@ struct cvar protected: FixedVersion<>version; /* Version of the CVT variation table * initially set to 0x00010000u */ - TupleVariationData tupleVariationData; /* TupleVariationDate for cvar table */ + TupleVariationData<> tupleVariationData; /* TupleVariationDate for cvar table */ public: DEFINE_SIZE_MIN (8); }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh index d60c3dbcf4e47..f2725eaa2823e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh @@ -43,7 +43,7 @@ static bool axis_coord_pinned_or_within_axis_range (const hb_array_t(coords[axis_index].to_float ()); if (axis_limit.is_point ()) { if (axis_limit.minimum != axis_coord) @@ -131,6 +131,7 @@ struct InstanceRecord { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_array (coordinatesZ.arrayZ, axis_count)); } @@ -232,7 +233,10 @@ struct AxisRecord { float min, default_, max; get_coordinates (min, default_, max); - return TripleDistances (min, default_, max); + return TripleDistances ( + static_cast(min), + static_cast(default_), + static_cast(max)); } bool subset (hb_subset_context_t *c) const @@ -277,8 +281,10 @@ struct fvar { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && c->check_struct (this) && + hb_barrier () && axisSize == 20 && /* Assumed in our code. */ instanceSize >= axisCount * 4 + 4 && get_axes ().sanitize (c) && diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh index fd32ef03f30d6..c3040187f6e7d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh @@ -28,6 +28,7 @@ #ifndef HB_OT_VAR_GVAR_TABLE_HH #define HB_OT_VAR_GVAR_TABLE_HH +#include "hb-decycler.hh" #include "hb-open-type.hh" #include "hb-ot-var-common.hh" @@ -36,15 +37,37 @@ * https://docs.microsoft.com/en-us/typography/opentype/spec/gvar */ #define HB_OT_TAG_gvar HB_TAG('g','v','a','r') +#define HB_OT_TAG_GVAR HB_TAG('G','V','A','R') -namespace OT { +struct hb_glyf_scratch_t +{ + // glyf + contour_point_vector_t all_points; + contour_point_vector_t comp_points; + hb_decycler_t decycler; + + // gvar + contour_point_vector_t orig_points; + hb_vector_t x_deltas; + hb_vector_t y_deltas; + contour_point_vector_t deltas; + hb_vector_t shared_indices; + hb_vector_t private_indices; + + // VARC + hb_vector_t axisIndices; + hb_vector_t axisValues; +}; -struct GlyphVariationData : TupleVariationData -{}; +namespace OT { +template struct glyph_variations_t { - using tuple_variations_t = TupleVariationData::tuple_variations_t; + // TODO: Move tuple_variations_t to outside of TupleVariationData + using tuple_variations_t = typename TupleVariationData::tuple_variations_t; + using GlyphVariationData = TupleVariationData; + hb_vector_t glyph_variations; hb_vector_t compiled_shared_tuples; @@ -72,7 +95,7 @@ struct glyph_variations_t const hb_subset_plan_t *plan, const hb_hashmap_t& new_gid_var_data_map) { - if (unlikely (!glyph_variations.alloc (plan->new_to_old_gid_list.length, true))) + if (unlikely (!glyph_variations.alloc_exact (plan->new_to_old_gid_list.length))) return false; auto it = hb_iter (plan->new_to_old_gid_list); @@ -86,10 +109,11 @@ struct glyph_variations_t hb_bytes_t var_data = new_gid_var_data_map.get (new_gid); const GlyphVariationData* p = reinterpret_cast (var_data.arrayZ); - hb_vector_t shared_indices; - GlyphVariationData::tuple_iterator_t iterator; + typename GlyphVariationData::tuple_iterator_t iterator; tuple_variations_t tuple_vars; + hb_vector_t shared_indices; + /* in case variation data is empty, push an empty struct into the vector, * keep the vector in sync with the new_to_old_gid_list */ if (!var_data || ! p->has_data () || !all_contour_points->length || @@ -101,10 +125,14 @@ struct glyph_variations_t continue; } + bool is_composite_glyph = false; + is_composite_glyph = plan->composite_new_gids.has (new_gid); + if (!p->decompile_tuple_variations (all_contour_points->length, true /* is_gvar */, iterator, &(plan->axes_old_index_tag_map), shared_indices, shared_tuples, - tuple_vars /* OUT */)) + tuple_vars, /* OUT */ + is_composite_glyph)) return false; glyph_variations.push (std::move (tuple_vars)); } @@ -114,13 +142,15 @@ struct glyph_variations_t bool instantiate (const hb_subset_plan_t *plan) { unsigned count = plan->new_to_old_gid_list.length; + bool iup_optimize = false; + iup_optimize = plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS; for (unsigned i = 0; i < count; i++) { hb_codepoint_t new_gid = plan->new_to_old_gid_list[i].first; contour_point_vector_t *all_points; if (!plan->new_gid_contour_points_map.has (new_gid, &all_points)) return false; - if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points)) + if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points, iup_optimize)) return false; } return true; @@ -134,6 +164,7 @@ struct glyph_variations_t for (tuple_variations_t& vars: glyph_variations) if (!vars.compile_bytes (axes_index_map, axes_old_index_tag_map, true, /* use shared points*/ + true, &shared_tuples_idx_map)) return false; @@ -252,7 +283,7 @@ struct glyph_variations_t hb_codepoint_t last_gid = 0; unsigned idx = 0; - TupleVariationData* cur_glyph = c->start_embed (); + GlyphVariationData* cur_glyph = c->start_embed (); if (!cur_glyph) return_trace (false); for (auto &_ : it) { @@ -266,7 +297,7 @@ struct glyph_variations_t if (idx >= glyph_variations.length) return_trace (false); if (!cur_glyph->serialize (c, true, glyph_variations[idx])) return_trace (false); - TupleVariationData* next_glyph = c->start_embed (); + GlyphVariationData* next_glyph = c->start_embed (); glyph_offset += (char *) next_glyph - (char *) cur_glyph; if (long_offset) @@ -289,14 +320,21 @@ struct glyph_variations_t } }; -struct gvar +template +struct gvar_GVAR { - static constexpr hb_tag_t tableTag = HB_OT_TAG_gvar; + static constexpr hb_tag_t tableTag = TableTag; + + using GlyphVariationData = TupleVariationData; + + bool has_data () const { return version.to_int () != 0; } bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && (version.major == 1) && + return_trace (c->check_struct (this) && + hb_barrier () && + (version.major == 1) && sharedTuples.sanitize (c, this, axisCount * sharedTupleCount) && (is_long_offset () ? c->check_array (get_long_offset_array (), c->get_num_glyphs () + 1) : @@ -308,7 +346,7 @@ struct gvar { return sanitize_shallow (c); } bool decompile_glyph_variations (hb_subset_context_t *c, - glyph_variations_t& glyph_vars /* OUT */) const + glyph_variations_t& glyph_vars /* OUT */) const { hb_hashmap_t new_gid_var_data_map; auto it = hb_iter (c->plan->new_to_old_gid_list); @@ -335,13 +373,14 @@ struct gvar template bool serialize (hb_serialize_context_t *c, - const glyph_variations_t& glyph_vars, + const glyph_variations_t& glyph_vars, Iterator it, unsigned axis_count, - unsigned num_glyphs) const + unsigned num_glyphs, + bool force_long_offsets) const { TRACE_SERIALIZE (this); - gvar *out = c->allocate_min (); + gvar_GVAR *out = c->allocate_min (); if (unlikely (!out)) return_trace (false); out->version.major = 1; @@ -350,7 +389,10 @@ struct gvar out->glyphCountX = hb_min (0xFFFFu, num_glyphs); unsigned glyph_var_data_size = glyph_vars.compiled_byte_size (); - bool long_offset = glyph_var_data_size & ~0xFFFFu; + /* According to the spec: If the short format (Offset16) is used for offsets, + * the value stored is the offset divided by 2, so the maximum data size should + * be 2 * 0xFFFFu, which is 0x1FFFEu */ + bool long_offset = glyph_var_data_size > 0x1FFFEu || force_long_offsets; out->flags = long_offset ? 1 : 0; HBUINT8 *glyph_var_data_offsets = c->allocate_size ((long_offset ? 4 : 2) * (num_glyphs + 1), false); @@ -380,7 +422,7 @@ struct gvar bool instantiate (hb_subset_context_t *c) const { TRACE_SUBSET (this); - glyph_variations_t glyph_vars; + glyph_variations_t glyph_vars; if (!decompile_glyph_variations (c, glyph_vars)) return_trace (false); @@ -391,7 +433,12 @@ struct gvar unsigned axis_count = c->plan->axes_index_map.get_population (); unsigned num_glyphs = c->plan->num_output_glyphs (); auto it = hb_iter (c->plan->new_to_old_gid_list); - return_trace (serialize (c->serializer, glyph_vars, it, axis_count, num_glyphs)); + + bool force_long_offsets = false; +#ifdef HB_EXPERIMENTAL_API + force_long_offsets = c->plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS; +#endif + return_trace (serialize (c->serializer, glyph_vars, it, axis_count, num_glyphs, force_long_offsets)); } bool subset (hb_subset_context_t *c) const @@ -405,7 +452,7 @@ struct gvar unsigned glyph_count = version.to_int () ? c->plan->source->get_num_glyphs () : 0; - gvar *out = c->serializer->allocate_min (); + gvar_GVAR *out = c->serializer->allocate_min (); if (unlikely (!out)) return_trace (false); out->version.major = 1; @@ -426,7 +473,13 @@ struct gvar subset_data_size += get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length; } - bool long_offset = subset_data_size & ~0xFFFFu; + /* According to the spec: If the short format (Offset16) is used for offsets, + * the value stored is the offset divided by 2, so the maximum data size should + * be 2 * 0xFFFFu, which is 0x1FFFEu */ + bool long_offset = subset_data_size > 0x1FFFEu; +#ifdef HB_EXPERIMENTAL_API + long_offset = long_offset || (c->plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS); +#endif out->flags = long_offset ? 1 : 0; HBUINT8 *subset_offsets = c->serializer->allocate_size ((long_offset ? 4 : 2) * (num_glyphs + 1), false); @@ -444,6 +497,8 @@ struct gvar hb_memcpy (tuples, this+sharedTuples, shared_tuple_size); } + /* This ordering relative to the shared tuples array, which puts the glyphVariationData + last in the table, is required when HB_SUBSET_FLAGS_IFTB_REQUIREMENTS is set */ char *subset_data = c->serializer->allocate_size (subset_data_size, false); if (!subset_data) return_trace (false); out->dataZ = subset_data - (char *) out; @@ -521,7 +576,7 @@ struct gvar unsigned get_offset (unsigned glyph_count, unsigned i) const { if (unlikely (i > glyph_count)) return 0; - _hb_compiler_memory_r_barrier (); + hb_barrier (); return is_long_offset () ? get_long_offset_array ()[i] : get_short_offset_array ()[i] * 2; } @@ -531,9 +586,11 @@ struct gvar public: struct accelerator_t { + bool has_data () const { return table->has_data (); } + accelerator_t (hb_face_t *face) { - table = hb_sanitize_context_t ().reference_table (face); + table = hb_sanitize_context_t ().reference_table (face); /* If sanitize failed, set glyphCount to 0. */ glyphCount = table->version.to_int () ? face->get_num_glyphs () : 0; @@ -599,37 +656,42 @@ struct gvar public: bool apply_deltas_to_points (hb_codepoint_t glyph, - hb_array_t coords, + hb_array_t coords, const hb_array_t points, + hb_glyf_scratch_t &scratch, bool phantom_only = false) const { if (unlikely (glyph >= glyphCount)) return true; hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyphCount, glyph); if (!var_data_bytes.as ()->has_data ()) return true; - hb_vector_t shared_indices; - GlyphVariationData::tuple_iterator_t iterator; + + auto &shared_indices = scratch.shared_indices; + shared_indices.clear (); + + typename GlyphVariationData::tuple_iterator_t iterator; if (!GlyphVariationData::get_tuple_iterator (var_data_bytes, table->axisCount, var_data_bytes.arrayZ, shared_indices, &iterator)) return true; /* so isn't applied at all */ /* Save original points for inferred delta calculation */ - contour_point_vector_t orig_points_vec; // Populated lazily + auto &orig_points_vec = scratch.orig_points; + orig_points_vec.clear (); // Populated lazily auto orig_points = orig_points_vec.as_array (); /* flag is used to indicate referenced point */ - contour_point_vector_t deltas_vec; // Populated lazily + auto &deltas_vec = scratch.deltas; + deltas_vec.clear (); // Populated lazily auto deltas = deltas_vec.as_array (); - hb_vector_t end_points; // Populated lazily - unsigned num_coords = table->axisCount; hb_array_t shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * num_coords); - hb_vector_t private_indices; - hb_vector_t x_deltas; - hb_vector_t y_deltas; + auto &private_indices = scratch.private_indices; + auto &x_deltas = scratch.x_deltas; + auto &y_deltas = scratch.y_deltas; + unsigned count = points.length; bool flush = false; do @@ -654,16 +716,16 @@ struct gvar bool has_private_points = iterator.current_tuple->has_private_points (); if (has_private_points && - !GlyphVariationData::unpack_points (p, private_indices, end)) + !GlyphVariationData::decompile_points (p, private_indices, end)) return false; const hb_array_t &indices = has_private_points ? private_indices : shared_indices; bool apply_to_all = (indices.length == 0); unsigned int num_deltas = apply_to_all ? points.length : indices.length; if (unlikely (!x_deltas.resize (num_deltas, false))) return false; - if (unlikely (!GlyphVariationData::unpack_deltas (p, x_deltas, end))) return false; + if (unlikely (!GlyphVariationData::decompile_deltas (p, x_deltas, end))) return false; if (unlikely (!y_deltas.resize (num_deltas, false))) return false; - if (unlikely (!GlyphVariationData::unpack_deltas (p, y_deltas, end))) return false; + if (unlikely (!GlyphVariationData::decompile_deltas (p, y_deltas, end))) return false; if (!apply_to_all) { @@ -700,8 +762,8 @@ struct gvar if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ - delta.x += x_deltas.arrayZ[i] * scalar; - delta.y += y_deltas.arrayZ[i] * scalar; + delta.add_delta (x_deltas.arrayZ[i] * scalar, + y_deltas.arrayZ[i] * scalar); } } else @@ -712,10 +774,9 @@ struct gvar if (apply_to_all) for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++) { - unsigned int pt_index = i; - auto &delta = deltas.arrayZ[pt_index]; - delta.x += x_deltas.arrayZ[i] * scalar; - delta.y += y_deltas.arrayZ[i] * scalar; + auto &delta = deltas.arrayZ[i]; + delta.add_delta (x_deltas.arrayZ[i] * scalar, + y_deltas.arrayZ[i] * scalar); } else for (unsigned int i = 0; i < num_deltas; i++) @@ -725,8 +786,8 @@ struct gvar if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ - delta.x += x_deltas.arrayZ[i] * scalar; - delta.y += y_deltas.arrayZ[i] * scalar; + delta.add_delta (x_deltas.arrayZ[i] * scalar, + y_deltas.arrayZ[i] * scalar); } } else @@ -734,10 +795,9 @@ struct gvar if (apply_to_all) for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++) { - unsigned int pt_index = i; - auto &delta = deltas.arrayZ[pt_index]; - delta.x += x_deltas.arrayZ[i]; - delta.y += y_deltas.arrayZ[i]; + auto &delta = deltas.arrayZ[i]; + delta.add_delta (x_deltas.arrayZ[i], + y_deltas.arrayZ[i]); } else for (unsigned int i = 0; i < num_deltas; i++) @@ -747,8 +807,8 @@ struct gvar if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ - delta.x += x_deltas.arrayZ[i]; - delta.y += y_deltas.arrayZ[i]; + delta.add_delta (x_deltas.arrayZ[i], + y_deltas.arrayZ[i]); } } } @@ -756,17 +816,14 @@ struct gvar /* infer deltas for unreferenced points */ if (!apply_to_all && !phantom_only) { - if (!end_points) - { - for (unsigned i = 0; i < count; ++i) - if (points.arrayZ[i].is_end_point) - end_points.push (i); - if (unlikely (end_points.in_error ())) return false; - } - unsigned start_point = 0; - for (unsigned end_point : end_points) + unsigned end_point = 0; + while (true) { + while (end_point < count && !points.arrayZ[end_point].is_end_point) + end_point++; + if (unlikely (end_point == count)) break; + /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */ unsigned unref_count = 0; for (unsigned i = start_point; i < end_point + 1; i++) @@ -809,7 +866,7 @@ struct gvar } } no_more_gaps: - start_point = end_point + 1; + start_point = end_point = end_point + 1; } } @@ -829,7 +886,7 @@ struct gvar unsigned int get_axis_count () const { return table->axisCount; } private: - hb_blob_ptr_t table; + hb_blob_ptr_t table; unsigned glyphCount; hb_vector_t> shared_tuple_active_idx; }; @@ -847,7 +904,7 @@ struct gvar NNOffset32To> sharedTuples; /* Offset from the start of this table to the shared tuple records. * Array of tuple records shared across all glyph variation data tables. */ - HBUINT16 glyphCountX; /* The number of glyphs in this font. This must match the number of + GidOffsetType glyphCountX; /* The number of glyphs in this font. This must match the number of * glyphs stored elsewhere in the font. */ HBUINT16 flags; /* Bit-field that gives the format of the offset array that follows. * If bit 0 is clear, the offsets are uint16; if bit 0 is set, the @@ -862,9 +919,15 @@ struct gvar DEFINE_SIZE_ARRAY (20, offsetZ); }; +using gvar = gvar_GVAR; +using GVAR = gvar_GVAR; + struct gvar_accelerator_t : gvar::accelerator_t { gvar_accelerator_t (hb_face_t *face) : gvar::accelerator_t (face) {} }; +struct GVAR_accelerator_t : GVAR::accelerator_t { + GVAR_accelerator_t (hb_face_t *face) : GVAR::accelerator_t (face) {} +}; } /* namespace OT */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh index c1b40dcb49d95..40a85a62b788a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh @@ -188,7 +188,7 @@ struct hvarvvar_subset_plan_t ~hvarvvar_subset_plan_t() { fini (); } void init (const hb_array_t &index_maps, - const VariationStore &_var_store, + const ItemVariationStore &_var_store, const hb_subset_plan_t *plan) { index_map_plans.resize (index_maps.length); @@ -263,7 +263,7 @@ struct hvarvvar_subset_plan_t hb_inc_bimap_t outer_map; hb_vector_t inner_maps; hb_vector_t index_map_plans; - const VariationStore *var_store; + const ItemVariationStore *var_store; protected: hb_vector_t inner_sets; @@ -288,6 +288,7 @@ struct HVARVVAR { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && varStore.sanitize (c, this) && advMap.sanitize (c, this) && @@ -295,7 +296,7 @@ struct HVARVVAR rsbMap.sanitize (c, this)); } - const VariationStore& get_var_store () const + const ItemVariationStore& get_var_store () const { return this+varStore; } void listup_index_maps (hb_vector_t &index_maps) const @@ -383,7 +384,7 @@ struct HVARVVAR float get_advance_delta_unscaled (hb_codepoint_t glyph, const int *coords, unsigned int coord_count, - VariationStore::cache_t *store_cache = nullptr) const + ItemVariationStore::cache_t *store_cache = nullptr) const { uint32_t varidx = (this+advMap).map (glyph); return (this+varStore).get_delta (varidx, @@ -404,7 +405,7 @@ struct HVARVVAR public: FixedVersion<>version; /* Version of the metrics variation table * initially set to 0x00010000u */ - Offset32To + Offset32To varStore; /* Offset to item variation store table. */ Offset32To advMap; /* Offset to advance var-idx mapping. */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh index ced04d89da3cd..c5a58d6f6bf93 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh @@ -56,7 +56,7 @@ struct VariationValueRecord public: Tag valueTag; /* Four-byte tag identifying a font-wide measure. */ - VarIdx varIdx; /* Outer/inner index into VariationStore item. */ + VarIdx varIdx; /* Outer/inner index into ItemVariationStore item. */ public: DEFINE_SIZE_STATIC (8); @@ -77,8 +77,10 @@ struct MVAR { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && c->check_struct (this) && + hb_barrier () && valueRecordSize >= VariationValueRecord::static_size && varStore.sanitize (c, this) && c->check_range (valuesZ.arrayZ, @@ -104,7 +106,7 @@ struct MVAR out->valueRecordCount = valueRecordCount; item_variations_t item_vars; - const VariationStore& src_var_store = this+varStore; + const ItemVariationStore& src_var_store = this+varStore; if (!item_vars.instantiate (src_var_store, c->plan)) return_trace (false); @@ -157,7 +159,7 @@ protected: HBUINT16 valueRecordSize;/* The size in bytes of each value record — * must be greater than zero. */ HBUINT16 valueRecordCount;/* The number of value records — may be zero. */ - Offset16To + Offset16To varStore; /* Offset to item variation store table. */ UnsizedArrayOf valuesZ; /* Array of value records. The records must be diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-varc-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-varc-table.hh new file mode 100644 index 0000000000000..603aeb258cf1d --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-varc-table.hh @@ -0,0 +1,32 @@ +/* + * Copyright © 2024 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_VAR_VARC_TABLE_HH +#define HB_OT_VAR_VARC_TABLE_HH + +#include "OT/Var/VARC/VARC.hh" + +#endif /* HB_OT_VAR_VARC_TABLE_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh index dd3039924ef1f..b2300a327da27 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh @@ -117,6 +117,7 @@ struct VORG { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && version.major == 1 && vertYOrigins.sanitize (c)); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh index 518228c414b54..18aa638c7adfe 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh @@ -28,169 +28,8 @@ #include "hb.hh" #include "hb-paint.h" +#include "hb-geometry.hh" -typedef struct hb_extents_t -{ - hb_extents_t () {} - hb_extents_t (float xmin, float ymin, float xmax, float ymax) : - xmin (xmin), ymin (ymin), xmax (xmax), ymax (ymax) {} - - bool is_empty () const { return xmin >= xmax || ymin >= ymax; } - bool is_void () const { return xmin > xmax; } - - void union_ (const hb_extents_t &o) - { - xmin = hb_min (xmin, o.xmin); - ymin = hb_min (ymin, o.ymin); - xmax = hb_max (xmax, o.xmax); - ymax = hb_max (ymax, o.ymax); - } - - void intersect (const hb_extents_t &o) - { - xmin = hb_max (xmin, o.xmin); - ymin = hb_max (ymin, o.ymin); - xmax = hb_min (xmax, o.xmax); - ymax = hb_min (ymax, o.ymax); - } - - void - add_point (float x, float y) - { - if (unlikely (is_void ())) - { - xmin = xmax = x; - ymin = ymax = y; - } - else - { - xmin = hb_min (xmin, x); - ymin = hb_min (ymin, y); - xmax = hb_max (xmax, x); - ymax = hb_max (ymax, y); - } - } - - float xmin = 0.f; - float ymin = 0.f; - float xmax = -1.f; - float ymax = -1.f; -} hb_extents_t; - -typedef struct hb_transform_t -{ - hb_transform_t () {} - hb_transform_t (float xx, float yx, - float xy, float yy, - float x0, float y0) : - xx (xx), yx (yx), xy (xy), yy (yy), x0 (x0), y0 (y0) {} - - void multiply (const hb_transform_t &o) - { - /* Copied from cairo, with "o" being "a" there and "this" being "b" there. */ - hb_transform_t r; - - r.xx = o.xx * xx + o.yx * xy; - r.yx = o.xx * yx + o.yx * yy; - - r.xy = o.xy * xx + o.yy * xy; - r.yy = o.xy * yx + o.yy * yy; - - r.x0 = o.x0 * xx + o.y0 * xy + x0; - r.y0 = o.x0 * yx + o.y0 * yy + y0; - - *this = r; - } - - void transform_distance (float &dx, float &dy) const - { - float new_x = xx * dx + xy * dy; - float new_y = yx * dx + yy * dy; - dx = new_x; - dy = new_y; - } - - void transform_point (float &x, float &y) const - { - transform_distance (x, y); - x += x0; - y += y0; - } - - void transform_extents (hb_extents_t &extents) const - { - float quad_x[4], quad_y[4]; - - quad_x[0] = extents.xmin; - quad_y[0] = extents.ymin; - quad_x[1] = extents.xmin; - quad_y[1] = extents.ymax; - quad_x[2] = extents.xmax; - quad_y[2] = extents.ymin; - quad_x[3] = extents.xmax; - quad_y[3] = extents.ymax; - - extents = hb_extents_t {}; - for (unsigned i = 0; i < 4; i++) - { - transform_point (quad_x[i], quad_y[i]); - extents.add_point (quad_x[i], quad_y[i]); - } - } - - float xx = 1.f; - float yx = 0.f; - float xy = 0.f; - float yy = 1.f; - float x0 = 0.f; - float y0 = 0.f; -} hb_transform_t; - -typedef struct hb_bounds_t -{ - enum status_t { - UNBOUNDED, - BOUNDED, - EMPTY, - }; - - hb_bounds_t (status_t status) : status (status) {} - hb_bounds_t (const hb_extents_t &extents) : - status (extents.is_empty () ? EMPTY : BOUNDED), extents (extents) {} - - void union_ (const hb_bounds_t &o) - { - if (o.status == UNBOUNDED) - status = UNBOUNDED; - else if (o.status == BOUNDED) - { - if (status == EMPTY) - *this = o; - else if (status == BOUNDED) - extents.union_ (o.extents); - } - } - - void intersect (const hb_bounds_t &o) - { - if (o.status == EMPTY) - status = EMPTY; - else if (o.status == BOUNDED) - { - if (status == UNBOUNDED) - *this = o; - else if (status == BOUNDED) - { - extents.intersect (o.extents); - if (extents.is_empty ()) - status = EMPTY; - } - } - } - - status_t status; - hb_extents_t extents; -} hb_bounds_t; typedef struct hb_paint_extents_context_t hb_paint_extents_context_t; @@ -231,7 +70,10 @@ struct hb_paint_extents_context_t const hb_transform_t &t = transforms.tail (); t.transform_extents (extents); - clips.push (hb_bounds_t {extents}); + auto bounds = hb_bounds_t {extents}; + bounds.intersect (clips.tail ()); + + clips.push (bounds); } void pop_clip () diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint.h b/src/java.desktop/share/native/libharfbuzz/hb-paint.h index 6215488e2e7bf..f0d9438506d72 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-paint.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-paint.h @@ -146,7 +146,7 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, * * A virtual method for the #hb_paint_funcs_t to render a color glyph by glyph index. * - * Return value: %true if the glyph was painted, %false otherwise. + * Return value: `true` if the glyph was painted, `false` otherwise. * * Since: 8.2.0 */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh b/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh index 2c8ccbfb68856..274d5df4c541c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh @@ -55,6 +55,9 @@ struct hb_priority_queue_t bool in_error () const { return heap.in_error (); } + bool alloc (unsigned size) + { return heap.alloc (size); } + #ifndef HB_OPTIMIZE_SIZE HB_ALWAYS_INLINE #endif @@ -160,7 +163,7 @@ struct hb_priority_queue_t goto repeat; } - void swap (unsigned a, unsigned b) + void swap (unsigned a, unsigned b) noexcept { assert (a < heap.length); assert (b < heap.length); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh b/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh index e9cd376ad3721..cb4fdeead2e1e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh @@ -238,6 +238,54 @@ bool _try_isolating_subgraphs (const hb_vector_t& over return true; } +static inline +bool _resolve_shared_overflow(const hb_vector_t& overflows, + int overflow_index, + graph_t& sorted_graph) +{ + const graph::overflow_record_t& r = overflows[overflow_index]; + + // Find all of the parents in overflowing links that link to this + // same child node. We will then try duplicating the child node and + // re-assigning all of these parents to the duplicate. + hb_set_t parents; + parents.add(r.parent); + for (int i = overflow_index - 1; i >= 0; i--) { + const graph::overflow_record_t& r2 = overflows[i]; + if (r2.child == r.child) { + parents.add(r2.parent); + } + } + + unsigned result = sorted_graph.duplicate(&parents, r.child); + if (result == (unsigned) -1 && parents.get_population() > 2) { + // All links to the child are overflowing, so we can't include all + // in the duplication. Remove one parent from the duplication. + // Remove the lowest index parent, which will be the closest to the child. + parents.del(parents.get_min()); + result = sorted_graph.duplicate(&parents, r.child); + } + + if (result == (unsigned) -1) return result; + + if (parents.get_population() > 1) { + // If the duplicated node has more than one parent pre-emptively raise it's priority to the maximum. + // This will place it close to the parents. Node's with only one parent, don't need this as normal overflow + // resolution will raise priority if needed. + // + // Reasoning: most of the parents to this child are likely at the same layer in the graph. Duplicating + // the child will theoretically allow it to be placed closer to it's parents. However, due to the shortest + // distance sort by default it's placement will remain in the same layer, thus it will remain in roughly the + // same position (and distance from parents) as the original child node. The overflow resolution will attempt + // to move nodes closer, but only for non-shared nodes. Since this node is shared, it will simply be given + // further duplication which defeats the attempt to duplicate with multiple parents. To fix this we + // pre-emptively raise priority now which allows the duplicated node to pack into the same layer as it's parents. + sorted_graph.vertices_[result].give_max_priority(); + } + + return result; +} + static inline bool _process_overflows (const hb_vector_t& overflows, hb_set_t& priority_bumped_parents, @@ -254,7 +302,7 @@ bool _process_overflows (const hb_vector_t& overflows, { // The child object is shared, we may be able to eliminate the overflow // by duplicating it. - if (sorted_graph.duplicate (r.parent, r.child) == (unsigned) -1) continue; + if (!_resolve_shared_overflow(overflows, i, sorted_graph)) continue; return true; } @@ -289,9 +337,10 @@ bool _process_overflows (const hb_vector_t& overflows, inline bool hb_resolve_graph_overflows (hb_tag_t table_tag, unsigned max_rounds , - bool recalculate_extensions, + bool always_recalculate_extensions, graph_t& sorted_graph /* IN/OUT */) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Repacking %c%c%c%c.", HB_UNTAG(table_tag)); sorted_graph.sort_shortest_distance (); if (sorted_graph.in_error ()) { @@ -303,12 +352,12 @@ hb_resolve_graph_overflows (hb_tag_t table_tag, if (!will_overflow) return true; + bool is_gsub_or_gpos = (table_tag == HB_OT_TAG_GPOS || table_tag == HB_OT_TAG_GSUB); graph::gsubgpos_graph_context_t ext_context (table_tag, sorted_graph); - if ((table_tag == HB_OT_TAG_GPOS - || table_tag == HB_OT_TAG_GSUB) - && will_overflow) + if (is_gsub_or_gpos && will_overflow) { - if (recalculate_extensions) + DEBUG_MSG (SUBSET_REPACK, nullptr, "Applying GSUB/GPOS repacking specializations."); + if (always_recalculate_extensions) { DEBUG_MSG (SUBSET_REPACK, nullptr, "Splitting subtables if needed."); if (!_presplit_subtables_if_needed (ext_context)) { @@ -364,6 +413,13 @@ hb_resolve_graph_overflows (hb_tag_t table_tag, if (graph::will_overflow (sorted_graph)) { + if (is_gsub_or_gpos && !always_recalculate_extensions) { + // If this a GSUB/GPOS table and we didn't try to extension promotion and table splitting then + // as a last ditch effort, re-run the repacker with it enabled. + DEBUG_MSG (SUBSET_REPACK, nullptr, "Failed to find a resolution. Re-running with extension promotion and table splitting enabled."); + return hb_resolve_graph_overflows (table_tag, max_rounds, true, sorted_graph); + } + DEBUG_MSG (SUBSET_REPACK, nullptr, "Offset overflow resolution failed."); return false; } @@ -388,7 +444,7 @@ template inline hb_blob_t* hb_resolve_overflows (const T& packed, hb_tag_t table_tag, - unsigned max_rounds = 20, + unsigned max_rounds = 32, bool recalculate_extensions = false) { graph_t sorted_graph (packed); if (sorted_graph.in_error ()) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh b/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh index 3a6ec4fed9c00..1f8ba32bae204 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh @@ -72,8 +72,8 @@ * * === The sanitize() contract === * - * The sanitize() method of each object type shall return true if it's safe to - * call other methods of the object, and %false otherwise. + * The sanitize() method of each object type shall return `true` if it's safe to + * call other methods of the object, and `false` otherwise. * * Note that what sanitize() checks for might align with what the specification * describes as valid table data, but does not have to be. In particular, we @@ -134,7 +134,10 @@ struct hb_sanitize_context_t : const char *get_name () { return "SANITIZE"; } template bool may_dispatch (const T *obj HB_UNUSED, const F *format) - { return format->sanitize (this); } + { + return format->sanitize (this) && + hb_barrier (); + } static return_t default_return_value () { return true; } static return_t no_dispatch_return_value () { return false; } bool stop_sublookup_iteration (const return_t r) const { return !r; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh b/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh index 675eb03cadf28..704d0ffd12ba2 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh @@ -36,9 +36,7 @@ #include "hb-map.hh" #include "hb-pool.hh" -#ifdef HB_EXPERIMENTAL_API -#include "hb-subset-repacker.h" -#endif +#include "hb-subset-serialize.h" /* * Serialize @@ -75,23 +73,41 @@ struct hb_serialize_context_t object_t () = default; -#ifdef HB_EXPERIMENTAL_API - object_t (const hb_object_t &o) + object_t (const hb_subset_serialize_object_t &o) { head = o.head; tail = o.tail; next = nullptr; - real_links.alloc (o.num_real_links, true); + real_links.alloc_exact (o.num_real_links); for (unsigned i = 0 ; i < o.num_real_links; i++) real_links.push (o.real_links[i]); - virtual_links.alloc (o.num_virtual_links, true); + virtual_links.alloc_exact (o.num_virtual_links); for (unsigned i = 0; i < o.num_virtual_links; i++) virtual_links.push (o.virtual_links[i]); } -#endif - friend void swap (object_t& a, object_t& b) + bool add_virtual_link (objidx_t objidx) + { + if (!objidx) + return false; + + auto& link = *virtual_links.push (); + if (virtual_links.in_error ()) + return false; + + link.objidx = objidx; + // Remaining fields were previously zero'd by push(): + // link.width = 0; + // link.is_signed = 0; + // link.whence = 0; + // link.position = 0; + // link.bias = 0; + + return true; + } + + friend void swap (object_t& a, object_t& b) noexcept { hb_swap (a.head, b.head); hb_swap (a.tail, b.tail); @@ -128,8 +144,7 @@ struct hb_serialize_context_t link_t () = default; -#ifdef HB_EXPERIMENTAL_API - link_t (const hb_link_t &o) + link_t (const hb_subset_serialize_link_t &o) { width = o.width; is_signed = 0; @@ -138,7 +153,6 @@ struct hb_serialize_context_t bias = 0; objidx = o.objidx; } -#endif HB_INTERNAL static int cmp (const void* a, const void* b) { @@ -156,9 +170,9 @@ struct hb_serialize_context_t object_t *next; auto all_links () const HB_AUTO_RETURN - (( hb_concat (this->real_links, this->virtual_links) )); + (( hb_concat (real_links, virtual_links) )); auto all_links_writer () HB_AUTO_RETURN - (( hb_concat (this->real_links.writer (), this->virtual_links.writer ()) )); + (( hb_concat (real_links.writer (), virtual_links.writer ()) )); }; struct snapshot_t @@ -380,6 +394,7 @@ struct hb_serialize_context_t { merge_virtual_links (obj, objidx); obj->fini (); + object_pool.release (obj); return objidx; } } @@ -443,9 +458,11 @@ struct hb_serialize_context_t while (packed.length > 1 && packed.tail ()->head < tail) { - packed_map.del (packed.tail ()); - assert (!packed.tail ()->next); - packed.tail ()->fini (); + object_t *obj = packed.tail (); + packed_map.del (obj); + assert (!obj->next); + obj->fini (); + object_pool.release (obj); packed.pop (); } if (packed.length > 1) @@ -469,16 +486,40 @@ struct hb_serialize_context_t assert (current); - auto& link = *current->virtual_links.push (); - if (current->virtual_links.in_error ()) + if (!current->add_virtual_link(objidx)) err (HB_SERIALIZE_ERROR_OTHER); + } - link.width = 0; - link.objidx = objidx; - link.is_signed = 0; - link.whence = 0; - link.position = 0; - link.bias = 0; + objidx_t last_added_child_index() const { + if (unlikely (in_error ())) return (objidx_t) -1; + + assert (current); + if (!bool(current->real_links)) { + return (objidx_t) -1; + } + + return current->real_links[current->real_links.length - 1].objidx; + } + + // For the current object ensure that the sub-table bytes for child objidx are always placed + // after the subtable bytes for any other existing children. This only ensures that the + // repacker will not move the target subtable before the other children + // (by adding virtual links). It is up to the caller to ensure the initial serialization + // order is correct. + void repack_last(objidx_t objidx) { + if (unlikely (in_error ())) return; + + if (!objidx) + return; + + assert (current); + for (auto& l : current->real_links) { + if (l.objidx == objidx) { + continue; + } + + packed[l.objidx]->add_virtual_link(objidx); + } } template diff --git a/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh b/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh index c1e107b4c2980..7bd14a2819343 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh @@ -56,7 +56,7 @@ * - For each glyph, if it doesn't match the subtable digest, * skip it. * - * The main filter we use is a combination of three bits-pattern + * The main filter we use is a combination of four bits-pattern * filters. A bits-pattern filter checks a number of bits (5 or 6) * of the input number (glyph-id in this case) and checks whether * its pattern is amongst the patterns of any of the accepted values. @@ -64,43 +64,60 @@ * check is done using four bitwise operations only. */ -template -struct hb_set_digest_bits_pattern_t +static constexpr unsigned hb_set_digest_shifts[] = {4, 0, 6}; + +struct hb_set_digest_t { + // No science in these. Intuition and testing only. + using mask_t = uint64_t; + + static constexpr unsigned n = ARRAY_LENGTH_CONST (hb_set_digest_shifts); static constexpr unsigned mask_bytes = sizeof (mask_t); static constexpr unsigned mask_bits = sizeof (mask_t) * 8; - static constexpr unsigned num_bits = 0 - + (mask_bytes >= 1 ? 3 : 0) - + (mask_bytes >= 2 ? 1 : 0) - + (mask_bytes >= 4 ? 1 : 0) - + (mask_bytes >= 8 ? 1 : 0) - + (mask_bytes >= 16? 1 : 0) - + 0; + static constexpr hb_codepoint_t mb1 = mask_bits - 1; + static constexpr mask_t one = 1; + static constexpr mask_t all = (mask_t) -1; - static_assert ((shift < sizeof (hb_codepoint_t) * 8), ""); - static_assert ((shift + num_bits <= sizeof (hb_codepoint_t) * 8), ""); + void init () + { for (unsigned i = 0; i < n; i++) masks[i] = 0; } - void init () { mask = 0; } + void clear () { init (); } - void add (const hb_set_digest_bits_pattern_t &o) { mask |= o.mask; } + static hb_set_digest_t full () + { + hb_set_digest_t d; + for (unsigned i = 0; i < n; i++) d.masks[i] = all; + return d; + } - void add (hb_codepoint_t g) { mask |= mask_for (g); } + void union_ (const hb_set_digest_t &o) + { for (unsigned i = 0; i < n; i++) masks[i] |= o.masks[i]; } bool add_range (hb_codepoint_t a, hb_codepoint_t b) { - if (mask == (mask_t) -1) return false; - if ((b >> shift) - (a >> shift) >= mask_bits - 1) - { - mask = (mask_t) -1; - return false; - } - else + bool ret; + + ret = false; + for (unsigned i = 0; i < n; i++) + if (masks[i] != all) + ret = true; + if (!ret) return false; + + ret = false; + for (unsigned i = 0; i < n; i++) { - mask_t ma = mask_for (a); - mask_t mb = mask_for (b); - mask |= mb + (mb - ma) - (mb < ma); - return true; + mask_t shift = hb_set_digest_shifts[i]; + if ((b >> shift) - (a >> shift) >= mb1) + masks[i] = all; + else + { + mask_t ma = one << ((a >> shift) & mb1); + mask_t mb = one << ((b >> shift) & mb1); + masks[i] |= mb + (mb - ma) - (mb < ma); + ret = true; + } } + return ret; } template @@ -123,95 +140,37 @@ struct hb_set_digest_bits_pattern_t template bool add_sorted_array (const hb_sorted_array_t& arr) { return add_sorted_array (&arr, arr.len ()); } - bool may_have (const hb_set_digest_bits_pattern_t &o) const - { return mask & o.mask; } - - bool may_have (hb_codepoint_t g) const - { return mask & mask_for (g); } - - private: - - static mask_t mask_for (hb_codepoint_t g) - { return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1)); } - mask_t mask; -}; - -template -struct hb_set_digest_combiner_t -{ - void init () - { - head.init (); - tail.init (); - } + bool operator [] (hb_codepoint_t g) const + { return may_have (g); } - void add (const hb_set_digest_combiner_t &o) - { - head.add (o.head); - tail.add (o.tail); - } void add (hb_codepoint_t g) { - head.add (g); - tail.add (g); - } - - bool add_range (hb_codepoint_t a, hb_codepoint_t b) - { - return (int) head.add_range (a, b) | (int) tail.add_range (a, b); - } - template - void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) - { - head.add_array (array, count, stride); - tail.add_array (array, count, stride); - } - template - void add_array (const hb_array_t& arr) { add_array (&arr, arr.len ()); } - template - bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) - { - return head.add_sorted_array (array, count, stride) && - tail.add_sorted_array (array, count, stride); + for (unsigned i = 0; i < n; i++) + masks[i] |= one << ((g >> hb_set_digest_shifts[i]) & mb1); } - template - bool add_sorted_array (const hb_sorted_array_t& arr) { return add_sorted_array (&arr, arr.len ()); } - bool may_have (const hb_set_digest_combiner_t &o) const + HB_ALWAYS_INLINE + bool may_have (hb_codepoint_t g) const { - return head.may_have (o.head) && tail.may_have (o.tail); + for (unsigned i = 0; i < n; i++) + if (!(masks[i] & (one << ((g >> hb_set_digest_shifts[i]) & mb1)))) + return false; + return true; } - bool may_have (hb_codepoint_t g) const + bool may_intersect (const hb_set_digest_t &o) const { - return head.may_have (g) && tail.may_have (g); + for (unsigned i = 0; i < n; i++) + if (!(masks[i] & o.masks[i])) + return false; + return true; } private: - head_t head; - tail_t tail; -}; - -/* - * hb_set_digest_t - * - * This is a combination of digests that performs "best". - * There is not much science to this: it's a result of intuition - * and testing. - */ -using hb_set_digest_t = - hb_set_digest_combiner_t - < - hb_set_digest_bits_pattern_t, - hb_set_digest_combiner_t - < - hb_set_digest_bits_pattern_t, - hb_set_digest_bits_pattern_t - > - > -; + mask_t masks[n] = {}; +}; #endif /* HB_SET_DIGEST_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-set.hh b/src/java.desktop/share/native/libharfbuzz/hb-set.hh index 4aa682616a2d8..eaa892ab9f588 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-set.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-set.hh @@ -35,6 +35,8 @@ template struct hb_sparseset_t { + static constexpr bool realloc_move = true; + hb_object_header_t header; impl_t s; @@ -42,10 +44,10 @@ struct hb_sparseset_t ~hb_sparseset_t () { fini (); } hb_sparseset_t (const hb_sparseset_t& other) : hb_sparseset_t () { set (other); } - hb_sparseset_t (hb_sparseset_t&& other) : hb_sparseset_t () { s = std::move (other.s); } + hb_sparseset_t (hb_sparseset_t&& other) noexcept : hb_sparseset_t () { s = std::move (other.s); } hb_sparseset_t& operator = (const hb_sparseset_t& other) { set (other); return *this; } - hb_sparseset_t& operator = (hb_sparseset_t&& other) { s = std::move (other.s); return *this; } - friend void swap (hb_sparseset_t& a, hb_sparseset_t& b) { hb_swap (a.s, b.s); } + hb_sparseset_t& operator = (hb_sparseset_t&& other) noexcept { s = std::move (other.s); return *this; } + friend void swap (hb_sparseset_t& a, hb_sparseset_t& b) noexcept { hb_swap (a.s, b.s); } hb_sparseset_t (std::initializer_list lst) : hb_sparseset_t () { @@ -84,7 +86,7 @@ struct hb_sparseset_t uint32_t hash () const { return s.hash (); } void add (hb_codepoint_t g) { s.add (g); } - bool add_range (hb_codepoint_t a, hb_codepoint_t b) { return s.add_range (a, b); } + bool add_range (hb_codepoint_t first, hb_codepoint_t last) { return s.add_range (first, last); } template void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) @@ -104,6 +106,7 @@ struct hb_sparseset_t void del_range (hb_codepoint_t a, hb_codepoint_t b) { s.del_range (a, b); } bool get (hb_codepoint_t g) const { return s.get (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } /* Has interface. */ bool operator [] (hb_codepoint_t k) const { return get (k); } @@ -118,6 +121,9 @@ struct hb_sparseset_t hb_sparseset_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } + bool may_intersect (const hb_sparseset_t &other) const + { return s.may_intersect (other.s); } + bool intersects (hb_codepoint_t first, hb_codepoint_t last) const { return s.intersects (first, last); } @@ -164,7 +170,7 @@ struct hb_set_t : hb_sparseset_t ~hb_set_t () = default; hb_set_t () : sparseset () {}; hb_set_t (const hb_set_t &o) : sparseset ((sparseset &) o) {}; - hb_set_t (hb_set_t&& o) : sparseset (std::move ((sparseset &) o)) {} + hb_set_t (hb_set_t&& o) noexcept : sparseset (std::move ((sparseset &) o)) {} hb_set_t& operator = (const hb_set_t&) = default; hb_set_t& operator = (hb_set_t&&) = default; hb_set_t (std::initializer_list lst) : sparseset (lst) {} diff --git a/src/java.desktop/share/native/libharfbuzz/hb-shape-plan.cc b/src/java.desktop/share/native/libharfbuzz/hb-shape-plan.cc index 970aaa0b40ba9..19188f8006a0d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-shape-plan.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-shape-plan.cc @@ -233,7 +233,7 @@ hb_shape_plan_create2 (hb_face_t *face, num_coords, shaper_list); - if (unlikely (props->direction == HB_DIRECTION_INVALID)) + if (unlikely (!HB_DIRECTION_IS_VALID (props->direction))) return hb_shape_plan_get_empty (); hb_shape_plan_t *shape_plan; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-shape.h b/src/java.desktop/share/native/libharfbuzz/hb-shape.h index bf7eafd2b4fe3..294105d3cb0a8 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-shape.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-shape.h @@ -53,6 +53,7 @@ hb_shape_full (hb_font_t *font, unsigned int num_features, const char * const *shaper_list); +#ifdef HB_EXPERIMENTAL_API HB_EXTERN hb_bool_t hb_shape_justify (hb_font_t *font, hb_buffer_t *buffer, @@ -64,6 +65,7 @@ hb_shape_justify (hb_font_t *font, float *advance, /* IN/OUT */ hb_tag_t *var_tag, /* OUT */ float *var_value /* OUT */); +#endif HB_EXTERN const char ** hb_shape_list_shapers (void); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-style.cc b/src/java.desktop/share/native/libharfbuzz/hb-style.cc index 20d4696b92626..7378a8895f4f0 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-style.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-style.cc @@ -61,8 +61,8 @@ _hb_ratio_to_angle (float r) * @style_tag: a style tag. * * Searches variation axes of a #hb_font_t object for a specific axis first, - * if not set, then tries to get default style values from different - * tables of the font. + * if not set, first tries to get default style values in `STAT` table + * then tries to polyfill from different tables of the font. * * Returns: Corresponding axis or default value to a style tag. * diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh index 4213f7e71c5c1..62206e0f5aab5 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh @@ -115,7 +115,7 @@ struct str_encoder_t encode_byte (OpCode_BCD); // Based on: - // https://github.com/fonttools/fonttools/blob/97ed3a61cde03e17b8be36f866192fbd56f1d1a7/Lib/fontTools/misc/psCharStrings.py#L265-L294 + // https://github.com/fonttools/fonttools/blob/0738c41dfbcbc213ab9263f486ef0cccc6eb5ce5/Lib/fontTools/misc/psCharStrings.py#L267-L316 char buf[16]; /* FontTools has the following comment: @@ -133,6 +133,10 @@ struct str_encoder_t (void) hb_uselocale (((void) freelocale (clocale), oldlocale)); char *s = buf; + size_t len; + char *comma = strchr (s, ','); + if (comma) // Comma for some European locales in case no uselocale available. + *comma = '.'; if (s[0] == '0' && s[1] == '.') s++; else if (s[0] == '-' && s[1] == '0' && s[2] == '.') @@ -140,6 +144,45 @@ struct str_encoder_t s[1] = '-'; s++; } + else if ((len = strlen (s)) > 3 && !strcmp (s + len - 3, "000")) + { + unsigned exponent = len - 3; + char *s2 = s + exponent - 1; + while (*s2 == '0' && exponent > 1) + { + s2--; + exponent++; + } + snprintf (s2 + 1, sizeof (buf) - (s2 + 1 - buf), "E%u", exponent); + } + else + { + char *dot = strchr (s, '.'); + char *e = strchr (s, 'E'); + if (dot && e) + { + memmove (dot, dot + 1, e - (dot + 1)); + int exponent = atoi (e + 1); + int new_exponent = exponent - (e - (dot + 1)); + if (new_exponent == 1) + { + e[-1] = '0'; + e[0] = '\0'; + } + else + snprintf (e - 1, sizeof (buf) - (e - 1 - buf), "E%d", new_exponent); + } + } + if ((s[0] == '.' && s[1] == '0') || (s[0] == '-' && s[1] == '.' && s[2] == '0')) + { + int sign = s[0] == '-'; + char *s2 = s + sign + 1; + while (*s2 == '0') + s2++; + len = strlen (s2); + memmove (s + sign, s2, len); + snprintf (s + sign + len, sizeof (buf) - (s + sign + len - buf), "E-%u", (unsigned) (strlen (s + sign) - 1)); + } hb_vector_t nibbles; while (*s) { @@ -155,20 +198,22 @@ struct str_encoder_t { s++; nibbles.push (0x0C); // E- - continue; + } else { + if (c2 == '+') + s++; + nibbles.push (0x0B); // E } - if (c2 == '+') + if (*s == '0') s++; - nibbles.push (0x0B); // E continue; } - case '.': case ',': // Comma for some European locales in case no uselocale available. + case '.': nibbles.push (0x0A); // . continue; case '-': - nibbles.push (0x0E); // . + nibbles.push (0x0E); // - continue; } @@ -1083,7 +1128,7 @@ struct subr_subsetter_t if (opstr.op == OpCode_callsubr || opstr.op == OpCode_callgsubr) size += 3; } - if (!buff.alloc (buff.length + size, true)) + if (!buff.alloc_exact (buff.length + size)) return false; for (auto &opstr : str.values) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc index 780bf34efaf66..4938c048d6d46 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc @@ -45,7 +45,7 @@ struct remap_sid_t void alloc (unsigned size) { map.alloc (size); - vector.alloc (size, true); + vector.alloc_exact (size); } bool in_error () const @@ -620,6 +620,12 @@ struct cff1_subset_plan drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING; desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE; + #ifdef HB_EXPERIMENTAL_API + min_charstrings_off_size = (plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS) ? 4 : 0; + #else + min_charstrings_off_size = 0; + #endif + subset_charset = !acc.is_predef_charset (); if (!subset_charset) /* check whether the subset renumbers any glyph IDs */ @@ -778,13 +784,43 @@ struct cff1_subset_plan unsigned int topDictModSIDs[name_dict_values_t::ValCount]; bool desubroutinize = false; + + unsigned min_charstrings_off_size = 0; }; } // namespace OT +static bool _serialize_cff1_charstrings (hb_serialize_context_t *c, + struct OT::cff1_subset_plan &plan, + const OT::cff1::accelerator_subset_t &acc) +{ + c->push (); + + unsigned data_size = 0; + unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings, &data_size, plan.min_charstrings_off_size); + if (unlikely (!c->start_zerocopy (total_size))) + return false; + + auto *cs = c->start_embed (); + if (unlikely (!cs->serialize (c, plan.subset_charstrings, &data_size, plan.min_charstrings_off_size))) { + c->pop_discard (); + return false; + } + + plan.info.char_strings_link = c->pop_pack (false); + return true; +} + bool OT::cff1::accelerator_subset_t::serialize (hb_serialize_context_t *c, struct OT::cff1_subset_plan &plan) const { + /* push charstrings onto the object stack first which will ensure it packs as the last + object in the table. Keeping the chastrings last satisfies the requirements for patching + via IFTB. If this ordering needs to be changed in the future, charstrings should be left + at the end whenever HB_SUBSET_FLAGS_ITFB_REQUIREMENTS is enabled. */ + if (!_serialize_cff1_charstrings(c, plan, *this)) + return false; + /* private dicts & local subrs */ for (int i = (int) privateDicts.length; --i >= 0 ;) { @@ -823,25 +859,6 @@ OT::cff1::accelerator_subset_t::serialize (hb_serialize_context_t *c, if (!is_CID ()) plan.info.privateDictInfo = plan.fontdicts_mod[0].privateDictInfo; - /* CharStrings */ - { - c->push (); - - unsigned data_size = 0; - unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings, &data_size); - if (unlikely (!c->start_zerocopy (total_size))) - return false; - - auto *cs = c->start_embed (); - if (likely (cs->serialize (c, plan.subset_charstrings, &data_size))) - plan.info.char_strings_link = c->pop_pack (false); - else - { - c->pop_discard (); - return false; - } - } - /* FDArray (FD Index) */ if (fdArray != &Null (CFF1FDArray)) { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc index 1f9bc209e88c2..1074d2403865d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc @@ -248,7 +248,7 @@ struct cff2_subr_subsetter_t : subr_subsetter_t normalized_coords) : c (c), varStore (varStore), normalized_coords (normalized_coords) {} @@ -284,7 +284,7 @@ struct cff2_private_blend_encoder_param_t unsigned ivs = 0; unsigned region_count = 0; hb_vector_t scalars; - const CFF2VariationStore *varStore = nullptr; + const CFF2ItemVariationStore *varStore = nullptr; hb_array_t normalized_coords; }; @@ -378,7 +378,7 @@ struct cff2_private_dict_blend_opset_t : dict_opset_t struct cff2_private_dict_op_serializer_t : op_serializer_t { cff2_private_dict_op_serializer_t (bool desubroutinize_, bool drop_hints_, bool pinned_, - const CFF::CFF2VariationStore* varStore_, + const CFF::CFF2ItemVariationStore* varStore_, hb_array_t normalized_coords_) : desubroutinize (desubroutinize_), drop_hints (drop_hints_), pinned (pinned_), varStore (varStore_), normalized_coords (normalized_coords_) {} @@ -416,7 +416,7 @@ struct cff2_private_dict_op_serializer_t : op_serializer_t const bool desubroutinize; const bool drop_hints; const bool pinned; - const CFF::CFF2VariationStore* varStore; + const CFF::CFF2ItemVariationStore* varStore; hb_array_t normalized_coords; }; @@ -439,6 +439,12 @@ struct cff2_subset_plan desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE || pinned; // For instancing we need this path + #ifdef HB_EXPERIMENTAL_API + min_charstrings_off_size = (plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS) ? 4 : 0; + #else + min_charstrings_off_size = 0; + #endif + if (desubroutinize) { /* Flatten global & local subrs */ @@ -510,14 +516,45 @@ struct cff2_subset_plan bool drop_hints = false; bool desubroutinize = false; + + unsigned min_charstrings_off_size = 0; }; } // namespace OT +static bool _serialize_cff2_charstrings (hb_serialize_context_t *c, + cff2_subset_plan &plan, + const OT::cff2::accelerator_subset_t &acc) +{ + c->push (); + + unsigned data_size = 0; + unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings, &data_size, plan.min_charstrings_off_size); + if (unlikely (!c->start_zerocopy (total_size))) + return false; + + auto *cs = c->start_embed (); + if (unlikely (!cs->serialize (c, plan.subset_charstrings, &data_size, plan.min_charstrings_off_size))) + { + c->pop_discard (); + return false; + } + + plan.info.char_strings_link = c->pop_pack (false); + return true; +} + bool OT::cff2::accelerator_subset_t::serialize (hb_serialize_context_t *c, struct cff2_subset_plan &plan, hb_array_t normalized_coords) const { + /* push charstrings onto the object stack first which will ensure it packs as the last + object in the table. Keeping the chastrings last satisfies the requirements for patching + via IFTB. If this ordering needs to be changed in the future, charstrings should be left + at the end whenever HB_SUBSET_FLAGS_ITFB_REQUIREMENTS is enabled. */ + if (!_serialize_cff2_charstrings(c, plan, *this)) + return false; + /* private dicts & local subrs */ hb_vector_t private_dict_infos; if (unlikely (!private_dict_infos.resize (plan.subset_fdcount))) return false; @@ -556,25 +593,6 @@ OT::cff2::accelerator_subset_t::serialize (hb_serialize_context_t *c, } } - /* CharStrings */ - { - c->push (); - - unsigned data_size = 0; - unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings, &data_size); - if (unlikely (!c->start_zerocopy (total_size))) - return false; - - auto *cs = c->start_embed (); - if (likely (cs->serialize (c, plan.subset_charstrings, &data_size))) - plan.info.char_strings_link = c->pop_pack (false); - else - { - c->pop_discard (); - return false; - } - } - /* FDSelect */ if (fdSelect != &Null (CFF2FDSelect)) { @@ -610,10 +628,10 @@ OT::cff2::accelerator_subset_t::serialize (hb_serialize_context_t *c, } /* variation store */ - if (varStore != &Null (CFF2VariationStore) && + if (varStore != &Null (CFF2ItemVariationStore) && !plan.pinned) { - auto *dest = c->push (); + auto *dest = c->push (); if (unlikely (!dest->serialize (c, varStore))) { c->pop_discard (); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc index 8c67f7f23f4d2..bbe50b1fb36f2 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc @@ -24,6 +24,7 @@ * Google Author(s): Garret Rieger, Rod Sheeter, Behdad Esfahbod */ +#include "hb-subset-instancer-solver.hh" #include "hb-subset.hh" #include "hb-set.hh" #include "hb-utf.hh" @@ -50,7 +51,6 @@ hb_subset_input_t::hb_subset_input_t () HB_TAG ('k', 'e', 'r', 'n'), // Copied from fontTools: - HB_TAG ('B', 'A', 'S', 'E'), HB_TAG ('J', 'S', 'T', 'F'), HB_TAG ('D', 'S', 'I', 'G'), HB_TAG ('E', 'B', 'D', 'T'), @@ -123,6 +123,12 @@ hb_subset_input_t::hb_subset_input_t () //justify HB_TAG ('j', 'a', 'l', 't'), // HarfBuzz doesn't use; others might + //East Asian spacing + HB_TAG ('c', 'h', 'w', 's'), + HB_TAG ('v', 'c', 'h', 'w'), + HB_TAG ('h', 'a', 'l', 't'), + HB_TAG ('v', 'h', 'a', 'l'), + //private HB_TAG ('H', 'a', 'r', 'f'), HB_TAG ('H', 'A', 'R', 'F'), @@ -406,11 +412,52 @@ hb_subset_input_keep_everything (hb_subset_input_t *input) hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_NOTDEF_OUTLINE | HB_SUBSET_FLAGS_GLYPH_NAMES | + HB_SUBSET_FLAGS_NAME_LEGACY | HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES | HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED); } #ifndef HB_NO_VAR +/** + * hb_subset_input_pin_all_axes_to_default: (skip) + * @input: a #hb_subset_input_t object. + * @face: a #hb_face_t object. + * + * Pin all axes to default locations in the given subset input object. + * + * All axes in a font must be pinned. Additionally, `CFF2` table, if present, + * will be de-subroutinized. + * + * Return value: `true` if success, `false` otherwise + * + * Since: 8.3.1 + **/ +HB_EXTERN hb_bool_t +hb_subset_input_pin_all_axes_to_default (hb_subset_input_t *input, + hb_face_t *face) +{ + unsigned axis_count = hb_ot_var_get_axis_count (face); + if (!axis_count) return false; + + hb_ot_var_axis_info_t *axis_infos = (hb_ot_var_axis_info_t *) hb_calloc (axis_count, sizeof (hb_ot_var_axis_info_t)); + if (unlikely (!axis_infos)) return false; + + (void) hb_ot_var_get_axis_infos (face, 0, &axis_count, axis_infos); + + for (unsigned i = 0; i < axis_count; i++) + { + hb_tag_t axis_tag = axis_infos[i].tag; + double default_val = (double) axis_infos[i].default_value; + if (!input->axes_location.set (axis_tag, Triple (default_val, default_val, default_val))) + { + hb_free (axis_infos); + return false; + } + } + hb_free (axis_infos); + return true; +} + /** * hb_subset_input_pin_axis_to_default: (skip) * @input: a #hb_subset_input_t object. @@ -435,7 +482,7 @@ hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) return false; - float default_val = axis_info.default_value; + double default_val = (double) axis_info.default_value; return input->axes_location.set (axis_tag, Triple (default_val, default_val, default_val)); } @@ -465,37 +512,32 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) return false; - float val = hb_clamp(axis_value, axis_info.min_value, axis_info.max_value); + double val = hb_clamp((double) axis_value, (double) axis_info.min_value, (double) axis_info.max_value); return input->axes_location.set (axis_tag, Triple (val, val, val)); } -#ifdef HB_EXPERIMENTAL_API /** * hb_subset_input_set_axis_range: (skip) * @input: a #hb_subset_input_t object. * @face: a #hb_face_t object. * @axis_tag: Tag of the axis - * @axis_min_value: Minimum value of the axis variation range to set - * @axis_max_value: Maximum value of the axis variation range to set - * @axis_def_value: Default value of the axis variation range to set, in case of - * null, it'll be determined automatically + * @axis_min_value: Minimum value of the axis variation range to set, if NaN the existing min will be used. + * @axis_max_value: Maximum value of the axis variation range to set if NaN the existing max will be used. + * @axis_def_value: Default value of the axis variation range to set, if NaN the existing default will be used. * * Restricting the range of variation on an axis in the given subset input object. * New min/default/max values will be clamped if they're not within the fvar axis range. - * If the new default value is null: - * If the fvar axis default value is within the new range, then new default - * value is the same as original default value. + * * If the fvar axis default value is not within the new range, the new default * value will be changed to the new min or max value, whichever is closer to the fvar * axis default. * * Note: input min value can not be bigger than input max value. If the input * default value is not within the new min/max range, it'll be clamped. - * Note: currently it supports gvar and cvar tables only. * * Return value: `true` if success, `false` otherwise * - * XSince: EXPERIMENTAL + * Since: 8.5.0 **/ HB_EXTERN hb_bool_t hb_subset_input_set_axis_range (hb_subset_input_t *input, @@ -503,22 +545,195 @@ hb_subset_input_set_axis_range (hb_subset_input_t *input, hb_tag_t axis_tag, float axis_min_value, float axis_max_value, - float *axis_def_value /* IN, maybe NULL */) + float axis_def_value) { - if (axis_min_value > axis_max_value) - return false; - hb_ot_var_axis_info_t axis_info; if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) return false; - float new_min_val = hb_clamp(axis_min_value, axis_info.min_value, axis_info.max_value); - float new_max_val = hb_clamp(axis_max_value, axis_info.min_value, axis_info.max_value); - float new_default_val = axis_def_value ? *axis_def_value : axis_info.default_value; - new_default_val = hb_clamp(new_default_val, new_min_val, new_max_val); - return input->axes_location.set (axis_tag, Triple (new_min_val, new_default_val, new_max_val)); + float min = !std::isnan(axis_min_value) ? axis_min_value : axis_info.min_value; + float max = !std::isnan(axis_max_value) ? axis_max_value : axis_info.max_value; + float def = !std::isnan(axis_def_value) ? axis_def_value : axis_info.default_value; + + if (min > max) + return false; + + float new_min_val = hb_clamp(min, axis_info.min_value, axis_info.max_value); + float new_max_val = hb_clamp(max, axis_info.min_value, axis_info.max_value); + float new_default_val = hb_clamp(def, new_min_val, new_max_val); + return input->axes_location.set (axis_tag, Triple ((double) new_min_val, (double) new_default_val, (double) new_max_val)); +} + +/** + * hb_subset_input_get_axis_range: (skip) + * @input: a #hb_subset_input_t object. + * @axis_tag: Tag of the axis + * @axis_min_value: Set to the previously configured minimum value of the axis variation range. + * @axis_max_value: Set to the previously configured maximum value of the axis variation range. + * @axis_def_value: Set to the previously configured default value of the axis variation range. + * + * Gets the axis range assigned by previous calls to hb_subset_input_set_axis_range. + * + * Return value: `true` if a range has been set for this axis tag, `false` otherwise. + * + * Since: 8.5.0 + **/ +HB_EXTERN hb_bool_t +hb_subset_input_get_axis_range (hb_subset_input_t *input, + hb_tag_t axis_tag, + float *axis_min_value, + float *axis_max_value, + float *axis_def_value) + +{ + Triple* triple; + if (!input->axes_location.has(axis_tag, &triple)) { + return false; + } + + *axis_min_value = triple->minimum; + *axis_def_value = triple->middle; + *axis_max_value = triple->maximum; + return true; +} + +/** + * hb_subset_axis_range_from_string: + * @str: a string to parse + * @len: length of @str, or -1 if str is NULL terminated + * @axis_min_value: (out): the axis min value to initialize with the parsed value + * @axis_max_value: (out): the axis max value to initialize with the parsed value + * @axis_def_value: (out): the axis default value to initialize with the parse + * value + * + * Parses a string into a subset axis range(min, def, max). + * Axis positions string is in the format of min:def:max or min:max + * When parsing axis positions, empty values as meaning the existing value for that part + * E.g: :300:500 + * Specifies min = existing, def = 300, max = 500 + * In the output axis_range, if a value should be set to it's default value, + * then it will be set to NaN + * + * Return value: + * `true` if @str is successfully parsed, `false` otherwise + * + * Since: 10.2.0 + */ +HB_EXTERN hb_bool_t +hb_subset_axis_range_from_string (const char *str, int len, + float *axis_min_value, + float *axis_max_value, + float *axis_def_value) +{ + if (len < 0) + len = strlen (str); + + const char *end = str + len; + const char* part = strpbrk (str, ":"); + if (!part) + { + // Single value. + if (strcmp (str, "drop") == 0) + { + *axis_min_value = NAN; + *axis_def_value = NAN; + *axis_max_value = NAN; + return true; + } + + double v; + if (!hb_parse_double (&str, end, &v)) return false; + + *axis_min_value = v; + *axis_def_value = v; + *axis_max_value = v; + return true; + } + + float values[3]; + int count = 0; + for (int i = 0; i < 3; i++) { + count++; + if (!*str || part == str) + { + values[i] = NAN; + + if (part == NULL) break; + str = part + 1; + part = strpbrk (str, ":"); + continue; + } + + double v; + if (!hb_parse_double (&str, part, &v)) return false; + values[i] = v; + + if (part == NULL) break; + str = part + 1; + part = strpbrk (str, ":"); + } + + if (count == 2) + { + *axis_min_value = values[0]; + *axis_def_value = NAN; + *axis_max_value = values[1]; + return true; + } + else if (count == 3) + { + *axis_min_value = values[0]; + *axis_def_value = values[1]; + *axis_max_value = values[2]; + return true; + } + return false; +} + +/** + * hb_subset_axis_range_to_string: + * @input: a #hb_subset_input_t object. + * @axis_tag: an axis to convert + * @buf: (array length=size) (out caller-allocates): output string + * @size: the allocated size of @buf + * + * Converts an axis range into a `NULL`-terminated string in the format + * understood by hb_subset_axis_range_from_string(). The client in responsible for + * allocating big enough size for @buf, 128 bytes is more than enough. + * + * Since: 10.2.0 + */ +HB_EXTERN void +hb_subset_axis_range_to_string (hb_subset_input_t *input, + hb_tag_t axis_tag, + char *buf, unsigned size) +{ + if (unlikely (!size)) return; + Triple* triple; + if (!input->axes_location.has(axis_tag, &triple)) { + return; + } + + char s[128]; + unsigned len = 0; + + hb_locale_t clocale HB_UNUSED; + hb_locale_t oldlocale HB_UNUSED; + oldlocale = hb_uselocale (clocale = newlocale (LC_ALL_MASK, "C", NULL)); + len += hb_max (0, snprintf (s, ARRAY_LENGTH (s) - len, "%g", (double) triple->minimum)); + s[len++] = ':'; + + len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) triple->middle)); + s[len++] = ':'; + + len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) triple->maximum)); + (void) hb_uselocale (((void) freelocale (clocale), oldlocale)); + + assert (len < ARRAY_LENGTH (s)); + len = hb_min (len, size - 1); + hb_memcpy (buf, s, len); + buf[len] = '\0'; } -#endif #endif /** @@ -653,7 +868,7 @@ hb_subset_input_override_name_table (hb_subset_input_t *input, src = hb_utf8_t::next (src, src_end, &unicode, replacement); if (unicode >= 0x0080u) { - printf ("Non-ascii character detected, ignored...This API supports acsii characters only for mac platform\n"); + printf ("Non-ascii character detected, ignored...This API supports ascii characters only for mac platform\n"); return false; } } @@ -667,5 +882,4 @@ hb_subset_input_override_name_table (hb_subset_input_t *input, input->name_table_overrides.set (hb_ot_name_record_ids_t (platform_id, encoding_id, language_id, name_id), name_bytes); return true; } - #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh new file mode 100644 index 0000000000000..01987bd258dd5 --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh @@ -0,0 +1,37 @@ +/* + * Copyright © 2024 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_SUBSET_INSTANCER_IUP_HH +#define HB_SUBSET_INSTANCER_IUP_HH + +#include "hb-subset-plan.hh" +/* given contour points and deltas, optimize a set of referenced points within error + * tolerance. Returns optimized referenced point indices */ +HB_INTERNAL bool iup_delta_optimize (const contour_point_vector_t& contour_points, + const hb_vector_t& x_deltas, + const hb_vector_t& y_deltas, + hb_vector_t& opt_indices, /* OUT */ + double tolerance = 0.0); + +#endif /* HB_SUBSET_INSTANCER_IUP_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc index 8ec36e3e80dcc..c67fee421c204 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc @@ -32,17 +32,17 @@ * This should be safe. */ -constexpr static float EPSILON = 1.f / (1 << 14); -constexpr static float MAX_F2DOT14 = float (0x7FFF) / (1 << 14); +constexpr static double EPSILON = 1.0 / (1 << 14); +constexpr static double MAX_F2DOT14 = double (0x7FFF) / (1 << 14); static inline Triple _reverse_negate(const Triple &v) { return {-v.maximum, -v.middle, -v.minimum}; } -static inline float supportScalar (float coord, const Triple &tent) +static inline double supportScalar (double coord, const Triple &tent) { /* Copied from VarRegionAxis::evaluate() */ - float start = tent.minimum, peak = tent.middle, end = tent.maximum; + double start = tent.minimum, peak = tent.middle, end = tent.maximum; if (unlikely (start > peak || peak > end)) return 1.; @@ -62,20 +62,20 @@ static inline float supportScalar (float coord, const Triple &tent) return (end - coord) / (end - peak); } -static inline result_t +static inline rebase_tent_result_t _solve (Triple tent, Triple axisLimit, bool negative = false) { - float axisMin = axisLimit.minimum; - float axisDef = axisLimit.middle; - float axisMax = axisLimit.maximum; - float lower = tent.minimum; - float peak = tent.middle; - float upper = tent.maximum; + double axisMin = axisLimit.minimum; + double axisDef = axisLimit.middle; + double axisMax = axisLimit.maximum; + double lower = tent.minimum; + double peak = tent.middle; + double upper = tent.maximum; // Mirror the problem such that axisDef <= peak if (axisDef > peak) { - result_t vec = _solve (_reverse_negate (tent), + rebase_tent_result_t vec = _solve (_reverse_negate (tent), _reverse_negate (axisLimit), !negative); @@ -98,7 +98,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) * axisMin axisDef axisMax lower upper */ if (axisMax <= lower && axisMax < peak) - return result_t{}; // No overlap + return rebase_tent_result_t{}; // No overlap /* case 2: Only the peak and outermost bound fall outside the new limit; * we keep the deltaset, update peak and outermost bound and scale deltas @@ -130,10 +130,10 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) */ if (axisMax < peak) { - float mult = supportScalar (axisMax, tent); + double mult = supportScalar (axisMax, tent); tent = Triple{lower, axisMax, axisMax}; - result_t vec = _solve (tent, axisLimit); + rebase_tent_result_t vec = _solve (tent, axisLimit); for (auto &p : vec) p = hb_pair (p.first * mult, p.second); @@ -143,13 +143,13 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) // lower <= axisDef <= peak <= axisMax - float gain = supportScalar (axisDef, tent); - result_t out {hb_pair (gain, Triple{})}; + double gain = supportScalar (axisDef, tent); + rebase_tent_result_t out {hb_pair (gain, Triple{})}; // First, the positive side // outGain is the scalar of axisMax at the tent. - float outGain = supportScalar (axisMax, tent); + double outGain = supportScalar (axisMax, tent); /* Case 3a: Gain is more than outGain. The tent down-slope crosses * the axis into negative. We have to split it into multiples. @@ -168,13 +168,15 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) * | * crossing */ - if (gain > outGain) + if (gain >= outGain) { + // Note that this is the branch taken if both gain and outGain are 0. + // Crossing point on the axis. - float crossing = peak + (1 - gain) * (upper - peak); + double crossing = peak + (1 - gain) * (upper - peak); - Triple loc{axisDef, peak, crossing}; - float scalar = 1.f; + Triple loc{hb_max (lower, axisDef), peak, crossing}; + double scalar = 1.0; // The part before the crossing point. out.push (hb_pair (scalar - gain, loc)); @@ -189,7 +191,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) if (upper >= axisMax) { Triple loc {crossing, axisMax, axisMax}; - float scalar = outGain; + double scalar = outGain; out.push (hb_pair (scalar - gain, loc)); } @@ -219,11 +221,11 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) // Downslope. Triple loc1 {crossing, upper, axisMax}; - float scalar1 = 0.f; + double scalar1 = 0.0; // Eternity justify. Triple loc2 {upper, axisMax, axisMax}; - float scalar2 = 0.f; + double scalar2 = 0.0; out.push (hb_pair (scalar1 - gain, loc1)); out.push (hb_pair (scalar2 - gain, loc2)); @@ -252,9 +254,12 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) * | | newUpper * axisDef axisMax */ - float newUpper = peak + (1 - gain) * (upper - peak); - assert (axisMax <= newUpper); // Because outGain >= gain - if (newUpper <= axisDef + (axisMax - axisDef) * 2) + double newUpper = peak + (1 - gain) * (upper - peak); + assert (axisMax <= newUpper); // Because outGain > gain + /* Disabled because ots doesn't like us: + * https://github.com/fonttools/fonttools/issues/3350 */ + + if (false && (newUpper <= axisDef + (axisMax - axisDef) * 2)) { upper = newUpper; if (!negative && axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper) @@ -265,7 +270,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) } Triple loc {hb_max (axisDef, lower), peak, upper}; - float scalar = 1.f; + double scalar = 1.0; out.push (hb_pair (scalar - gain, loc)); } @@ -289,10 +294,10 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) else { Triple loc1 {hb_max (axisDef, lower), peak, axisMax}; - float scalar1 = 1.f; + double scalar1 = 1.0; Triple loc2 {peak, axisMax, axisMax}; - float scalar2 = outGain; + double scalar2 = outGain; out.push (hb_pair (scalar1 - gain, loc1)); // Don't add a dirac delta! @@ -320,7 +325,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) if (lower <= axisMin) { Triple loc {axisMin, axisMin, axisDef}; - float scalar = supportScalar (axisMin, tent); + double scalar = supportScalar (axisMin, tent); out.push (hb_pair (scalar - gain, loc)); } @@ -348,11 +353,11 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) // Downslope. Triple loc1 {axisMin, lower, axisDef}; - float scalar1 = 0.f; + double scalar1 = 0.0; // Eternity justify. Triple loc2 {axisMin, axisMin, lower}; - float scalar2 = 0.f; + double scalar2 = 0.0; out.push (hb_pair (scalar1 - gain, loc1)); out.push (hb_pair (scalar2 - gain, loc2)); @@ -364,19 +369,19 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) static inline TripleDistances _reverse_triple_distances (const TripleDistances &v) { return TripleDistances (v.positive, v.negative); } -float renormalizeValue (float v, const Triple &triple, - const TripleDistances &triple_distances, bool extrapolate) +double renormalizeValue (double v, const Triple &triple, + const TripleDistances &triple_distances, bool extrapolate) { - float lower = triple.minimum, def = triple.middle, upper = triple.maximum; + double lower = triple.minimum, def = triple.middle, upper = triple.maximum; assert (lower <= def && def <= upper); if (!extrapolate) - v = hb_max (hb_min (v, upper), lower); + v = hb_clamp (v, lower, upper); if (v == def) - return 0.f; + return 0.0; - if (def < 0.f) + if (def < 0.0) return -renormalizeValue (-v, _reverse_negate (triple), _reverse_triple_distances (triple_distances), extrapolate); @@ -385,14 +390,14 @@ float renormalizeValue (float v, const Triple &triple, return (v - def) / (upper - def); /* v < def */ - if (lower >= 0.f) + if (lower >= 0.0) return (v - def) / (def - lower); /* lower < 0 and v < default */ - float total_distance = triple_distances.negative * (-lower) + triple_distances.positive * def; + double total_distance = triple_distances.negative * (-lower) + triple_distances.positive * def; - float v_distance; - if (v >= 0.f) + double v_distance; + if (v >= 0.0) v_distance = (def - v) * triple_distances.positive; else v_distance = (-v) * triple_distances.negative + triple_distances.positive * def; @@ -400,18 +405,18 @@ float renormalizeValue (float v, const Triple &triple, return (-v_distance) /total_distance; } -result_t +rebase_tent_result_t rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances) { - assert (-1.f <= axisLimit.minimum && axisLimit.minimum <= axisLimit.middle && axisLimit.middle <= axisLimit.maximum && axisLimit.maximum <= +1.f); - assert (-2.f <= tent.minimum && tent.minimum <= tent.middle && tent.middle <= tent.maximum && tent.maximum <= +2.f); - assert (tent.middle != 0.f); + assert (-1.0 <= axisLimit.minimum && axisLimit.minimum <= axisLimit.middle && axisLimit.middle <= axisLimit.maximum && axisLimit.maximum <= +1.0); + assert (-2.0 <= tent.minimum && tent.minimum <= tent.middle && tent.middle <= tent.maximum && tent.maximum <= +2.0); + assert (tent.middle != 0.0); - result_t sols = _solve (tent, axisLimit); + rebase_tent_result_t sols = _solve (tent, axisLimit); - auto n = [&axisLimit, &axis_triple_distances] (float v) { return renormalizeValue (v, axisLimit, axis_triple_distances); }; + auto n = [&axisLimit, &axis_triple_distances] (double v) { return renormalizeValue (v, axisLimit, axis_triple_distances); }; - result_t out; + rebase_tent_result_t out; for (auto &p : sols) { if (!p.first) continue; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh index e8ca1dc4e6360..9764dcc1725b0 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh @@ -30,24 +30,24 @@ /* pre-normalized distances */ struct TripleDistances { - TripleDistances (): negative (1.f), positive (1.f) {} - TripleDistances (float neg_, float pos_): negative (neg_), positive (pos_) {} - TripleDistances (float min, float default_, float max) + TripleDistances (): negative (1.0), positive (1.0) {} + TripleDistances (double neg_, double pos_): negative (neg_), positive (pos_) {} + TripleDistances (double min, double default_, double max) { negative = default_ - min; positive = max - default_; } - float negative; - float positive; + double negative; + double positive; }; struct Triple { Triple () : - minimum (0.f), middle (0.f), maximum (0.f) {} + minimum (0.0), middle (0.0), maximum (0.0) {} - Triple (float minimum_, float middle_, float maximum_) : + Triple (double minimum_, double middle_, double maximum_) : minimum (minimum_), middle (middle_), maximum (maximum_) {} bool operator == (const Triple &o) const @@ -63,7 +63,7 @@ struct Triple { bool is_point () const { return minimum == middle && middle == maximum; } - bool contains (float point) const + bool contains (double point) const { return minimum <= point && point <= maximum; } /* from hb_array_t hash ()*/ @@ -82,18 +82,18 @@ struct Triple { } - float minimum; - float middle; - float maximum; + double minimum; + double middle; + double maximum; }; -using result_item_t = hb_pair_t; -using result_t = hb_vector_t; +using rebase_tent_result_item_t = hb_pair_t; +using rebase_tent_result_t = hb_vector_t; /* renormalize a normalized value v to the range of an axis, * considering the prenormalized distances as well as the new axis limits. * Ported from fonttools */ -HB_INTERNAL float renormalizeValue (float v, const Triple &triple, +HB_INTERNAL double renormalizeValue (double v, const Triple &triple, const TripleDistances &triple_distances, bool extrapolate = true); /* Given a tuple (lower,peak,upper) "tent" and new axis limits @@ -107,6 +107,8 @@ HB_INTERNAL float renormalizeValue (float v, const Triple &triple, * If tent value is Triple{}, that is a special deltaset that should * be always-enabled (called "gain"). */ -HB_INTERNAL result_t rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances); +HB_INTERNAL rebase_tent_result_t rebase_tent (Triple tent, + Triple axisLimit, + TripleDistances axis_triple_distances); #endif /* HB_SUBSET_INSTANCER_SOLVER_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh index 8bc1fcb56820e..ade8278c40fdd 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh @@ -70,6 +70,9 @@ HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset_colred) HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_lookups) HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_lookups) +//use_mark_sets mapping: old->new +HB_SUBSET_PLAN_MEMBER (hb_map_t, used_mark_sets_map) + //active langsys we'd like to retain HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gsub_langsys) HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpos_langsys) @@ -87,9 +90,24 @@ HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpo HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), gsub_feature_substitutes_map) HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), gpos_feature_substitutes_map) +// old feature_indexes set, used to reinstate the old features +HB_SUBSET_PLAN_MEMBER (hb_set_t, gsub_old_features) +HB_SUBSET_PLAN_MEMBER (hb_set_t, gpos_old_features) + +//feature_index->pair of (address of old feature, feature tag), used for inserting a catch all record +//if necessary +HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E()>), gsub_old_feature_idx_tag_map) +HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E()>), gpos_old_feature_idx_tag_map) + //active layers/palettes we'd like to retain HB_SUBSET_PLAN_MEMBER (hb_map_t, colrv1_layers) HB_SUBSET_PLAN_MEMBER (hb_map_t, colr_palettes) +//colrv1 varstore retained varidx mapping +HB_SUBSET_PLAN_MEMBER (hb_vector_t, colrv1_varstore_inner_maps) +//colrv1 retained varidx -> (new varidx, delta) mapping +HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E()>), colrv1_variation_idx_delta_map) +//colrv1 retained new delta set index -> new varidx mapping +HB_SUBSET_PLAN_MEMBER (hb_map_t, colrv1_new_deltaset_idx_varidx_map) //Old layout item variation index -> (New varidx, delta) mapping HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E()>), layout_variation_idx_delta_map) @@ -128,6 +146,15 @@ HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t, bounds_height_vec) //map: new_gid -> contour points vector HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(), new_gid_contour_points_map) +//new gids set for composite glyphs +HB_SUBSET_PLAN_MEMBER (hb_set_t, composite_new_gids) + +//Old BASE item variation index -> (New varidx, 0) mapping +HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E()>), base_variation_idx_map) + +//BASE table varstore retained varidx mapping +HB_SUBSET_PLAN_MEMBER (hb_vector_t, base_varstore_inner_maps) + #ifdef HB_EXPERIMENTAL_API // name table overrides map: hb_ot_name_record_ids_t-> name string new value or // None to indicate should remove diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc index b9cc4fd0bcd79..fb5282916b92c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc @@ -32,6 +32,7 @@ #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" +#include "hb-ot-layout-base-table.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-layout-gsub-table.hh" @@ -150,7 +151,8 @@ static void _collect_layout_indices (hb_subset_plan_t *plan, hb_set_t *feature_indices, /* OUT */ hb_hashmap_t> *feature_record_cond_idx_map, /* OUT */ hb_hashmap_t *feature_substitutes_map, /* OUT */ - bool& insert_catch_all_feature_variation_record) + hb_set_t& catch_all_record_feature_idxes, /* OUT */ + hb_hashmap_t>& catch_all_record_idx_feature_map /* OUT */) { unsigned num_features = table.get_feature_count (); hb_vector_t features; @@ -186,7 +188,7 @@ static void _collect_layout_indices (hb_subset_plan_t *plan, &plan->axes_location, feature_record_cond_idx_map, feature_substitutes_map, - insert_catch_all_feature_variation_record, + catch_all_record_feature_idxes, feature_indices, false, false, @@ -208,17 +210,25 @@ static void _collect_layout_indices (hb_subset_plan_t *plan, f->add_lookup_indexes_to (lookup_indices); } +#ifndef HB_NO_VAR + if (catch_all_record_feature_idxes) + { + for (unsigned feature_index : catch_all_record_feature_idxes) + { + const OT::Feature& f = table.get_feature (feature_index); + f.add_lookup_indexes_to (lookup_indices); + const void *tag = reinterpret_cast (&(table.get_feature_list ().get_tag (feature_index))); + catch_all_record_idx_feature_map.set (feature_index, hb_pair (&f, tag)); + } + } + // If all axes are pinned then all feature variations will be dropped so there's no need // to collect lookups from them. if (!plan->all_axes_pinned) - { - // TODO(qxliu76): this collection doesn't work correctly for feature variations that are dropped - // but not applied. The collection will collect and retain the lookup indices - // associated with those dropped but not activated rules. Since partial instancing - // isn't yet supported this isn't an issue yet but will need to be fixed for - // partial instancing. - table.feature_variation_collect_lookups (feature_indices, feature_substitutes_map, lookup_indices); - } + table.feature_variation_collect_lookups (feature_indices, + plan->user_axes_location.is_empty () ? nullptr: feature_record_cond_idx_map, + lookup_indices); +#endif } @@ -302,7 +312,8 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan, script_langsys_map *langsys_map, hb_hashmap_t> *feature_record_cond_idx_map, hb_hashmap_t *feature_substitutes_map, - bool& insert_catch_all_feature_variation_record) + hb_set_t &catch_all_record_feature_idxes, + hb_hashmap_t>& catch_all_record_idx_feature_map) { hb_blob_ptr_t table = plan->source_table (); hb_tag_t table_tag = table->tableTag; @@ -313,7 +324,8 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan, &feature_indices, feature_record_cond_idx_map, feature_substitutes_map, - insert_catch_all_feature_variation_record); + catch_all_record_feature_idxes, + catch_all_record_idx_feature_map); if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE)) hb_ot_layout_lookups_substitute_closure (plan->source, @@ -386,13 +398,56 @@ _get_hb_font_with_variations (const hb_subset_plan_t *plan) return font; } +static inline void +_remap_variation_indices (const OT::ItemVariationStore &var_store, + const hb_set_t &variation_indices, + const hb_vector_t& normalized_coords, + bool calculate_delta, /* not pinned at default */ + bool no_variations, /* all axes pinned */ + hb_hashmap_t> &variation_idx_delta_map /* OUT */) +{ + if (&var_store == &Null (OT::ItemVariationStore)) return; + unsigned subtable_count = var_store.get_sub_table_count (); + float *store_cache = var_store.create_cache (); + + unsigned new_major = 0, new_minor = 0; + unsigned last_major = (variation_indices.get_min ()) >> 16; + for (unsigned idx : variation_indices) + { + int delta = 0; + if (calculate_delta) + delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ, + normalized_coords.length, store_cache)); + + if (no_variations) + { + variation_idx_delta_map.set (idx, hb_pair_t (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); + continue; + } + + uint16_t major = idx >> 16; + if (major >= subtable_count) break; + if (major != last_major) + { + new_minor = 0; + ++new_major; + } + + unsigned new_idx = (new_major << 16) + new_minor; + variation_idx_delta_map.set (idx, hb_pair_t (new_idx, delta)); + ++new_minor; + last_major = major; + } + var_store.destroy_cache (store_cache); +} + static inline void _collect_layout_variation_indices (hb_subset_plan_t* plan) { hb_blob_ptr_t gdef = plan->source_table (); hb_blob_ptr_t gpos = plan->source_table (); - if (!gdef->has_data ()) + if (!gdef->has_data () || !gdef->has_var_store ()) { gdef.destroy (); gpos.destroy (); @@ -408,18 +463,47 @@ _collect_layout_variation_indices (hb_subset_plan_t* plan) if (hb_ot_layout_has_positioning (plan->source)) gpos->collect_variation_indices (&c); - gdef->remap_layout_variation_indices (&varidx_set, - plan->normalized_coords, - !plan->pinned_at_default, - plan->all_axes_pinned, - &plan->layout_variation_idx_delta_map); + _remap_variation_indices (gdef->get_var_store (), + varidx_set, plan->normalized_coords, + !plan->pinned_at_default, + plan->all_axes_pinned, + plan->layout_variation_idx_delta_map); - unsigned subtable_count = gdef->has_var_store () ? gdef->get_var_store ().get_sub_table_count () : 0; + unsigned subtable_count = gdef->get_var_store ().get_sub_table_count (); _generate_varstore_inner_maps (varidx_set, subtable_count, plan->gdef_varstore_inner_maps); gdef.destroy (); gpos.destroy (); } + +#ifndef HB_NO_BASE +static inline void +_collect_base_variation_indices (hb_subset_plan_t* plan) +{ + hb_blob_ptr_t base = plan->source_table (); + if (!base->has_var_store ()) + { + base.destroy (); + return; + } + + hb_set_t varidx_set; + base->collect_variation_indices (plan, varidx_set); + const OT::ItemVariationStore &var_store = base->get_var_store (); + unsigned subtable_count = var_store.get_sub_table_count (); + + + _remap_variation_indices (var_store, varidx_set, + plan->normalized_coords, + !plan->pinned_at_default, + plan->all_axes_pinned, + plan->base_variation_idx_map); + _generate_varstore_inner_maps (varidx_set, subtable_count, plan->base_varstore_inner_maps); + + base.destroy (); +} + +#endif #endif static inline void @@ -431,12 +515,45 @@ _cmap_closure (hb_face_t *face, cmap.table->closure_glyphs (unicodes, glyphset); } -static void _colr_closure (hb_face_t *face, - hb_map_t *layers_map, - hb_map_t *palettes_map, +#ifndef HB_NO_VAR +static void +_remap_colrv1_delta_set_index_indices (const OT::DeltaSetIndexMap &index_map, + const hb_set_t &delta_set_idxes, + hb_hashmap_t> &variation_idx_delta_map, /* IN/OUT */ + hb_map_t &new_deltaset_idx_varidx_map /* OUT */) +{ + if (!index_map.get_map_count ()) + return; + + hb_hashmap_t> delta_set_idx_delta_map; + unsigned new_delta_set_idx = 0; + for (unsigned delta_set_idx : delta_set_idxes) + { + unsigned var_idx = index_map.map (delta_set_idx); + unsigned new_varidx = HB_OT_LAYOUT_NO_VARIATIONS_INDEX; + int delta = 0; + + if (var_idx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) + { + hb_pair_t *new_varidx_delta; + if (!variation_idx_delta_map.has (var_idx, &new_varidx_delta)) continue; + + new_varidx = hb_first (*new_varidx_delta); + delta = hb_second (*new_varidx_delta); + } + + new_deltaset_idx_varidx_map.set (new_delta_set_idx, new_varidx); + delta_set_idx_delta_map.set (delta_set_idx, hb_pair_t (new_delta_set_idx, delta)); + new_delta_set_idx++; + } + variation_idx_delta_map = std::move (delta_set_idx_delta_map); +} +#endif + +static void _colr_closure (hb_subset_plan_t* plan, hb_set_t *glyphs_colred) { - OT::COLR::accelerator_t colr (face); + OT::COLR::accelerator_t colr (plan->source); if (!colr.is_valid ()) return; hb_set_t palette_indices, layer_indices; @@ -448,11 +565,45 @@ static void _colr_closure (hb_face_t *face, glyphs_colred->union_ (glyphset_colrv0); //closure for COLRv1 - colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices); + hb_set_t variation_indices, delta_set_indices; + colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices, &variation_indices, &delta_set_indices); colr.closure_V0palette_indices (glyphs_colred, &palette_indices); - _remap_indexes (&layer_indices, layers_map); - _remap_palette_indexes (&palette_indices, palettes_map); + _remap_indexes (&layer_indices, &plan->colrv1_layers); + _remap_palette_indexes (&palette_indices, &plan->colr_palettes); + +#ifndef HB_NO_VAR + if (!colr.has_var_store () || !variation_indices) return; + + const OT::ItemVariationStore &var_store = colr.get_var_store (); + // generated inner_maps is used by ItemVariationStore serialize(), which is subset only + unsigned subtable_count = var_store.get_sub_table_count (); + _generate_varstore_inner_maps (variation_indices, subtable_count, plan->colrv1_varstore_inner_maps); + + /* colr variation indices mapping during planning phase: + * generate colrv1_variation_idx_delta_map. When delta set index map is not + * included, it's a mapping from varIdx-> (new varIdx,delta). Otherwise, it's + * a mapping from old delta set idx-> (new delta set idx, delta). Mapping + * delta set indices is the same as gid mapping. + * Besides, we need to generate a delta set idx-> new var_idx map for updating + * delta set index map if exists. This map will be updated again after + * instancing. */ + if (!plan->all_axes_pinned) + { + _remap_variation_indices (var_store, + variation_indices, + plan->normalized_coords, + false, /* no need to calculate delta for COLR during planning */ + plan->all_axes_pinned, + plan->colrv1_variation_idx_delta_map); + + if (colr.has_delta_set_index_map ()) + _remap_colrv1_delta_set_index_indices (colr.get_delta_set_index_map (), + delta_set_indices, + plan->colrv1_variation_idx_delta_map, + plan->colrv1_new_deltaset_idx_varidx_map); + } +#endif } static inline void @@ -465,6 +616,24 @@ _math_closure (hb_subset_plan_t *plan, math.destroy (); } +static inline void +_remap_used_mark_sets (hb_subset_plan_t *plan, + hb_map_t& used_mark_sets_map) +{ + hb_blob_ptr_t gdef = plan->source_table (); + + if (!gdef->has_data () || !gdef->has_mark_glyph_sets ()) + { + gdef.destroy (); + return; + } + + hb_set_t used_mark_sets; + gdef->get_mark_glyph_sets ().collect_used_mark_sets (plan->_glyphset_gsub, used_mark_sets); + gdef.destroy (); + + _remap_indexes (&used_mark_sets, &used_mark_sets_map); +} static inline void _remove_invalid_gids (hb_set_t *glyphs, @@ -473,6 +642,36 @@ _remove_invalid_gids (hb_set_t *glyphs, glyphs->del_range (num_glyphs, HB_SET_VALUE_INVALID); } +template +static void +_fill_unicode_and_glyph_map(hb_subset_plan_t *plan, + I unicode_iterator, + F unicode_to_gid_for_iterator, + G unicode_to_gid_general) +{ + for (hb_codepoint_t cp : unicode_iterator) + { + hb_codepoint_t gid = unicode_to_gid_for_iterator(cp); + if (!GID_ALWAYS_EXISTS && gid == HB_MAP_VALUE_INVALID) + { + DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp); + continue; + } + + plan->codepoint_to_glyph->set (cp, gid); + plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); + } +} + +template +static void +_fill_unicode_and_glyph_map(hb_subset_plan_t *plan, + I unicode_iterator, + F unicode_to_gid_for_iterator) +{ + _fill_unicode_and_glyph_map(plan, unicode_iterator, unicode_to_gid_for_iterator, unicode_to_gid_for_iterator); +} + static void _populate_unicodes_to_retain (const hb_set_t *unicodes, const hb_set_t *glyphs, @@ -480,6 +679,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, { OT::cmap::accelerator_t cmap (plan->source); unsigned size_threshold = plan->source->get_num_glyphs (); + if (glyphs->is_empty () && unicodes->get_population () < size_threshold) { @@ -492,35 +692,21 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, // not excessively large (eg. an inverted set). plan->unicode_to_new_gid_list.alloc (unicodes->get_population ()); if (!unicode_to_gid) { - for (hb_codepoint_t cp : *unicodes) - { + _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { hb_codepoint_t gid; - if (!cmap.get_nominal_glyph (cp, &gid)) - { - DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp); - continue; + if (!cmap.get_nominal_glyph (cp, &gid)) { + return HB_MAP_VALUE_INVALID; } - - plan->codepoint_to_glyph->set (cp, gid); - plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); - } + return gid; + }); } else { // Use in memory unicode to gid map it's faster then looking up from // the map. This code is mostly duplicated from above to avoid doing // conditionals on the presence of the unicode_to_gid map each // iteration. - for (hb_codepoint_t cp : *unicodes) - { - hb_codepoint_t gid = unicode_to_gid->get (cp); - if (gid == HB_MAP_VALUE_INVALID) - { - DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp); - continue; - } - - plan->codepoint_to_glyph->set (cp, gid); - plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); - } + _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { + return unicode_to_gid->get (cp); + }); } } else @@ -550,42 +736,46 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, plan->codepoint_to_glyph->alloc (unicodes->get_population () + glyphs->get_population ()); auto &gid_to_unicodes = plan->accelerator->gid_to_unicodes; + for (hb_codepoint_t gid : *glyphs) { auto unicodes = gid_to_unicodes.get (gid); - - for (hb_codepoint_t cp : unicodes) - { - plan->codepoint_to_glyph->set (cp, gid); - plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); - } + _fill_unicode_and_glyph_map(plan, unicodes, [&] (hb_codepoint_t cp) { + return gid; + }, + [&] (hb_codepoint_t cp) { + return unicode_glyphid_map->get(cp); + }); } - for (hb_codepoint_t cp : *unicodes) - { - /* Don't double-add entry. */ + + _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { + /* Don't double-add entry. */ if (plan->codepoint_to_glyph->has (cp)) - continue; + return HB_MAP_VALUE_INVALID; - hb_codepoint_t *gid; - if (!unicode_glyphid_map->has(cp, &gid)) - continue; + return unicode_glyphid_map->get(cp); + }, + [&] (hb_codepoint_t cp) { + return unicode_glyphid_map->get(cp); + }); - plan->codepoint_to_glyph->set (cp, *gid); - plan->unicode_to_new_gid_list.push (hb_pair (cp, *gid)); - } plan->unicode_to_new_gid_list.qsort (); } else { plan->codepoint_to_glyph->alloc (cmap_unicodes->get_population ()); - for (hb_codepoint_t cp : *cmap_unicodes) + hb_codepoint_t first = HB_SET_VALUE_INVALID, last = HB_SET_VALUE_INVALID; + for (; cmap_unicodes->next_range (&first, &last); ) { - hb_codepoint_t gid = (*unicode_glyphid_map)[cp]; - if (!unicodes->has (cp) && !glyphs->has (gid)) - continue; - - plan->codepoint_to_glyph->set (cp, gid); - plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); + _fill_unicode_and_glyph_map(plan, hb_range(first, last + 1), [&] (hb_codepoint_t cp) { + hb_codepoint_t gid = (*unicode_glyphid_map)[cp]; + if (!unicodes->has (cp) && !glyphs->has (gid)) + return HB_MAP_VALUE_INVALID; + return gid; + }, + [&] (hb_codepoint_t cp) { + return unicode_glyphid_map->get(cp); + }); } } @@ -608,11 +798,22 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, plan->unicodes.add_sorted_array (&arr.arrayZ->first, arr.length, sizeof (*arr.arrayZ)); plan->_glyphset_gsub.add_array (&arr.arrayZ->second, arr.length, sizeof (*arr.arrayZ)); } -} -#ifndef HB_COMPOSITE_OPERATIONS_PER_GLYPH -#define HB_COMPOSITE_OPERATIONS_PER_GLYPH 64 -#endif + // Variation selectors don't have glyphs associated with them in the cmap so they will have been filtered out above + // but should still be retained. Add them back here. + + // However, the min and max codepoints for OS/2 should be calculated without considering variation selectors, + // so record those first. + plan->os2_info.min_cmap_codepoint = plan->unicodes.get_min(); + plan->os2_info.max_cmap_codepoint = plan->unicodes.get_max(); + + hb_set_t variation_selectors_to_retain; + cmap.collect_variation_selectors(&variation_selectors_to_retain); + + variation_selectors_to_retain.iter() + | hb_filter(unicodes) + | hb_sink(&plan->unicodes) + ; +} static unsigned _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf, @@ -639,18 +840,6 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf, operation_count, depth); -#ifndef HB_NO_VAR_COMPOSITES - for (auto &item : glyph.get_var_composite_iterator ()) - { - operation_count = - _glyf_add_gid_and_children (glyf, - item.get_gid (), - gids_to_retain, - operation_count, - depth); - } -#endif - return operation_count; } @@ -714,7 +903,8 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, &plan->gsub_langsys, &plan->gsub_feature_record_cond_idx_map, &plan->gsub_feature_substitutes_map, - plan->gsub_insert_catch_all_feature_variation_rec); + plan->gsub_old_features, + plan->gsub_old_feature_idx_tag_map); if (!drop_tables->has (HB_OT_TAG_GPOS)) _closure_glyphs_lookups_features ( @@ -725,7 +915,8 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, &plan->gpos_langsys, &plan->gpos_feature_record_cond_idx_map, &plan->gpos_feature_substitutes_map, - plan->gpos_insert_catch_all_feature_variation_rec); + plan->gpos_old_features, + plan->gpos_old_feature_idx_tag_map); #endif _remove_invalid_gids (&plan->_glyphset_gsub, plan->source->get_num_glyphs ()); @@ -739,19 +930,21 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, hb_set_t cur_glyphset = plan->_glyphset_mathed; if (!drop_tables->has (HB_OT_TAG_COLR)) { - _colr_closure (plan->source, &plan->colrv1_layers, &plan->colr_palettes, &cur_glyphset); + _colr_closure (plan, &cur_glyphset); _remove_invalid_gids (&cur_glyphset, plan->source->get_num_glyphs ()); } plan->_glyphset_colred = cur_glyphset; + // XXX TODO VARC closure / subset + _nameid_closure (plan, drop_tables); /* Populate a full set of glyphs to retain by adding all referenced * composite glyphs. */ if (glyf.has_data ()) for (hb_codepoint_t gid : cur_glyphset) _glyf_add_gid_and_children (glyf, gid, &plan->_glyphset, - cur_glyphset.get_population () * HB_COMPOSITE_OPERATIONS_PER_GLYPH); + cur_glyphset.get_population () * HB_MAX_COMPOSITE_OPERATIONS_PER_GLYPH); else plan->_glyphset.union_ (cur_glyphset); #ifndef HB_NO_SUBSET_CFF @@ -871,9 +1064,11 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, *num_glyphs = max_glyph + 1; } + reverse_glyph_map->alloc (reverse_glyph_map->get_population () + new_to_old_gid_list->length); + hb_iter (new_to_old_gid_list) | hb_sink (reverse_glyph_map) ; + glyph_map->alloc (glyph_map->get_population () + new_to_old_gid_list->length); + hb_iter (new_to_old_gid_list) | hb_map (&hb_codepoint_pair_t::reverse) | hb_sink (glyph_map) @@ -932,9 +1127,9 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) normalized_default = seg_maps->map (normalized_default); normalized_max = seg_maps->map (normalized_max); } - plan->axes_location.set (axis_tag, Triple (static_cast (normalized_min / 16384.f), - static_cast (normalized_default / 16384.f), - static_cast (normalized_max / 16384.f))); + plan->axes_location.set (axis_tag, Triple (static_cast (normalized_min / 16384.0), + static_cast (normalized_default / 16384.0), + static_cast (normalized_max / 16384.0))); if (normalized_default != 0) plan->pinned_at_default = false; @@ -957,8 +1152,8 @@ _update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) OT::cff2::accelerator_t cff2 (plan->source); if (!cff2.is_valid ()) return; - hb_font_t *font = nullptr; - if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan)))) + hb_font_t *font = _get_hb_font_with_variations (plan); + if (unlikely (!plan->check_success (font != nullptr))) { hb_font_destroy (font); return; @@ -1036,8 +1231,8 @@ _update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) static bool _get_instance_glyphs_contour_points (hb_subset_plan_t *plan) { - /* contour_points vector only needed for updating gvar table (infer delta) - * during partial instancing */ + /* contour_points vector only needed for updating gvar table (infer delta and + * iup delta optimization) during partial instancing */ if (plan->user_axes_location.is_empty () || plan->all_axes_pinned) return true; @@ -1055,10 +1250,15 @@ _get_instance_glyphs_contour_points (hb_subset_plan_t *plan) } hb_codepoint_t old_gid = _.second; - if (unlikely (!glyf.glyph_for_gid (old_gid).get_all_points_without_var (plan->source, all_points))) + auto glyph = glyf.glyph_for_gid (old_gid); + if (unlikely (!glyph.get_all_points_without_var (plan->source, all_points))) return false; if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) return false; + + /* composite new gids are only needed by iup delta optimization */ + if ((plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS) && glyph.is_composite ()) + plan->composite_new_gids.add (new_gid); } return true; } @@ -1093,6 +1293,7 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, user_axes_location = input->axes_location; all_axes_pinned = false; pinned_at_default = true; + has_gdef_varstore = false; #ifdef HB_EXPERIMENTAL_API for (auto _ : input->name_table_overrides) @@ -1112,6 +1313,10 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, attach_accelerator_data = input->attach_accelerator_data; force_long_loca = input->force_long_loca; +#ifdef HB_EXPERIMENTAL_API + force_long_loca = force_long_loca || (flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS); +#endif + if (accel) accelerator = (hb_subset_accelerator_t*) accel; @@ -1160,6 +1365,16 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, for (auto &v : bounds_height_vec) v = 0xFFFFFFFF; + if (!drop_tables.has (HB_OT_TAG_GDEF)) + _remap_used_mark_sets (this, used_mark_sets_map); + +#ifndef HB_NO_VAR +#ifndef HB_NO_BASE + if (!drop_tables.has (HB_OT_TAG_BASE)) + _collect_base_variation_indices (this); +#endif +#endif + if (unlikely (in_error ())) return; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh index 40a6ff112af93..a6bae23966a79 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh @@ -41,6 +41,13 @@ namespace OT { struct Feature; } +struct os2_info_t { + hb_codepoint_t min_cmap_codepoint; + hb_codepoint_t max_cmap_codepoint; +}; + +typedef struct os2_info_t os2_info_t; + struct head_maxp_info_t { head_maxp_info_t () @@ -78,10 +85,16 @@ struct contour_point_t y = x * matrix[1] + y * matrix[3]; x = x_; } + + void add_delta (float delta_x, float delta_y) + { + x += delta_x; + y += delta_y; + } + HB_ALWAYS_INLINE void translate (const contour_point_t &p) { x += p.x; y += p.y; } - float x; float y; uint8_t flag; @@ -90,14 +103,20 @@ struct contour_point_t struct contour_point_vector_t : hb_vector_t { - void extend (const hb_array_t &a) + bool add_deltas (hb_array_t deltas_x, + hb_array_t deltas_y, + hb_array_t indices) { - unsigned int old_len = length; - if (unlikely (!resize (old_len + a.length, false))) - return; - auto arrayZ = this->arrayZ + old_len; - unsigned count = a.length; - hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0])); + if (indices.length != deltas_x.length || + indices.length != deltas_y.length) + return false; + + for (unsigned i = 0; i < indices.length; i++) + { + if (!indices.arrayZ[i]) continue; + arrayZ[i].add_delta (deltas_x.arrayZ[i], deltas_y.arrayZ[i]); + } + return true; } }; @@ -147,6 +166,9 @@ struct hb_subset_plan_t bool gsub_insert_catch_all_feature_variation_rec; bool gpos_insert_catch_all_feature_variation_rec; + // whether GDEF ItemVariationStore is retained + mutable bool has_gdef_varstore; + #define HB_SUBSET_PLAN_MEMBER(Type, Name) Type Name; #include "hb-subset-plan-member-list.hh" #undef HB_SUBSET_PLAN_MEMBER @@ -154,6 +176,8 @@ struct hb_subset_plan_t //recalculated head/maxp table info after instancing mutable head_maxp_info_t head_maxp_info; + os2_info_t os2_info; + const hb_subset_accelerator_t* accelerator; hb_subset_accelerator_t* inprogress_accelerator; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-serialize.h b/src/java.desktop/share/native/libharfbuzz/hb-subset-serialize.h new file mode 100644 index 0000000000000..9035d4ced7a1e --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-serialize.h @@ -0,0 +1,83 @@ +/* + * Copyright © 2022 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + */ + +#ifndef HB_SUBSET_SERIALIZE_H +#define HB_SUBSET_SERIALIZE_H + +#include "hb.h" + +HB_BEGIN_DECLS + +/** + * hb_subset_serialize_link_t: + * @width: offsetSize in bytes + * @position: position of the offset field in bytes from + * beginning of subtable + * @objidx: index of subtable + * + * Represents a link between two objects in the object graph + * to be serialized. + * + * Since: 10.2.0 + */ +typedef struct hb_subset_serialize_link_t { + unsigned int width; + unsigned int position; + unsigned int objidx; +} hb_subset_serialize_link_t; + +/** + * hb_subset_serialize_object_t: + * @head: start of object data + * @tail: end of object data + * @num_real_links: number of offset field in the object + * @real_links: array of offset info + * @num_virtual_links: number of objects that must be packed + * after current object in the final + * serialized order + * @virtual_links: array of virtual link info + * + * Represents an object in the object graph to be serialized. + * + * Since: 10.2.0 + */ +typedef struct hb_subset_serialize_object_t { + char *head; + char *tail; + unsigned int num_real_links; + hb_subset_serialize_link_t *real_links; + unsigned int num_virtual_links; + hb_subset_serialize_link_t *virtual_links; +} hb_subset_serialize_object_t; + +HB_EXTERN hb_blob_t * +hb_subset_serialize_or_fail (hb_tag_t table_tag, + hb_subset_serialize_object_t *hb_objects, + unsigned num_hb_objs); + + +HB_END_DECLS + +#endif /* HB_SUBSET_SERIALIZE_H */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset.cc index c125a435b2b7b..595cafc283eee 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.cc @@ -48,6 +48,7 @@ #include "hb-ot-cff2-table.hh" #include "hb-ot-vorg-table.hh" #include "hb-ot-name-table.hh" +#include "hb-ot-layout-base-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-var-avar-table.hh" @@ -294,8 +295,8 @@ _try_subset (const TableType *table, DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (c->table_tag), buf_size); - if (unlikely (buf_size > c->source_blob->length * 16 || - !buf->alloc (buf_size, true))) + if (unlikely (buf_size > c->source_blob->length * 256 || + !buf->alloc_exact (buf_size))) { DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (c->table_tag), buf_size); @@ -460,9 +461,10 @@ _dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag, case HB_OT_TAG_hmtx: case HB_OT_TAG_vmtx: case HB_OT_TAG_maxp: + case HB_OT_TAG_OS2: return !plan->normalized_coords || !pending_subset_tags.has (HB_OT_TAG_glyf); case HB_OT_TAG_GPOS: - return !plan->normalized_coords || plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF); + return plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF); default: return true; } @@ -502,6 +504,7 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_CBLC: return _subset (plan, buf); case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */ case HB_OT_TAG_MATH: return _subset (plan, buf); + case HB_OT_TAG_BASE: return _subset (plan, buf); #ifndef HB_NO_SUBSET_CFF case HB_OT_TAG_CFF1: return _subset (plan, buf); @@ -547,6 +550,7 @@ _subset_table (hb_subset_plan_t *plan, } #endif return _passthrough (plan, tag); + default: if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) return _passthrough (plan, tag); @@ -590,14 +594,20 @@ static void _attach_accelerator_data (hb_subset_plan_t* plan, * @input: input to use for the subsetting. * * Subsets a font according to provided input. Returns nullptr - * if the subset operation fails. + * if the subset operation fails or the face has no glyphs. * * Since: 2.9.0 **/ hb_face_t * hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input) { - if (unlikely (!input || !source)) return hb_face_get_empty (); + if (unlikely (!input || !source)) return nullptr; + + if (unlikely (!source->get_num_glyphs ())) + { + DEBUG_MSG (SUBSET, nullptr, "No glyphs in source font."); + return nullptr; + } hb_subset_plan_t *plan = hb_subset_plan_create_or_fail (source, input); if (unlikely (!plan)) { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.h b/src/java.desktop/share/native/libharfbuzz/hb-subset.h index 8ea24da41b94f..13fcd5332e6b8 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.h @@ -73,6 +73,11 @@ typedef struct hb_subset_plan_t hb_subset_plan_t; * OS/2 will not be recalculated. * @HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE: If set don't perform glyph closure on layout * substitution rules (GSUB). Since: 7.2.0. + * @HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS: If set perform IUP delta optimization on the + * remaining gvar table's deltas. Since: 8.5.0 + * @HB_SUBSET_FLAGS_IFTB_REQUIREMENTS: If set enforce requirements on the output subset + * to allow it to be used with incremental font transfer IFTB patches. Primarily, + * this forces all outline data to use long (32 bit) offsets. Since: EXPERIMENTAL * * List of boolean properties that can be configured on the subset input. * @@ -90,6 +95,10 @@ typedef enum { /*< flags >*/ HB_SUBSET_FLAGS_GLYPH_NAMES = 0x00000080u, HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES = 0x00000100u, HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE = 0x00000200u, + HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS = 0x00000400u, +#ifdef HB_EXPERIMENTAL_API + HB_SUBSET_FLAGS_IFTB_REQUIREMENTS = 0x00000800u, +#endif } hb_subset_flags_t; /** @@ -164,6 +173,10 @@ HB_EXTERN void hb_subset_input_set_flags (hb_subset_input_t *input, unsigned value); +HB_EXTERN hb_bool_t +hb_subset_input_pin_all_axes_to_default (hb_subset_input_t *input, + hb_face_t *face); + HB_EXTERN hb_bool_t hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, hb_face_t *face, @@ -175,15 +188,34 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, hb_tag_t axis_tag, float axis_value); -#ifdef HB_EXPERIMENTAL_API +HB_EXTERN hb_bool_t +hb_subset_input_get_axis_range (hb_subset_input_t *input, + hb_tag_t axis_tag, + float *axis_min_value, + float *axis_max_value, + float *axis_def_value); + HB_EXTERN hb_bool_t hb_subset_input_set_axis_range (hb_subset_input_t *input, hb_face_t *face, hb_tag_t axis_tag, float axis_min_value, float axis_max_value, - float *axis_def_value); + float axis_def_value); + +HB_EXTERN hb_bool_t +hb_subset_axis_range_from_string (const char *str, int len, + float *axis_min_value, + float *axis_max_value, + float *axis_def_value); +HB_EXTERN void +hb_subset_axis_range_to_string (hb_subset_input_t *input, + hb_tag_t axis_tag, + char *buf, + unsigned size); + +#ifdef HB_EXPERIMENTAL_API HB_EXTERN hb_bool_t hb_subset_input_override_name_table (hb_subset_input_t *input, hb_ot_name_id_t name_id, @@ -192,7 +224,6 @@ hb_subset_input_override_name_table (hb_subset_input_t *input, unsigned language_id, const char *name_str, int str_len); - #endif HB_EXTERN hb_face_t * diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh index 8d3807a80f0cd..8731a0bcf8d72 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh @@ -4,7 +4,7 @@ * * ./gen-ucd-table.py ucd.nounihan.grouped.xml * - * on file with this description: Unicode 15.1.0 + * on file with this description: Unicode 16.0.0 */ #ifndef HB_UCD_TABLE_HH @@ -13,7 +13,7 @@ #include "hb.hh" static const hb_script_t -_hb_ucd_sc_map[165] = +_hb_ucd_sc_map[172] = { HB_SCRIPT_COMMON, HB_SCRIPT_INHERITED, HB_SCRIPT_UNKNOWN, HB_SCRIPT_ARABIC, @@ -97,7 +97,10 @@ _hb_ucd_sc_map[165] = HB_SCRIPT_OLD_UYGHUR, HB_SCRIPT_TANGSA, HB_SCRIPT_TOTO, HB_SCRIPT_VITHKUQI, HB_SCRIPT_MATH, HB_SCRIPT_KAWI, - HB_SCRIPT_NAG_MUNDARI, + HB_SCRIPT_NAG_MUNDARI, HB_SCRIPT_GARAY, + HB_SCRIPT_GURUNG_KHEMA, HB_SCRIPT_KIRAT_RAI, + HB_SCRIPT_OL_ONAL, HB_SCRIPT_SUNUWAR, + HB_SCRIPT_TODHRI, HB_SCRIPT_TULU_TIGALARI, }; static const uint16_t _hb_ucd_dm1_p0_map[825] = @@ -868,7 +871,7 @@ _hb_ucd_dm2_u32_map[638] = HB_CODEPOINT_ENCODE3_11_7_14 (0x04E9u, 0x0308u, 0x04EBu), }; static const uint64_t -_hb_ucd_dm2_u64_map[388] = +_hb_ucd_dm2_u64_map[408] = { HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B8u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D1u, 0x05BCu, 0x0000u), @@ -1051,13 +1054,23 @@ _hb_ucd_dm2_u64_map[388] = HB_CODEPOINT_ENCODE3 (0x30F0u, 0x3099u, 0x30F8u), HB_CODEPOINT_ENCODE3 (0x30F1u, 0x3099u, 0x30F9u), HB_CODEPOINT_ENCODE3 (0x30F2u, 0x3099u, 0x30FAu), HB_CODEPOINT_ENCODE3 (0x30FDu, 0x3099u, 0x30FEu), HB_CODEPOINT_ENCODE3 (0xFB49u, 0x05C1u, 0x0000u), HB_CODEPOINT_ENCODE3 (0xFB49u, 0x05C2u, 0x0000u), + HB_CODEPOINT_ENCODE3 (0x105D2u, 0x0307u, 0x105C9u), HB_CODEPOINT_ENCODE3 (0x105DAu, 0x0307u, 0x105E4u), HB_CODEPOINT_ENCODE3 (0x11099u, 0x110BAu, 0x1109Au),HB_CODEPOINT_ENCODE3 (0x1109Bu, 0x110BAu, 0x1109Cu), HB_CODEPOINT_ENCODE3 (0x110A5u, 0x110BAu, 0x110ABu),HB_CODEPOINT_ENCODE3 (0x11131u, 0x11127u, 0x1112Eu), HB_CODEPOINT_ENCODE3 (0x11132u, 0x11127u, 0x1112Fu),HB_CODEPOINT_ENCODE3 (0x11347u, 0x1133Eu, 0x1134Bu), - HB_CODEPOINT_ENCODE3 (0x11347u, 0x11357u, 0x1134Cu),HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114B0u, 0x114BCu), - HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BAu, 0x114BBu),HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BDu, 0x114BEu), - HB_CODEPOINT_ENCODE3 (0x115B8u, 0x115AFu, 0x115BAu),HB_CODEPOINT_ENCODE3 (0x115B9u, 0x115AFu, 0x115BBu), - HB_CODEPOINT_ENCODE3 (0x11935u, 0x11930u, 0x11938u), HB_CODEPOINT_ENCODE3 (0x1D157u, 0x1D165u, 0x0000u), + HB_CODEPOINT_ENCODE3 (0x11347u, 0x11357u, 0x1134Cu),HB_CODEPOINT_ENCODE3 (0x11382u, 0x113C9u, 0x11383u), + HB_CODEPOINT_ENCODE3 (0x11384u, 0x113BBu, 0x11385u),HB_CODEPOINT_ENCODE3 (0x1138Bu, 0x113C2u, 0x1138Eu), + HB_CODEPOINT_ENCODE3 (0x11390u, 0x113C9u, 0x11391u),HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113B8u, 0x113C7u), + HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113C2u, 0x113C5u),HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113C9u, 0x113C8u), + HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114B0u, 0x114BCu),HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BAu, 0x114BBu), + HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BDu, 0x114BEu),HB_CODEPOINT_ENCODE3 (0x115B8u, 0x115AFu, 0x115BAu), + HB_CODEPOINT_ENCODE3 (0x115B9u, 0x115AFu, 0x115BBu),HB_CODEPOINT_ENCODE3 (0x11935u, 0x11930u, 0x11938u), + HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x1611Eu, 0x16121u),HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x1611Fu, 0x16123u), + HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x16120u, 0x16125u),HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x16129u, 0x16122u), + HB_CODEPOINT_ENCODE3 (0x16121u, 0x1611Fu, 0x16126u),HB_CODEPOINT_ENCODE3 (0x16121u, 0x16120u, 0x16128u), + HB_CODEPOINT_ENCODE3 (0x16122u, 0x1611Fu, 0x16127u),HB_CODEPOINT_ENCODE3 (0x16129u, 0x1611Fu, 0x16124u), + HB_CODEPOINT_ENCODE3 (0x16D63u, 0x16D67u, 0x16D69u),HB_CODEPOINT_ENCODE3 (0x16D67u, 0x16D67u, 0x16D68u), + HB_CODEPOINT_ENCODE3 (0x16D69u, 0x16D67u, 0x16D6Au), HB_CODEPOINT_ENCODE3 (0x1D157u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D158u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Fu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D170u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D171u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D172u, 0x0000u), @@ -1069,90 +1082,59 @@ _hb_ucd_dm2_u64_map[388] = #ifndef HB_OPTIMIZE_SIZE static const uint8_t -_hb_ucd_u8[17884] = +_hb_ucd_u8[17612] = { - 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 11, 12, 13, 13, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 22, 22, 22, 22, 24, 7, 7, - 25, 26, 22, 22, 22, 27, 28, 29, 22, 30, 31, 32, 33, 34, 35, 36, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 22, 42, - 7, 7, 43, 7, 44, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 45, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 46, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 47, + 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 5, 5, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 5, 17, 15, 18, 19, 20, 21, 22, 23, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 25, 26, 5, 27, 28, + 5, 29, 30, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 31, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 32, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 33, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 34, 35, 36, 37, 38, 39, 34, 34, 34, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 64, 65, 66, 67, 68, 69, 70, 71, 69, 72, 73, - 69, 69, 64, 74, 64, 64, 75, 76, 77, 78, 79, 80, 81, 82, 69, 83, - 84, 85, 86, 87, 88, 89, 69, 69, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 90, 34, 34, 34, 34, - 91, 34, 34, 34, 34, 34, 34, 34, 34, 92, 34, 34, 93, 94, 95, 96, - 97, 98, 99,100,101,102,103,104, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,105, - 106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, - 107,107, 34, 34,108,109,110,111, 34, 34,112,113,114,115,116,117, - 118,119,120,121,122,123,124,125,126,127,128,129, 34, 34,130,131, - 132,133,134,135,136,137,138,139,140,141,142,122,143,144,145,146, - 147,148,149,150,151,152,153,122,154,155,122,156,157,158,159,122, - 160,161,162,163,164,165,166,122,167,168,169,170,122,171,172,173, - 34, 34, 34, 34, 34, 34, 34,174,175, 34,176,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,177, - 34, 34, 34, 34, 34, 34, 34, 34,178,122,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122, 34, 34, 34, 34,179,122,122,122, - 34, 34, 34, 34,180,181,182,183,122,122,122,122,184,185,186,187, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,188, - 34, 34, 34, 34, 34, 34, 34, 34, 34,189,190,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,191, - 34, 34,192, 34, 34,193,122,122,122,122,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122,194,195,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,196,197, - 69,198,199,200,201,202,203,122,204,205,206,207,208,209,210,211, - 69, 69, 69, 69,212,213,122,122,122,122,122,122,122,122,214,122, - 215,216,217,122,122,218,122,122,122,219,122,122,122,122,122,220, - 34,221,222,122,122,122,122,122,223,224,225,122,226,227,122,122, - 228,229,230,231,232,122, 69,233, 69, 69, 69, 69, 69,234,235,236, - 237,238, 69, 69,239,240, 69,241,122,122,122,122,122,122,122,122, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,242, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,243, 34, - 244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,245, 34, 34, - 34, 34, 34, 34, 34, 34, 34,246, 34, 34, 34, 34,247,122,122,122, - 34, 34, 34, 34,248,122,122,122,122,122,122,122,122,122,122,122, - 34, 34, 34, 34, 34, 34,249, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34,250,122,122,122,122,122,122,122,122, - 251,122,252,253,122,122,122,122,122,122,122,122,122,122,122,122, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,254, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,255, + 16, 17, 18, 19, 20, 17, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 33, 41, 42, 43, 44, 45, + 46, 47, 48, 39, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 50, 17, 17, 17, 51, 17, 52, 53, 54, 55, 56, 57, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 58, 59, 59, 59, 59, 59, 59, 59, 59, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 17, 61, 62, 17, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 17, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 17, 17, 17, 97, 98, 99,100,100,100,100,100,100,100,100,100,101, + 17, 17, 17, 17,102, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17,103, 17, 17,104,100,100,100,100,100,100,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,105,100,100,100,100,100,100, 17, 17,106,107,100,108,109,110, + 17, 17, 17, 17, 17, 17, 17,111, 17, 17, 17, 17,112,113,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,114, + 17,115,116,100,100,100,100,100,100,100,100,100,117,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,118, 39,119,120, + 121,122,123,124,125,126,127,128, 39, 39,129,100,100,100,100,130, + 131,132,133,100,134,135,100,136,137,138,100,100,139,140,141,100, + 142,143,144,145, 39, 39,146,147,148, 39,149,150,100,100,100,100, + 17, 17, 17, 17, 17, 17,151, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17,152,153, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,154, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,155, 17, 17,156,100, + 100,100,100,100,100,100,100,100, 17, 17,157,100,100,100,100,100, + 17, 17, 17,158, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17,159,100,100,100,100,100,100,100,100,100,100,100,100, + 160,161,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,162, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,163, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, @@ -1189,7 +1171,7 @@ _hb_ucd_u8[17884] = 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, - 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 44, 43, 43, 43, 43, + 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 57, 43, 43, 43, 43, 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43, 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86, 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36, @@ -1262,13 +1244,13 @@ _hb_ucd_u8[17884] = 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57, 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109, 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36, - 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 44, - 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 64, + 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 2, + 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 2, 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36, 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2, 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2, 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 16, 16, 16, 16,110, 44, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, + 16, 16, 16, 16, 34,110, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43, 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44, 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16, @@ -1296,33 +1278,33 @@ _hb_ucd_u8[17884] = 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67, 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, - 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 92, 44, 44, 27, 27, 27, 27, 27, 27, 67, 67, - 67, 67, 67, 67, 67, 27, 27, 27, 67, 67, 67, 26, 67, 67, 67, 67, - 26, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, 8, 8, - 67, 67, 67, 67, 67, 67, 67, 26, 67, 67, 67, 67, 4, 4, 4, 4, - 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, - 8, 8,129,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, - 8,129,148,148,148,148,148,148,148,148,148,148,147, 8, 8, 8, - 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, - 8, 8,144, 26, 8, 8,144, 67, 67, 67, 44, 67, 67, 67, 67, 67, - 67, 67, 67, 55, 67, 67, 67, 67, 32, 11, 32, 34, 34, 34, 34, 11, - 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,140, 67, 67,138, 34,149, - 43, 32, 44, 44, 93, 2, 99, 2, 16, 16, 16,150, 44, 44,150, 44, - 36, 36, 36, 36, 44, 44, 44, 52, 64, 44, 44, 44, 44, 44, 44, 57, - 36, 36, 36, 61, 44, 44, 44, 44, 36, 36, 36, 61, 36, 36, 36, 61, - 2,121,121, 2,125,126,121, 2, 2, 2, 2, 6, 2,108,121, 2, - 121, 4, 4, 4, 4, 2, 2, 88, 2, 2, 2, 2, 2,120, 2, 2, - 108,151, 2, 2, 2, 2, 2, 2, 67, 2,152,148,148,148,153, 44, - 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 44, 44, 44, 44, 44, 1, 2,154,155, 4, 4, 4, 4, - 4, 67, 4, 4, 4, 4,156,157,158,105,105,105,105, 43, 43, 86, - 159, 40, 40, 67,105,160, 63, 67, 36, 36, 36, 61, 57,161,162, 69, - 36, 36, 36, 36, 36, 63, 40, 69, 44, 44, 62, 36, 36, 36, 36, 36, - 67, 27, 27, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 44, 55, - 67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67, - 67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, - 36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164, 2, + 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, + 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, + 67, 67, 67, 26, 67, 67, 67, 67, 26, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 26, + 67, 67, 67, 67, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, + 27, 27, 67, 67, 67, 67, 67, 67, 8, 8,129,147, 8, 8, 8, 8, + 8, 8, 8, 4, 4, 4, 4, 4, 8,129,148,148,148,148,148,148, + 148,148,148,148,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, + 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,144, 26, 8, 8,144, 67, + 67, 67, 44, 67, 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, + 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, + 32, 32,140, 67, 67,138, 34,149, 43, 32, 44, 44, 93, 2, 99, 2, + 16, 16, 16,150, 44, 44,150, 44, 36, 36, 36, 36, 44, 44, 44, 52, + 64, 44, 44, 44, 44, 44, 44, 57, 36, 36, 36, 61, 44, 44, 44, 44, + 36, 36, 36, 61, 36, 36, 36, 61, 2,121,121, 2,125,126,121, 2, + 2, 2, 2, 6, 2,108,121, 2,121, 4, 4, 4, 4, 2, 2, 88, + 2, 2, 2, 2, 2,120, 2, 2,108,151, 2, 2, 2, 2, 2, 2, + 67, 2,152,148,148,148,153, 44, 67, 67, 67, 67, 67, 55, 67, 67, + 67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44, + 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, + 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, + 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, + 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, + 67, 67, 67, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, 92, + 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, + 163, 27, 27, 27, 27, 27, 27, 27, 36, 36, 83, 36, 36, 36, 36, 36, + 67, 67, 67, 92, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36,164, 2, 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70, 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43, 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44, @@ -1330,7 +1312,7 @@ _hb_ucd_u8[17884] = 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, - 32, 32, 11, 11, 34,110, 44, 44, 32,150,150, 32, 32, 44, 44, 44, + 32, 32, 11, 11, 34, 34, 32, 44, 32,150,150, 32, 32, 32, 47, 44, 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44, 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36, @@ -1391,8 +1373,10 @@ _hb_ucd_u8[17884] = 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44, 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, - 27, 27, 27, 27, 27, 27, 27,100, 36, 36, 36, 36, 36, 57,184, 44, - 36, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 57, 43, + 7, 7, 7, 7, 7, 36, 36, 69, 11, 11, 11, 44, 57, 43, 43,159, + 16, 16, 16, 44, 44, 44, 44, 8, 27, 27, 27, 27, 27, 27, 27,100, + 36, 36, 36, 36, 36, 57,184, 44, 36, 44, 44, 44, 44, 44, 44, 44, + 44, 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44, 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44, 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, @@ -1410,14 +1394,18 @@ _hb_ucd_u8[17884] = 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44, 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44, - 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 94, 86, 43, 43, 43, 43, - 86, 43, 85, 71, 36, 63, 2, 2, 7, 7, 7, 7, 7, 2, 93, 71, - 86, 87, 43, 43, 85, 85, 86, 87, 85, 43, 36, 72, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 94, 86, 43, 43, 44, 86, 86, 43, 87, - 60, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 44, - 86, 87, 43, 43, 43, 85, 87, 87, 60, 2, 61, 44, 44, 44, 44, 44, - 2, 2, 2, 2, 2, 2, 64, 44, 36, 36, 36, 36, 36, 70, 87, 86, - 43, 43, 43, 87, 63, 44, 44, 44, 86, 43, 43, 87, 43, 43, 44, 44, + 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 62, 44, 61, + 36, 36, 36, 62, 86, 87, 43, 43, 80, 90, 89, 89, 86, 90, 86, 85, + 71, 71, 2, 93, 64, 44, 44, 44, 57, 80, 44, 44, 44, 44, 44, 44, + 36, 36, 94, 86, 43, 43, 43, 43, 86, 43, 85, 71, 36, 63, 2, 2, + 7, 7, 7, 7, 7, 2, 93, 71, 86, 87, 43, 43, 85, 85, 86, 87, + 85, 43, 36, 72, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 94, + 86, 43, 43, 44, 86, 86, 43, 87, 60, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 36, 36, 43, 44, 86, 87, 43, 43, 43, 85, 87, 87, + 60, 2, 61, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 2, 64, 44, + 36, 36, 36, 36, 36, 70, 87, 86, 43, 43, 43, 87, 63, 44, 44, 44, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 44, 44, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 61, 57, 87, 86, 43, 43, 87, 43, 43, 44, 44, 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44, 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71, @@ -1427,49 +1415,52 @@ _hb_ucd_u8[17884] = 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2, 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44, - 43, 43, 43, 80, 43, 43, 43, 87, 63, 2, 2, 44, 44, 44, 44, 44, - 2, 36, 36, 36, 36, 36, 36, 36, 44, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 89, 43, 43, 43, 85, 43, 87, 80, 44, 44, 44, 44, - 36, 36, 36, 61, 36, 62, 36, 36, 70, 43, 43, 80, 44, 80, 43, 57, - 43, 43, 43, 70, 44, 44, 44, 44, 36, 36, 36, 62, 61, 36, 36, 36, - 36, 36, 36, 36, 36, 86, 86, 90, 43, 89, 87, 87, 61, 44, 44, 44, - 36, 70, 85,107, 64, 44, 44, 44, 43, 94, 36, 36, 36, 36, 36, 36, - 36, 36, 86, 43, 43, 80, 44, 86, 85, 60, 2, 2, 2, 2, 2, 2, + 63, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 87, + 63, 2, 2, 44, 44, 44, 44, 44, 2, 36, 36, 36, 36, 36, 36, 36, + 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, + 85, 43, 87, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, + 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, + 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 86, 86, 90, + 43, 89, 87, 87, 61, 44, 44, 44, 36, 70, 85,107, 64, 44, 44, 44, + 43, 94, 36, 36, 36, 36, 36, 36, 36, 36, 86, 43, 43, 80, 44, 86, + 85, 60, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 80, 44, 44, 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181, 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44, 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43, - 43, 43, 43, 44, 44, 44, 44, 44, 43, 43, 60, 44, 44, 44, 44, 44, + 43, 43, 43, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 43, + 43, 43, 43, 43, 43, 86, 87, 43, 43, 43, 60, 44, 44, 44, 44, 44, 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44, 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 62, 36, 27, 27, 27, 30, 2, 64, 44, 44, + 36, 36, 36, 36, 44, 44, 62, 36, 40, 69, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 83,164, 2, 27, 27, 27, 30, 2, 64, 44, 44, 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57, 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44, - 86, 44, 44, 44, 44, 44, 44, 44, 40, 40, 52, 40, 40, 40, 52, 81, - 36, 61, 44, 44, 44, 44, 44, 44, 44, 61, 44, 44, 44, 44, 44, 44, - 36, 61, 62, 44, 44, 44, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 44, 50, 60, 65, 65, 44, 44, 44, 44, 44, 44, - 43, 43, 43, 43, 43, 43, 43, 44, 43, 43, 43, 80, 44, 44, 44, 44, - 67, 67, 67, 92, 55, 67, 67, 67, 67, 67,186, 87, 43, 67,186, 86, - 86,187, 65, 65, 65, 84, 43, 43, 43, 76, 50, 43, 43, 43, 67, 67, - 67, 67, 67, 67, 67, 43, 43, 67, 67, 43, 76, 44, 44, 44, 44, 44, - 27, 27, 44, 44, 44, 44, 44, 44, 11, 11, 11, 11, 11, 16, 16, 16, - 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, - 16, 16,110, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 47, 11, 44, 47, 48, 47, 48, 11, 47, 11, - 11, 11, 11, 16, 16,150,150, 16, 16, 16,150, 16, 16, 16, 16, 16, - 16, 16, 11, 48, 11, 47, 48, 11, 11, 11, 47, 11, 11, 11, 47, 16, - 16, 16, 16, 16, 11, 48, 11, 47, 11, 11, 47, 47, 44, 11, 11, 11, - 47, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, - 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 44, 11, 11, 11, 11, - 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, - 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, - 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, - 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 44, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 43, 43, 43, 76, 67, 50, 43, 43, + 86, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 62, + 40, 40, 52, 40, 40, 40, 52, 81, 36, 61, 44, 44, 44, 44, 44, 44, + 44, 61, 44, 44, 44, 44, 44, 44, 36, 61, 62, 44, 44, 44, 44, 44, + 44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60, + 65, 65, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 44, + 43, 43, 43, 80, 44, 44, 44, 44, 67, 67, 67, 92, 55, 67, 67, 67, + 67, 67,186, 87, 43, 67,186, 86, 86,187, 65, 65, 65, 84, 43, 43, + 43, 76, 50, 43, 43, 43, 67, 67, 67, 67, 67, 67, 67, 43, 43, 67, + 67, 43, 76, 44, 44, 44, 44, 44, 27, 27, 44, 44, 44, 44, 44, 44, + 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 16, 16, 16,110, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 11, + 44, 47, 48, 47, 48, 11, 47, 11, 11, 11, 11, 16, 16,150,150, 16, + 16, 16,150, 16, 16, 16, 16, 16, 16, 16, 11, 48, 11, 47, 48, 11, + 11, 11, 47, 11, 11, 11, 47, 16, 16, 16, 16, 16, 11, 48, 11, 47, + 11, 11, 47, 47, 44, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, + 16, 16, 16, 44, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, + 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, + 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, + 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, + 16, 33, 16, 16, 16, 32, 44, 7, 43, 43, 43, 76, 67, 50, 43, 43, 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110, @@ -1479,22 +1470,23 @@ _hb_ucd_u8[17884] = 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77, 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43, 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43, - 36, 36, 36, 61, 36, 36, 62, 61, 36, 36, 61,179, 27, 27, 27, 27, - 16, 16, 43, 43, 43, 74, 44, 44, 27, 27, 27, 27, 27, 27,163, 27, - 188, 27,100, 44, 44, 44, 44, 44, 27, 27, 27, 27, 27, 27, 27,163, - 27, 27, 27, 27, 27, 27, 27, 44, 36, 36, 62, 36, 36, 36, 36, 36, - 62, 61, 61, 62, 62, 36, 36, 36, 36, 61, 36, 36, 62, 62, 44, 44, - 44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62, - 62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61, - 36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36, - 8, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44, - 55, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, 27, 27, 91, 67, - 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, - 67, 92, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 92, 44, 44, 44, - 67, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 25, 41, 41, - 67, 67, 67, 67, 44, 44, 67, 67, 67, 67, 67, 92, 44, 55, 67, 67, - 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 67, 55, - 67, 67, 67, 44, 44, 44, 44, 67, 67, 92, 67, 67, 67, 67, 67, 67, + 188, 7, 7, 7, 7,189, 44, 93, 36, 36, 36, 61, 36, 36, 62, 61, + 36, 36, 61,179, 27, 27, 27, 27, 16, 16, 43, 43, 43, 74, 44, 44, + 27, 27, 27, 27, 27, 27,163, 27,190, 27,100, 44, 44, 44, 44, 44, + 27, 27, 27, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 44, + 36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36, + 36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36, + 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, + 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, + 62, 36, 62, 36, 36, 62, 36, 36, 8, 44, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, + 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, + 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67, + 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 92, 44, 44, 44, 67, + 67, 67, 67, 67, 67, 67, 92, 55, 67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44, 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, @@ -1520,366 +1512,350 @@ _hb_ucd_u8[17884] = 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, - 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, - 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, + 7, 13, 13, 2, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, - 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 35, 0, 36, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, - 0, 0, 40, 41, 42, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, - 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, 16, 18, - 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, 0, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, - 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, - 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, 0, 0, - 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, 62, 63, - 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, 0, 0, - 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, - 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, 0, 0, - 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 75, 76, 0, 77, 78, 0, - 0, 79, 80, 0, 81, 62, 0, 82, 83, 0, 0, 84, 85, 86, 0, 0, - 0, 87, 0, 88, 0, 0, 51, 89, 51, 0, 90, 0, 91, 0, 0, 0, - 80, 0, 0, 0, 92, 93, 0, 94, 95, 96, 97, 0, 0, 0, 0, 0, - 51, 0, 0, 0, 0, 98, 99, 0, 0, 0, 0, 0, 0,100, 0, 0, - 0, 0, 0,101,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,103, - 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105,106, 0, - 0,107, 0, 0, 0, 0, 0, 0,108, 0,109, 0,102, 0, 0, 0, - 0, 0,110,111, 0, 0, 0, 0, 0, 0, 0,112, 0, 0, 0, 0, - 0, 0, 0,113, 0,114, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, - 5, 6, 7, 0, 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, - 0, 13, 0, 0, 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, - 21, 0, 0, 0, 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, - 0, 27, 0, 0, 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, - 33, 0, 0, 35, 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, - 38, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, - 42, 0, 0, 0, 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, - 47, 0, 0, 0, 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, - 0, 51, 0, 52, 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, - 0, 56, 0, 0, 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, - 0, 0, 0, 61, 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, - 0, 0, 0, 67, 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, - 0, 0, 77, 78, 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, - 0, 81, 0, 0, 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, - 84, 0, 85, 0, 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, - 0, 0, 0, 88, 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, - 0, 0, 33, 0, 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, - 0, 0, 93, 0, 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, - 0, 0, 98, 0, 0, 0, 99, 0, 0, 0, 0,100,101, 93, 0, 0, - 102, 0, 0, 0, 84, 0, 0,103, 0, 0, 0,104,105, 0, 0,106, - 107, 0, 0, 0, 0, 0, 0,108, 0, 0,109, 0, 0, 0, 0,110, - 33, 0,111,112,113, 35, 0, 0,114, 0, 0, 0,115, 0, 0, 0, - 0, 0, 0,116, 0, 0,117, 0, 0, 0, 0,118, 88, 0, 0, 0, - 0, 0, 57, 0, 0, 0, 0, 52,119, 0, 0, 0, 0,120, 0, 0, - 121, 0, 0, 0, 0,119, 0, 0,122, 0, 0, 0, 0, 0, 0,123, - 0, 0, 0,124, 0, 0, 0,125, 0,126, 0, 0, 0, 0,127,128, - 129, 0,130, 0,131, 0, 0, 0,132,133,134, 0, 77, 0, 0, 0, - 0, 0, 35, 0, 0, 0,135, 0, 0, 0,136, 0, 0,137, 0, 0, - 138, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, - 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, - 18, 1, 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, - 25, 26, 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, - 34, 35, 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, - 42, 0, 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, - 21, 0, 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, - 0, 0, 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, - 54, 21, 35, 1, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, - 0, 0, 0, 59, 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, - 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, - 0, 0, 68, 0, 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, - 0, 77, 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, - 0, 80, 0, 0, 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, - 0, 0, 83, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, - 1, 52, 15, 86, 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, - 1, 0, 0, 0, 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, - 0, 78, 0, 0, 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, - 21, 1, 21, 92, 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, - 81, 99,100, 4, 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, - 0, 0, 0, 61, 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, - 0, 0, 0, 38, 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, - 61, 0, 0, 0, 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, - 0, 0, 0,107, 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, - 0, 0, 0,108, 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, + 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, + 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, + 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, + 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, + 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, + 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, + 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, + 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, + 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, + 0, 0, 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, + 0, 78, 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, + 86, 87, 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, + 93, 0, 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, + 0, 0, 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, + 0,102, 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104, + 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, + 0, 0, 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, + 0, 0, 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, + 0,118, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, + 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, + 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, + 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, + 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, + 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, + 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, + 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, + 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, + 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, + 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, + 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, + 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, + 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, + 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, + 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, + 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, + 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, + 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, + 0, 0, 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0, + 103, 0, 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107, + 108, 0, 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, + 33, 0,112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0, + 117, 0, 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, + 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, + 0,122, 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, + 0, 0, 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, + 0,128, 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0, + 134,135,136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, + 0, 0,138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, + 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, + 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, + 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, + 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, + 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, + 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, + 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, + 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, + 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, + 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, + 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, + 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, + 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, + 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, + 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, + 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, + 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, + 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, + 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, + 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, + 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, + 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, + 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, + 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, - 0, 38, 1, 58, 1, 58, 0, 0, 63, 89, 0, 0,115, 0, 0, 0, - 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, 0, 79, - 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, 0, 0, - 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, 0,117, - 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, 38, 50, - 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, 87, 0, - 0, 0, 0, 1, 0, 0, 0,123, 4,122, 0, 0, 0, 1,124, 0, - 0, 0, 0, 0,230,230,230,230,230,232,220,220,220,220,232,216, - 220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220, - 1, 1, 1, 1, 1,220,220,220,220,230,230,230,230,240,230,220, - 220,220,230,230,230,220,220, 0,230,230,230,220,220,220,220,230, - 232,220,220,230,233,234,234,233,234,234,233,230, 0, 0, 0,230, - 0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220, - 230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, - 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, - 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230, - 220,230,230,220, 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230, - 230, 0,220,230,230,220, 0, 0, 0, 36, 0, 0,230,220,230,230, - 220,220,230,220,220,230,220,230,220,230,230, 0, 0,220, 0, 0, - 230,230, 0,230, 0,230,230,230,230,230, 0, 0, 0,220,220,220, - 230,220,220,220,230,230, 0,220, 27, 28, 29,230, 7, 0, 0, 0, - 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0, - 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0, - 103,103, 9, 0,107,107,107,107,118,118, 9, 0,122,122,122,122, - 220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0, - 132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230, - 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, - 9, 9, 0, 0, 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220, - 220, 0, 0, 0,230, 0, 0,220,230,220, 0,220,230,230,230, 0, - 0, 0, 9, 9, 0, 0, 7, 0,230, 0, 1, 1, 1, 0, 0, 0, - 230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230, - 233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230, - 220,230, 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, - 0, 0, 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, - 0,220, 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, - 0, 0,230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, - 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, - 0,226,216,216,216,216,216, 0,220,220,220, 0,232,232,220,230, - 230,230, 7, 0, 16, 17, 17, 17, 17, 17, 17, 33, 17, 17, 17, 19, - 17, 17, 17, 17, 20,101, 17,113,129,169, 17, 27, 28, 17, 17, 17, + 0, 38, 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0, + 115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, + 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, + 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, + 0, 0, 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, + 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, + 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, + 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230, + 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220, + 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220, + 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0, + 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233, + 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230, + 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0, + 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, + 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, + 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, + 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230, + 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230, + 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, + 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230, + 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107, + 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, + 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, + 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, + 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, + 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220, + 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0, + 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230, + 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, + 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228, + 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230, + 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, + 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, + 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, + 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, + 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 17, + 17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113, + 129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,237, 0, 1, 2, 2, 0, 3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 0, 6, 7, 8, 9, 0, 0, 0, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, - 0, 0, 21, 22, 0, 0, 0, 0, 23, 24, 25, 26, 0, 27, 0, 28, - 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 33, 34, 35, 36, 0, - 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, - 0, 0, 0, 0, 1, 2, 40, 41, 0, 1, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 0, 0, 3, 4, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, - 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, - 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 11, 12, - 0, 13, 0, 14, 15, 16, 0, 0, 0, 0, 0, 1, 17, 18, 0, 19, - 7, 1, 0, 0, 0, 20, 20, 7, 20, 20, 20, 20, 20, 20, 20, 8, - 21, 0, 22, 0, 7, 23, 24, 0, 20, 20, 25, 0, 0, 0, 26, 27, - 1, 7, 20, 20, 20, 20, 20, 1, 28, 29, 30, 31, 0, 0, 20, 0, - 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 20, 20, - 20, 1, 0, 0, 8, 21, 32, 4, 0, 10, 0, 33, 7, 20, 20, 20, - 0, 0, 0, 0, 8, 34, 34, 35, 36, 34, 37, 0, 38, 1, 20, 20, - 0, 0, 39, 0, 1, 1, 0, 8, 21, 1, 20, 0, 0, 0, 1, 0, - 0, 40, 1, 1, 0, 0, 8, 21, 0, 1, 0, 1, 0, 1, 0, 0, - 0, 0, 26, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 7, 20, 41, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 0, 42, 43, 44, 0, 45, - 0, 8, 21, 0, 0, 0, 0, 0, 0, 0, 0, 46, 7, 1, 10, 1, - 0, 0, 0, 1, 20, 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 26, 34, 9, 0, 0, 20, 20, 1, 20, 20, 0, 0, 0, 0, 0, - 0, 0, 26, 21, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, - 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13, - 13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 13, 42, 7, 7, 43, 7, - 44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237, 0, 1, 2, 2, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 7, 8, + 9, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 21, 22, 0, 0, 0, 0, + 23, 24, 25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 0, 0, 0, 0, + 0, 0, 0, 33, 34, 35, 36, 0, 0, 0, 0, 0, 37, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, 1, 2, 40, 41, + 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 5, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, + 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 11, 12, 0, 13, 0, 14, 15, 16, 0, 0, + 0, 0, 0, 1, 17, 18, 0, 19, 7, 1, 0, 0, 0, 20, 20, 7, + 20, 20, 20, 20, 20, 20, 20, 8, 21, 0, 22, 0, 7, 23, 24, 0, + 20, 20, 25, 0, 0, 0, 26, 27, 1, 7, 20, 20, 20, 20, 20, 1, + 28, 29, 30, 31, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, 20, 20, 20, 1, 0, 0, 8, 21, 32, 4, + 0, 10, 0, 33, 7, 20, 20, 20, 0, 0, 0, 0, 8, 34, 34, 35, + 36, 34, 37, 0, 38, 1, 20, 20, 0, 0, 39, 0, 1, 1, 0, 8, + 21, 1, 20, 0, 0, 0, 1, 0, 0, 40, 1, 1, 0, 0, 8, 21, + 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 26, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 21, 7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 21, 0, 42, 43, 44, 0, 45, 0, 8, 21, 0, 0, 0, 0, 0, + 0, 0, 0, 46, 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 34, 9, 0, 0, 20, 20, + 1, 20, 20, 0, 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 16, 17, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 20, 20, 20, 20, 20, 20, + 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 20, 33, + 34, 35, 34, 34, 36, 37, 20, 20, 20, 20, 20, 20, 38, 20, 39, 40, + 41, 41, 41, 41, 41, 42, 43, 44, 20, 20, 20, 20, 20, 20, 20, 45, + 46, 20, 20, 47, 20, 20, 20, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 20, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45, 0, 0, 1, - 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 2, 2, 53, 54, 55, 56, - 57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61, - 59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109, - 110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123, - 124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138, - 139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151, - 152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164, - 164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169, - 169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173, - 173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182, - 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, - 182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182, - 182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189, - 190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197, - 198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208, - 208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212, - 213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218, - 219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226, - 59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233, - 59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,240, 70, 70, 70, 70, - 70, 70, 70, 70, 70,241, 70, 70, 70, 70,242, 96, 96, 96, 70, 70, - 70, 70,243, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, - 70, 70, 70, 70,244, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70,245, 96, 96, 96, 96, 96, 96, 96, 96,246, 96, - 247,248, 0, 1, 2, 2, 0, 1, 2, 2, 2, 3, 4, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, - 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0, - 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, - 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, - 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, - 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, 4, 4, 2, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, - 2, 2, 2, 2, 2, 2, 14, 14, 14, 2, 2, 2, 2, 14, 14, 14, - 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, - 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, - 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, - 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 2, 2, 95, 2, 37, 37, 37, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 3, - 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, - 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5, - 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, - 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, - 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, - 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2, - 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5, - 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11, - 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, - 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, - 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, - 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11, - 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2, - 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 10, - 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, - 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, - 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, - 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2, - 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, - 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21, - 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, - 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, - 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, - 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, - 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, - 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, - 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, - 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 2, - 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, - 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, - 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, - 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 23, 23, - 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, - 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, - 2, 2, 2, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 2, 16, - 16, 16, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 2, 2, - 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 2, 36, - 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, - 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, 2, - 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 2, 2, 2, 2, 2, 18, - 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, - 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, - 18, 18, 18, 18, 18, 2, 18, 18, 2, 2, 18, 18, 18, 18, 25, 25, - 25, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 2, 2, 2, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, - 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 2, 2, 2, 2, 33, 33, - 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 8, 8, - 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, - 30, 30, 30, 30, 30, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, - 30, 30, 30, 2, 2, 2, 30, 30, 2, 2, 2, 2, 2, 2, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, - 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 2, 2, 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31, - 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, 2, - 2, 2, 2, 2, 2, 2, 32, 32, 32, 2, 2, 2, 2, 2, 28, 28, - 28, 28, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 2, 48, 48, 48, 48, 2, 2, 2, 2, 48, 2, - 2, 2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 2, 2, 52, 52, 52, 52, 52, 2, 2, 2, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 2, 2, 2, 2, 58, 58, - 2, 2, 2, 2, 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91, - 91, 91, 91, 2, 2, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, - 91, 91, 91, 91, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 2, 2, 2, 62, 62, - 62, 62, 62, 62, 62, 2, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 60, 13, 13, + 13, 61, 62, 13, 13, 13, 13, 63, 13, 13, 13, 13, 13, 13, 64, 65, + 20, 20, 66, 20, 13, 13, 13, 13, 67, 13, 13, 13, 68, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 19, 19, + 19, 19, 19, 19, 19, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 19, + 19, 19, 19, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, + 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, + 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 2, 9, 9, 9, 9, 9, 9, 9, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 1, 1, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, + 4, 2, 2, 4, 4, 4, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 14, 14, + 14, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 2, 2, 2, 3, 3, + 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 0, 0, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, + 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 2, 2, 2, 2, 2, 2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 2, 2, 90, 90, 90, 90, 90, 90, 90, 2, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 2, 2, 95, 2, 37, 37, + 37, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, + 2, 2, 2, 2, 2, 3, 3, 3, 0, 3, 3, 3, 3, 3, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7, + 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, + 5, 5, 5, 2, 2, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 2, + 5, 2, 2, 2, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 2, + 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, + 2, 2, 5, 5, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 2, 2, 11, 11, 11, 2, 11, 11, 11, 11, 11, + 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 11, 11, 11, 11, 11, 2, + 11, 11, 2, 11, 11, 2, 11, 11, 2, 2, 11, 2, 11, 11, 11, 2, + 2, 11, 11, 11, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, + 11, 11, 11, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 2, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 2, + 10, 10, 2, 10, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, 10, 10, + 2, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 10, 10, + 10, 10, 2, 2, 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, 10, + 10, 10, 10, 10, 10, 10, 2, 21, 21, 21, 2, 21, 21, 21, 21, 21, + 21, 21, 21, 2, 2, 21, 21, 2, 2, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 2, + 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, 21, 2, + 2, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 2, 2, + 2, 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, 2, + 22, 22, 2, 22, 22, 22, 22, 22, 22, 2, 2, 2, 22, 22, 22, 2, + 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 22, 2, 22, 22, 2, 2, + 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 2, 2, 2, 2, 22, 22, 22, 2, 2, 2, 2, 2, 2, 22, 2, 2, + 2, 2, 2, 2, 22, 22, 22, 22, 22, 2, 2, 2, 2, 2, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2, + 23, 23, 23, 23, 23, 23, 23, 23, 2, 2, 23, 23, 23, 23, 23, 2, + 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 2, 23, 23, + 23, 2, 2, 23, 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 2, 2, + 2, 2, 2, 2, 2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 2, 16, 16, 16, 2, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 2, 16, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, 16, 2, + 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 16, 2, 16, 16, + 16, 16, 2, 2, 16, 16, 2, 16, 16, 16, 2, 2, 2, 2, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, + 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, + 20, 20, 2, 2, 20, 20, 2, 36, 36, 36, 2, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, + 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 36, + 36, 36, 36, 2, 36, 2, 2, 2, 2, 2, 2, 2, 36, 36, 2, 2, + 36, 36, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 24, 24, + 24, 24, 2, 2, 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, + 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 2, 18, 18, + 18, 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 18, 18, + 2, 2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 2, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2, 2, 2, 25, 25, + 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 25, + 25, 2, 2, 2, 2, 2, 33, 33, 33, 33, 33, 33, 33, 33, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 8, 2, 2, + 2, 2, 2, 8, 2, 2, 8, 8, 8, 0, 8, 8, 8, 8, 12, 12, + 12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30, 2, + 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, + 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 2, 2, 2, 30, 30, + 2, 2, 2, 2, 2, 2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, + 2, 2, 2, 2, 2, 2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 2, 2, 2, 2, 2, 2, 2, 2, 2, 45, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 2, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 2, 2, 2, 2, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 2, 46, 46, 46, 2, + 46, 46, 2, 2, 2, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 2, 2, 31, 31, 2, 2, 2, 2, 2, 2, 32, 32, + 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2, 2, 2, 32, 32, + 32, 2, 2, 2, 2, 2, 28, 28, 28, 28, 28, 28, 2, 2, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 2, 48, 48, + 48, 48, 2, 2, 2, 2, 48, 2, 2, 2, 48, 48, 48, 48, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 2, 2, 52, 52, + 52, 52, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 2, 2, 2, 2, 58, 58, 2, 2, 2, 2, 2, 2, 58, 58, + 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 2, 2, 91, 91, 91, + 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 2, 62, 62, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 73, 73, - 73, 73, 73, 73, 73, 73, 6, 2, 2, 2, 2, 2, 2, 2, 8, 8, + 73, 73, 73, 73, 73, 73, 6, 6, 6, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 19, 19, @@ -1896,31 +1872,30 @@ _hb_ucd_u8[17884] = 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, 0, 0, 2, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, - 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 56, 56, - 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, - 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, - 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13, - 13, 13, 13, 13, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, 13, - 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, - 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, - 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 0, 0, - 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 12, 12, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 27, 27, + 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55, + 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, 61, + 61, 61, 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, 2, 61, 61, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 0, 0, + 0, 0, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 1, 1, 1, 1, 12, 12, 13, 13, 13, 13, 0, 0, 0, 0, 2, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 0, 0, 17, 17, 17, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 0, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 19, 19, 19, 19, 19, 19, 0, 0, - 0, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 19, 19, - 2, 19, 2, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 2, 2, 2, - 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 65, 65, + 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 19, 19, + 2, 19, 2, 19, 19, 19, 2, 2, 19, 19, 19, 19, 19, 19, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 2, 2, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, @@ -1943,36 +1918,38 @@ _hb_ucd_u8[17884] = 2, 14, 14, 2, 14, 14, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 1, 1, - 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 3, 3, - 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, - 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, - 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, - 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2, - 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118, - 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, - 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 50, 50, - 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135, - 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,104,104, - 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161, - 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161, - 2,161,161,161,161,161,161,161, 2,161,161, 2, 2, 2,110,110, - 110,110,110,110,110,110,110,110,110,110,110,110,110, 2,110,110, - 110,110,110,110, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 2, - 19, 19, 19, 19, 19, 19, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, + 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, + 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 2, 2, + 12, 12, 12, 12, 12, 12, 2, 2, 12, 12, 12, 2, 2, 2, 2, 0, + 0, 0, 0, 0, 2, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, + 49, 2, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 2, 2, 49, 49, + 49, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, + 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1, 2, 2, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 2, 2, 2, 2, 2, 2, 2, 1, 0, + 0, 0, 0, 0, 0, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 2, 2, 2, 2, 2, 2, 2, 2, 2, 42, 42, 42, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 2, 2, 2, 2, 2,118,118, + 118,118,118,118,118,118,118,118,118, 2, 2, 2, 2, 2, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 2, 53, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2, 2, 2, 2, 59, 59, + 59, 59, 59, 59, 2, 2, 40, 40, 40, 40, 40, 40, 40, 40, 51, 51, + 51, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 2, 2, 50, 50, 2, 2, 2, 2, 2, 2,135,135, + 135,135,135,135,135,135,135,135,135,135, 2, 2, 2, 2,106,106, + 106,106,106,106,106,106,104,104,104,104,104,104,104,104,104,104, + 104,104, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,104,161,161, + 161,161,161,161,161,161,161,161,161, 2,161,161,161,161,161,161, + 161, 2,161,161, 2,161,161,161, 2,161,161,161,161,161,161,161, + 2,161,161, 2, 2, 2,170,170,170,170,170,170,170,170,170,170, + 170,170, 2, 2, 2, 2,110,110,110,110,110,110,110,110,110,110, + 110,110,110,110,110, 2,110,110,110,110,110,110, 2, 2, 19, 19, + 19, 19, 19, 19, 2, 19, 19, 2, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 2, 2, 2, 2, 2, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2, 81,120,120, @@ -1998,122 +1975,135 @@ _hb_ucd_u8[17884] = 122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,130,130,130,130, 130, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,144,144, - 144,144,144,144,144,144,144,144, 2, 2, 2, 2, 2, 2,156,156, + 144,144,144,144,144,144,144,144, 2, 2, 2, 2, 2, 2,165,165, + 165,165,165,165,165,165,165,165,165,165,165,165, 2, 2, 2,165, + 165,165,165,165,165,165, 2, 2, 2, 2, 2, 2,165,165,156,156, 156,156,156,156,156,156,156,156, 2,156,156,156, 2, 2,156,156, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3,147,147, - 147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148, - 2, 2, 2, 2, 2, 2,158,158,158,158,158,158,158,158,158,158, - 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153, - 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149, - 149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 2, 2, - 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101, - 101,101,101,101,101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101, - 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 2, 96, 96,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111, 2,100,100,100,100,100,100,100,100, 2, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2,108,108, - 108,108,108,108,108,108,108,108, 2,108,108,108,108,108,108,108, - 2, 2, 2, 2, 2, 2,129,129,129,129,129,129,129, 2,129, 2, - 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, - 129,129,129,129, 2,129,129,129, 2, 2, 2, 2, 2, 2,109,109, - 109,109,109,109,109,109,109,109,109, 2, 2, 2, 2, 2,109,109, - 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107,107, - 107,107,107, 2, 2,107,107, 2, 2,107,107,107,107,107,107,107, - 107,107,107,107,107,107,107, 2,107,107,107,107,107,107,107, 2, - 107,107, 2,107,107,107,107,107, 2, 1,107,107,107,107,107, 2, - 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2, - 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,107,107, - 107,107,107, 2, 2, 2,137,137,137,137,137,137,137,137,137,137, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, + 2, 2, 3, 3, 3, 3,147,147,147,147,147,147,147,147,148,148, + 148,148,148,148,148,148,148,148, 2, 2, 2, 2, 2, 2,158,158, + 158,158,158,158,158,158,158,158, 2, 2, 2, 2, 2, 2,153,153, + 153,153,153,153,153,153,153,153,153,153, 2, 2, 2, 2,149,149, + 149,149,149,149,149,149,149,149,149,149,149,149,149, 2, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, + 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 2, 2, 2, 94, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 85, 2, 2,101,101,101,101,101,101,101,101,101, 2, + 2, 2, 2, 2, 2, 2,101,101, 2, 2, 2, 2, 2, 2, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 2, 96, 96,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111, 2,100,100, + 100,100,100,100,100,100, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 2, 2, 2,108,108,108,108,108,108,108,108,108,108, + 2,108,108,108,108,108,108,108, 2, 2, 2, 2, 2, 2,129,129, + 129,129,129,129,129, 2,129, 2,129,129,129,129, 2,129,129,129, + 129,129,129,129,129,129,129,129,129,129,129,129, 2,129,129,129, + 2, 2, 2, 2, 2, 2,109,109,109,109,109,109,109,109,109,109, + 109, 2, 2, 2, 2, 2,109,109, 2, 2, 2, 2, 2, 2,107,107, + 107,107, 2,107,107,107,107,107,107,107,107, 2, 2,107,107, 2, + 2,107,107,107,107,107,107,107,107,107,107,107,107,107,107, 2, + 107,107,107,107,107,107,107, 2,107,107, 2,107,107,107,107,107, + 2, 1,107,107,107,107,107, 2, 2,107,107,107, 2, 2,107, 2, + 2, 2, 2, 2, 2,107, 2, 2, 2, 2, 2,107,107,107,107,107, + 107,107, 2, 2,107,107,107,107,107,107,107, 2, 2, 2,171,171, + 171,171,171,171,171,171,171,171, 2,171, 2, 2,171, 2,171,171, + 171,171,171,171, 2,171,171, 2,171, 2, 2,171, 2,171,171,171, + 171, 2,171,171,171,171,171, 2, 2, 2, 2, 2, 2, 2, 2,171, + 171, 2, 2, 2, 2, 2,137,137,137,137,137,137,137,137,137,137, 137,137, 2,137,137,137,137,137, 2, 2, 2, 2, 2, 2,124,124, 124,124,124,124,124,124,124,124, 2, 2, 2, 2, 2, 2,123,123, 123,123,123,123,123,123,123,123,123,123,123,123, 2, 2,114,114, 114,114,114,114,114,114,114,114,114,114,114, 2, 2, 2,114,114, 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 2, 2, 2,102,102, - 102,102,102,102,102,102,102,102, 2, 2, 2, 2, 2, 2,126,126, - 126,126,126,126,126,126,126,126,126, 2, 2,126,126,126,126,126, - 126,126, 2, 2, 2, 2,126,126,126,126,126,126,126, 2,142,142, - 142,142,142,142,142,142,142,142,142,142, 2, 2, 2, 2,125,125, - 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, - 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154,154, - 154,154,154,154,154,154,154,154,154,154,154,154, 2,154,154, 2, - 2,154,154,154,154,154,154,154, 2, 2, 2, 2, 2, 2,150,150, - 150,150,150,150,150,150, 2, 2,150,150,150,150,150,150,150,150, - 150,150,150, 2, 2, 2,141,141,141,141,141,141,141,141,140,140, - 140,140,140,140,140,140,140,140,140, 2, 2, 2, 2, 2,121,121, - 121,121,121,121,121,121,121, 2, 2, 2, 2, 2, 2, 2, 7, 7, - 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133, 2, - 133,133,133,133,133,133,133,133,133,133,133,133,133, 2,133,133, - 133,133,133,133, 2, 2,133,133,133,133,133, 2, 2, 2,134,134, - 134,134,134,134,134,134, 2, 2,134,134,134,134,134,134, 2,134, - 134,134,134,134,134,134,134,134,134,134,134,134,134, 2,138,138, - 138,138,138,138,138, 2,138,138, 2,138,138,138,138,138,138,138, - 138,138,138,138,138,138, 2, 2,138, 2,138,138, 2,138,138,138, - 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, 2, - 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, - 143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, - 2, 2, 2, 2, 2, 2,143,143, 2, 2, 2, 2, 2, 2,145,145, - 145,145,145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2,163,163, - 163,163,163,163,163,163,163, 2,163,163,163,163,163,163,163,163, - 163, 2, 2, 2,163,163,163,163, 2, 2, 2, 2, 2, 2, 86, 2, - 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, - 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2,157,157, - 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 2,127,127, - 127,127,127,127,127,127,127,127,127,127,127,127,127, 2, 79, 2, + 102,102,102,102,102,102,102,102, 2, 2, 2, 2, 2, 2, 33, 33, + 33, 33, 2, 2, 2, 2,126,126,126,126,126,126,126,126,126,126, + 126, 2, 2,126,126,126,126,126,126,126, 2, 2, 2, 2,126,126, + 126,126,126,126,126, 2,142,142,142,142,142,142,142,142,142,142, + 142,142, 2, 2, 2, 2,125,125,125,125,125,125,125,125,125,125, + 125, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,125,154,154, + 154,154,154,154,154, 2, 2,154, 2, 2,154,154,154,154,154,154, + 154,154, 2,154,154, 2,154,154,154,154,154,154,154,154,154,154, + 154,154,154,154, 2,154,154, 2, 2,154,154,154,154,154,154,154, + 2, 2, 2, 2, 2, 2,150,150,150,150,150,150,150,150, 2, 2, + 150,150,150,150,150,150,150,150,150,150,150, 2, 2, 2,141,141, + 141,141,141,141,141,141,140,140,140,140,140,140,140,140,140,140, + 140, 2, 2, 2, 2, 2,121,121,121,121,121,121,121,121,121, 2, + 2, 2, 2, 2, 2, 2, 7, 7, 2, 2, 2, 2, 2, 2,169,169, + 169,169,169,169,169,169,169,169, 2, 2, 2, 2, 2, 2,133,133, + 133,133,133,133,133,133,133, 2,133,133,133,133,133,133,133,133, + 133,133,133,133,133, 2,133,133,133,133,133,133, 2, 2,133,133, + 133,133,133, 2, 2, 2,134,134,134,134,134,134,134,134, 2, 2, + 134,134,134,134,134,134, 2,134,134,134,134,134,134,134,134,134, + 134,134,134,134,134, 2,138,138,138,138,138,138,138, 2,138,138, + 2,138,138,138,138,138,138,138,138,138,138,138,138,138, 2, 2, + 138, 2,138,138, 2,138,138,138, 2, 2, 2, 2, 2, 2,143,143, + 143,143,143,143, 2,143,143, 2,143,143,143,143,143,143,143,143, + 143,143,143,143,143,143,143,143,143,143,143,143,143, 2,143,143, + 2,143,143,143,143,143,143, 2, 2, 2, 2, 2, 2, 2,143,143, + 2, 2, 2, 2, 2, 2,145,145,145,145,145,145,145,145,145, 2, + 2, 2, 2, 2, 2, 2,163,163,163,163,163,163,163,163,163, 2, + 163,163,163,163,163,163,163,163,163, 2, 2, 2,163,163,163,163, + 163, 2, 2, 2, 2, 2, 86, 2, 2, 2, 2, 2, 2, 2, 22, 22, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, 63, 63, + 63, 63, 63, 63, 63, 2, 63, 63, 63, 63, 63, 2, 2, 2, 63, 63, + 63, 63, 2, 2, 2, 2,157,157,157,157,157,157,157,157,157,157, + 157, 2, 2, 2, 2, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 2, 2, 80, 80, 80, 2, 2, 2, 2, 2,127,127, + 127,127,127,127,127,127,127,127,127,127,127,127,127, 2,166,166, + 166,166,166,166,166,166,166,166, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2,115,115,115,115,115,115,115,115,115,115, 115,115,115,115,115, 2,115,115, 2, 2, 2, 2,115,115,159,159, 159,159,159,159,159,159,159,159,159,159,159,159,159, 2,159,159, 2, 2, 2, 2, 2, 2,103,103,103,103,103,103,103,103,103,103, 103,103,103,103, 2, 2,119,119,119,119,119,119,119,119,119,119, 119,119,119,119, 2, 2,119,119, 2,119,119,119,119,119, 2, 2, - 2, 2, 2,119,119,119,146,146,146,146,146,146,146,146,146,146, + 2, 2, 2,119,119,119,167,167,167,167,167,167,167,167,167,167, + 2, 2, 2, 2, 2, 2,146,146,146,146,146,146,146,146,146,146, 146, 2, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2,136,136,136,136,136,136,136,136,155,155, - 155,155,155,155,155,155,155,155,155,155,155,155, 2, 2,136, 2, - 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17, - 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17, - 17, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2, 2, 2, 2, 15, 15, - 15, 2, 2, 17, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17,139,139, - 139,139,139,139,139,139,139,139,139,139, 2, 2, 2, 2,105,105, - 105,105,105,105,105,105,105,105,105, 2, 2, 2, 2, 2,105,105, - 105,105,105, 2, 2, 2,105, 2, 2, 2, 2, 2, 2, 2,105,105, - 2, 2,105,105,105,105, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2, - 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, - 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, - 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, - 0, 0, 0, 0, 0, 0,131,131,131,131,131,131,131,131,131,131, - 131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131, - 131,131,131,131,131,131, 2, 2, 2, 2, 2, 19, 19, 19, 56, 56, - 56, 56, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 56, 56, 56, 56, - 2, 56, 56, 2, 56, 56, 56, 56, 56, 2, 2, 2, 2, 2, 6, 6, - 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,151,151, - 151,151,151,151,151,151,151,151,151,151,151, 2, 2, 2,151,151, - 151,151,151,151, 2, 2,151,151, 2, 2, 2, 2,151,151,160,160, - 160,160,160,160,160,160,160,160,160,160,160,160,160, 2,152,152, - 152,152,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164, - 164,164,164,164,164,164,164,164, 2, 2, 2, 2, 2, 2, 30, 30, - 30, 30, 2, 30, 30, 2,113,113,113,113,113,113,113,113,113,113, - 113,113,113, 2, 2,113,113,113,113,113,113,113,113, 2,132,132, - 132,132,132,132,132,132,132,132,132,132, 2, 2, 2, 2,132,132, - 2, 2, 2, 2,132,132, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, - 3, 2, 3, 2, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, - 3, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3, - 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, - 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 15, 0, + 155,155,155,155,155,155,155,155,155,155,155,155, 2, 2, 2, 2, + 2, 2, 2, 2, 2,155,136, 2, 2, 2, 2, 2, 2, 2, 17, 17, + 17, 17, 2, 17, 17, 17, 17, 17, 17, 17, 2, 17, 17, 2, 17, 15, + 15, 15, 15, 15, 15, 15, 17, 17, 17, 2, 2, 2, 2, 2, 2, 2, + 15, 2, 2, 2, 2, 2, 15, 15, 15, 2, 2, 17, 2, 2, 2, 2, + 2, 2, 17, 17, 17, 17,139,139,139,139,139,139,139,139,139,139, + 139,139, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, + 105, 2, 2, 2, 2, 2,105,105,105,105,105, 2, 2, 2,105, 2, + 2, 2, 2, 2, 2, 2,105,105, 2, 2,105,105,105,105, 1, 1, + 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,131,131, + 131,131,131,131,131,131,131,131,131,131, 2, 2, 2, 2, 2, 2, + 2,131,131,131,131,131, 2,131,131,131,131,131,131,131, 2, 2, + 2, 2, 2, 19, 19, 19, 56, 56, 56, 56, 56, 56, 56, 2, 56, 2, + 2, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, 2, 56, 56, 56, 56, + 56, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 6,151,151,151,151,151,151,151,151,151,151, + 151,151,151, 2, 2, 2,151,151,151,151,151,151, 2, 2,151,151, + 2, 2, 2, 2,151,151,160,160,160,160,160,160,160,160,160,160, + 160,160,160,160,160, 2,152,152,152,152,152,152,152,152,152,152, + 2, 2, 2, 2, 2,152,164,164,164,164,164,164,164,164,164,164, + 2, 2, 2, 2, 2, 2,168,168,168,168,168,168,168,168,168,168, + 168, 2, 2, 2, 2,168, 30, 30, 30, 30, 2, 30, 30, 2,113,113, + 113,113,113,113,113,113,113,113,113,113,113, 2, 2,113,113,113, + 113,113,113,113,113, 2,132,132,132,132,132,132,132,132,132,132, + 132,132, 2, 2, 2, 2,132,132, 2, 2, 2, 2,132,132, 3, 3, + 3, 3, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, + 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, + 2, 3, 2, 3, 3, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 3, 3, 3, 2, 3, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 0, 0, 0, 13, 2, 2, 2, 2, 2, 2, 2, 13, 13, + 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, + 0, 0, 0, 2, 2, 0, 13, 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -2123,13 +2113,14 @@ _hb_ucd_u8[17884] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 18, 9, 9, 9, 9, 9, 19, 20, 21, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 23, 9, + 9, 9, 9, 9, 24, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 25, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -2137,8 +2128,7 @@ _hb_ucd_u8[17884] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2175,23 +2165,29 @@ _hb_ucd_u8[17884] = 132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147, 148,149,150,151,152,153,154,155,156,157, 0, 0, 0,158,159,160, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,162,163, 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,162, 0,163, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,164,165, 0, 0, 0, 0, 0, 0, 0,166, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 167, 0, 0, 0,168,169, 0, 0,170, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,171, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,172, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,173, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,169,170, 0, 0, 0, 0,171,172, 0, 0, 0,173,174,175,176, - 177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192, - 193,194,195,196,197,198,199,200,201,202,203,204,205,206, 0, 0, + 0,176,177, 0, 0, 0, 0,178,179, 0, 0, 0,180,181,182,183, + 184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199, + 200,201,202,203,204,205,206,207,208,209,210,211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, }; static const uint16_t -_hb_ucd_u16[9344] = +_hb_ucd_u16[10400] = { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -2210,9 +2206,10 @@ _hb_ucd_u16[9344] = 136, 48, 48, 137, 138, 139, 140, 140, 141, 48, 142, 143, 144, 145, 140, 140, 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 140, 140, 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 168, 169, 48, 48, - 168, 48, 48, 170, 171, 172, 48, 48, 48, 171, 48, 48, 48, 173, 174, 175, - 48, 176, 9, 9, 9, 9, 9, 177, 178, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 168, 169, 48, 48, 168, 48, 48, 170, 171, 172, 48, 48, + 48, 171, 48, 48, 48, 173, 174, 175, 48, 176, 9, 9, 9, 9, 9, 177, + 178, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193, 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, @@ -2225,28 +2222,34 @@ _hb_ucd_u16[9344] = 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, - 279, 279, 279, 279, 279, 279, 279, 279, 280, 209, 281, 209, 209, 209, 209, 282, - 209, 283, 279, 284, 209, 285, 286, 209, 209, 209, 287, 140, 288, 140, 271, 271, - 271, 289, 209, 209, 209, 209, 290, 271, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 291, 292, 209, 209, 293, 209, 209, 209, 209, 209, 209, 294, 209, - 209, 209, 209, 209, 209, 209, 295, 296, 271, 297, 209, 209, 298, 279, 299, 279, - 300, 301, 279, 279, 279, 302, 279, 303, 209, 209, 209, 279, 304, 209, 209, 305, - 209, 306, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 307, 308, - 13, 13, 13, 13, 13, 13, 309, 310, 11, 11, 311, 48, 48, 48, 312, 313, - 48, 314, 315, 315, 315, 315, 32, 32, 316, 317, 318, 319, 320, 321, 140, 140, - 209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 209, - 325, 326, 327, 328, 136, 48, 48, 48, 48, 329, 178, 48, 48, 48, 48, 330, - 331, 48, 48, 136, 48, 48, 48, 48, 200, 332, 48, 48, 209, 209, 333, 48, - 209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209, - 48, 48, 48, 48, 209, 209, 209, 209, 48, 338, 48, 48, 48, 48, 48, 48, - 151, 209, 209, 209, 287, 48, 48, 229, 339, 48, 340, 140, 13, 13, 341, 342, - 13, 343, 48, 48, 48, 48, 344, 345, 31, 346, 347, 348, 13, 13, 13, 349, - 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360, - 361, 48, 48, 362, 363, 192, 32, 364, 64, 48, 365, 48, 366, 367, 48, 151, - 76, 48, 48, 368, 369, 370, 371, 372, 48, 48, 373, 374, 375, 376, 48, 377, - 48, 48, 48, 378, 379, 380, 381, 382, 383, 384, 315, 11, 11, 385, 386, 11, - 11, 11, 11, 11, 48, 48, 387, 192, 48, 48, 388, 48, 389, 48, 48, 206, - 390, 390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 280, 209, 281, 209, 209, 209, 209, 282, 209, 283, 279, 284, 209, 285, 286, 209, + 209, 209, 176, 140, 287, 140, 271, 271, 271, 288, 209, 209, 209, 209, 289, 271, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 290, 291, 209, 209, 292, + 209, 209, 209, 209, 209, 209, 293, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 294, 295, 271, 296, 209, 209, 297, 279, 298, 279, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 279, 279, 279, 279, 279, 279, 279, 279, 299, 300, 279, 279, 279, 301, 279, 302, + 209, 209, 209, 279, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209, + 9, 9, 9, 11, 11, 11, 306, 307, 13, 13, 13, 13, 13, 13, 308, 309, + 11, 11, 310, 48, 48, 48, 311, 312, 48, 313, 314, 314, 314, 314, 32, 32, + 315, 316, 317, 318, 319, 320, 140, 140, 209, 321, 209, 209, 209, 209, 209, 322, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, 140, 209, + 324, 325, 326, 327, 136, 48, 48, 48, 48, 328, 178, 48, 48, 48, 48, 329, + 330, 48, 48, 136, 48, 48, 48, 48, 200, 331, 48, 48, 209, 209, 332, 48, + 209, 333, 334, 209, 335, 336, 209, 209, 334, 209, 209, 336, 209, 209, 209, 209, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 209, 209, 209, 209, + 48, 337, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 229, + 339, 48, 340, 140, 13, 13, 341, 342, 13, 343, 48, 48, 48, 48, 344, 345, + 31, 346, 347, 348, 13, 13, 13, 349, 350, 351, 352, 353, 354, 355, 140, 356, + 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, + 64, 48, 365, 48, 366, 367, 48, 151, 76, 48, 48, 368, 369, 370, 371, 372, + 48, 48, 373, 374, 375, 376, 48, 377, 48, 48, 48, 378, 379, 380, 381, 382, + 383, 384, 314, 11, 11, 385, 386, 11, 11, 11, 11, 11, 48, 48, 387, 192, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 48, 389, 48, 48, 206, + 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140, 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48, 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403, @@ -2257,108 +2260,204 @@ _hb_ucd_u16[9344] = 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140, 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439, - 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 140, 140, 140, 140, - 48, 48, 48, 314, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, + 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 48, 48, 48, 388, + 48, 48, 48, 313, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453, 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271, 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, - 48, 48, 475, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 271, 476, - 48, 48, 477, 478, 140, 140, 140, 479, 48, 464, 480, 48, 62, 481, 140, 48, - 482, 140, 140, 48, 483, 140, 48, 314, 484, 48, 48, 485, 486, 457, 487, 488, - 222, 48, 48, 489, 490, 48, 196, 192, 491, 48, 492, 493, 494, 48, 48, 495, - 222, 48, 48, 496, 497, 498, 499, 500, 48, 97, 501, 502, 503, 140, 140, 140, - 504, 505, 506, 48, 48, 507, 508, 192, 509, 83, 84, 510, 511, 512, 513, 514, - 48, 48, 48, 515, 516, 517, 478, 140, 48, 48, 48, 518, 519, 192, 140, 140, - 48, 48, 520, 521, 522, 523, 140, 140, 48, 48, 48, 524, 525, 192, 526, 140, - 48, 48, 527, 528, 192, 140, 140, 140, 48, 173, 529, 530, 314, 140, 140, 140, - 48, 48, 501, 531, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 532, - 533, 534, 48, 535, 536, 192, 140, 140, 140, 140, 537, 48, 48, 538, 539, 140, - 540, 48, 48, 541, 542, 543, 48, 48, 544, 545, 546, 48, 48, 48, 48, 196, - 547, 140, 140, 140, 140, 140, 140, 140, 84, 48, 520, 548, 549, 148, 175, 550, - 48, 551, 552, 553, 140, 140, 140, 140, 554, 48, 48, 555, 556, 192, 557, 48, - 558, 559, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 560, - 561, 115, 48, 562, 563, 192, 140, 140, 140, 140, 140, 100, 271, 564, 565, 566, - 48, 207, 140, 140, 140, 140, 140, 140, 272, 272, 272, 272, 272, 272, 567, 568, - 48, 48, 48, 48, 388, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 569, - 48, 48, 48, 570, 571, 572, 140, 140, 48, 48, 48, 48, 314, 140, 140, 140, - 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 573, - 48, 48, 48, 574, 575, 576, 577, 578, 48, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 9, 9, 11, 11, 271, 579, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 580, 581, 582, 582, 583, 584, 140, 140, 140, 140, 585, 586, - 48, 48, 48, 48, 48, 48, 48, 440, 48, 48, 48, 48, 48, 199, 140, 140, - 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 587, - 48, 48, 588, 589, 140, 590, 591, 48, 48, 48, 48, 48, 48, 48, 48, 206, - 48, 48, 48, 48, 48, 48, 71, 151, 196, 592, 593, 140, 140, 140, 140, 140, - 32, 32, 594, 32, 595, 209, 209, 209, 209, 209, 209, 209, 323, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 324, 209, 209, 596, 209, 209, 209, 597, 598, - 599, 209, 600, 209, 209, 209, 288, 140, 209, 209, 209, 209, 601, 140, 140, 140, - 140, 140, 140, 140, 271, 602, 271, 602, 209, 209, 209, 209, 209, 287, 271, 461, - 9, 603, 11, 604, 605, 606, 241, 9, 607, 608, 609, 610, 611, 9, 603, 11, - 612, 613, 11, 614, 615, 616, 617, 9, 618, 11, 9, 603, 11, 604, 605, 11, - 241, 9, 607, 617, 9, 618, 11, 9, 603, 11, 619, 9, 620, 621, 622, 623, - 11, 624, 9, 625, 626, 627, 628, 11, 629, 9, 630, 11, 631, 632, 632, 632, - 32, 32, 32, 633, 32, 32, 634, 635, 636, 637, 45, 140, 140, 140, 140, 140, - 638, 639, 640, 140, 140, 140, 140, 140, 641, 642, 643, 27, 27, 27, 644, 140, - 645, 140, 140, 140, 140, 140, 140, 140, 48, 48, 151, 646, 647, 140, 140, 140, - 140, 48, 648, 140, 48, 48, 649, 650, 140, 140, 140, 140, 140, 48, 651, 192, - 140, 140, 140, 140, 140, 140, 652, 200, 48, 48, 48, 48, 653, 595, 140, 140, - 9, 9, 607, 11, 654, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 499, - 271, 271, 655, 656, 140, 140, 140, 140, 499, 271, 657, 658, 140, 140, 140, 140, - 659, 48, 660, 661, 662, 663, 664, 665, 666, 206, 667, 206, 140, 140, 140, 668, - 209, 209, 669, 209, 209, 209, 209, 209, 209, 323, 334, 670, 670, 670, 209, 324, - 671, 209, 209, 209, 209, 209, 209, 209, 209, 209, 672, 140, 140, 140, 673, 209, - 674, 209, 209, 669, 675, 676, 324, 140, 209, 209, 209, 209, 209, 209, 209, 677, - 209, 209, 209, 209, 209, 678, 426, 426, 209, 209, 209, 209, 209, 209, 209, 679, - 209, 209, 209, 209, 209, 176, 669, 427, 669, 209, 209, 209, 680, 176, 209, 209, - 680, 209, 672, 676, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 672, 426, - 675, 209, 209, 681, 682, 669, 675, 675, 209, 683, 209, 209, 288, 140, 140, 192, - 48, 48, 48, 48, 48, 48, 140, 140, 48, 48, 48, 207, 48, 48, 48, 48, - 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 478, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 100, 48, 48, 48, 48, 48, 48, 204, 140, 140, - 48, 204, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 71, 48, 48, 48, - 48, 48, 48, 140, 140, 140, 140, 140, 684, 140, 570, 570, 570, 570, 570, 570, + 48, 48, 475, 192, 476, 9, 477, 11, 478, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 271, 479, 48, 48, 480, 481, 482, 140, 140, 483, + 48, 464, 484, 48, 62, 485, 140, 48, 486, 140, 140, 48, 487, 140, 48, 313, + 488, 48, 48, 489, 490, 457, 491, 492, 222, 48, 48, 493, 494, 48, 196, 192, + 495, 48, 496, 497, 498, 48, 48, 499, 222, 48, 48, 500, 501, 502, 503, 504, + 48, 97, 505, 506, 507, 140, 140, 140, 508, 509, 510, 48, 48, 511, 512, 192, + 513, 83, 84, 514, 515, 516, 517, 518, 519, 48, 48, 520, 521, 522, 523, 140, + 48, 48, 48, 524, 525, 526, 481, 140, 48, 48, 48, 527, 528, 192, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 529, 530, 531, 532, 140, 140, + 48, 48, 48, 533, 534, 192, 535, 140, 48, 48, 536, 537, 192, 538, 539, 140, + 48, 540, 541, 542, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 505, 543, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 544, + 545, 546, 48, 547, 548, 192, 140, 140, 140, 140, 549, 48, 48, 550, 551, 140, + 552, 48, 48, 553, 554, 555, 48, 48, 556, 557, 558, 48, 48, 48, 48, 196, + 559, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 560, 192, + 84, 48, 529, 561, 562, 148, 175, 563, 48, 564, 565, 566, 140, 140, 140, 140, + 567, 48, 48, 568, 569, 192, 570, 48, 571, 572, 192, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 573, + 574, 115, 48, 575, 576, 577, 140, 140, 140, 140, 140, 100, 271, 578, 579, 580, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, + 272, 272, 272, 272, 272, 272, 581, 582, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 388, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 583, + 48, 48, 48, 584, 585, 586, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 71, + 48, 48, 48, 48, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 587, 588, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 589, + 48, 48, 48, 590, 591, 592, 593, 594, 48, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 595, 48, 596, 192, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 9, 9, 11, 11, 271, 597, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 598, 599, 600, 600, 601, 602, 140, 140, 140, 140, 603, 604, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 440, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 605, + 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 606, + 48, 48, 607, 608, 140, 609, 610, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 206, + 48, 48, 48, 48, 48, 48, 71, 151, 196, 611, 612, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 192, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 140, + 32, 32, 613, 32, 614, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, + 209, 209, 615, 209, 209, 209, 616, 617, 618, 209, 619, 209, 209, 209, 287, 140, + 209, 209, 209, 209, 620, 140, 140, 140, 140, 140, 140, 140, 271, 621, 271, 621, + 209, 209, 209, 209, 209, 338, 271, 461, 140, 140, 140, 140, 140, 140, 140, 140, + 9, 622, 11, 623, 624, 625, 241, 9, 626, 627, 628, 629, 630, 9, 622, 11, + 631, 632, 11, 633, 634, 635, 636, 9, 637, 11, 9, 622, 11, 623, 624, 11, + 241, 9, 626, 636, 9, 637, 11, 9, 622, 11, 638, 9, 639, 640, 641, 642, + 11, 643, 9, 644, 645, 646, 647, 11, 648, 9, 649, 11, 650, 538, 538, 538, + 32, 32, 32, 651, 32, 32, 652, 653, 654, 655, 45, 140, 140, 140, 140, 140, + 656, 657, 658, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 659, 660, 661, 27, 27, 27, 662, 140, 663, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 151, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 666, 140, 48, 48, 667, 668, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 669, 192, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 587, 670, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 671, 200, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 672, 614, 140, 140, + 9, 9, 626, 11, 673, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 503, 271, 271, 674, 675, 140, 140, 140, 140, + 503, 271, 676, 677, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 678, 48, 679, 680, 681, 682, 683, 684, 685, 206, 686, 206, 140, 140, 140, 687, + 209, 209, 688, 209, 209, 209, 209, 209, 209, 322, 333, 689, 689, 689, 209, 323, + 690, 209, 209, 209, 209, 209, 209, 209, 209, 209, 691, 140, 140, 140, 692, 209, + 693, 209, 209, 688, 694, 695, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 696, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 697, 426, 426, + 209, 209, 209, 209, 209, 209, 209, 698, 209, 209, 209, 209, 209, 176, 688, 427, + 688, 209, 209, 209, 699, 176, 209, 209, 699, 209, 691, 688, 695, 140, 140, 140, + 209, 209, 209, 209, 209, 322, 691, 426, 700, 209, 209, 209, 701, 702, 176, 694, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 703, 209, 209, 209, 209, 209, 192, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, + 48, 48, 48, 207, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 481, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 48, + 48, 48, 48, 48, 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, + 704, 140, 584, 584, 584, 584, 584, 584, 140, 140, 140, 140, 140, 140, 140, 140, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, - 391, 391, 391, 391, 391, 391, 391, 685, 391, 391, 391, 391, 391, 391, 391, 686, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 705, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 706, + 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, + 11, 11, 12, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 57, 58, 59, 60, 60, 60, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 7, 4, 4, 4, 4, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 110, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 112, 112, 112, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 114, 0, + 115, 116, 117, 118, 119, 120, 121, 122, 0, 123, 124, 125, 126, 126, 126, 127, + 128, 129, 130, 131, 132, 60, 133, 134, 135, 136, 0, 137, 138, 139, 0, 0, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 0, 126, 126, 126, 126, 126, 126, 126, 126, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 141, 142, 143, 143, 143, 143, 144, 11, 145, 146, 147, 4, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 166, 167, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 168, 168, 168, 168, 126, 126, 126, 126, 126, 169, 126, 170, 171, 172, 19, 173, + 19, 19, 19, 19, 174, 19, 175, 176, 177, 178, 19, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 168, 168, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 206, 206, 206, 207, 208, 209, 168, + 210, 211, 212, 213, 214, 168, 215, 216, 217, 218, 219, 220, 221, 222, 223, 168, + 224, 225, 226, 227, 228, 229, 230, 168, 168, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 168, 168, 258, 259, 260, 261, 262, 263, 264, 265, 168, 168, + 266, 168, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 168, 168, 278, + 279, 280, 281, 168, 282, 283, 284, 168, 168, 168, 168, 285, 286, 287, 288, 289, + 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, 168, + 290, 292, 290, 290, 290, 293, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 294, 295, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 297, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 298, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 168, 168, 168, 168, 168, 168, + 168, 168, 168, 168, 301, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 302, 302, 302, 302, 302, 302, 302, 302, 303, 304, 305, 306, 307, 308, 309, 168, + 168, 168, 168, 168, 168, 310, 168, 168, 168, 311, 312, 168, 313, 314, 315, 316, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 318, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 319, 319, 319, 319, + 319, 319, 319, 320, 321, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 322, + 323, 324, 324, 324, 325, 326, 327, 327, 327, 327, 327, 328, 168, 168, 168, 168, + 329, 330, 331, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, 333, 168, 334, 335, 0, 336, + 0, 0, 0, 337, 338, 339, 340, 341, 189, 342, 168, 343, 0, 344, 168, 168, + 0, 345, 346, 347, 348, 349, 0, 0, 0, 0, 350, 0, 0, 0, 0, 351, + 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 353, 168, 168, 168, 168, 168, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 354, 168, 168, 168, + 355, 356, 357, 168, 358, 359, 168, 168, 168, 168, 360, 361, 168, 168, 168, 168, + 168, 168, 168, 362, 168, 168, 168, 363, 168, 168, 168, 168, 168, 168, 168, 364, + 365, 365, 365, 366, 367, 368, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 168, 369, 370, 168, 371, 168, 168, 168, 372, 373, 374, 375, 168, 168, 168, 168, + 376, 0, 377, 378, 0, 0, 379, 380, 381, 382, 168, 168, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 383, 0, 384, 0, 385, + 386, 387, 388, 389, 0, 0, 0, 0, 0, 390, 391, 392, 0, 0, 393, 332, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 394, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 395, 126, 126, 126, + 396, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 397, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 398, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 399, 168, 168, 168, 168, 168, 168, + 126, 126, 126, 126, 126, 126, 126, 126, 399, 168, 168, 168, 168, 168, 168, 168, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 400, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 401, 168, + 402, 0, 168, 168, 7, 7, 7, 403, 0, 1, 2, 3, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 4, 0, 4, 2, 2, 5, 2, 2, 2, 5, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 6, 0, 0, 0, 0, 7, 8, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 11, - 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, 16, 17, 14, 14, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 20, 21, 21, 21, 22, 20, 21, 21, 21, 21, - 21, 23, 24, 25, 25, 25, 25, 25, 25, 26, 25, 25, 25, 27, 28, 26, - 29, 30, 31, 32, 31, 31, 31, 31, 33, 34, 35, 31, 31, 31, 36, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 29, 31, 31, 31, 31, - 37, 38, 37, 37, 37, 37, 37, 37, 37, 39, 31, 31, 31, 31, 31, 31, - 40, 40, 40, 40, 40, 40, 41, 26, 42, 42, 42, 42, 42, 42, 42, 43, - 44, 44, 44, 44, 44, 45, 44, 46, 47, 47, 47, 48, 37, 49, 31, 31, - 31, 50, 51, 31, 31, 31, 31, 31, 31, 31, 31, 31, 52, 31, 31, 31, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, 53, 55, 53, 53, 53, - 56, 57, 58, 59, 59, 60, 61, 62, 57, 63, 64, 65, 66, 59, 59, 67, - 68, 69, 70, 71, 71, 72, 73, 74, 69, 75, 76, 77, 78, 71, 79, 26, - 80, 81, 82, 83, 83, 84, 85, 86, 81, 87, 88, 26, 89, 83, 90, 91, - 92, 93, 94, 95, 95, 96, 97, 98, 93, 99, 100, 101, 102, 95, 95, 26, - 103, 104, 105, 106, 107, 104, 108, 109, 104, 105, 110, 26, 111, 108, 108, 112, - 113, 114, 115, 113, 113, 115, 113, 116, 114, 117, 118, 119, 120, 113, 121, 113, - 122, 123, 124, 122, 122, 124, 125, 126, 123, 127, 128, 128, 129, 122, 130, 26, - 131, 132, 133, 131, 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131, - 136, 137, 138, 139, 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145, 26, - 146, 147, 147, 147, 147, 147, 147, 148, 147, 147, 147, 149, 26, 26, 26, 26, - 150, 151, 152, 152, 153, 152, 152, 154, 155, 156, 152, 157, 26, 26, 26, 26, - 158, 158, 158, 158, 158, 158, 158, 158, 158, 159, 158, 158, 158, 160, 159, 158, - 158, 158, 158, 159, 158, 158, 158, 161, 158, 161, 162, 163, 26, 26, 26, 26, - 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, + 0, 0, 0, 0, 7, 8, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, + 14, 14, 14, 14, 16, 17, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, + 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 21, + 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, + 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, + 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 29, 31, 31, 31, 31, 37, 38, 37, 37, 37, 37, 37, 37, + 37, 39, 31, 31, 31, 31, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, + 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, + 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 52, 31, 31, 31, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, 59, 60, 61, 62, + 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, 71, 72, 73, 74, + 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, 83, 84, 85, 86, + 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, + 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, 107, 104, 108, 109, + 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116, + 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126, + 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, 131, 131, 131, 131, + 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, 137, 137, 140, 141, + 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, 147, 147, 147, 148, + 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, 153, 152, 152, 154, + 155, 156, 152, 157, 26, 26, 26, 26, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, + 158, 161, 162, 163, 26, 26, 26, 26, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168, - 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 171, 172, 171, 170, 170, 170, 170, - 170, 171, 170, 170, 170, 170, 171, 172, 171, 170, 172, 170, 170, 170, 170, 170, - 170, 170, 171, 170, 170, 170, 170, 170, 170, 170, 170, 173, 170, 170, 170, 174, - 170, 170, 170, 175, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 177, 177, - 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172, + 171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170, + 170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, + 176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 182, 181, 183, 184, 184, 185, 186, 187, 187, 188, 26, 189, 189, 190, 26, 191, 192, 193, 26, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196, @@ -2368,208 +2467,164 @@ _hb_ucd_u16[9344] = 210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 194, 194, 194, 194, 214, 214, 214, 215, 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, 216, 220, 9, 9, 9, 221, 26, 26, 26, 26, 26, 26, - 222, 222, 222, 222, 222, 222, 222, 222, 222, 223, 222, 222, 222, 222, 222, 224, - 225, 225, 225, 225, 225, 225, 225, 225, 226, 226, 226, 226, 226, 226, 227, 228, - 229, 229, 229, 229, 229, 229, 229, 230, 229, 231, 232, 232, 232, 232, 232, 232, - 18, 233, 165, 165, 165, 165, 165, 234, 225, 26, 235, 9, 236, 237, 238, 239, - 2, 2, 2, 2, 240, 241, 2, 2, 2, 2, 2, 242, 243, 244, 2, 245, - 2, 2, 2, 2, 2, 2, 2, 246, 9, 9, 9, 9, 9, 9, 9, 9, - 14, 14, 247, 247, 14, 14, 14, 14, 247, 247, 14, 248, 14, 14, 14, 247, - 14, 14, 14, 14, 14, 14, 249, 14, 249, 14, 250, 251, 14, 14, 252, 253, - 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 256, 257, - 0, 258, 2, 259, 0, 0, 0, 0, 260, 26, 9, 9, 9, 9, 261, 26, - 0, 0, 0, 0, 262, 263, 4, 0, 0, 264, 0, 0, 2, 2, 2, 2, - 2, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 258, 26, 26, 26, 0, 266, 26, 26, 0, 0, 0, 0, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, - 0, 0, 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 2, 2, 2, 2, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 271, 272, - 165, 165, 165, 165, 166, 167, 273, 273, 273, 273, 273, 273, 273, 274, 275, 274, - 170, 170, 172, 26, 172, 172, 172, 172, 172, 172, 172, 172, 18, 18, 18, 18, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, 26, 26, 26, 26, + 222, 222, 222, 222, 222, 222, 222, 222, 222, 223, 222, 222, 222, 222, 222, 222, + 224, 224, 224, 224, 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, + 228, 228, 228, 228, 228, 228, 228, 229, 228, 230, 231, 231, 231, 231, 231, 231, + 18, 232, 165, 165, 165, 165, 165, 233, 224, 26, 234, 9, 235, 236, 237, 238, + 2, 2, 2, 2, 239, 240, 2, 2, 2, 2, 2, 241, 242, 243, 2, 244, + 2, 2, 2, 2, 2, 2, 2, 245, 14, 14, 246, 246, 14, 14, 14, 14, + 246, 246, 14, 247, 14, 14, 14, 246, 14, 14, 14, 14, 14, 14, 248, 14, + 248, 14, 249, 250, 14, 14, 251, 252, 0, 253, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 254, 0, 255, 256, 0, 257, 2, 258, 0, 0, 0, 0, + 259, 26, 9, 9, 9, 9, 260, 26, 0, 0, 0, 0, 261, 262, 4, 0, + 0, 263, 0, 0, 2, 2, 2, 2, 2, 264, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 265, 26, 26, 0, 266, 26, 26, 0, 0, 0, 0, + 267, 267, 267, 267, 267, 267, 267, 267, 0, 0, 0, 0, 0, 0, 268, 0, + 0, 0, 269, 0, 0, 0, 0, 0, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 2, 2, 2, 2, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 271, 272, 165, 165, 165, 165, 166, 167, 273, 273, + 273, 273, 273, 273, 273, 274, 275, 274, 170, 170, 172, 26, 172, 172, 172, 172, + 172, 172, 172, 172, 18, 18, 18, 18, 0, 0, 0, 276, 26, 26, 26, 26, 277, 277, 277, 278, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 279, 26, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 26, 26, 26, 0, 0, 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, - 292, 293, 293, 293, 293, 293, 294, 169, 169, 169, 169, 169, 169, 169, 169, 169, - 169, 295, 0, 0, 293, 293, 293, 293, 0, 0, 0, 0, 296, 297, 290, 290, - 169, 169, 169, 295, 0, 0, 0, 0, 0, 0, 0, 0, 169, 169, 169, 298, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 290, 290, 290, 290, 299, + 292, 293, 293, 293, 293, 293, 294, 169, 169, 295, 0, 0, 293, 293, 293, 293, + 0, 0, 0, 0, 276, 296, 290, 290, 169, 169, 169, 295, 0, 0, 0, 0, + 0, 0, 0, 0, 169, 169, 169, 297, 0, 0, 290, 290, 290, 290, 290, 298, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 0, 0, 0, 0, 0, - 277, 277, 277, 277, 277, 277, 277, 277, 0, 0, 0, 0, 0, 0, 0, 0, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 301, 300, 300, 300, 300, 300, 300, 302, 26, 303, 303, 303, 303, 303, 303, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 305, 26, 26, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 26, - 0, 0, 0, 0, 307, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 308, 2, 2, 2, 2, 2, 2, 2, 309, 310, 311, 26, 26, 312, 2, - 313, 313, 313, 313, 313, 314, 0, 315, 316, 316, 316, 316, 316, 316, 316, 26, - 317, 317, 317, 317, 317, 317, 317, 317, 318, 319, 317, 320, 53, 53, 53, 53, - 321, 321, 321, 321, 321, 322, 323, 323, 323, 323, 324, 325, 169, 169, 169, 326, - 327, 327, 327, 327, 327, 327, 327, 327, 327, 328, 327, 329, 164, 164, 164, 330, - 331, 331, 331, 331, 331, 331, 332, 26, 331, 333, 331, 334, 164, 164, 164, 164, - 335, 335, 335, 335, 335, 335, 335, 335, 336, 26, 26, 337, 338, 338, 339, 26, - 340, 340, 340, 26, 172, 172, 2, 2, 2, 2, 2, 341, 342, 343, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 338, 338, 338, 338, 338, 344, 338, 345, - 169, 169, 169, 169, 346, 26, 169, 169, 295, 347, 169, 169, 169, 169, 169, 346, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 348, 26, 26, 26, 26, - 349, 26, 350, 351, 25, 25, 352, 353, 354, 25, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 355, 26, 356, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 357, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 358, 31, 31, 31, 31, 31, 31, 359, 26, 26, 26, 26, 31, 31, - 9, 9, 0, 315, 9, 360, 0, 0, 0, 0, 361, 0, 258, 296, 362, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 363, - 364, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 365, 290, 289, 290, - 290, 290, 290, 366, 169, 169, 169, 295, 367, 367, 367, 368, 258, 258, 26, 369, - 370, 371, 370, 370, 372, 370, 370, 373, 370, 374, 370, 374, 26, 26, 26, 26, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 375, - 376, 0, 0, 0, 0, 0, 377, 0, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 253, 0, 378, 379, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 380, - 381, 381, 381, 382, 383, 383, 383, 383, 383, 383, 384, 26, 385, 0, 0, 296, - 386, 386, 386, 386, 387, 388, 389, 389, 389, 390, 391, 391, 391, 391, 391, 392, - 393, 393, 393, 394, 395, 395, 395, 395, 396, 395, 397, 26, 26, 26, 26, 26, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 399, 399, 399, 399, 399, 399, - 400, 400, 400, 401, 400, 402, 403, 403, 403, 403, 404, 403, 403, 403, 403, 404, - 405, 405, 405, 405, 405, 26, 406, 406, 406, 406, 406, 406, 407, 408, 409, 410, - 409, 410, 411, 409, 412, 409, 412, 413, 26, 26, 26, 26, 26, 26, 26, 26, - 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, - 414, 414, 414, 414, 414, 414, 415, 26, 414, 414, 416, 26, 414, 26, 26, 26, - 417, 2, 2, 2, 2, 2, 418, 309, 26, 26, 26, 26, 26, 26, 26, 26, - 419, 420, 421, 421, 421, 421, 422, 423, 424, 424, 425, 424, 426, 426, 426, 426, - 427, 427, 427, 428, 429, 427, 26, 26, 26, 26, 26, 26, 430, 430, 431, 432, - 433, 433, 433, 434, 435, 435, 435, 436, 26, 26, 26, 26, 26, 26, 26, 26, - 437, 437, 437, 437, 438, 438, 438, 439, 438, 438, 440, 438, 438, 438, 438, 438, - 441, 442, 443, 444, 445, 445, 446, 447, 445, 448, 445, 448, 449, 449, 449, 449, - 450, 450, 450, 450, 26, 26, 26, 26, 451, 451, 451, 451, 452, 453, 452, 26, - 454, 454, 454, 454, 454, 454, 455, 456, 457, 457, 458, 457, 459, 459, 460, 459, - 461, 461, 462, 463, 26, 464, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 466, 26, 26, 26, 26, 26, 26, - 467, 467, 467, 467, 467, 467, 468, 26, 467, 467, 467, 467, 467, 467, 468, 469, - 470, 470, 470, 470, 470, 26, 470, 471, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 31, 31, 50, - 472, 472, 472, 472, 472, 473, 474, 26, 26, 26, 26, 26, 26, 26, 26, 475, - 476, 476, 476, 476, 476, 26, 477, 477, 477, 477, 477, 478, 26, 26, 479, 479, - 479, 480, 26, 26, 26, 26, 481, 481, 481, 482, 26, 26, 483, 483, 484, 26, - 485, 485, 485, 485, 485, 485, 485, 485, 485, 486, 487, 485, 485, 485, 486, 488, - 489, 489, 489, 489, 489, 489, 489, 489, 490, 491, 492, 492, 492, 493, 492, 494, - 495, 495, 495, 495, 495, 495, 496, 495, 495, 26, 497, 497, 497, 497, 498, 26, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 500, 137, 501, 26, - 502, 502, 503, 502, 502, 502, 502, 502, 504, 26, 26, 26, 26, 26, 26, 26, - 505, 506, 507, 508, 507, 509, 510, 510, 510, 510, 510, 510, 510, 511, 510, 512, - 513, 514, 515, 516, 516, 517, 518, 519, 514, 520, 521, 522, 523, 524, 524, 26, - 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 526, 527, 26, 26, 26, - 528, 528, 528, 528, 528, 528, 528, 528, 528, 26, 528, 529, 26, 26, 26, 26, - 530, 530, 530, 530, 530, 530, 531, 530, 530, 530, 530, 531, 26, 26, 26, 26, - 532, 532, 532, 532, 532, 532, 532, 532, 533, 26, 532, 534, 198, 535, 26, 26, - 536, 536, 536, 536, 536, 536, 536, 537, 536, 537, 26, 26, 26, 26, 26, 26, - 538, 538, 538, 539, 538, 540, 538, 538, 541, 26, 26, 26, 26, 26, 26, 26, - 542, 542, 542, 542, 542, 542, 542, 543, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 545, 546, - 547, 548, 549, 550, 550, 550, 551, 552, 547, 26, 550, 553, 26, 26, 26, 26, - 26, 26, 26, 26, 554, 555, 554, 554, 554, 554, 554, 555, 556, 26, 26, 26, - 557, 557, 557, 557, 557, 557, 557, 557, 557, 26, 558, 558, 558, 558, 558, 558, - 558, 558, 558, 558, 559, 26, 178, 178, 560, 560, 560, 560, 560, 560, 560, 561, - 53, 562, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 563, 564, 563, 563, 563, 563, 565, 563, 566, 26, 563, 563, 563, 567, 568, 568, - 568, 568, 569, 568, 568, 570, 571, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 572, 573, 574, 574, 574, 574, 572, 575, 574, 26, 574, 576, 577, 578, 579, 579, - 579, 580, 581, 582, 579, 583, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 584, 584, 584, 585, - 586, 586, 587, 586, 586, 586, 586, 588, 586, 586, 586, 589, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 590, 26, 108, 108, 108, 108, 108, 108, 591, 592, - 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, - 593, 593, 593, 594, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 595, 596, 26, - 593, 593, 593, 593, 593, 593, 593, 593, 597, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 599, 26, - 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, - 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 601, 26, 26, 26, 26, 26, - 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, - 602, 602, 602, 602, 602, 602, 602, 602, 603, 26, 26, 26, 26, 26, 26, 26, - 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 306, 306, 306, 306, 306, 306, 306, 604, 605, 605, 605, 606, 605, 607, 608, 608, - 608, 608, 608, 608, 608, 608, 608, 609, 608, 610, 611, 611, 611, 612, 612, 26, - 613, 613, 613, 613, 613, 613, 613, 613, 614, 26, 613, 615, 615, 613, 613, 616, - 613, 613, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 617, 617, 617, 617, 617, 617, 617, 617, - 617, 617, 617, 618, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 619, 619, 619, 619, 619, 619, 619, 619, 619, 620, 619, 619, 619, 619, 619, 619, - 619, 621, 619, 619, 26, 26, 26, 26, 26, 26, 26, 26, 622, 26, 348, 26, - 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, - 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 26, - 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, - 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 625, 26, 26, 26, 26, 26, - 623, 626, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 627, 628, - 629, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 286, 286, 630, 26, 631, 26, 26, 26, 632, 26, 633, 26, 634, 634, - 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, - 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 635, - 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 637, 636, 638, - 636, 639, 636, 640, 296, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 9, 9, 9, 9, 9, 641, 9, 9, 221, 26, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 296, 26, 26, 26, 26, 26, 26, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, 26, - 0, 0, 0, 0, 258, 364, 0, 0, 0, 0, 0, 0, 642, 643, 0, 644, - 645, 646, 0, 0, 0, 647, 0, 0, 0, 0, 0, 0, 0, 266, 26, 26, - 14, 14, 14, 14, 14, 14, 14, 14, 247, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 296, 26, 0, 0, 296, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 26, 0, 0, 0, 260, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 255, 648, 649, 0, 650, 651, 0, 0, 0, 0, 0, 0, 0, - 269, 652, 255, 255, 0, 0, 0, 653, 654, 655, 656, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, - 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, - 657, 658, 26, 659, 660, 657, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 2, 2, 2, 349, 661, 309, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 662, 270, 270, 663, 664, 665, 18, 18, 18, 18, 18, 18, 18, 666, 26, 26, - 26, 667, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 668, 668, 668, 668, 668, 669, 668, 670, 668, 671, 26, 26, 26, 26, 26, 26, - 26, 26, 672, 672, 672, 673, 26, 26, 674, 674, 674, 674, 674, 674, 674, 675, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 676, 676, 676, 676, 676, 677, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 172, 678, 170, 172, - 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, - 679, 679, 679, 679, 679, 679, 679, 679, 680, 679, 681, 26, 26, 26, 26, 26, - 682, 682, 682, 682, 682, 682, 682, 682, 682, 683, 682, 684, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 364, 0, - 0, 0, 0, 0, 0, 0, 378, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 364, 0, 0, 0, 0, 0, 0, 276, 26, 26, 26, 26, 26, 26, 26, 26, - 685, 31, 31, 31, 686, 687, 688, 689, 690, 691, 686, 692, 686, 688, 688, 693, - 31, 694, 31, 695, 696, 694, 31, 695, 26, 26, 26, 26, 26, 26, 51, 26, - 0, 0, 0, 0, 0, 296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 26, 0, 258, 364, 0, 364, 0, 364, 0, 0, 0, 276, 26, - 0, 0, 0, 0, 0, 276, 26, 26, 26, 26, 26, 26, 697, 0, 0, 0, - 698, 26, 0, 0, 0, 0, 0, 296, 0, 260, 315, 26, 276, 26, 26, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 699, 0, 378, 0, 378, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 700, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 315, 0, 296, 260, 26, - 0, 296, 0, 0, 0, 0, 0, 0, 0, 26, 0, 315, 0, 0, 0, 0, - 0, 26, 0, 0, 0, 276, 315, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, 26, 0, 276, 0, 378, - 0, 260, 0, 0, 0, 0, 0, 269, 276, 697, 0, 296, 0, 260, 0, 260, - 0, 0, 361, 0, 0, 0, 0, 0, 0, 266, 26, 26, 26, 26, 0, 315, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 26, 26, 26, - 277, 277, 277, 277, 277, 277, 277, 348, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 348, 26, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 701, 26, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 26, 26, 26, 26, - 277, 277, 277, 280, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 702, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 703, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 299, 299, 299, 299, 299, 299, + 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 304, 26, 26, 18, 18, 18, 18, 305, 305, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 26, 0, 0, 0, 0, 306, 2, 2, 2, + 2, 307, 2, 2, 2, 2, 2, 2, 2, 308, 309, 258, 26, 26, 310, 2, + 311, 311, 311, 311, 311, 312, 0, 265, 313, 313, 313, 313, 313, 313, 313, 26, + 314, 314, 314, 314, 314, 314, 314, 314, 315, 316, 314, 317, 53, 53, 53, 53, + 318, 318, 318, 318, 318, 319, 320, 320, 320, 320, 321, 322, 169, 169, 169, 323, + 324, 324, 324, 324, 324, 324, 324, 324, 324, 325, 324, 326, 164, 164, 164, 327, + 328, 328, 328, 328, 328, 328, 329, 26, 328, 330, 328, 331, 164, 164, 164, 164, + 332, 332, 332, 332, 332, 332, 332, 332, 333, 26, 26, 334, 335, 335, 336, 26, + 337, 337, 337, 26, 172, 172, 2, 2, 2, 2, 2, 338, 339, 340, 176, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 335, 335, 335, 335, 335, 341, 335, 342, + 169, 169, 169, 169, 343, 26, 169, 169, 295, 344, 169, 169, 169, 169, 169, 343, + 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 280, 277, 277, + 277, 277, 277, 345, 26, 26, 26, 26, 346, 26, 347, 348, 25, 25, 349, 350, + 351, 25, 31, 31, 31, 31, 31, 31, 352, 26, 353, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 354, 31, 31, 355, 31, 31, 31, 31, 31, + 31, 356, 26, 26, 26, 26, 31, 31, 9, 9, 0, 265, 9, 357, 0, 0, + 0, 0, 358, 0, 257, 359, 360, 31, 31, 31, 31, 31, 31, 31, 31, 361, + 362, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 363, 290, 289, 290, + 290, 290, 290, 364, 169, 169, 169, 295, 365, 365, 365, 366, 257, 257, 26, 367, + 368, 369, 368, 368, 370, 368, 368, 371, 368, 372, 368, 372, 26, 26, 26, 26, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 373, + 374, 0, 0, 0, 0, 0, 375, 0, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 252, 0, 376, 377, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 378, + 379, 379, 379, 380, 381, 381, 381, 381, 381, 381, 382, 26, 383, 0, 0, 359, + 384, 384, 384, 384, 385, 386, 387, 387, 387, 388, 389, 389, 389, 389, 389, 390, + 391, 391, 391, 392, 393, 393, 393, 393, 394, 393, 395, 26, 26, 26, 26, 26, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 397, 397, 397, 397, 397, 397, + 398, 398, 398, 399, 398, 400, 401, 401, 401, 401, 402, 401, 401, 401, 401, 402, + 403, 403, 403, 403, 403, 26, 404, 404, 404, 404, 404, 404, 405, 406, 407, 408, + 407, 408, 409, 407, 410, 407, 410, 411, 412, 412, 412, 412, 412, 412, 413, 26, + 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 415, 26, + 414, 414, 416, 26, 414, 26, 26, 26, 417, 2, 2, 2, 2, 2, 418, 419, + 420, 421, 422, 422, 422, 422, 423, 424, 425, 425, 426, 425, 427, 427, 427, 427, + 428, 428, 428, 429, 430, 428, 26, 26, 26, 26, 26, 26, 431, 431, 432, 433, + 434, 434, 434, 435, 436, 436, 436, 437, 438, 438, 438, 438, 439, 439, 439, 440, + 439, 439, 441, 439, 439, 439, 439, 439, 442, 443, 444, 445, 446, 446, 447, 448, + 446, 449, 446, 449, 450, 450, 450, 450, 451, 451, 451, 451, 26, 26, 26, 26, + 452, 452, 452, 452, 453, 454, 453, 26, 455, 455, 455, 455, 455, 455, 456, 457, + 458, 458, 459, 458, 460, 460, 461, 460, 462, 462, 463, 464, 26, 465, 26, 26, + 466, 466, 466, 466, 466, 466, 466, 466, 466, 467, 26, 26, 26, 26, 26, 26, + 468, 468, 468, 468, 468, 468, 469, 26, 468, 468, 468, 468, 468, 468, 469, 470, + 471, 471, 471, 471, 471, 26, 471, 472, 473, 473, 473, 473, 474, 475, 473, 473, + 474, 476, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 31, 31, 50, + 477, 477, 477, 477, 477, 478, 479, 26, 480, 26, 26, 26, 26, 26, 26, 481, + 482, 482, 482, 482, 482, 26, 483, 483, 483, 483, 483, 484, 26, 26, 485, 485, + 485, 486, 26, 26, 26, 26, 487, 487, 487, 488, 26, 26, 489, 489, 490, 26, + 491, 491, 491, 491, 491, 491, 491, 491, 491, 492, 493, 491, 491, 491, 492, 494, + 495, 495, 495, 495, 495, 495, 495, 495, 496, 497, 498, 498, 498, 499, 498, 500, + 501, 501, 501, 501, 501, 501, 502, 501, 501, 26, 503, 503, 503, 503, 504, 26, + 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 506, 137, 507, 26, + 508, 508, 509, 508, 508, 508, 508, 508, 510, 26, 26, 26, 26, 26, 26, 26, + 511, 512, 513, 514, 513, 515, 516, 516, 516, 516, 516, 516, 516, 517, 516, 518, + 519, 520, 521, 522, 522, 523, 524, 525, 520, 526, 527, 528, 529, 530, 530, 26, + 531, 532, 531, 531, 531, 531, 533, 531, 534, 535, 533, 536, 537, 26, 26, 26, + 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 539, 540, 26, 26, 26, + 541, 541, 541, 541, 541, 541, 541, 541, 541, 26, 541, 542, 26, 26, 26, 26, + 543, 543, 543, 543, 543, 543, 544, 543, 543, 543, 543, 544, 26, 26, 26, 26, + 545, 545, 545, 545, 545, 545, 545, 545, 546, 26, 545, 547, 198, 548, 26, 26, + 549, 549, 549, 549, 549, 549, 549, 550, 549, 550, 164, 164, 551, 26, 26, 26, + 552, 552, 552, 553, 552, 554, 552, 552, 555, 26, 26, 26, 26, 26, 26, 26, + 556, 556, 556, 556, 556, 556, 556, 557, 26, 26, 26, 26, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 559, 560, 561, 562, 563, 564, 564, 564, 565, 566, + 561, 26, 564, 567, 26, 26, 26, 26, 26, 26, 26, 26, 568, 569, 568, 568, + 568, 568, 568, 569, 570, 26, 26, 26, 571, 571, 571, 571, 571, 571, 571, 571, + 571, 26, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 573, 26, 178, 178, + 574, 574, 574, 574, 574, 574, 574, 575, 53, 576, 26, 26, 26, 26, 26, 26, + 577, 577, 577, 577, 578, 26, 577, 578, 579, 580, 579, 579, 579, 579, 581, 579, + 582, 26, 579, 579, 579, 583, 584, 584, 584, 584, 585, 584, 584, 586, 587, 26, + 588, 589, 590, 590, 590, 590, 588, 591, 590, 26, 590, 592, 593, 594, 595, 595, + 595, 596, 597, 598, 595, 599, 26, 26, 26, 26, 26, 26, 600, 600, 600, 601, + 602, 602, 603, 602, 602, 602, 602, 604, 602, 602, 602, 605, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 606, 26, 108, 108, 108, 108, 108, 108, 607, 608, + 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 610, 26, 26, 26, 26, + 609, 609, 609, 609, 609, 611, 612, 26, 613, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 615, 26, + 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617, 26, 616, 616, 616, 616, + 616, 616, 616, 616, 616, 616, 616, 618, 619, 619, 619, 619, 619, 619, 619, 619, + 620, 26, 26, 26, 26, 26, 26, 26, 621, 621, 621, 621, 621, 621, 621, 622, + 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 623, + 624, 624, 624, 625, 624, 626, 627, 627, 627, 627, 627, 627, 627, 627, 627, 628, + 627, 629, 630, 630, 630, 631, 631, 26, 632, 632, 632, 632, 632, 632, 632, 632, + 633, 26, 632, 634, 634, 632, 632, 635, 632, 632, 26, 26, 26, 26, 26, 26, + 636, 636, 636, 636, 636, 636, 636, 637, 638, 638, 638, 638, 638, 638, 638, 638, + 638, 638, 638, 639, 26, 26, 26, 26, 640, 640, 640, 640, 640, 640, 640, 640, + 640, 641, 640, 640, 640, 640, 640, 640, 640, 642, 640, 640, 26, 26, 26, 26, + 26, 26, 26, 26, 643, 26, 345, 26, 644, 644, 644, 644, 644, 644, 644, 644, + 644, 644, 644, 644, 644, 644, 644, 26, 645, 645, 645, 645, 645, 645, 645, 645, + 645, 645, 646, 26, 26, 26, 26, 647, 644, 648, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 649, 650, 651, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 652, 26, 653, 26, + 26, 26, 654, 26, 655, 26, 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, + 656, 656, 656, 656, 656, 656, 656, 657, 658, 658, 658, 658, 658, 658, 658, 658, + 658, 658, 658, 658, 658, 659, 658, 660, 658, 661, 658, 662, 359, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 265, 0, 0, 0, 0, 0, 0, 359, 26, + 9, 9, 9, 9, 9, 663, 9, 9, 221, 26, 0, 0, 0, 0, 0, 0, + 359, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 276, 26, + 0, 0, 0, 0, 257, 362, 0, 0, 0, 0, 0, 0, 664, 665, 0, 666, + 667, 668, 0, 0, 0, 669, 0, 0, 0, 0, 0, 0, 0, 266, 26, 26, + 246, 26, 26, 26, 26, 26, 26, 26, 0, 0, 359, 26, 0, 0, 359, 26, + 0, 0, 257, 26, 0, 0, 0, 259, 0, 0, 254, 0, 0, 0, 0, 0, + 0, 0, 0, 254, 670, 671, 0, 672, 673, 0, 0, 0, 0, 0, 0, 0, + 269, 674, 254, 254, 0, 0, 0, 675, 676, 677, 678, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 276, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, + 679, 679, 679, 679, 679, 679, 679, 679, 679, 680, 26, 681, 682, 679, 26, 26, + 2, 2, 2, 346, 683, 419, 26, 26, 684, 270, 270, 685, 686, 687, 18, 18, + 18, 18, 18, 18, 18, 688, 26, 26, 26, 689, 26, 26, 26, 26, 26, 26, + 690, 690, 690, 690, 690, 691, 690, 692, 690, 693, 26, 26, 26, 26, 26, 26, + 26, 26, 694, 694, 694, 695, 26, 26, 696, 696, 696, 696, 696, 696, 696, 697, + 26, 26, 698, 698, 698, 698, 698, 699, 26, 26, 700, 700, 700, 700, 700, 701, + 26, 26, 26, 26, 172, 702, 170, 172, 703, 703, 703, 703, 703, 703, 703, 703, + 704, 703, 705, 26, 26, 26, 26, 26, 706, 706, 706, 706, 706, 706, 706, 706, + 706, 707, 706, 708, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 362, 0, + 0, 0, 0, 0, 0, 0, 376, 26, 362, 0, 0, 0, 0, 0, 0, 276, + 709, 31, 31, 31, 710, 711, 712, 713, 714, 715, 710, 716, 710, 712, 712, 717, + 31, 718, 31, 719, 720, 718, 31, 719, 26, 26, 26, 26, 26, 26, 721, 26, + 0, 0, 0, 0, 0, 359, 0, 0, 0, 0, 359, 26, 0, 257, 362, 0, + 362, 0, 362, 0, 0, 0, 276, 26, 0, 0, 0, 0, 0, 276, 26, 26, + 26, 26, 26, 26, 722, 0, 0, 0, 723, 26, 0, 0, 0, 0, 0, 359, + 0, 259, 265, 26, 276, 26, 26, 26, 0, 0, 0, 724, 0, 376, 0, 376, + 0, 0, 0, 0, 0, 0, 257, 725, 0, 0, 0, 265, 0, 359, 259, 26, + 0, 359, 0, 0, 0, 0, 0, 0, 0, 26, 0, 265, 0, 0, 0, 0, + 0, 26, 0, 0, 0, 276, 0, 359, 265, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 359, 26, 0, 276, 0, 376, 0, 726, 0, 0, 0, 0, 0, 0, + 257, 722, 0, 727, 0, 265, 0, 259, 0, 0, 358, 0, 0, 0, 0, 0, + 277, 277, 277, 277, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 345, + 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 345, 26, 277, 277, + 277, 277, 277, 277, 728, 26, 277, 277, 277, 277, 277, 280, 26, 26, 26, 26, + 277, 729, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 26, + 730, 26, 26, 26, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, @@ -2732,17 +2787,24 @@ _hb_ucd_u16[9344] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603,1934,1935,1574,1575, 1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589,1591, 0,1592, 0, 1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582,1578,1590,1597, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0,1937, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1939,1940, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1944,1943, 0,1945, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1946,1947, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1949,1950, - 1951,1952,1953,1954,1955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1956,1957,1958,1960,1959, - 1961, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0,1939, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1940, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1941,1942, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1943,1944, 0, 0, 0, + 0, 0, 0,1945, 0,1946, 0, 0, 0, 0, 0, 0, 0, 0,1947, 0, + 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1950, 0,1949,1951, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1953,1952, 0,1954, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1957, 0, 0, 0, 0, 0, 0, 0, + 0,1958,1961,1959,1965,1960,1962,1964,1963, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1967,1966,1968, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1969,1970, + 1971,1972,1973,1974,1975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1976,1977,1978,1980,1979, + 1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, @@ -2799,12 +2861,12 @@ _hb_ucd_i16[196] = static inline uint_fast8_t _hb_ucd_gc (unsigned u) { - return u<1114110u?_hb_ucd_u8[6808+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + return u<1114110u?_hb_ucd_u8[6472+(((_hb_ucd_u8[816+(((_hb_ucd_u16[((_hb_ucd_u8[272+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15u))])<<4)+((u>>1>>3)&15u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; } static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[8800+(((_hb_ucd_u8[8244+(((_hb_ucd_u8[7784+(((_hb_ucd_u8[7432+(((_hb_ucd_u8[7186+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + return u<125259u?_hb_ucd_u8[8504+(((_hb_ucd_u8[7936+(((_hb_ucd_u8[7460+(((_hb_ucd_u8[7100+(((_hb_ucd_u8[6854+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -2814,107 +2876,76 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9548+(((_hb_ucd_u8[9428+(((_hb_ucd_b4(9300+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9252+(((_hb_ucd_u8[9132+(((_hb_ucd_b4(9004+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[11070+(((_hb_ucd_u16[2048+(((_hb_ucd_u8[10334+(((_hb_ucd_u8[9884+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2; + return u<918000u?_hb_ucd_u8[10486+(((_hb_ucd_u16[3744+(((_hb_ucd_u16[2624+(((_hb_ucd_u8[9588+(u>>3>>3>>4)])<<4)+((u>>3>>3)&15u))])<<3)+((u>>3)&7u))])<<3)+((u)&7u))]:2; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6032+(((_hb_ucd_u8[17084+(((_hb_ucd_u8[16702+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102u?_hb_ucd_u16[6976+(((_hb_ucd_u8[16716+(((_hb_ucd_u8[16334+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; } #elif !defined(HB_NO_UCD_UNASSIGNED) static const uint8_t -_hb_ucd_u8[14752] = +_hb_ucd_u8[17524] = { - 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 11, 12, 13, 13, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 22, 22, 22, 22, 24, 7, 7, - 25, 26, 22, 22, 22, 27, 28, 29, 22, 30, 31, 32, 33, 34, 35, 36, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 22, 42, - 7, 7, 43, 7, 44, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 45, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 46, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 47, + 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 5, 5, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 5, 17, 15, 18, 19, 20, 21, 22, 23, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 25, 26, 5, 27, 28, + 5, 29, 30, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 31, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 32, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 33, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 34, 35, 36, 37, 38, 39, 34, 34, 34, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 64, 65, 66, 67, 68, 69, 70, 71, 69, 72, 73, - 69, 69, 64, 74, 64, 64, 75, 76, 77, 78, 79, 80, 81, 82, 69, 83, - 84, 85, 86, 87, 88, 89, 69, 69, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 90, 34, 34, 34, 34, - 91, 34, 34, 34, 34, 34, 34, 34, 34, 92, 34, 34, 93, 94, 95, 96, - 97, 98, 99,100,101,102,103,104, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,105, - 106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, - 107,107, 34, 34,108,109,110,111, 34, 34,112,113,114,115,116,117, - 118,119,120,121,122,123,124,125,126,127,128,129, 34, 34,130,131, - 132,133,134,135,136,137,138,139,140,141,142,122,143,144,145,146, - 147,148,149,150,151,152,153,122,154,155,122,156,157,158,159,122, - 160,161,162,163,164,165,166,122,167,168,169,170,122,171,172,173, - 34, 34, 34, 34, 34, 34, 34,174,175, 34,176,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,177, - 34, 34, 34, 34, 34, 34, 34, 34,178,122,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122, 34, 34, 34, 34,179,122,122,122, - 34, 34, 34, 34,180,181,182,183,122,122,122,122,184,185,186,187, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,188, - 34, 34, 34, 34, 34, 34, 34, 34, 34,189,190,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,191, - 34, 34,192, 34, 34,193,122,122,122,122,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122,194,195,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,196,197, - 69,198,199,200,201,202,203,122,204,205,206,207,208,209,210,211, - 69, 69, 69, 69,212,213,122,122,122,122,122,122,122,122,214,122, - 215,216,217,122,122,218,122,122,122,219,122,122,122,122,122,220, - 34,221,222,122,122,122,122,122,223,224,225,122,226,227,122,122, - 228,229,230,231,232,122, 69,233, 69, 69, 69, 69, 69,234,235,236, - 237,238, 69, 69,239,240, 69,241,122,122,122,122,122,122,122,122, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,242, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,243, 34, - 244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,245, 34, 34, - 34, 34, 34, 34, 34, 34, 34,246, 34, 34, 34, 34,247,122,122,122, - 34, 34, 34, 34,248,122,122,122,122,122,122,122,122,122,122,122, - 34, 34, 34, 34, 34, 34,249, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34,250,122,122,122,122,122,122,122,122, - 251,122,252,253,122,122,122,122,122,122,122,122,122,122,122,122, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,254, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,255, + 16, 17, 18, 19, 20, 17, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 33, 41, 42, 43, 44, 45, + 46, 47, 48, 39, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 50, 17, 17, 17, 51, 17, 52, 53, 54, 55, 56, 57, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 58, 59, 59, 59, 59, 59, 59, 59, 59, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 17, 61, 62, 17, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 17, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 17, 17, 17, 97, 98, 99,100,100,100,100,100,100,100,100,100,101, + 17, 17, 17, 17,102, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17,103, 17, 17,104,100,100,100,100,100,100,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,105,100,100,100,100,100,100, 17, 17,106,107,100,108,109,110, + 17, 17, 17, 17, 17, 17, 17,111, 17, 17, 17, 17,112,113,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,114, + 17,115,116,100,100,100,100,100,100,100,100,100,117,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,118, 39,119,120, + 121,122,123,124,125,126,127,128, 39, 39,129,100,100,100,100,130, + 131,132,133,100,134,135,100,136,137,138,100,100,139,140,141,100, + 142,143,144,145, 39, 39,146,147,148, 39,149,150,100,100,100,100, + 17, 17, 17, 17, 17, 17,151, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17,152,153, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,154, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,155, 17, 17,156,100, + 100,100,100,100,100,100,100,100, 17, 17,157,100,100,100,100,100, + 17, 17, 17,158, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17,159,100,100,100,100,100,100,100,100,100,100,100,100, + 160,161,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,162, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,163, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, @@ -2951,7 +2982,7 @@ _hb_ucd_u8[14752] = 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, - 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 44, 43, 43, 43, 43, + 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 57, 43, 43, 43, 43, 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43, 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86, 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36, @@ -3024,13 +3055,13 @@ _hb_ucd_u8[14752] = 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57, 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109, 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36, - 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 44, - 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 64, + 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 2, + 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 2, 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36, 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2, 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2, 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 16, 16, 16, 16,110, 44, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, + 16, 16, 16, 16, 34,110, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43, 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44, 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16, @@ -3058,33 +3089,33 @@ _hb_ucd_u8[14752] = 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67, 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, - 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 92, 44, 44, 27, 27, 27, 27, 27, 27, 67, 67, - 67, 67, 67, 67, 67, 27, 27, 27, 67, 67, 67, 26, 67, 67, 67, 67, - 26, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, 8, 8, - 67, 67, 67, 67, 67, 67, 67, 26, 67, 67, 67, 67, 4, 4, 4, 4, - 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, - 8, 8,129,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, - 8,129,148,148,148,148,148,148,148,148,148,148,147, 8, 8, 8, - 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, - 8, 8,144, 26, 8, 8,144, 67, 67, 67, 44, 67, 67, 67, 67, 67, - 67, 67, 67, 55, 67, 67, 67, 67, 32, 11, 32, 34, 34, 34, 34, 11, - 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,140, 67, 67,138, 34,149, - 43, 32, 44, 44, 93, 2, 99, 2, 16, 16, 16,150, 44, 44,150, 44, - 36, 36, 36, 36, 44, 44, 44, 52, 64, 44, 44, 44, 44, 44, 44, 57, - 36, 36, 36, 61, 44, 44, 44, 44, 36, 36, 36, 61, 36, 36, 36, 61, - 2,121,121, 2,125,126,121, 2, 2, 2, 2, 6, 2,108,121, 2, - 121, 4, 4, 4, 4, 2, 2, 88, 2, 2, 2, 2, 2,120, 2, 2, - 108,151, 2, 2, 2, 2, 2, 2, 67, 2,152,148,148,148,153, 44, - 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 44, 44, 44, 44, 44, 1, 2,154,155, 4, 4, 4, 4, - 4, 67, 4, 4, 4, 4,156,157,158,105,105,105,105, 43, 43, 86, - 159, 40, 40, 67,105,160, 63, 67, 36, 36, 36, 61, 57,161,162, 69, - 36, 36, 36, 36, 36, 63, 40, 69, 44, 44, 62, 36, 36, 36, 36, 36, - 67, 27, 27, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 44, 55, - 67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67, - 67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, - 36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164, 2, + 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, + 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, + 67, 67, 67, 26, 67, 67, 67, 67, 26, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 26, + 67, 67, 67, 67, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, + 27, 27, 67, 67, 67, 67, 67, 67, 8, 8,129,147, 8, 8, 8, 8, + 8, 8, 8, 4, 4, 4, 4, 4, 8,129,148,148,148,148,148,148, + 148,148,148,148,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, + 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,144, 26, 8, 8,144, 67, + 67, 67, 44, 67, 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, + 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, + 32, 32,140, 67, 67,138, 34,149, 43, 32, 44, 44, 93, 2, 99, 2, + 16, 16, 16,150, 44, 44,150, 44, 36, 36, 36, 36, 44, 44, 44, 52, + 64, 44, 44, 44, 44, 44, 44, 57, 36, 36, 36, 61, 44, 44, 44, 44, + 36, 36, 36, 61, 36, 36, 36, 61, 2,121,121, 2,125,126,121, 2, + 2, 2, 2, 6, 2,108,121, 2,121, 4, 4, 4, 4, 2, 2, 88, + 2, 2, 2, 2, 2,120, 2, 2,108,151, 2, 2, 2, 2, 2, 2, + 67, 2,152,148,148,148,153, 44, 67, 67, 67, 67, 67, 55, 67, 67, + 67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44, + 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, + 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, + 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, + 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, + 67, 67, 67, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, 92, + 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, + 163, 27, 27, 27, 27, 27, 27, 27, 36, 36, 83, 36, 36, 36, 36, 36, + 67, 67, 67, 92, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36,164, 2, 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70, 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43, 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44, @@ -3092,7 +3123,7 @@ _hb_ucd_u8[14752] = 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, - 32, 32, 11, 11, 34,110, 44, 44, 32,150,150, 32, 32, 44, 44, 44, + 32, 32, 11, 11, 34, 34, 32, 44, 32,150,150, 32, 32, 32, 47, 44, 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44, 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36, @@ -3153,8 +3184,10 @@ _hb_ucd_u8[14752] = 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44, 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, - 27, 27, 27, 27, 27, 27, 27,100, 36, 36, 36, 36, 36, 57,184, 44, - 36, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 57, 43, + 7, 7, 7, 7, 7, 36, 36, 69, 11, 11, 11, 44, 57, 43, 43,159, + 16, 16, 16, 44, 44, 44, 44, 8, 27, 27, 27, 27, 27, 27, 27,100, + 36, 36, 36, 36, 36, 57,184, 44, 36, 44, 44, 44, 44, 44, 44, 44, + 44, 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44, 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44, 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, @@ -3172,14 +3205,18 @@ _hb_ucd_u8[14752] = 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44, 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44, - 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 94, 86, 43, 43, 43, 43, - 86, 43, 85, 71, 36, 63, 2, 2, 7, 7, 7, 7, 7, 2, 93, 71, - 86, 87, 43, 43, 85, 85, 86, 87, 85, 43, 36, 72, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 94, 86, 43, 43, 44, 86, 86, 43, 87, - 60, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 44, - 86, 87, 43, 43, 43, 85, 87, 87, 60, 2, 61, 44, 44, 44, 44, 44, - 2, 2, 2, 2, 2, 2, 64, 44, 36, 36, 36, 36, 36, 70, 87, 86, - 43, 43, 43, 87, 63, 44, 44, 44, 86, 43, 43, 87, 43, 43, 44, 44, + 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 62, 44, 61, + 36, 36, 36, 62, 86, 87, 43, 43, 80, 90, 89, 89, 86, 90, 86, 85, + 71, 71, 2, 93, 64, 44, 44, 44, 57, 80, 44, 44, 44, 44, 44, 44, + 36, 36, 94, 86, 43, 43, 43, 43, 86, 43, 85, 71, 36, 63, 2, 2, + 7, 7, 7, 7, 7, 2, 93, 71, 86, 87, 43, 43, 85, 85, 86, 87, + 85, 43, 36, 72, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 94, + 86, 43, 43, 44, 86, 86, 43, 87, 60, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 36, 36, 43, 44, 86, 87, 43, 43, 43, 85, 87, 87, + 60, 2, 61, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 2, 64, 44, + 36, 36, 36, 36, 36, 70, 87, 86, 43, 43, 43, 87, 63, 44, 44, 44, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 44, 44, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 61, 57, 87, 86, 43, 43, 87, 43, 43, 44, 44, 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44, 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71, @@ -3189,49 +3226,52 @@ _hb_ucd_u8[14752] = 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2, 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44, - 43, 43, 43, 80, 43, 43, 43, 87, 63, 2, 2, 44, 44, 44, 44, 44, - 2, 36, 36, 36, 36, 36, 36, 36, 44, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 89, 43, 43, 43, 85, 43, 87, 80, 44, 44, 44, 44, - 36, 36, 36, 61, 36, 62, 36, 36, 70, 43, 43, 80, 44, 80, 43, 57, - 43, 43, 43, 70, 44, 44, 44, 44, 36, 36, 36, 62, 61, 36, 36, 36, - 36, 36, 36, 36, 36, 86, 86, 90, 43, 89, 87, 87, 61, 44, 44, 44, - 36, 70, 85,107, 64, 44, 44, 44, 43, 94, 36, 36, 36, 36, 36, 36, - 36, 36, 86, 43, 43, 80, 44, 86, 85, 60, 2, 2, 2, 2, 2, 2, + 63, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 87, + 63, 2, 2, 44, 44, 44, 44, 44, 2, 36, 36, 36, 36, 36, 36, 36, + 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, + 85, 43, 87, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, + 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, + 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 86, 86, 90, + 43, 89, 87, 87, 61, 44, 44, 44, 36, 70, 85,107, 64, 44, 44, 44, + 43, 94, 36, 36, 36, 36, 36, 36, 36, 36, 86, 43, 43, 80, 44, 86, + 85, 60, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 80, 44, 44, 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181, 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44, 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43, - 43, 43, 43, 44, 44, 44, 44, 44, 43, 43, 60, 44, 44, 44, 44, 44, + 43, 43, 43, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 43, + 43, 43, 43, 43, 43, 86, 87, 43, 43, 43, 60, 44, 44, 44, 44, 44, 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44, 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 62, 36, 27, 27, 27, 30, 2, 64, 44, 44, + 36, 36, 36, 36, 44, 44, 62, 36, 40, 69, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 83,164, 2, 27, 27, 27, 30, 2, 64, 44, 44, 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57, 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44, - 86, 44, 44, 44, 44, 44, 44, 44, 40, 40, 52, 40, 40, 40, 52, 81, - 36, 61, 44, 44, 44, 44, 44, 44, 44, 61, 44, 44, 44, 44, 44, 44, - 36, 61, 62, 44, 44, 44, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 44, 50, 60, 65, 65, 44, 44, 44, 44, 44, 44, - 43, 43, 43, 43, 43, 43, 43, 44, 43, 43, 43, 80, 44, 44, 44, 44, - 67, 67, 67, 92, 55, 67, 67, 67, 67, 67,186, 87, 43, 67,186, 86, - 86,187, 65, 65, 65, 84, 43, 43, 43, 76, 50, 43, 43, 43, 67, 67, - 67, 67, 67, 67, 67, 43, 43, 67, 67, 43, 76, 44, 44, 44, 44, 44, - 27, 27, 44, 44, 44, 44, 44, 44, 11, 11, 11, 11, 11, 16, 16, 16, - 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, - 16, 16,110, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 47, 11, 44, 47, 48, 47, 48, 11, 47, 11, - 11, 11, 11, 16, 16,150,150, 16, 16, 16,150, 16, 16, 16, 16, 16, - 16, 16, 11, 48, 11, 47, 48, 11, 11, 11, 47, 11, 11, 11, 47, 16, - 16, 16, 16, 16, 11, 48, 11, 47, 11, 11, 47, 47, 44, 11, 11, 11, - 47, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, - 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 44, 11, 11, 11, 11, - 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, - 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, - 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, - 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 44, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 43, 43, 43, 76, 67, 50, 43, 43, + 86, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 62, + 40, 40, 52, 40, 40, 40, 52, 81, 36, 61, 44, 44, 44, 44, 44, 44, + 44, 61, 44, 44, 44, 44, 44, 44, 36, 61, 62, 44, 44, 44, 44, 44, + 44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60, + 65, 65, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 44, + 43, 43, 43, 80, 44, 44, 44, 44, 67, 67, 67, 92, 55, 67, 67, 67, + 67, 67,186, 87, 43, 67,186, 86, 86,187, 65, 65, 65, 84, 43, 43, + 43, 76, 50, 43, 43, 43, 67, 67, 67, 67, 67, 67, 67, 43, 43, 67, + 67, 43, 76, 44, 44, 44, 44, 44, 27, 27, 44, 44, 44, 44, 44, 44, + 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 16, 16, 16,110, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 11, + 44, 47, 48, 47, 48, 11, 47, 11, 11, 11, 11, 16, 16,150,150, 16, + 16, 16,150, 16, 16, 16, 16, 16, 16, 16, 11, 48, 11, 47, 48, 11, + 11, 11, 47, 11, 11, 11, 47, 16, 16, 16, 16, 16, 11, 48, 11, 47, + 11, 11, 47, 47, 44, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, + 16, 16, 16, 44, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, + 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, + 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, + 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, + 16, 33, 16, 16, 16, 32, 44, 7, 43, 43, 43, 76, 67, 50, 43, 43, 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110, @@ -3241,22 +3281,23 @@ _hb_ucd_u8[14752] = 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77, 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43, 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43, - 36, 36, 36, 61, 36, 36, 62, 61, 36, 36, 61,179, 27, 27, 27, 27, - 16, 16, 43, 43, 43, 74, 44, 44, 27, 27, 27, 27, 27, 27,163, 27, - 188, 27,100, 44, 44, 44, 44, 44, 27, 27, 27, 27, 27, 27, 27,163, - 27, 27, 27, 27, 27, 27, 27, 44, 36, 36, 62, 36, 36, 36, 36, 36, - 62, 61, 61, 62, 62, 36, 36, 36, 36, 61, 36, 36, 62, 62, 44, 44, - 44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62, - 62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61, - 36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36, - 8, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44, - 55, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, 27, 27, 91, 67, - 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, - 67, 92, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 92, 44, 44, 44, - 67, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 25, 41, 41, - 67, 67, 67, 67, 44, 44, 67, 67, 67, 67, 67, 92, 44, 55, 67, 67, - 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 67, 55, - 67, 67, 67, 44, 44, 44, 44, 67, 67, 92, 67, 67, 67, 67, 67, 67, + 188, 7, 7, 7, 7,189, 44, 93, 36, 36, 36, 61, 36, 36, 62, 61, + 36, 36, 61,179, 27, 27, 27, 27, 16, 16, 43, 43, 43, 74, 44, 44, + 27, 27, 27, 27, 27, 27,163, 27,190, 27,100, 44, 44, 44, 44, 44, + 27, 27, 27, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 44, + 36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36, + 36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36, + 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, + 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, + 62, 36, 62, 36, 36, 62, 36, 36, 8, 44, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, + 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, + 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67, + 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 92, 44, 44, 44, 67, + 67, 67, 67, 67, 67, 67, 92, 55, 67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44, 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, @@ -3282,420 +3323,609 @@ _hb_ucd_u8[14752] = 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, - 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, - 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, + 7, 13, 13, 2, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, - 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 35, 0, 36, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, - 0, 0, 40, 41, 42, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, - 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, 16, 18, - 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, 0, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, - 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, - 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, 0, 0, - 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, 62, 63, - 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, 0, 0, - 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, - 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, 0, 0, - 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 75, 76, 0, 77, 78, 0, - 0, 79, 80, 0, 81, 62, 0, 82, 83, 0, 0, 84, 85, 86, 0, 0, - 0, 87, 0, 88, 0, 0, 51, 89, 51, 0, 90, 0, 91, 0, 0, 0, - 80, 0, 0, 0, 92, 93, 0, 94, 95, 96, 97, 0, 0, 0, 0, 0, - 51, 0, 0, 0, 0, 98, 99, 0, 0, 0, 0, 0, 0,100, 0, 0, - 0, 0, 0,101,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,103, - 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105,106, 0, - 0,107, 0, 0, 0, 0, 0, 0,108, 0,109, 0,102, 0, 0, 0, - 0, 0,110,111, 0, 0, 0, 0, 0, 0, 0,112, 0, 0, 0, 0, - 0, 0, 0,113, 0,114, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, - 5, 6, 7, 0, 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, - 0, 13, 0, 0, 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, - 21, 0, 0, 0, 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, - 0, 27, 0, 0, 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, - 33, 0, 0, 35, 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, - 38, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, - 42, 0, 0, 0, 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, - 47, 0, 0, 0, 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, - 0, 51, 0, 52, 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, - 0, 56, 0, 0, 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, - 0, 0, 0, 61, 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, - 0, 0, 0, 67, 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, - 0, 0, 77, 78, 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, - 0, 81, 0, 0, 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, - 84, 0, 85, 0, 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, - 0, 0, 0, 88, 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, - 0, 0, 33, 0, 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, - 0, 0, 93, 0, 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, - 0, 0, 98, 0, 0, 0, 99, 0, 0, 0, 0,100,101, 93, 0, 0, - 102, 0, 0, 0, 84, 0, 0,103, 0, 0, 0,104,105, 0, 0,106, - 107, 0, 0, 0, 0, 0, 0,108, 0, 0,109, 0, 0, 0, 0,110, - 33, 0,111,112,113, 35, 0, 0,114, 0, 0, 0,115, 0, 0, 0, - 0, 0, 0,116, 0, 0,117, 0, 0, 0, 0,118, 88, 0, 0, 0, - 0, 0, 57, 0, 0, 0, 0, 52,119, 0, 0, 0, 0,120, 0, 0, - 121, 0, 0, 0, 0,119, 0, 0,122, 0, 0, 0, 0, 0, 0,123, - 0, 0, 0,124, 0, 0, 0,125, 0,126, 0, 0, 0, 0,127,128, - 129, 0,130, 0,131, 0, 0, 0,132,133,134, 0, 77, 0, 0, 0, - 0, 0, 35, 0, 0, 0,135, 0, 0, 0,136, 0, 0,137, 0, 0, - 138, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, - 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, - 18, 1, 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, - 25, 26, 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, - 34, 35, 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, - 42, 0, 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, - 21, 0, 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, - 0, 0, 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, - 54, 21, 35, 1, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, - 0, 0, 0, 59, 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, - 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, - 0, 0, 68, 0, 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, - 0, 77, 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, - 0, 80, 0, 0, 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, - 0, 0, 83, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, - 1, 52, 15, 86, 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, - 1, 0, 0, 0, 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, - 0, 78, 0, 0, 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, - 21, 1, 21, 92, 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, - 81, 99,100, 4, 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, - 0, 0, 0, 61, 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, - 0, 0, 0, 38, 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, - 61, 0, 0, 0, 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, - 0, 0, 0,107, 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, - 0, 0, 0,108, 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, + 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, + 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, + 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, + 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, + 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, + 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, + 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, + 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, + 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, + 0, 0, 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, + 0, 78, 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, + 86, 87, 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, + 93, 0, 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, + 0, 0, 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, + 0,102, 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104, + 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, + 0, 0, 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, + 0, 0, 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, + 0,118, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, + 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, + 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, + 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, + 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, + 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, + 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, + 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, + 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, + 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, + 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, + 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, + 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, + 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, + 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, + 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, + 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, + 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, + 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, + 0, 0, 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0, + 103, 0, 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107, + 108, 0, 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, + 33, 0,112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0, + 117, 0, 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, + 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, + 0,122, 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, + 0, 0, 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, + 0,128, 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0, + 134,135,136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, + 0, 0,138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, + 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, + 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, + 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, + 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, + 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, + 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, + 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, + 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, + 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, + 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, + 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, + 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, + 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, + 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, + 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, + 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, + 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, + 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, + 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, + 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, + 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, + 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, + 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, + 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, - 0, 38, 1, 58, 1, 58, 0, 0, 63, 89, 0, 0,115, 0, 0, 0, - 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, 0, 79, - 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, 0, 0, - 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, 0,117, - 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, 38, 50, - 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, 87, 0, - 0, 0, 0, 1, 0, 0, 0,123, 4,122, 0, 0, 0, 1,124, 0, - 0, 0, 0, 0,230,230,230,230,230,232,220,220,220,220,232,216, - 220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220, - 1, 1, 1, 1, 1,220,220,220,220,230,230,230,230,240,230,220, - 220,220,230,230,230,220,220, 0,230,230,230,220,220,220,220,230, - 232,220,220,230,233,234,234,233,234,234,233,230, 0, 0, 0,230, - 0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220, - 230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, - 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, - 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230, - 220,230,230,220, 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230, - 230, 0,220,230,230,220, 0, 0, 0, 36, 0, 0,230,220,230,230, - 220,220,230,220,220,230,220,230,220,230,230, 0, 0,220, 0, 0, - 230,230, 0,230, 0,230,230,230,230,230, 0, 0, 0,220,220,220, - 230,220,220,220,230,230, 0,220, 27, 28, 29,230, 7, 0, 0, 0, - 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0, - 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0, - 103,103, 9, 0,107,107,107,107,118,118, 9, 0,122,122,122,122, - 220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0, - 132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230, - 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, - 9, 9, 0, 0, 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220, - 220, 0, 0, 0,230, 0, 0,220,230,220, 0,220,230,230,230, 0, - 0, 0, 9, 9, 0, 0, 7, 0,230, 0, 1, 1, 1, 0, 0, 0, - 230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230, - 233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230, - 220,230, 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, - 0, 0, 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, - 0,220, 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, - 0, 0,230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, - 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, - 0,226,216,216,216,216,216, 0,220,220,220, 0,232,232,220,230, - 230,230, 7, 0, 16, 17, 17, 33, 17, 49, 17, 17, 84, 97,135,145, - 26, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 0, 38, 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0, + 115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, + 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, + 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, + 0, 0, 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, + 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, + 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, + 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230, + 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220, + 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220, + 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0, + 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233, + 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230, + 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0, + 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, + 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, + 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, + 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230, + 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230, + 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, + 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230, + 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107, + 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, + 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, + 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, + 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, + 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220, + 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0, + 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230, + 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, + 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228, + 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230, + 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, + 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, + 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, + 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, + 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 33, + 17, 49, 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,177, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, - 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, 9, 10, 11, 12, - 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, 3, 3, 3, 3, - 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, 23, 24, 3, 3, - 3, 3, 3, 3, 25, 3, 3, 3, 3, 3, 3, 3, 3, 26, 3, 3, - 27, 28, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, - 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, - 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, - 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, 19, 20, 21, 22, - 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, 0, 31, 0, 0, - 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, 32, 33, 9, 34, - 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, 42, 43, 44, 31, - 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, 0, 0, 0, 0, - 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51, - 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, 6, 55, 0, 14, - 19, 1, 0, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 19, 58, 31, - 0, 0, 0, 0, 0, 0, 0, 59, 14, 0, 0, 0, 0, 1, 0, 2, - 0, 0, 0, 3, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 2, 3, 0, 4, 5, 0, 0, 6, 0, 0, - 0, 7, 0, 0, 0, 1, 1, 0, 0, 8, 9, 0, 8, 9, 0, 0, - 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, 13, 0, 0, 0, 0, 14, - 15, 16, 17, 0, 0, 0, 1, 0, 0, 18, 19, 0, 0, 0, 20, 0, - 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 8, - 21, 9, 0, 0, 22, 0, 0, 0, 0, 1, 0, 23, 24, 25, 0, 0, - 26, 0, 0, 0, 8, 21, 27, 0, 1, 0, 0, 1, 1, 1, 1, 0, - 1, 28, 29, 30, 0, 31, 32, 20, 1, 1, 0, 0, 0, 8, 21, 9, - 1, 4, 5, 0, 0, 0, 33, 9, 0, 1, 1, 1, 0, 8, 21, 21, - 21, 21, 34, 1, 35, 21, 21, 21, 9, 36, 0, 0, 37, 38, 1, 0, - 39, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 8, 21, 9, 1, 0, - 0, 0, 40, 0, 8, 21, 21, 21, 21, 21, 21, 21, 21, 9, 0, 1, - 1, 1, 1, 8, 21, 21, 21, 9, 0, 0, 0, 41, 0, 42, 43, 0, - 0, 0, 1, 44, 0, 0, 0, 45, 8, 9, 1, 0, 0, 0, 8, 21, - 21, 21, 9, 0, 1, 0, 1, 1, 8, 21, 21, 9, 0, 4, 5, 8, - 9, 1, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 12, 13, - 13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 13, 22, 13, 13, 13, - 13, 23, 24, 24, 25, 26, 13, 13, 13, 27, 28, 29, 13, 30, 31, 32, - 33, 34, 35, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, - 7, 41, 13, 42, 7, 7, 43, 7, 44, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 45, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37, - 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 2, 2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59, - 59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 79, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, - 82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, 97, 98, 99,100,101,101, - 102,103,104,105,106,107,108,109,110,111, 96,112,113,114,115,116, - 117,118,119,119,120,121,122,123,124,125,126,127,128,129,130,131, - 132, 96,133,134,135,136,137,138,139,140,141,142,143, 96,144,145, - 96,146,147,148,149, 96,150,151,152,153,154,155,156, 96,157,158, - 159,160, 96,161,162,163,164,164,164,164,164,164,164,165,166,164, - 167, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96,168,169,169,169,169,169,169,169,169,170, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,171,171, - 171,171,172, 96, 96, 96,173,173,173,173,174,175,176,177, 96, 96, - 96, 96,178,179,180,181,182,182,182,182,182,182,182,182,182,182, - 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, - 182,182,182,182,182,183,182,182,182,182,182,182,184,184,184,185, - 186, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96,187,188,189,190,191,191,192, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,193,194, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96,195,196, 59,197,198,199,200,201,202, 96,203,204, - 205, 59, 59,206, 59,207,208,208,208,208,208,209, 96, 96, 96, 96, - 96, 96, 96, 96,210, 96,211,212,213, 96, 96,214, 96, 96, 96,215, - 96, 96, 96, 96, 96,216,217,218,219, 96, 96, 96, 96, 96,220,221, - 222, 96,223,224, 96, 96,225,226, 59,227,228, 96, 59, 59, 59, 59, - 59, 59, 59,229,230,231,232,233, 59, 59,234,235, 59,236, 96, 96, - 96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70,237, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70,238, 70,239, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70,240, 70, 70, 70, 70, 70, 70, 70, 70, 70,241, 70, 70, - 70, 70,242, 96, 96, 96, 70, 70, 70, 70,243, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70,244, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,245, 96, 96, - 96, 96, 96, 96, 96, 96,246, 96,247,248, 0, 1, 2, 2, 0, 1, - 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, 0, 0, - 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, - 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, - 9, 2, 9, 2, 9, 9, 9, 9, 2, 9, 9, 9, 55, 55, 55, 55, - 55, 55, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 2, 2, 2, 2, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, - 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, - 3, 3, 1, 3, 3, 3, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, - 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 2, 2, 64, 64, - 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, - 2, 2, 90, 90, 90, 2, 95, 95, 95, 95, 2, 2, 95, 2, 3, 3, - 3, 2, 3, 3, 2, 2, 3, 3, 0, 3, 7, 7, 7, 7, 7, 1, - 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, - 5, 5, 5, 2, 2, 5, 5, 2, 5, 5, 5, 2, 5, 2, 2, 2, - 5, 5, 5, 5, 2, 2, 5, 5, 5, 2, 2, 2, 2, 5, 5, 5, - 2, 5, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, - 2, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, - 2, 2, 2, 11, 2, 2, 11, 2, 11, 2, 2, 2, 11, 11, 2, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, - 2, 2, 10, 2, 2, 2, 2, 2, 10, 10, 2, 21, 21, 21, 21, 21, - 21, 21, 21, 2, 2, 21, 21, 2, 21, 21, 21, 21, 2, 2, 21, 21, - 2, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, - 22, 2, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, - 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 23, 23, 23, 23, 23, 2, - 23, 23, 23, 23, 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, - 2, 2, 2, 2, 23, 23, 2, 2, 2, 23, 16, 16, 16, 16, 16, 2, - 16, 16, 2, 16, 16, 16, 16, 16, 2, 2, 2, 16, 16, 2, 2, 2, - 16, 16, 20, 20, 20, 20, 20, 2, 20, 20, 2, 2, 20, 20, 2, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, - 2, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 2, - 36, 2, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 2, 2, 2, 2, 0, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, - 18, 2, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, 2, 2, 18, 2, - 18, 2, 25, 25, 25, 25, 2, 25, 25, 25, 25, 2, 2, 2, 25, 2, - 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 33, 33, 33, 33, 8, 8, - 8, 8, 8, 8, 2, 8, 2, 8, 2, 2, 8, 8, 8, 0, 12, 12, - 12, 12, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, - 30, 2, 2, 30, 30, 30, 30, 2, 2, 2, 29, 29, 29, 29, 29, 29, - 2, 2, 28, 28, 28, 28, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, - 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 45, 45, - 45, 45, 45, 45, 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 0, - 0, 2, 43, 43, 43, 43, 46, 46, 46, 46, 46, 2, 46, 46, 31, 31, - 31, 31, 31, 31, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, - 32, 32, 32, 32, 2, 2, 32, 2, 2, 2, 32, 32, 32, 2, 28, 28, - 2, 2, 48, 48, 48, 48, 48, 48, 48, 2, 48, 2, 2, 2, 52, 52, - 52, 52, 52, 52, 2, 2, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, - 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 2, 2, - 54, 54, 91, 91, 91, 91, 91, 91, 91, 2, 91, 2, 2, 91, 91, 91, - 2, 2, 1, 1, 1, 2, 62, 62, 62, 62, 62, 2, 2, 2, 62, 62, - 62, 2, 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 2, 2, - 2, 70, 70, 70, 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 6, 2, - 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 0, - 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 2, 19, 19, - 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, 9, 9, 19, 19, 9, 9, - 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, 9, 9, 2, 2, 2, 9, - 2, 9, 2, 9, 9, 9, 1, 1, 0, 0, 0, 2, 0, 0, 0, 19, - 2, 2, 0, 0, 0, 19, 0, 0, 0, 2, 19, 2, 2, 2, 0, 2, - 2, 2, 1, 2, 2, 2, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, - 27, 27, 2, 2, 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 2, 55, - 55, 55, 61, 61, 61, 61, 2, 2, 2, 61, 61, 2, 2, 2, 0, 0, - 2, 2, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 2, 2, 0, 13, - 0, 13, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 2, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, - 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 2, 26, - 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 2, 12, 12, - 12, 0, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, 39, 2, 86, 86, - 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, 19, 19, 19, 2, 19, 19, - 2, 19, 2, 19, 19, 19, 19, 19, 2, 2, 2, 2, 19, 19, 60, 60, - 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, - 2, 2, 2, 2, 75, 75, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, - 74, 74, 2, 2, 2, 74, 12, 2, 2, 2, 84, 84, 84, 84, 84, 84, - 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33, 33, 2, 68, 68, - 68, 68, 68, 68, 68, 2, 68, 68, 2, 2, 92, 92, 92, 92, 92, 92, - 92, 2, 2, 2, 2, 92, 87, 87, 87, 87, 87, 87, 87, 2, 19, 9, - 19, 19, 19, 19, 0, 0, 87, 87, 2, 2, 2, 2, 2, 12, 2, 2, - 2, 4, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 2, 2, - 2, 3, 3, 3, 0, 0, 2, 2, 3, 3, 1, 1, 6, 6, 3, 2, - 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 17, 17, 17, 17, - 0, 0, 2, 2, 12, 12, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, - 49, 2, 49, 49, 2, 49, 49, 49, 2, 2, 9, 2, 2, 2, 0, 1, - 2, 2, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 2, - 2, 2, 42, 42, 42, 42, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, - 41, 2,118,118,118,118,118,118,118, 2, 53, 53, 53, 53, 53, 53, - 2, 53, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, 40, 40, 51, 51, - 51, 51, 50, 50, 50, 50, 50, 50, 2, 2,135,135,135,135,106,106, - 106,106,104,104,104,104, 2, 2, 2,104,161,161,161,161,161,161, - 161, 2,161,161, 2,161,161, 2, 2, 2,110,110,110,110,110,110, - 110, 2,110,110, 2, 2, 19, 2, 19, 19, 47, 47, 47, 47, 47, 47, - 2, 2, 47, 2, 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, - 2, 47, 81, 81, 81, 81, 81, 81, 2, 81,120,120,120,120,116,116, - 116,116,116,116,116, 2, 2, 2, 2,116,128,128,128,128,128,128, - 128, 2,128,128, 2, 2, 2, 2, 2,128, 66, 66, 66, 66, 2, 2, - 2, 66, 72, 72, 72, 72, 72, 72, 2, 2, 2, 2, 2, 72, 98, 98, - 98, 98, 97, 97, 97, 97, 2, 2, 97, 97, 57, 57, 57, 57, 2, 57, - 57, 2, 2, 57, 57, 57, 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, - 2, 57, 57, 2, 2, 2, 88, 88, 88, 88,117,117,117,117,112,112, - 112,112,112,112,112, 2, 2, 2, 2,112, 78, 78, 78, 78, 78, 78, - 2, 2, 2, 78, 78, 78, 83, 83, 83, 83, 83, 83, 2, 2, 82, 82, - 82, 82, 82, 82, 82, 2,122,122,122,122,122,122, 2, 2, 2,122, - 122,122,122, 2, 2, 2, 89, 89, 89, 89, 89, 2, 2, 2,130,130, - 130,130,130,130,130, 2, 2, 2,130,130,144,144,144,144,144,144, - 2, 2,156,156,156,156,156,156, 2,156,156,156, 2, 2, 2, 3, - 3, 3,147,147,147,147,148,148,148,148,148,148, 2, 2,158,158, - 158,158,158,158, 2, 2,153,153,153,153,149,149,149,149,149,149, - 149, 2, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 2, 2, - 2, 94, 85, 85, 85, 85, 85, 85, 85, 2, 2, 85, 2, 2,101,101, - 101,101,101, 2, 2, 2,101,101, 2, 2, 96, 96, 96, 96, 96, 2, - 96, 96,111,111,111,111,111,111,111, 2,100,100,100,100,108,108, - 108,108,108,108, 2,108,108,108, 2, 2,129,129,129,129,129,129, - 129, 2,129, 2,129,129,129,129, 2,129,129,129, 2, 2,109,109, - 109,109,109,109,109, 2,109,109, 2, 2,107,107,107,107, 2,107, - 107,107,107, 2, 2,107,107, 2,107,107,107,107, 2, 1,107,107, - 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2,107,107,137,137, - 137,137, 2,137,137,137,137,137, 2, 2,124,124,124,124,124,124, - 2, 2,123,123,123,123,123,123, 2, 2,114,114,114,114,114, 2, - 2, 2,114,114, 2, 2,102,102,102,102,102,102, 2, 2,126,126, - 126,126,126,126,126, 2, 2,126,126,126,142,142,142,142,125,125, - 125,125,125,125,125, 2, 2, 2, 2,125,154,154,154,154,154,154, - 154, 2, 2,154, 2, 2, 2,154,154, 2,154,154, 2,154,154, 2, - 2,154,154,154, 2, 2,150,150,150,150, 2, 2,150,150,150, 2, - 2, 2,141,141,141,141,140,140,140,140,140,140,140, 2,121,121, - 121,121,121, 2, 2, 2, 7, 7, 2, 2,133,133,133,133,133, 2, - 133,133,133,133,133, 2,133,133, 2, 2,133, 2, 2, 2,134,134, - 134,134, 2, 2,134,134, 2,134,134,134,134,134,134, 2,138,138, - 138,138,138,138,138, 2,138,138, 2,138, 2, 2,138, 2,138,138, - 2, 2,143,143,143,143,143,143, 2,143,143, 2,143,143,143,143, - 143, 2,143, 2, 2, 2,143,143, 2, 2,145,145,145,145,145, 2, - 2, 2,163,163,163,163,163, 2,163,163,163,163,163, 2, 2, 2, - 163,163,163,163, 2, 2, 86, 2, 2, 2, 63, 63, 63, 63, 63, 63, - 2, 2, 63, 63, 63, 2, 63, 2, 2, 2,157,157,157,157,157,157, - 157, 2, 80, 80, 80, 80, 80, 80, 2, 2,127,127,127,127,127,127, - 127, 2, 79, 2, 2, 2,115,115,115,115,115,115,115, 2,115,115, - 2, 2, 2, 2,115,115,159,159,159,159,159,159,159, 2,159,159, - 2, 2,103,103,103,103,103,103, 2, 2,119,119,119,119,119,119, - 2, 2,119,119, 2,119, 2,119,119,119,146,146,146,146,146,146, - 146, 2, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99,136,139, - 13, 13,155, 2, 2, 2,136,136,136,136,155,155,155,155,155,155, - 2, 2,136, 2, 2, 2, 2, 17, 17, 17, 2, 17, 17, 2, 17, 15, - 15, 15, 17, 17, 17, 2, 2, 2, 15, 2, 2, 17, 2, 2,139,139, - 139,139,105,105,105,105,105,105,105, 2,105, 2, 2, 2,105,105, - 2, 2, 1, 1, 2, 2, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, - 1, 1, 2, 2, 0, 2, 2, 0, 0, 2, 0, 2, 0, 2,131,131, - 131,131, 2, 2, 2,131, 2,131,131,131, 56, 56, 56, 2, 56, 2, - 2, 56, 56, 56, 2, 56, 56, 2, 56, 56, 6, 6, 2, 2, 2, 2, - 2, 6,151,151,151,151,151, 2, 2, 2,151,151, 2, 2, 2, 2, - 151,151,160,160,160,160,160,160,160, 2,152,152,152,152,152,152, - 2, 2, 2, 2, 2,152,164,164,164,164,164,164, 2, 2, 2, 30, - 30, 2,113,113,113,113,113, 2, 2,113,113,113,113, 2,132,132, - 132,132,132,132, 2, 2, 2, 2,132,132, 2, 3, 3, 2, 3, 2, - 2, 3, 2, 3, 2, 3, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, - 2, 3, 15, 0, 0, 2, 13, 2, 2, 2, 13, 13, 13, 2, 2, 0, - 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, - 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, + 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, + 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, + 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, + 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, + 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, + 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, + 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, + 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, + 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, + 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, + 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, + 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, + 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, + 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, + 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, + 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, + 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, + 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, + 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, + 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, + 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, + 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, + 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, + 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, + 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, + 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, + 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, + 4, 5, 5, 5, 5, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 9, 16, 17, 18, 9, 19, 20, 21, 22, 23, 24, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 25, 26, 27, 5, 28, 29, 5, 30, 31, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 32, 0, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 1, 29, 30, 31, + 32, 32, 33, 32, 32, 32, 34, 32, 32, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 46, 46, + 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 44, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 95, + 95, 96, 97, 98, 56, 56, 56, 56, 56, 56, 56, 56, 56, 99,100,100, + 100,100,101,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,102,103,103,104, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,105, + 56, 56, 56, 56, 56, 56,106,106,107,108, 56,109,110,111,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, + 112,112,112,112,112,113,112,112,112,114,115,116, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,117,118,119, + 120, 56, 56, 56, 56, 56, 56, 56, 56, 56,121, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,122, 32,123,124,125,126, + 127,128,129,130,131,132,133,133,134, 56, 56, 56, 56,135,136,137, + 138, 56,139,140, 56,141,142,143, 56, 56,144,145,146, 56,147,148, + 149, 32, 32, 32,150,151,152, 32,153,154, 56, 56, 56, 56, 44, 44, + 44, 44, 44, 44,155, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44,156,157, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,158, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44,159, 44, 44,160, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 44, 44,161, 56, 56, 56, 56, 56, 44, 44, + 44,162, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44,163, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,164,165, + 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0, + 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, + 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, + 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, + 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, 4, 4, 2, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, + 2, 2, 2, 2, 2, 2, 14, 14, 14, 2, 2, 2, 2, 14, 14, 14, + 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, + 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, + 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, + 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 2, 2, 95, 2, 37, 37, 37, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, + 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, + 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5, + 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, + 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, + 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, + 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2, + 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5, + 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11, + 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, + 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, + 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, + 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11, + 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2, + 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 10, + 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, + 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, + 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, + 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2, + 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, + 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21, + 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, + 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, + 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, + 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, + 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, + 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, + 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, + 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 2, + 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, + 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, + 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, + 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 23, 23, + 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, + 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, + 2, 2, 2, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 2, 16, + 16, 16, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 2, 2, + 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 2, 36, + 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, + 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, 2, + 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, + 2, 2, 2, 2, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 2, 2, 2, 2, 2, 18, + 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, + 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, + 18, 18, 18, 18, 18, 2, 18, 18, 2, 2, 18, 18, 18, 18, 25, 25, + 25, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 2, 2, 2, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, + 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 2, 2, 2, 2, 33, 33, + 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 8, 8, + 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, + 30, 30, 30, 30, 30, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, + 30, 30, 30, 2, 2, 2, 30, 30, 2, 2, 2, 2, 2, 2, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, + 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 2, 2, 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31, + 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, 2, + 2, 2, 2, 2, 2, 2, 32, 32, 32, 2, 2, 2, 2, 2, 28, 28, + 28, 28, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 2, 48, 48, 48, 48, 2, 2, 2, 2, 48, 2, + 2, 2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 2, 2, 52, 52, 52, 52, 52, 2, 2, 2, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 2, 2, 2, 2, 58, 58, + 2, 2, 2, 2, 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91, + 91, 91, 91, 2, 2, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, + 91, 91, 91, 91, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 2, 62, 62, 76, 76, + 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, + 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, + 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 6, 6, + 6, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, + 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, + 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, + 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, + 9, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9, + 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, + 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19, + 19, 19, 19, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, + 0, 0, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, + 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 56, 56, + 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, + 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, + 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13, + 13, 13, 13, 13, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, 13, + 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, + 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, + 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, + 2, 2, 2, 2, 2, 0, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, + 17, 17, 17, 17, 17, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 86, 86, + 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, + 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 2, 2, 19, 19, 2, 19, 2, 19, 19, 19, 2, 2, + 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, + 2, 2, 2, 2, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, 12, 2, 2, 2, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, + 2, 2, 2, 2, 84, 84, 33, 33, 33, 33, 33, 33, 33, 2, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, + 68, 68, 68, 68, 2, 2, 68, 68, 2, 2, 68, 68, 68, 68, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 2, 2, 2, + 2, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 2, 2, 30, 30, 30, 30, 30, 30, 2, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 19, 19, 19, 19, + 0, 0, 2, 2, 2, 2, 87, 87, 87, 87, 87, 87, 2, 2, 87, 87, + 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, + 2, 12, 12, 12, 12, 12, 13, 13, 2, 2, 2, 2, 2, 2, 19, 19, + 19, 19, 19, 19, 19, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, + 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14, + 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 3, 3, + 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 0, 0, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, + 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 6, 6, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, + 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, + 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0, + 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, + 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2, + 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118, + 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, + 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 50, 50, + 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135, + 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,104,104, + 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161, + 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161, + 2,161,161,161,161,161,161,161, 2,161,161, 2, 2, 2,170,170, + 170,170,170,170,170,170,170,170,170,170, 2, 2, 2, 2,110,110, + 110,110,110,110,110,110,110,110,110,110,110,110,110, 2,110,110, + 110,110,110,110, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 2, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 47, 47, + 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2, + 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 2, 81,120,120,120,120,120,120,120,120,116,116, + 116,116,116,116,116,116,116,116,116,116,116,116,116, 2, 2, 2, + 2, 2, 2, 2, 2,116,128,128,128,128,128,128,128,128,128,128, + 128, 2,128,128, 2, 2, 2, 2, 2,128,128,128,128,128, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 2, 2, 2, 2, 2, 72, 98, 98, + 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 2, 2, + 2, 2, 97, 97, 97, 97, 2, 2, 97, 97, 97, 97, 97, 97, 57, 57, + 57, 57, 2, 57, 57, 2, 2, 2, 2, 2, 57, 57, 57, 57, 57, 57, + 57, 57, 2, 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 57, 57, + 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 2, 2, 2, 2, 88, 88, + 88, 88, 88, 88, 88, 88,117,117,117,117,117,117,117,117,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112, 2, 2, 2, + 2,112,112,112,112,112, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 78, 78, 78, 78, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 2, 2, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 2, 2, 2, 2, 2,122,122, + 122,122,122,122,122,122,122,122, 2, 2, 2, 2, 2, 2, 2,122, + 122,122,122, 2, 2, 2, 2,122,122,122,122,122,122,122, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 2, 2, 2, 2, 2, 2, 2,130,130, + 130,130,130,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, + 130,130,130,130,130,130,144,144,144,144,144,144,144,144,144,144, + 2, 2, 2, 2, 2, 2,165,165,165,165,165,165,165,165,165,165, + 165,165,165,165, 2, 2, 2,165,165,165,165,165,165,165, 2, 2, + 2, 2, 2, 2,165,165,156,156,156,156,156,156,156,156,156,156, + 2,156,156,156, 2, 2,156,156, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,147,147, + 147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148, + 2, 2, 2, 2, 2, 2,158,158,158,158,158,158,158,158,158,158, + 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153, + 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149, + 149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 2, 2, + 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101, + 101,101,101,101,101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101, + 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 2, 96, 96,111,111,111,111,111,111,111,111,111,111, + 111,111,111,111,111, 2,100,100,100,100,100,100,100,100, 2, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2,108,108, + 108,108,108,108,108,108,108,108, 2,108,108,108,108,108,108,108, + 2, 2, 2, 2, 2, 2,129,129,129,129,129,129,129, 2,129, 2, + 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, + 129,129,129,129, 2,129,129,129, 2, 2, 2, 2, 2, 2,109,109, + 109,109,109,109,109,109,109,109,109, 2, 2, 2, 2, 2,109,109, + 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107,107, + 107,107,107, 2, 2,107,107, 2, 2,107,107,107,107,107,107,107, + 107,107,107,107,107,107,107, 2,107,107,107,107,107,107,107, 2, + 107,107, 2,107,107,107,107,107, 2, 1,107,107,107,107,107, 2, + 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2, + 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,107,107, + 107,107,107, 2, 2, 2,171,171,171,171,171,171,171,171,171,171, + 2,171, 2, 2,171, 2,171,171,171,171,171,171, 2,171,171, 2, + 171, 2, 2,171, 2,171,171,171,171, 2,171,171,171,171,171, 2, + 2, 2, 2, 2, 2, 2, 2,171,171, 2, 2, 2, 2, 2,137,137, + 137,137,137,137,137,137,137,137,137,137, 2,137,137,137,137,137, + 2, 2, 2, 2, 2, 2,124,124,124,124,124,124,124,124,124,124, + 2, 2, 2, 2, 2, 2,123,123,123,123,123,123,123,123,123,123, + 123,123,123,123, 2, 2,114,114,114,114,114,114,114,114,114,114, + 114,114,114, 2, 2, 2,114,114, 2, 2, 2, 2, 2, 2, 32, 32, + 32, 32, 32, 2, 2, 2,102,102,102,102,102,102,102,102,102,102, + 2, 2, 2, 2, 2, 2, 33, 33, 33, 33, 2, 2, 2, 2,126,126, + 126,126,126,126,126,126,126,126,126, 2, 2,126,126,126,126,126, + 126,126, 2, 2, 2, 2,126,126,126,126,126,126,126, 2,142,142, + 142,142,142,142,142,142,142,142,142,142, 2, 2, 2, 2,125,125, + 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, + 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154,154, + 154,154,154,154,154,154,154,154,154,154,154,154, 2,154,154, 2, + 2,154,154,154,154,154,154,154, 2, 2, 2, 2, 2, 2,150,150, + 150,150,150,150,150,150, 2, 2,150,150,150,150,150,150,150,150, + 150,150,150, 2, 2, 2,141,141,141,141,141,141,141,141,140,140, + 140,140,140,140,140,140,140,140,140, 2, 2, 2, 2, 2,121,121, + 121,121,121,121,121,121,121, 2, 2, 2, 2, 2, 2, 2, 7, 7, + 2, 2, 2, 2, 2, 2,169,169,169,169,169,169,169,169,169,169, + 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133, 2, + 133,133,133,133,133,133,133,133,133,133,133,133,133, 2,133,133, + 133,133,133,133, 2, 2,133,133,133,133,133, 2, 2, 2,134,134, + 134,134,134,134,134,134, 2, 2,134,134,134,134,134,134, 2,134, + 134,134,134,134,134,134,134,134,134,134,134,134,134, 2,138,138, + 138,138,138,138,138, 2,138,138, 2,138,138,138,138,138,138,138, + 138,138,138,138,138,138, 2, 2,138, 2,138,138, 2,138,138,138, + 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, 2, + 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, + 143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, + 2, 2, 2, 2, 2, 2,143,143, 2, 2, 2, 2, 2, 2,145,145, + 145,145,145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2,163,163, + 163,163,163,163,163,163,163, 2,163,163,163,163,163,163,163,163, + 163, 2, 2, 2,163,163,163,163,163, 2, 2, 2, 2, 2, 86, 2, + 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, + 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2,157,157, + 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 2, 80, 80, + 80, 2, 2, 2, 2, 2,127,127,127,127,127,127,127,127,127,127, + 127,127,127,127,127, 2,166,166,166,166,166,166,166,166,166,166, + 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2,115,115, + 115,115,115,115,115,115,115,115,115,115,115,115,115, 2,115,115, + 2, 2, 2, 2,115,115,159,159,159,159,159,159,159,159,159,159, + 159,159,159,159,159, 2,159,159, 2, 2, 2, 2, 2, 2,103,103, + 103,103,103,103,103,103,103,103,103,103,103,103, 2, 2,119,119, + 119,119,119,119,119,119,119,119,119,119,119,119, 2, 2,119,119, + 2,119,119,119,119,119, 2, 2, 2, 2, 2,119,119,119,167,167, + 167,167,167,167,167,167,167,167, 2, 2, 2, 2, 2, 2,146,146, + 146,146,146,146,146,146,146,146,146, 2, 2, 2, 2, 2, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 2, 2, + 2, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2,136,136, + 136,136,136,136,136,136,155,155,155,155,155,155,155,155,155,155, + 155,155,155,155, 2, 2, 2, 2, 2, 2, 2, 2, 2,155,136, 2, + 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17, + 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17, + 17, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2, 2, 2, 2, 15, 15, + 15, 2, 2, 17, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17,139,139, + 139,139,139,139,139,139,139,139,139,139, 2, 2, 2, 2,105,105, + 105,105,105,105,105,105,105,105,105, 2, 2, 2, 2, 2,105,105, + 105,105,105, 2, 2, 2,105, 2, 2, 2, 2, 2, 2, 2,105,105, + 2, 2,105,105,105,105, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2, + 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0,131,131,131,131,131,131,131,131,131,131, + 131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131, + 131,131,131,131,131,131, 2, 2, 2, 2, 2, 19, 19, 19, 56, 56, + 56, 56, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 56, 56, 56, 56, + 2, 56, 56, 2, 56, 56, 56, 56, 56, 2, 2, 2, 2, 2, 6, 6, + 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,151,151, + 151,151,151,151,151,151,151,151,151,151,151, 2, 2, 2,151,151, + 151,151,151,151, 2, 2,151,151, 2, 2, 2, 2,151,151,160,160, + 160,160,160,160,160,160,160,160,160,160,160,160,160, 2,152,152, + 152,152,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164, + 164,164,164,164,164,164,164,164, 2, 2, 2, 2, 2, 2,168,168, + 168,168,168,168,168,168,168,168,168, 2, 2, 2, 2,168, 30, 30, + 30, 30, 2, 30, 30, 2,113,113,113,113,113,113,113,113,113,113, + 113,113,113, 2, 2,113,113,113,113,113,113,113,113, 2,132,132, + 132,132,132,132,132,132,132,132,132,132, 2, 2, 2, 2,132,132, + 2, 2, 2, 2,132,132, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, + 3, 2, 3, 2, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, + 3, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, + 3, 3, 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 13, 2, + 2, 2, 2, 2, 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 16, 17, 9, 9, 9, 9, 18, 9, 9, 9, 9, 9, 19, 20, + 21, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 23, 9, 9, 9, 9, 9, 24, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -3704,60 +3934,66 @@ _hb_ucd_u8[14752] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 23, 24, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, - 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, + 9, 9, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, + 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, + 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, + 0, 0, 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, + 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, + 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, + 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, + 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, - 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, - 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, - 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, - 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0, + 107, 0, 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, + 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124, + 125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,128,129,130,131,132,133,134,135,136,137,138,139, + 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155, + 156,157, 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102, - 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, 0, - 108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0,115, 0, - 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, 0,127, + 162, 0,163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, + 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0, + 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, - 144,145,146,147,148,149,150,151,152,153,154,155,156,157, 0, 0, - 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,162,163, 0, 0, 0, 0, 0, - 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,169,170, 0, 0, 0, 0,171,172, 0, 0, 0, - 173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188, - 189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204, - 205,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178, + 179, 0, 0, 0,180,181,182,183,184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, + 208,209,210,211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, }; static const uint16_t -_hb_ucd_u16[10060] = +_hb_ucd_u16[9668] = { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -3776,9 +4012,10 @@ _hb_ucd_u16[10060] = 136, 48, 48, 137, 138, 139, 140, 140, 141, 48, 142, 143, 144, 145, 140, 140, 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 140, 140, 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 168, 169, 48, 48, - 168, 48, 48, 170, 171, 172, 48, 48, 48, 171, 48, 48, 48, 173, 174, 175, - 48, 176, 9, 9, 9, 9, 9, 177, 178, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 168, 169, 48, 48, 168, 48, 48, 170, 171, 172, 48, 48, + 48, 171, 48, 48, 48, 173, 174, 175, 48, 176, 9, 9, 9, 9, 9, 177, + 178, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193, 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, @@ -3791,28 +4028,34 @@ _hb_ucd_u16[10060] = 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, - 279, 279, 279, 279, 279, 279, 279, 279, 280, 209, 281, 209, 209, 209, 209, 282, - 209, 283, 279, 284, 209, 285, 286, 209, 209, 209, 287, 140, 288, 140, 271, 271, - 271, 289, 209, 209, 209, 209, 290, 271, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 291, 292, 209, 209, 293, 209, 209, 209, 209, 209, 209, 294, 209, - 209, 209, 209, 209, 209, 209, 295, 296, 271, 297, 209, 209, 298, 279, 299, 279, - 300, 301, 279, 279, 279, 302, 279, 303, 209, 209, 209, 279, 304, 209, 209, 305, - 209, 306, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 307, 308, - 13, 13, 13, 13, 13, 13, 309, 310, 11, 11, 311, 48, 48, 48, 312, 313, - 48, 314, 315, 315, 315, 315, 32, 32, 316, 317, 318, 319, 320, 321, 140, 140, - 209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 209, - 325, 326, 327, 328, 136, 48, 48, 48, 48, 329, 178, 48, 48, 48, 48, 330, - 331, 48, 48, 136, 48, 48, 48, 48, 200, 332, 48, 48, 209, 209, 333, 48, - 209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209, - 48, 48, 48, 48, 209, 209, 209, 209, 48, 338, 48, 48, 48, 48, 48, 48, - 151, 209, 209, 209, 287, 48, 48, 229, 339, 48, 340, 140, 13, 13, 341, 342, - 13, 343, 48, 48, 48, 48, 344, 345, 31, 346, 347, 348, 13, 13, 13, 349, - 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360, - 361, 48, 48, 362, 363, 192, 32, 364, 64, 48, 365, 48, 366, 367, 48, 151, - 76, 48, 48, 368, 369, 370, 371, 372, 48, 48, 373, 374, 375, 376, 48, 377, - 48, 48, 48, 378, 379, 380, 381, 382, 383, 384, 315, 11, 11, 385, 386, 11, - 11, 11, 11, 11, 48, 48, 387, 192, 48, 48, 388, 48, 389, 48, 48, 206, - 390, 390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 280, 209, 281, 209, 209, 209, 209, 282, 209, 283, 279, 284, 209, 285, 286, 209, + 209, 209, 176, 140, 287, 140, 271, 271, 271, 288, 209, 209, 209, 209, 289, 271, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 290, 291, 209, 209, 292, + 209, 209, 209, 209, 209, 209, 293, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 294, 295, 271, 296, 209, 209, 297, 279, 298, 279, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 279, 279, 279, 279, 279, 279, 279, 279, 299, 300, 279, 279, 279, 301, 279, 302, + 209, 209, 209, 279, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209, + 9, 9, 9, 11, 11, 11, 306, 307, 13, 13, 13, 13, 13, 13, 308, 309, + 11, 11, 310, 48, 48, 48, 311, 312, 48, 313, 314, 314, 314, 314, 32, 32, + 315, 316, 317, 318, 319, 320, 140, 140, 209, 321, 209, 209, 209, 209, 209, 322, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, 140, 209, + 324, 325, 326, 327, 136, 48, 48, 48, 48, 328, 178, 48, 48, 48, 48, 329, + 330, 48, 48, 136, 48, 48, 48, 48, 200, 331, 48, 48, 209, 209, 332, 48, + 209, 333, 334, 209, 335, 336, 209, 209, 334, 209, 209, 336, 209, 209, 209, 209, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 209, 209, 209, 209, + 48, 337, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 229, + 339, 48, 340, 140, 13, 13, 341, 342, 13, 343, 48, 48, 48, 48, 344, 345, + 31, 346, 347, 348, 13, 13, 13, 349, 350, 351, 352, 353, 354, 355, 140, 356, + 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, + 64, 48, 365, 48, 366, 367, 48, 151, 76, 48, 48, 368, 369, 370, 371, 372, + 48, 48, 373, 374, 375, 376, 48, 377, 48, 48, 48, 378, 379, 380, 381, 382, + 383, 384, 314, 11, 11, 385, 386, 11, 11, 11, 11, 11, 48, 48, 387, 192, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 48, 389, 48, 48, 206, + 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140, 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48, 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403, @@ -3823,571 +4066,540 @@ _hb_ucd_u16[10060] = 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140, 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439, - 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 140, 140, 140, 140, - 48, 48, 48, 314, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, + 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 48, 48, 48, 388, + 48, 48, 48, 313, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453, 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271, 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, - 48, 48, 475, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 271, 476, - 48, 48, 477, 478, 140, 140, 140, 479, 48, 464, 480, 48, 62, 481, 140, 48, - 482, 140, 140, 48, 483, 140, 48, 314, 484, 48, 48, 485, 486, 457, 487, 488, - 222, 48, 48, 489, 490, 48, 196, 192, 491, 48, 492, 493, 494, 48, 48, 495, - 222, 48, 48, 496, 497, 498, 499, 500, 48, 97, 501, 502, 503, 140, 140, 140, - 504, 505, 506, 48, 48, 507, 508, 192, 509, 83, 84, 510, 511, 512, 513, 514, - 48, 48, 48, 515, 516, 517, 478, 140, 48, 48, 48, 518, 519, 192, 140, 140, - 48, 48, 520, 521, 522, 523, 140, 140, 48, 48, 48, 524, 525, 192, 526, 140, - 48, 48, 527, 528, 192, 140, 140, 140, 48, 173, 529, 530, 314, 140, 140, 140, - 48, 48, 501, 531, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 532, - 533, 534, 48, 535, 536, 192, 140, 140, 140, 140, 537, 48, 48, 538, 539, 140, - 540, 48, 48, 541, 542, 543, 48, 48, 544, 545, 546, 48, 48, 48, 48, 196, - 547, 140, 140, 140, 140, 140, 140, 140, 84, 48, 520, 548, 549, 148, 175, 550, - 48, 551, 552, 553, 140, 140, 140, 140, 554, 48, 48, 555, 556, 192, 557, 48, - 558, 559, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 560, - 561, 115, 48, 562, 563, 192, 140, 140, 140, 140, 140, 100, 271, 564, 565, 566, - 48, 207, 140, 140, 140, 140, 140, 140, 272, 272, 272, 272, 272, 272, 567, 568, - 48, 48, 48, 48, 388, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 569, - 48, 48, 48, 570, 571, 572, 140, 140, 48, 48, 48, 48, 314, 140, 140, 140, - 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 573, - 48, 48, 48, 574, 575, 576, 577, 578, 48, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 9, 9, 11, 11, 271, 579, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 580, 581, 582, 582, 583, 584, 140, 140, 140, 140, 585, 586, - 48, 48, 48, 48, 48, 48, 48, 440, 48, 48, 48, 48, 48, 199, 140, 140, - 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 587, - 48, 48, 588, 589, 140, 590, 591, 48, 48, 48, 48, 48, 48, 48, 48, 206, - 48, 48, 48, 48, 48, 48, 71, 151, 196, 592, 593, 140, 140, 140, 140, 140, - 32, 32, 594, 32, 595, 209, 209, 209, 209, 209, 209, 209, 323, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 324, 209, 209, 596, 209, 209, 209, 597, 598, - 599, 209, 600, 209, 209, 209, 288, 140, 209, 209, 209, 209, 601, 140, 140, 140, - 140, 140, 140, 140, 271, 602, 271, 602, 209, 209, 209, 209, 209, 287, 271, 461, - 9, 603, 11, 604, 605, 606, 241, 9, 607, 608, 609, 610, 611, 9, 603, 11, - 612, 613, 11, 614, 615, 616, 617, 9, 618, 11, 9, 603, 11, 604, 605, 11, - 241, 9, 607, 617, 9, 618, 11, 9, 603, 11, 619, 9, 620, 621, 622, 623, - 11, 624, 9, 625, 626, 627, 628, 11, 629, 9, 630, 11, 631, 632, 632, 632, - 32, 32, 32, 633, 32, 32, 634, 635, 636, 637, 45, 140, 140, 140, 140, 140, - 638, 639, 640, 140, 140, 140, 140, 140, 641, 642, 643, 27, 27, 27, 644, 140, - 645, 140, 140, 140, 140, 140, 140, 140, 48, 48, 151, 646, 647, 140, 140, 140, - 140, 48, 648, 140, 48, 48, 649, 650, 140, 140, 140, 140, 140, 48, 651, 192, - 140, 140, 140, 140, 140, 140, 652, 200, 48, 48, 48, 48, 653, 595, 140, 140, - 9, 9, 607, 11, 654, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 499, - 271, 271, 655, 656, 140, 140, 140, 140, 499, 271, 657, 658, 140, 140, 140, 140, - 659, 48, 660, 661, 662, 663, 664, 665, 666, 206, 667, 206, 140, 140, 140, 668, - 209, 209, 669, 209, 209, 209, 209, 209, 209, 323, 334, 670, 670, 670, 209, 324, - 671, 209, 209, 209, 209, 209, 209, 209, 209, 209, 672, 140, 140, 140, 673, 209, - 674, 209, 209, 669, 675, 676, 324, 140, 209, 209, 209, 209, 209, 209, 209, 677, - 209, 209, 209, 209, 209, 678, 426, 426, 209, 209, 209, 209, 209, 209, 209, 679, - 209, 209, 209, 209, 209, 176, 669, 427, 669, 209, 209, 209, 680, 176, 209, 209, - 680, 209, 672, 676, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 672, 426, - 675, 209, 209, 681, 682, 669, 675, 675, 209, 683, 209, 209, 288, 140, 140, 192, - 48, 48, 48, 48, 48, 48, 140, 140, 48, 48, 48, 207, 48, 48, 48, 48, - 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 478, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 100, 48, 48, 48, 48, 48, 48, 204, 140, 140, - 48, 204, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 71, 48, 48, 48, - 48, 48, 48, 140, 140, 140, 140, 140, 684, 140, 570, 570, 570, 570, 570, 570, + 48, 48, 475, 192, 476, 9, 477, 11, 478, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 271, 479, 48, 48, 480, 481, 482, 140, 140, 483, + 48, 464, 484, 48, 62, 485, 140, 48, 486, 140, 140, 48, 487, 140, 48, 313, + 488, 48, 48, 489, 490, 457, 491, 492, 222, 48, 48, 493, 494, 48, 196, 192, + 495, 48, 496, 497, 498, 48, 48, 499, 222, 48, 48, 500, 501, 502, 503, 504, + 48, 97, 505, 506, 507, 140, 140, 140, 508, 509, 510, 48, 48, 511, 512, 192, + 513, 83, 84, 514, 515, 516, 517, 518, 519, 48, 48, 520, 521, 522, 523, 140, + 48, 48, 48, 524, 525, 526, 481, 140, 48, 48, 48, 527, 528, 192, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 529, 530, 531, 532, 140, 140, + 48, 48, 48, 533, 534, 192, 535, 140, 48, 48, 536, 537, 192, 538, 539, 140, + 48, 540, 541, 542, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 505, 543, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 544, + 545, 546, 48, 547, 548, 192, 140, 140, 140, 140, 549, 48, 48, 550, 551, 140, + 552, 48, 48, 553, 554, 555, 48, 48, 556, 557, 558, 48, 48, 48, 48, 196, + 559, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 560, 192, + 84, 48, 529, 561, 562, 148, 175, 563, 48, 564, 565, 566, 140, 140, 140, 140, + 567, 48, 48, 568, 569, 192, 570, 48, 571, 572, 192, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 573, + 574, 115, 48, 575, 576, 577, 140, 140, 140, 140, 140, 100, 271, 578, 579, 580, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, + 272, 272, 272, 272, 272, 272, 581, 582, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 388, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 583, + 48, 48, 48, 584, 585, 586, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 71, + 48, 48, 48, 48, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 587, 588, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 589, + 48, 48, 48, 590, 591, 592, 593, 594, 48, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 595, 48, 596, 192, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 9, 9, 11, 11, 271, 597, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 598, 599, 600, 600, 601, 602, 140, 140, 140, 140, 603, 604, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 440, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 605, + 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 606, + 48, 48, 607, 608, 140, 609, 610, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 206, + 48, 48, 48, 48, 48, 48, 71, 151, 196, 611, 612, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 192, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 140, + 32, 32, 613, 32, 614, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, + 209, 209, 615, 209, 209, 209, 616, 617, 618, 209, 619, 209, 209, 209, 287, 140, + 209, 209, 209, 209, 620, 140, 140, 140, 140, 140, 140, 140, 271, 621, 271, 621, + 209, 209, 209, 209, 209, 338, 271, 461, 140, 140, 140, 140, 140, 140, 140, 140, + 9, 622, 11, 623, 624, 625, 241, 9, 626, 627, 628, 629, 630, 9, 622, 11, + 631, 632, 11, 633, 634, 635, 636, 9, 637, 11, 9, 622, 11, 623, 624, 11, + 241, 9, 626, 636, 9, 637, 11, 9, 622, 11, 638, 9, 639, 640, 641, 642, + 11, 643, 9, 644, 645, 646, 647, 11, 648, 9, 649, 11, 650, 538, 538, 538, + 32, 32, 32, 651, 32, 32, 652, 653, 654, 655, 45, 140, 140, 140, 140, 140, + 656, 657, 658, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 659, 660, 661, 27, 27, 27, 662, 140, 663, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 151, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 666, 140, 48, 48, 667, 668, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 669, 192, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 587, 670, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 671, 200, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 672, 614, 140, 140, + 9, 9, 626, 11, 673, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 503, 271, 271, 674, 675, 140, 140, 140, 140, + 503, 271, 676, 677, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 678, 48, 679, 680, 681, 682, 683, 684, 685, 206, 686, 206, 140, 140, 140, 687, + 209, 209, 688, 209, 209, 209, 209, 209, 209, 322, 333, 689, 689, 689, 209, 323, + 690, 209, 209, 209, 209, 209, 209, 209, 209, 209, 691, 140, 140, 140, 692, 209, + 693, 209, 209, 688, 694, 695, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 696, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 697, 426, 426, + 209, 209, 209, 209, 209, 209, 209, 698, 209, 209, 209, 209, 209, 176, 688, 427, + 688, 209, 209, 209, 699, 176, 209, 209, 699, 209, 691, 688, 695, 140, 140, 140, + 209, 209, 209, 209, 209, 322, 691, 426, 700, 209, 209, 209, 701, 702, 176, 694, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 703, 209, 209, 209, 209, 209, 192, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, + 48, 48, 48, 207, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 481, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 48, + 48, 48, 48, 48, 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, + 704, 140, 584, 584, 584, 584, 584, 584, 140, 140, 140, 140, 140, 140, 140, 140, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, - 391, 391, 391, 391, 391, 391, 391, 685, 391, 391, 391, 391, 391, 391, 391, 686, - 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, - 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 12, 11, 11, 11, 13, 11, - 14, 14, 14, 14, 14, 14, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 16, 17, 18, 17, 17, 19, 20, 21, 21, 22, 21, 23, 24, - 25, 26, 27, 27, 28, 29, 27, 30, 27, 27, 27, 27, 27, 31, 27, 27, - 32, 33, 33, 33, 34, 27, 27, 27, 35, 35, 35, 36, 37, 37, 37, 38, - 39, 39, 40, 41, 42, 43, 44, 27, 45, 46, 27, 27, 27, 27, 47, 27, - 48, 48, 48, 48, 48, 49, 50, 48, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 109, 110, 111, 112, 109, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 122, 123, 122, 124, 125, 125, 126, 127, 128, 129, 130, 131, 125, 125, - 132, 132, 132, 132, 133, 132, 134, 135, 132, 133, 132, 136, 136, 137, 125, 125, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 140, 139, 139, 141, - 142, 142, 142, 142, 142, 142, 142, 142, 143, 143, 143, 143, 144, 145, 143, 143, - 144, 143, 143, 146, 147, 148, 143, 143, 143, 147, 143, 143, 143, 149, 143, 150, - 143, 151, 152, 152, 152, 152, 152, 153, 154, 154, 154, 154, 154, 154, 154, 154, - 155, 156, 157, 157, 157, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 168, 168, 168, 168, 169, 170, 170, 171, 172, 173, 173, 173, 173, 173, 174, - 173, 173, 175, 154, 154, 154, 154, 176, 177, 178, 179, 179, 180, 181, 182, 183, - 184, 184, 185, 184, 186, 187, 168, 168, 188, 189, 190, 190, 190, 191, 190, 192, - 193, 193, 194, 8, 195, 125, 125, 125, 196, 196, 196, 196, 197, 196, 196, 198, - 199, 199, 199, 199, 200, 200, 200, 201, 202, 202, 202, 203, 204, 205, 205, 205, - 206, 139, 139, 207, 208, 209, 210, 211, 4, 4, 212, 4, 4, 213, 214, 215, - 4, 4, 4, 216, 8, 8, 8, 8, 11, 217, 11, 11, 217, 218, 11, 219, - 11, 11, 11, 220, 220, 221, 11, 222, 223, 0, 0, 0, 0, 0, 224, 225, - 226, 227, 0, 0, 228, 8, 8, 229, 0, 0, 230, 231, 232, 0, 4, 4, - 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 234, 125, 235, 125, 0, 0, 236, 236, 236, 236, 236, 236, 236, 236, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 238, 0, 0, 0, 0, 0, 0, - 239, 239, 239, 239, 239, 239, 4, 4, 240, 240, 240, 240, 240, 240, 240, 241, - 139, 139, 140, 242, 242, 242, 243, 244, 143, 245, 246, 246, 246, 246, 14, 14, - 0, 0, 0, 0, 0, 247, 125, 125, 248, 249, 248, 248, 248, 248, 248, 250, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 125, 0, - 252, 0, 253, 254, 255, 256, 256, 256, 256, 257, 258, 259, 259, 259, 259, 260, - 261, 262, 262, 263, 142, 142, 142, 142, 264, 0, 262, 262, 0, 0, 265, 259, - 142, 264, 0, 0, 0, 0, 142, 266, 0, 0, 0, 0, 0, 259, 259, 267, - 259, 259, 259, 259, 259, 268, 0, 0, 248, 248, 248, 248, 0, 0, 0, 0, - 269, 269, 269, 269, 269, 269, 269, 269, 270, 269, 269, 269, 271, 272, 272, 272, - 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 274, 125, 14, 14, 14, 14, - 14, 14, 275, 275, 275, 275, 275, 276, 0, 0, 277, 4, 4, 4, 4, 4, - 278, 4, 4, 4, 279, 280, 125, 281, 282, 282, 283, 284, 285, 285, 285, 286, - 287, 287, 287, 287, 288, 289, 48, 48, 290, 290, 291, 292, 292, 293, 142, 294, - 295, 295, 295, 295, 296, 297, 138, 298, 299, 299, 299, 300, 301, 302, 138, 138, - 303, 303, 303, 303, 304, 305, 306, 307, 308, 309, 246, 4, 4, 310, 311, 152, - 152, 152, 152, 152, 306, 306, 312, 313, 142, 142, 314, 142, 315, 142, 142, 316, - 125, 125, 125, 125, 125, 125, 125, 125, 248, 248, 248, 248, 248, 248, 317, 248, - 248, 248, 248, 248, 248, 318, 125, 125, 319, 320, 21, 321, 322, 27, 27, 27, - 27, 27, 27, 27, 323, 324, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 325, 27, 27, 27, 27, 27, 326, 27, 27, 327, 125, 125, 27, - 8, 284, 328, 0, 0, 329, 330, 331, 27, 27, 27, 27, 27, 27, 27, 332, - 333, 0, 1, 2, 1, 2, 334, 258, 259, 335, 142, 264, 336, 337, 338, 339, - 340, 341, 342, 343, 344, 344, 125, 125, 341, 341, 341, 341, 341, 341, 341, 345, - 346, 0, 0, 347, 11, 11, 11, 11, 348, 349, 350, 125, 125, 0, 0, 351, - 352, 353, 354, 354, 354, 355, 356, 357, 358, 358, 359, 360, 361, 362, 362, 363, - 364, 365, 366, 366, 367, 368, 125, 125, 369, 369, 369, 369, 369, 370, 370, 370, - 371, 372, 373, 374, 374, 375, 374, 376, 377, 377, 378, 379, 379, 379, 380, 381, - 381, 382, 383, 384, 125, 125, 125, 125, 385, 385, 385, 385, 385, 385, 385, 385, - 385, 385, 385, 386, 385, 387, 388, 125, 389, 4, 4, 390, 125, 125, 125, 125, - 391, 392, 392, 393, 394, 395, 396, 396, 397, 398, 399, 125, 125, 125, 400, 401, - 402, 403, 404, 405, 125, 125, 125, 125, 406, 406, 407, 408, 407, 409, 407, 407, - 410, 411, 412, 413, 414, 414, 415, 415, 416, 416, 125, 125, 417, 417, 418, 419, - 420, 420, 420, 421, 422, 423, 424, 425, 426, 427, 428, 125, 125, 125, 125, 125, - 429, 429, 429, 429, 430, 125, 125, 125, 431, 431, 431, 432, 431, 431, 431, 433, - 434, 434, 435, 436, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 27, 45, - 437, 437, 438, 439, 125, 125, 125, 440, 441, 441, 442, 443, 443, 444, 125, 445, - 446, 125, 125, 447, 448, 125, 449, 450, 451, 451, 451, 451, 452, 453, 451, 454, - 455, 455, 455, 455, 456, 457, 458, 459, 460, 460, 460, 461, 462, 463, 463, 464, - 465, 465, 465, 465, 465, 465, 466, 467, 468, 469, 468, 468, 470, 125, 125, 125, - 471, 472, 473, 474, 474, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, - 485, 485, 485, 485, 485, 486, 487, 125, 488, 488, 488, 488, 489, 490, 125, 125, - 491, 491, 491, 492, 491, 493, 125, 125, 494, 494, 494, 494, 495, 496, 497, 125, - 498, 498, 498, 499, 499, 125, 125, 125, 500, 501, 502, 500, 503, 125, 125, 125, - 504, 504, 504, 505, 125, 125, 125, 125, 125, 125, 506, 506, 506, 506, 506, 507, - 508, 509, 510, 511, 512, 513, 125, 125, 125, 125, 514, 515, 515, 514, 516, 125, - 517, 517, 517, 517, 518, 519, 519, 519, 519, 519, 520, 154, 521, 521, 521, 522, - 523, 125, 125, 125, 125, 125, 125, 125, 524, 525, 525, 526, 527, 525, 528, 529, - 529, 530, 531, 532, 125, 125, 125, 125, 533, 534, 534, 535, 536, 537, 538, 539, - 540, 541, 542, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 543, 544, - 545, 546, 545, 547, 545, 548, 125, 125, 125, 125, 125, 549, 550, 550, 550, 551, - 552, 552, 552, 552, 552, 552, 552, 552, 552, 553, 125, 125, 125, 125, 125, 125, - 552, 552, 552, 552, 552, 552, 554, 555, 552, 552, 552, 552, 556, 125, 125, 125, - 125, 557, 557, 557, 557, 557, 557, 558, 559, 559, 559, 559, 559, 559, 559, 559, - 559, 559, 559, 559, 559, 560, 125, 125, 561, 561, 561, 561, 561, 561, 561, 561, - 561, 561, 561, 561, 562, 125, 125, 125, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 563, 564, 565, 566, 567, 567, 567, 567, 568, 569, 570, 571, 572, - 573, 573, 573, 573, 574, 575, 576, 577, 573, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 578, 578, 578, 578, 578, 579, 125, 125, 125, 125, 125, 125, - 580, 580, 580, 580, 581, 580, 580, 580, 582, 580, 125, 125, 125, 125, 583, 584, - 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 586, - 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 588, 125, 125, - 589, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 590, - 591, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 592, 593, 125, 594, 595, 596, 596, 596, 596, 596, 596, 596, 596, 596, - 596, 596, 596, 596, 596, 596, 596, 597, 598, 598, 598, 598, 598, 598, 599, 600, - 601, 602, 603, 125, 125, 125, 125, 125, 8, 8, 604, 8, 605, 0, 0, 0, - 0, 0, 0, 0, 603, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 606, - 0, 0, 607, 0, 0, 0, 608, 609, 610, 0, 611, 0, 0, 0, 235, 125, - 11, 11, 11, 11, 612, 125, 125, 125, 125, 125, 125, 125, 0, 603, 0, 603, - 0, 0, 0, 0, 0, 234, 0, 613, 0, 0, 0, 0, 0, 224, 0, 0, - 0, 614, 615, 616, 617, 0, 0, 0, 618, 619, 0, 620, 621, 622, 0, 0, - 0, 0, 623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 624, 0, 0, 0, - 625, 625, 625, 625, 625, 625, 625, 625, 626, 627, 628, 125, 125, 125, 125, 125, - 4, 629, 630, 125, 125, 125, 125, 125, 631, 632, 633, 14, 14, 14, 634, 125, - 635, 125, 125, 125, 125, 125, 125, 125, 636, 636, 637, 638, 639, 125, 125, 125, - 125, 640, 641, 125, 642, 642, 642, 643, 125, 125, 125, 125, 125, 644, 644, 645, - 125, 125, 125, 125, 125, 125, 646, 647, 648, 648, 648, 648, 648, 648, 648, 648, - 648, 648, 648, 648, 649, 650, 125, 125, 651, 651, 651, 651, 652, 653, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 333, 0, 0, 0, 654, 125, 125, 125, 125, - 333, 0, 0, 247, 125, 125, 125, 125, 655, 27, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 663, 125, 125, 125, 665, 0, 0, 357, 0, 0, 0, 0, 0, - 0, 603, 226, 333, 333, 333, 0, 606, 0, 0, 247, 125, 125, 125, 666, 0, - 667, 0, 0, 357, 613, 668, 606, 125, 0, 0, 0, 0, 0, 669, 349, 349, - 0, 0, 0, 0, 0, 0, 0, 670, 0, 0, 0, 0, 0, 284, 357, 228, - 357, 0, 0, 0, 671, 284, 0, 0, 671, 0, 247, 668, 125, 125, 125, 125, - 0, 0, 0, 0, 0, 603, 247, 349, 613, 0, 0, 672, 673, 357, 613, 613, - 0, 329, 0, 0, 235, 125, 125, 284, 248, 248, 248, 248, 248, 248, 125, 125, - 248, 248, 248, 318, 248, 248, 248, 248, 248, 317, 248, 248, 248, 248, 248, 248, - 248, 248, 584, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 674, 248, - 248, 248, 248, 248, 248, 317, 125, 125, 248, 317, 125, 125, 125, 125, 125, 125, - 248, 248, 248, 248, 675, 248, 248, 248, 248, 248, 248, 125, 125, 125, 125, 125, - 676, 125, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 1, 2, 2, 2, - 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, - 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 8, 8, 8, 8, 16, 8, 8, 8, 17, 18, 18, 18, - 19, 19, 19, 19, 19, 20, 19, 19, 21, 22, 22, 22, 22, 22, 22, 22, - 22, 23, 21, 22, 22, 22, 23, 21, 24, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 12, 12, 25, 25, 26, 27, 25, 28, 12, 12, 29, 30, 29, 31, - 29, 29, 32, 32, 29, 29, 29, 29, 31, 29, 33, 7, 7, 34, 29, 29, - 35, 29, 29, 29, 29, 29, 29, 30, 36, 36, 36, 37, 36, 36, 36, 36, - 36, 36, 38, 39, 40, 40, 40, 40, 41, 12, 12, 12, 42, 42, 42, 42, - 42, 42, 43, 44, 45, 45, 45, 45, 45, 45, 45, 46, 45, 45, 45, 47, - 48, 48, 48, 48, 48, 48, 48, 49, 36, 36, 38, 12, 29, 29, 29, 50, - 51, 12, 29, 29, 52, 29, 29, 29, 53, 53, 53, 53, 54, 55, 53, 53, - 53, 56, 53, 53, 57, 58, 57, 59, 59, 57, 57, 57, 57, 57, 60, 57, - 61, 62, 63, 57, 57, 59, 59, 64, 12, 65, 12, 66, 57, 62, 57, 57, - 57, 57, 57, 64, 67, 67, 68, 69, 70, 71, 71, 71, 71, 71, 72, 71, - 72, 73, 74, 72, 68, 69, 70, 74, 75, 12, 67, 76, 12, 77, 71, 71, - 71, 68, 12, 12, 78, 78, 79, 80, 80, 79, 79, 79, 79, 79, 81, 79, - 81, 78, 82, 79, 79, 80, 80, 82, 83, 12, 12, 12, 79, 84, 79, 79, - 82, 12, 78, 79, 85, 85, 86, 87, 87, 86, 86, 86, 86, 86, 88, 86, - 88, 85, 89, 86, 86, 87, 87, 89, 12, 85, 12, 90, 86, 91, 86, 86, - 86, 86, 12, 12, 92, 93, 94, 92, 95, 96, 97, 95, 98, 99, 94, 92, - 100, 100, 96, 92, 94, 92, 95, 96, 99, 98, 12, 12, 12, 92, 100, 100, - 100, 100, 94, 12, 101, 101, 101, 102, 102, 101, 101, 101, 101, 101, 102, 101, - 101, 101, 103, 101, 101, 102, 102, 103, 12, 104, 105, 106, 101, 107, 101, 101, - 12, 108, 101, 101, 109, 109, 109, 110, 110, 109, 109, 109, 109, 109, 110, 109, - 109, 111, 112, 109, 109, 110, 110, 112, 12, 113, 12, 113, 109, 114, 109, 109, - 111, 12, 12, 12, 115, 115, 115, 116, 116, 115, 115, 115, 115, 115, 115, 115, - 115, 116, 116, 115, 12, 115, 115, 115, 115, 117, 115, 115, 118, 118, 119, 119, - 119, 120, 121, 119, 119, 119, 119, 119, 122, 119, 119, 123, 119, 120, 124, 125, - 119, 126, 119, 119, 12, 121, 119, 119, 121, 127, 12, 12, 128, 129, 129, 129, - 129, 129, 129, 129, 129, 129, 130, 131, 129, 129, 129, 12, 12, 12, 12, 12, - 132, 133, 134, 135, 135, 135, 135, 135, 135, 136, 135, 135, 135, 135, 135, 137, - 135, 138, 135, 134, 135, 135, 137, 135, 139, 139, 139, 139, 139, 139, 140, 139, - 139, 139, 139, 141, 140, 139, 139, 139, 139, 139, 139, 142, 139, 143, 144, 12, - 145, 145, 145, 145, 146, 146, 146, 146, 146, 147, 12, 148, 146, 146, 149, 146, - 150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 152, 153, 151, 154, 152, 153, - 152, 153, 151, 154, 152, 153, 151, 151, 151, 154, 151, 151, 151, 151, 154, 155, - 151, 151, 151, 156, 151, 151, 153, 12, 157, 157, 157, 157, 157, 158, 157, 158, - 159, 159, 159, 159, 160, 160, 160, 160, 160, 160, 160, 161, 162, 162, 162, 162, - 162, 162, 163, 164, 162, 162, 165, 12, 166, 166, 166, 166, 166, 167, 12, 168, - 169, 169, 169, 169, 169, 170, 12, 12, 171, 171, 171, 171, 171, 12, 12, 12, - 172, 172, 172, 173, 173, 12, 12, 12, 174, 174, 174, 174, 174, 174, 174, 175, - 174, 174, 175, 12, 176, 177, 178, 178, 178, 178, 179, 12, 178, 178, 178, 178, - 178, 178, 180, 12, 178, 178, 181, 12, 159, 182, 12, 12, 183, 183, 183, 183, - 183, 183, 183, 184, 183, 183, 183, 12, 185, 183, 183, 183, 186, 186, 186, 186, - 186, 186, 186, 187, 186, 188, 12, 12, 189, 189, 189, 189, 189, 189, 189, 12, - 189, 189, 190, 12, 189, 189, 191, 192, 193, 193, 193, 193, 193, 193, 193, 194, - 195, 195, 195, 195, 195, 195, 195, 196, 195, 195, 195, 197, 195, 195, 198, 12, - 195, 195, 195, 198, 7, 7, 7, 199, 200, 200, 200, 200, 200, 200, 200, 201, - 200, 200, 200, 202, 203, 203, 203, 203, 204, 204, 204, 204, 204, 12, 12, 204, - 205, 205, 205, 205, 205, 205, 206, 205, 205, 205, 207, 208, 209, 209, 209, 209, - 19, 19, 210, 12, 146, 146, 211, 212, 203, 203, 12, 12, 213, 7, 7, 7, - 214, 7, 215, 216, 0, 215, 217, 12, 2, 218, 219, 2, 2, 2, 2, 220, - 221, 218, 222, 2, 2, 2, 223, 2, 2, 2, 2, 224, 8, 225, 8, 225, - 8, 8, 226, 226, 8, 8, 8, 225, 8, 15, 8, 8, 8, 10, 8, 227, - 10, 15, 8, 14, 0, 0, 0, 228, 0, 229, 0, 0, 230, 0, 0, 231, - 0, 0, 0, 232, 2, 2, 2, 233, 234, 12, 12, 12, 235, 12, 12, 12, - 0, 236, 237, 0, 4, 0, 0, 0, 0, 0, 0, 4, 2, 2, 5, 12, - 0, 232, 12, 12, 0, 0, 232, 12, 238, 238, 238, 238, 0, 239, 0, 0, - 0, 240, 0, 0, 241, 241, 241, 241, 18, 18, 18, 18, 18, 12, 242, 18, - 243, 243, 243, 243, 243, 243, 12, 244, 245, 12, 12, 244, 151, 154, 12, 12, - 151, 154, 151, 154, 0, 0, 0, 246, 247, 247, 247, 247, 247, 247, 248, 247, - 247, 12, 12, 12, 247, 249, 12, 12, 0, 250, 0, 0, 251, 247, 252, 253, - 0, 0, 247, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 256, 257, 258, - 259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 259, 12, 262, 263, 263, - 263, 263, 263, 263, 264, 150, 150, 150, 150, 150, 150, 265, 0, 12, 12, 131, - 150, 150, 150, 266, 260, 260, 260, 261, 260, 260, 0, 0, 267, 267, 267, 267, - 267, 267, 267, 268, 267, 269, 12, 12, 270, 270, 270, 270, 271, 271, 271, 271, - 271, 271, 271, 12, 272, 272, 272, 272, 272, 272, 12, 12, 237, 2, 2, 2, - 2, 2, 231, 2, 2, 2, 273, 12, 274, 275, 276, 12, 277, 2, 2, 2, - 278, 278, 278, 278, 278, 278, 278, 279, 0, 0, 246, 12, 280, 280, 280, 280, - 280, 280, 12, 12, 281, 281, 281, 281, 281, 282, 12, 283, 281, 281, 282, 12, - 284, 284, 284, 284, 284, 284, 284, 285, 286, 286, 286, 286, 286, 12, 12, 287, - 150, 150, 150, 288, 289, 289, 289, 289, 289, 289, 289, 290, 289, 289, 291, 292, - 145, 145, 145, 293, 294, 294, 294, 294, 294, 295, 12, 12, 294, 294, 294, 296, - 294, 294, 296, 294, 297, 297, 297, 297, 298, 12, 12, 12, 12, 12, 299, 297, - 300, 300, 300, 300, 300, 301, 12, 12, 155, 154, 155, 154, 155, 154, 12, 12, - 2, 2, 3, 2, 2, 302, 303, 12, 300, 300, 300, 304, 300, 300, 304, 12, - 150, 12, 12, 12, 150, 265, 305, 150, 150, 150, 150, 12, 247, 247, 247, 249, - 247, 247, 249, 12, 2, 273, 12, 12, 306, 22, 12, 24, 25, 26, 25, 307, - 308, 309, 25, 25, 50, 12, 12, 12, 310, 29, 29, 29, 29, 29, 29, 311, - 312, 29, 29, 29, 29, 29, 12, 310, 7, 7, 7, 313, 232, 0, 0, 0, - 0, 232, 0, 12, 29, 314, 29, 29, 29, 29, 29, 315, 316, 0, 0, 0, - 0, 317, 260, 260, 260, 260, 260, 318, 319, 150, 319, 150, 319, 150, 319, 288, - 0, 232, 0, 232, 12, 12, 316, 246, 320, 320, 320, 321, 320, 320, 320, 320, - 320, 322, 320, 320, 320, 320, 322, 323, 320, 320, 320, 324, 320, 320, 322, 12, - 232, 131, 0, 0, 0, 131, 0, 0, 8, 8, 8, 14, 0, 0, 0, 234, - 325, 12, 12, 12, 0, 0, 0, 326, 327, 327, 327, 327, 327, 327, 327, 328, - 329, 329, 329, 329, 330, 12, 12, 12, 215, 0, 0, 0, 0, 0, 0, 12, - 331, 331, 331, 331, 331, 12, 12, 332, 333, 333, 333, 333, 333, 333, 334, 12, - 335, 335, 335, 335, 335, 335, 336, 12, 337, 337, 337, 337, 337, 337, 337, 338, - 339, 339, 339, 339, 339, 12, 339, 339, 339, 340, 12, 12, 341, 341, 341, 341, - 342, 342, 342, 342, 343, 343, 343, 343, 343, 343, 343, 344, 343, 343, 344, 12, - 345, 345, 345, 345, 345, 12, 345, 345, 345, 345, 345, 12, 346, 346, 346, 346, - 346, 346, 12, 12, 347, 347, 347, 347, 347, 12, 12, 348, 349, 349, 350, 349, - 350, 351, 349, 349, 351, 349, 349, 349, 351, 349, 351, 352, 353, 353, 353, 353, - 353, 354, 12, 12, 353, 355, 12, 12, 353, 353, 12, 12, 2, 274, 2, 2, - 356, 2, 273, 12, 357, 358, 359, 357, 357, 357, 357, 357, 357, 360, 361, 362, - 363, 363, 363, 363, 363, 364, 363, 363, 365, 365, 365, 365, 366, 366, 366, 366, - 366, 366, 366, 367, 12, 368, 366, 366, 369, 369, 369, 369, 370, 371, 372, 369, - 373, 373, 373, 373, 373, 373, 373, 374, 375, 375, 375, 375, 375, 375, 376, 377, - 378, 378, 378, 378, 379, 379, 379, 379, 379, 379, 12, 379, 380, 379, 379, 379, - 381, 382, 12, 381, 381, 383, 383, 381, 381, 381, 381, 381, 381, 384, 385, 386, - 381, 381, 387, 12, 388, 388, 388, 388, 389, 389, 389, 389, 390, 390, 390, 390, - 390, 391, 392, 390, 390, 391, 12, 12, 393, 393, 393, 393, 393, 394, 395, 393, - 396, 396, 396, 396, 396, 397, 396, 396, 398, 398, 398, 398, 399, 12, 398, 398, - 400, 400, 400, 400, 401, 12, 402, 403, 12, 12, 402, 400, 404, 404, 404, 404, - 404, 404, 405, 12, 406, 406, 406, 406, 407, 12, 12, 12, 407, 12, 408, 406, - 409, 409, 409, 409, 409, 409, 12, 12, 409, 409, 410, 12, 411, 411, 411, 411, - 411, 411, 412, 413, 413, 12, 12, 12, 12, 12, 12, 414, 415, 415, 415, 415, - 415, 415, 12, 12, 416, 416, 416, 416, 416, 416, 417, 12, 418, 418, 418, 418, - 418, 418, 419, 12, 420, 420, 420, 420, 420, 420, 420, 12, 421, 421, 421, 421, - 421, 422, 12, 12, 423, 423, 423, 423, 423, 423, 423, 424, 425, 423, 423, 423, - 423, 424, 12, 426, 427, 427, 427, 427, 428, 12, 12, 429, 430, 430, 430, 430, - 430, 430, 431, 12, 430, 430, 432, 12, 433, 433, 433, 433, 433, 434, 433, 433, - 433, 433, 12, 12, 435, 435, 435, 435, 435, 436, 12, 12, 437, 437, 437, 437, - 118, 119, 119, 119, 119, 127, 12, 12, 438, 438, 438, 438, 439, 438, 438, 438, - 440, 12, 12, 12, 441, 442, 443, 444, 441, 441, 441, 444, 441, 441, 445, 12, - 446, 446, 446, 446, 446, 446, 447, 12, 446, 446, 448, 12, 449, 450, 449, 451, - 451, 449, 449, 449, 449, 449, 452, 449, 452, 450, 453, 449, 449, 451, 451, 454, - 455, 456, 12, 450, 449, 457, 449, 455, 449, 455, 12, 12, 458, 458, 458, 458, - 458, 458, 458, 459, 460, 12, 12, 12, 461, 461, 461, 461, 461, 461, 12, 12, - 461, 461, 462, 12, 463, 463, 463, 463, 463, 464, 463, 463, 463, 463, 463, 464, - 465, 465, 465, 465, 465, 466, 12, 12, 465, 465, 467, 12, 178, 178, 178, 180, - 468, 468, 468, 468, 468, 468, 469, 12, 470, 470, 470, 470, 470, 470, 471, 472, - 470, 470, 470, 12, 470, 471, 12, 12, 473, 473, 473, 473, 473, 473, 473, 12, - 474, 474, 474, 474, 475, 12, 12, 476, 477, 478, 479, 477, 477, 480, 477, 477, - 477, 477, 477, 477, 477, 481, 482, 477, 477, 478, 12, 12, 477, 477, 483, 12, - 484, 484, 485, 484, 484, 484, 484, 484, 484, 486, 12, 12, 487, 487, 487, 487, - 487, 487, 12, 12, 488, 488, 488, 488, 489, 12, 12, 12, 490, 490, 490, 490, - 490, 490, 491, 12, 53, 53, 492, 12, 493, 493, 494, 493, 493, 493, 493, 493, - 493, 495, 493, 493, 493, 496, 12, 12, 493, 493, 493, 497, 498, 498, 498, 498, - 499, 498, 498, 498, 498, 498, 500, 498, 498, 501, 12, 12, 502, 503, 504, 502, - 502, 502, 502, 502, 502, 503, 505, 504, 502, 502, 12, 12, 502, 502, 506, 12, - 507, 508, 509, 507, 507, 507, 507, 507, 507, 507, 507, 510, 508, 507, 511, 12, - 507, 507, 512, 12, 513, 513, 513, 513, 513, 513, 514, 12, 515, 515, 515, 515, - 516, 515, 515, 515, 515, 515, 517, 518, 515, 515, 519, 12, 520, 12, 12, 12, - 100, 100, 100, 100, 96, 12, 12, 98, 521, 521, 521, 521, 521, 521, 522, 12, - 521, 521, 521, 523, 521, 524, 12, 12, 521, 12, 12, 12, 525, 525, 525, 525, - 526, 12, 12, 12, 527, 527, 527, 527, 527, 528, 12, 12, 529, 529, 529, 529, - 529, 530, 12, 12, 272, 272, 531, 12, 532, 532, 532, 532, 532, 532, 532, 533, - 532, 532, 534, 535, 536, 536, 536, 536, 536, 536, 536, 537, 536, 536, 538, 12, - 539, 539, 539, 539, 539, 539, 539, 540, 539, 540, 12, 12, 541, 541, 541, 541, - 541, 542, 12, 12, 541, 541, 543, 541, 543, 541, 541, 541, 541, 541, 12, 544, - 545, 545, 545, 545, 545, 545, 546, 12, 547, 547, 547, 547, 547, 547, 548, 549, - 547, 547, 12, 549, 550, 551, 12, 12, 249, 12, 12, 12, 552, 552, 552, 552, - 552, 552, 12, 12, 553, 553, 553, 553, 553, 554, 12, 12, 552, 552, 555, 12, - 260, 556, 260, 557, 558, 255, 255, 255, 559, 12, 12, 12, 560, 12, 12, 12, - 256, 561, 12, 12, 12, 260, 12, 12, 562, 562, 562, 562, 562, 562, 562, 12, - 563, 563, 563, 563, 563, 563, 564, 12, 563, 563, 563, 565, 563, 563, 565, 12, - 563, 563, 566, 563, 0, 12, 12, 12, 7, 7, 7, 567, 7, 199, 12, 12, - 0, 246, 12, 12, 0, 232, 316, 0, 0, 568, 228, 0, 0, 0, 568, 7, - 213, 569, 7, 0, 0, 0, 570, 228, 8, 225, 12, 12, 0, 0, 234, 12, - 0, 0, 0, 229, 571, 572, 316, 229, 0, 0, 240, 316, 0, 316, 0, 0, - 0, 240, 232, 316, 0, 229, 0, 229, 0, 0, 240, 232, 0, 573, 239, 0, - 229, 0, 0, 0, 0, 246, 0, 0, 0, 0, 0, 239, 574, 574, 574, 574, - 574, 574, 574, 12, 12, 12, 575, 574, 576, 574, 574, 574, 2, 2, 2, 273, - 12, 275, 273, 12, 241, 577, 241, 241, 241, 241, 578, 241, 579, 580, 577, 12, - 19, 19, 19, 581, 12, 12, 12, 582, 583, 583, 583, 583, 583, 583, 583, 584, - 583, 583, 583, 585, 583, 583, 585, 586, 587, 587, 587, 587, 587, 587, 587, 588, - 589, 589, 589, 589, 589, 589, 590, 591, 592, 592, 592, 592, 592, 592, 593, 12, - 151, 154, 151, 594, 151, 151, 151, 154, 595, 595, 595, 595, 595, 596, 595, 595, - 595, 597, 12, 12, 598, 598, 598, 598, 598, 598, 598, 12, 598, 598, 599, 600, - 0, 234, 12, 12, 29, 414, 29, 29, 601, 602, 414, 29, 50, 29, 603, 12, - 604, 310, 603, 414, 601, 602, 603, 603, 601, 602, 50, 29, 50, 29, 414, 605, - 29, 29, 606, 29, 29, 29, 29, 12, 414, 414, 606, 29, 51, 12, 12, 12, - 12, 239, 0, 0, 607, 12, 12, 12, 246, 12, 12, 12, 0, 0, 12, 0, - 0, 232, 131, 0, 0, 0, 12, 12, 0, 0, 0, 240, 0, 246, 12, 239, - 608, 12, 12, 12, 247, 247, 609, 12, 610, 12, 12, 12, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, - 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041, - 1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127, - 1131,1133, 0,1147,1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227, - 1228,1229,1233, 0, 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, - 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, - 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, - 994,1179, 0, 0,1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0, - 1016,1201,1020,1206, 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032, - 1218,1037,1223,1035,1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0, - 1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264, - 1074,1261, 0, 0,1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283, - 1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1093,1280, 0, 0, 0, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 705, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 706, + 0, 0, 1, 1, 0, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 5, 0, 6, 7, 7, 7, 8, 9, 10, 11, 12, + 13, 13, 13, 13, 14, 13, 13, 13, 13, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 23, 23, 26, 23, 27, 28, 29, 23, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 23, 23, 39, 40, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 82, 86, 86, 87, 88, 89, 90, 91, 82, + 92, 92, 92, 92, 92, 93, 94, 95, 96, 96, 96, 96, 96, 96, 96, 96, + 97, 97, 98, 97, 99, 100, 101, 97, 102, 97, 103, 104, 105, 106, 106, 107, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 110, 110, 111, + 112, 113, 114, 115, 116, 116, 117, 118, 119, 120, 120, 121, 120, 122, 108, 123, + 124, 125, 126, 127, 128, 129, 130, 116, 131, 132, 133, 134, 135, 136, 137, 82, + 138, 138, 139, 138, 140, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 4, 151, 152, 153, 4, 154, 7, 7, 155, 11, 156, 157, 11, 158, 159, 160, + 161, 0, 0, 162, 163, 0, 164, 165, 0, 166, 167, 4, 168, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 170, 0, 0, 0, 0, 0, + 171, 171, 171, 171, 171, 171, 171, 171, 0, 0, 0, 172, 173, 0, 0, 0, + 174, 174, 174, 4, 175, 175, 175, 176, 93, 177, 178, 179, 180, 181, 181, 13, + 0, 0, 182, 82, 183, 184, 184, 185, 184, 184, 184, 184, 184, 184, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 96, 96, 198, 199, 0, 200, + 201, 0, 0, 202, 0, 0, 203, 204, 194, 194, 205, 0, 0, 0, 0, 0, + 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 0, 0, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 207, 206, 208, 209, + 210, 210, 210, 210, 210, 210, 210, 210, 210, 211, 13, 13, 13, 212, 212, 213, + 0, 214, 4, 4, 215, 4, 216, 217, 218, 219, 220, 221, 222, 222, 223, 40, + 224, 225, 226, 227, 228, 228, 229, 230, 231, 232, 233, 92, 234, 234, 235, 236, + 237, 238, 239, 240, 106, 106, 241, 242, 96, 96, 96, 96, 96, 243, 244, 245, + 82, 82, 82, 82, 82, 82, 82, 82, 184, 184, 184, 246, 184, 184, 247, 82, + 248, 249, 250, 23, 23, 23, 251, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 252, 23, 23, 253, 23, 254, 255, 256, 257, 258, 259, 23, 23, 23, 260, + 261, 1, 1, 262, 263, 201, 264, 265, 266, 267, 268, 82, 269, 269, 269, 270, + 271, 272, 11, 11, 273, 274, 187, 275, 82, 82, 82, 82, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 82, 287, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 303, 304, 305, 306, 307, 82, 82, 308, 309, 310, 311, 312, 313, 82, 314, + 315, 316, 82, 82, 317, 318, 319, 320, 321, 322, 323, 324, 325, 82, 326, 327, + 328, 329, 330, 331, 332, 333, 82, 82, 334, 334, 335, 82, 336, 337, 336, 338, + 339, 340, 341, 342, 343, 82, 82, 82, 82, 82, 82, 344, 345, 346, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 357, 358, 359, 360, 360, 361, 362, + 363, 364, 365, 366, 367, 367, 367, 368, 369, 370, 371, 82, 372, 373, 374, 375, + 376, 377, 378, 379, 380, 381, 382, 383, 384, 384, 385, 386, 387, 387, 388, 82, + 82, 82, 82, 82, 389, 390, 391, 82, 392, 392, 393, 394, 395, 396, 397, 398, + 399, 400, 401, 82, 82, 82, 82, 82, 402, 403, 82, 82, 82, 404, 404, 405, + 406, 407, 408, 82, 82, 409, 410, 411, 412, 412, 413, 414, 414, 415, 416, 417, + 418, 82, 82, 82, 82, 82, 419, 420, 421, 422, 423, 424, 425, 426, 82, 82, + 427, 428, 429, 430, 431, 432, 82, 82, 82, 82, 82, 82, 82, 82, 82, 433, + 434, 435, 436, 82, 82, 437, 438, 439, 440, 440, 440, 440, 440, 440, 440, 440, + 440, 440, 440, 440, 441, 82, 82, 82, 440, 440, 440, 442, 440, 440, 440, 440, + 440, 440, 443, 82, 82, 82, 82, 82, 82, 82, 82, 82, 444, 445, 445, 446, + 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 448, 447, 447, 447, 447, 447, + 447, 447, 447, 447, 447, 447, 447, 449, 450, 450, 450, 450, 450, 450, 450, 450, + 450, 450, 451, 82, 82, 82, 82, 82, 452, 453, 82, 82, 82, 82, 82, 82, + 212, 212, 212, 212, 212, 212, 212, 212, 212, 454, 455, 456, 457, 458, 459, 460, + 461, 461, 462, 463, 464, 82, 82, 82, 82, 82, 465, 466, 82, 82, 82, 82, + 82, 82, 467, 467, 468, 82, 82, 82, 469, 469, 470, 469, 471, 82, 82, 472, + 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 474, + 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 476, 477, + 478, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 479, + 480, 191, 191, 191, 191, 191, 191, 191, 191, 481, 482, 483, 484, 484, 484, 484, + 484, 484, 484, 484, 484, 484, 484, 485, 486, 486, 486, 487, 488, 489, 82, 82, + 0, 0, 0, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 491, 82, 82, + 7, 492, 493, 0, 0, 0, 489, 82, 0, 0, 0, 0, 0, 0, 0, 494, + 0, 495, 0, 496, 497, 498, 0, 170, 11, 11, 499, 82, 82, 82, 491, 491, + 0, 0, 500, 501, 82, 82, 82, 82, 0, 0, 502, 0, 503, 504, 505, 0, + 506, 507, 508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 509, 0, 0, + 0, 0, 0, 0, 0, 0, 510, 0, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 512, 513, 82, 82, 514, 515, 82, 82, 82, 82, 82, 82, + 516, 517, 13, 518, 519, 82, 82, 82, 520, 521, 522, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 523, 524, 525, 526, 82, 82, 82, 82, 82, 82, 527, 528, + 82, 82, 82, 82, 82, 82, 529, 530, 82, 82, 82, 82, 82, 82, 82, 531, + 532, 532, 532, 532, 532, 532, 533, 82, 534, 534, 535, 82, 82, 82, 82, 82, + 82, 82, 82, 536, 0, 537, 82, 82, 261, 182, 82, 82, 82, 82, 82, 82, + 538, 539, 540, 541, 542, 543, 82, 544, 0, 545, 0, 0, 491, 546, 547, 494, + 0, 0, 0, 0, 0, 548, 82, 549, 550, 551, 552, 553, 82, 82, 82, 82, + 0, 0, 0, 0, 0, 0, 554, 555, 0, 0, 0, 556, 0, 0, 490, 557, + 545, 0, 558, 0, 559, 560, 561, 82, 0, 0, 491, 562, 563, 0, 564, 565, + 0, 0, 0, 0, 258, 0, 0, 490, 184, 184, 184, 184, 184, 184, 184, 82, + 184, 247, 184, 184, 184, 184, 184, 184, 566, 184, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 567, 184, 184, 184, 184, 184, 184, 184, 184, 184, 568, + 184, 184, 566, 82, 82, 82, 82, 82, 566, 82, 82, 82, 82, 82, 82, 82, + 184, 184, 569, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 570, 82, 82, + 571, 0, 0, 0, 82, 82, 82, 82, 7, 7, 7, 7, 7, 7, 7, 572, + 0, 0, 0, 0, 1, 2, 2, 3, 0, 4, 0, 4, 2, 2, 5, 2, + 2, 2, 2, 2, 2, 2, 2, 6, 7, 8, 0, 0, 9, 9, 9, 9, + 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, + 16, 17, 14, 14, 18, 18, 18, 18, 19, 18, 18, 18, 18, 18, 20, 21, + 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, + 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, + 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 29, 37, 38, 37, 37, + 37, 37, 37, 37, 37, 39, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, + 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, + 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 52, 31, 31, 31, + 53, 53, 53, 53, 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, + 59, 60, 61, 62, 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, + 71, 72, 73, 74, 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, + 83, 84, 85, 86, 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, + 95, 96, 97, 98, 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, + 107, 104, 108, 109, 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, + 113, 115, 113, 116, 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, + 122, 124, 125, 126, 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, + 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, + 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, + 147, 147, 147, 148, 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, + 153, 152, 152, 154, 155, 156, 152, 157, 158, 158, 158, 158, 158, 159, 158, 158, + 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, 158, 161, 162, 163, + 164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168, + 169, 169, 169, 169, 170, 170, 170, 170, 170, 171, 172, 171, 170, 171, 170, 170, + 170, 170, 171, 172, 171, 170, 172, 170, 170, 170, 171, 170, 170, 170, 170, 173, + 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, 176, 176, 177, 177, + 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181, 181, 182, 181, 183, + 184, 184, 185, 186, 187, 187, 188, 26, 189, 189, 190, 26, 191, 192, 193, 26, + 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 198, 199, + 198, 198, 198, 198, 198, 198, 198, 200, 198, 201, 178, 178, 178, 178, 202, 26, + 203, 203, 203, 204, 203, 205, 203, 205, 206, 203, 207, 207, 207, 208, 209, 26, + 210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 214, 214, 214, 215, + 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, + 216, 220, 9, 9, 9, 221, 26, 26, 222, 222, 222, 222, 222, 223, 222, 222, + 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, 228, 228, 228, 228, + 228, 228, 228, 229, 228, 230, 231, 231, 231, 231, 231, 231, 18, 232, 165, 165, + 165, 165, 165, 233, 224, 26, 234, 9, 235, 236, 237, 238, 239, 240, 2, 2, + 2, 2, 2, 241, 242, 243, 2, 244, 2, 2, 2, 245, 14, 14, 246, 246, + 246, 246, 14, 247, 14, 14, 14, 246, 14, 14, 248, 14, 248, 14, 249, 250, + 14, 14, 251, 252, 0, 253, 0, 0, 254, 0, 255, 256, 0, 257, 2, 258, + 259, 26, 9, 9, 9, 9, 260, 26, 261, 262, 4, 0, 0, 263, 0, 0, + 2, 264, 0, 0, 0, 265, 26, 26, 0, 266, 26, 26, 267, 267, 267, 267, + 0, 0, 268, 0, 0, 0, 269, 0, 270, 270, 270, 270, 17, 17, 17, 17, + 17, 17, 271, 272, 166, 167, 273, 273, 273, 273, 273, 273, 273, 274, 275, 274, + 170, 170, 172, 26, 172, 172, 172, 172, 0, 0, 0, 276, 277, 277, 277, 278, + 277, 277, 277, 277, 277, 277, 279, 26, 277, 277, 280, 26, 26, 26, 0, 0, + 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, + 292, 293, 293, 293, 293, 293, 294, 169, 169, 295, 0, 0, 293, 293, 293, 293, + 276, 296, 290, 290, 169, 169, 169, 295, 169, 169, 169, 297, 0, 0, 290, 290, + 290, 290, 290, 298, 290, 290, 290, 0, 299, 299, 299, 299, 299, 300, 299, 299, + 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 304, 26, 26, + 305, 305, 305, 305, 305, 305, 305, 26, 306, 2, 2, 2, 2, 307, 2, 2, + 2, 308, 309, 258, 26, 26, 310, 2, 311, 311, 311, 311, 311, 312, 0, 265, + 313, 313, 313, 313, 313, 313, 313, 26, 314, 314, 314, 314, 315, 316, 314, 317, + 318, 318, 318, 318, 318, 319, 320, 320, 320, 320, 321, 322, 169, 169, 169, 323, + 324, 324, 324, 324, 324, 325, 324, 326, 164, 164, 164, 327, 328, 328, 328, 328, + 328, 328, 329, 26, 328, 330, 328, 331, 332, 332, 332, 332, 333, 26, 26, 334, + 335, 335, 336, 26, 337, 337, 337, 26, 172, 172, 2, 2, 2, 2, 2, 338, + 339, 340, 176, 176, 335, 335, 335, 335, 335, 341, 335, 342, 343, 26, 169, 169, + 295, 344, 169, 169, 169, 169, 169, 343, 277, 280, 277, 277, 277, 277, 277, 345, + 346, 26, 347, 348, 25, 25, 349, 350, 351, 25, 31, 31, 352, 26, 353, 31, + 31, 31, 31, 354, 31, 31, 355, 31, 31, 356, 26, 26, 26, 26, 31, 31, + 9, 9, 0, 265, 9, 357, 0, 0, 0, 0, 358, 0, 257, 359, 360, 31, + 31, 31, 31, 361, 362, 0, 0, 0, 363, 290, 289, 290, 290, 290, 290, 364, + 365, 365, 365, 366, 257, 257, 26, 367, 368, 369, 368, 368, 370, 368, 368, 371, + 368, 372, 368, 372, 368, 368, 368, 368, 368, 368, 368, 373, 374, 0, 0, 0, + 0, 0, 375, 0, 14, 252, 0, 376, 377, 26, 26, 26, 0, 0, 0, 378, + 379, 379, 379, 380, 381, 381, 381, 381, 381, 381, 382, 26, 383, 0, 0, 359, + 384, 384, 384, 384, 385, 386, 387, 387, 387, 388, 389, 389, 389, 389, 389, 390, + 391, 391, 391, 392, 393, 393, 393, 393, 394, 393, 395, 26, 396, 396, 396, 396, + 396, 396, 397, 397, 397, 397, 397, 397, 398, 398, 398, 399, 398, 400, 401, 401, + 401, 401, 402, 401, 401, 401, 401, 402, 403, 403, 403, 403, 403, 26, 404, 404, + 404, 404, 404, 404, 405, 406, 407, 408, 407, 408, 409, 407, 410, 407, 410, 411, + 412, 412, 412, 412, 412, 412, 413, 26, 414, 414, 414, 414, 414, 414, 415, 26, + 414, 414, 416, 26, 414, 26, 26, 26, 417, 2, 2, 2, 2, 2, 418, 419, + 420, 421, 422, 422, 422, 422, 423, 424, 425, 425, 426, 425, 427, 427, 427, 427, + 428, 428, 428, 429, 430, 428, 26, 26, 431, 431, 432, 433, 434, 434, 434, 435, + 436, 436, 436, 437, 438, 438, 438, 438, 439, 439, 439, 440, 439, 439, 441, 439, + 439, 439, 439, 439, 442, 443, 444, 445, 446, 446, 447, 448, 446, 449, 446, 449, + 450, 450, 450, 450, 451, 451, 451, 451, 452, 452, 452, 452, 453, 454, 453, 26, + 455, 455, 455, 455, 455, 455, 456, 457, 458, 458, 459, 458, 460, 460, 461, 460, + 462, 462, 463, 464, 26, 465, 26, 26, 466, 466, 466, 466, 466, 467, 26, 26, + 468, 468, 468, 468, 468, 468, 469, 26, 468, 468, 469, 470, 471, 471, 471, 471, + 471, 26, 471, 472, 473, 473, 473, 473, 474, 475, 473, 473, 474, 476, 26, 26, + 31, 31, 31, 50, 477, 477, 477, 477, 477, 478, 479, 26, 480, 26, 26, 26, + 26, 26, 26, 481, 482, 482, 482, 482, 482, 26, 483, 483, 483, 483, 483, 484, + 26, 26, 485, 485, 485, 486, 26, 26, 26, 26, 487, 487, 487, 488, 26, 26, + 489, 489, 490, 26, 491, 491, 491, 491, 491, 492, 493, 491, 491, 491, 492, 494, + 495, 495, 495, 495, 496, 497, 498, 498, 498, 499, 498, 500, 501, 501, 501, 501, + 501, 501, 502, 501, 501, 26, 503, 503, 503, 503, 504, 26, 505, 505, 505, 505, + 506, 137, 507, 26, 508, 508, 509, 508, 508, 508, 508, 508, 510, 26, 26, 26, + 511, 512, 513, 514, 513, 515, 516, 516, 516, 516, 516, 516, 516, 517, 516, 518, + 519, 520, 521, 522, 522, 523, 524, 525, 520, 526, 527, 528, 529, 530, 530, 26, + 531, 532, 531, 531, 531, 531, 533, 531, 534, 535, 533, 536, 537, 26, 26, 26, + 538, 538, 538, 538, 538, 538, 538, 539, 540, 26, 26, 26, 541, 541, 541, 541, + 541, 26, 541, 542, 543, 543, 543, 543, 543, 543, 544, 543, 543, 543, 543, 544, + 545, 545, 545, 545, 546, 26, 545, 547, 198, 548, 26, 26, 549, 549, 549, 549, + 549, 549, 549, 550, 549, 550, 164, 164, 551, 26, 26, 26, 552, 552, 552, 553, + 552, 554, 552, 552, 555, 26, 26, 26, 556, 556, 556, 556, 556, 556, 556, 557, + 558, 558, 558, 558, 558, 558, 559, 560, 561, 562, 563, 564, 564, 564, 565, 566, + 561, 26, 564, 567, 568, 569, 568, 568, 568, 568, 568, 569, 570, 26, 26, 26, + 571, 571, 571, 571, 571, 26, 572, 572, 572, 572, 572, 572, 573, 26, 178, 178, + 574, 574, 574, 574, 574, 574, 574, 575, 53, 576, 26, 26, 577, 577, 577, 577, + 578, 26, 577, 578, 579, 580, 579, 579, 579, 579, 581, 579, 582, 26, 579, 579, + 579, 583, 584, 584, 584, 584, 585, 584, 584, 586, 587, 26, 588, 589, 590, 590, + 590, 590, 588, 591, 590, 26, 590, 592, 593, 594, 595, 595, 595, 596, 597, 598, + 595, 599, 26, 26, 600, 600, 600, 601, 602, 602, 603, 602, 602, 602, 602, 604, + 602, 602, 602, 605, 26, 26, 606, 26, 108, 108, 108, 108, 108, 108, 607, 608, + 609, 609, 609, 609, 609, 609, 609, 610, 609, 611, 612, 26, 613, 26, 26, 26, + 26, 26, 614, 614, 614, 614, 614, 614, 614, 614, 615, 26, 616, 616, 616, 616, + 616, 616, 617, 26, 616, 616, 616, 618, 619, 619, 619, 619, 620, 26, 26, 26, + 621, 621, 621, 621, 621, 621, 621, 622, 305, 305, 305, 623, 624, 624, 624, 625, + 624, 626, 627, 627, 627, 627, 627, 627, 627, 627, 627, 628, 627, 629, 630, 630, + 630, 631, 631, 26, 632, 632, 632, 632, 633, 26, 632, 634, 634, 632, 632, 635, + 632, 632, 26, 26, 636, 636, 636, 636, 636, 636, 636, 637, 638, 638, 638, 638, + 638, 638, 638, 639, 640, 640, 640, 640, 640, 641, 640, 640, 640, 642, 640, 640, + 643, 26, 345, 26, 644, 644, 644, 644, 644, 644, 644, 26, 645, 645, 645, 645, + 645, 645, 646, 26, 26, 26, 26, 647, 644, 648, 26, 26, 26, 26, 649, 650, + 651, 286, 286, 286, 652, 26, 653, 26, 26, 26, 654, 26, 655, 26, 656, 656, + 656, 656, 656, 656, 656, 656, 656, 657, 658, 658, 658, 658, 658, 659, 658, 660, + 658, 661, 658, 662, 359, 26, 26, 26, 0, 0, 0, 265, 0, 0, 359, 26, + 9, 663, 9, 9, 221, 26, 0, 0, 0, 0, 276, 26, 257, 362, 0, 0, + 664, 665, 0, 666, 667, 668, 0, 0, 0, 669, 0, 0, 246, 26, 26, 26, + 0, 0, 257, 26, 0, 0, 0, 259, 0, 0, 254, 0, 0, 0, 0, 254, + 670, 671, 0, 672, 673, 0, 0, 0, 269, 674, 254, 254, 0, 0, 0, 675, + 676, 677, 678, 0, 276, 0, 0, 0, 0, 268, 0, 0, 679, 679, 679, 679, + 679, 680, 26, 681, 682, 679, 26, 26, 2, 2, 2, 346, 683, 419, 26, 26, + 684, 270, 270, 685, 686, 687, 18, 18, 18, 688, 26, 26, 26, 689, 26, 26, + 690, 690, 690, 690, 690, 691, 690, 692, 690, 693, 26, 26, 26, 26, 694, 694, + 694, 695, 26, 26, 696, 696, 696, 696, 696, 696, 696, 697, 26, 26, 698, 698, + 698, 698, 698, 699, 26, 26, 700, 700, 700, 700, 700, 701, 172, 702, 170, 172, + 703, 703, 703, 703, 704, 703, 705, 26, 706, 706, 706, 706, 706, 707, 706, 708, + 26, 26, 362, 0, 0, 0, 376, 26, 709, 31, 31, 31, 710, 711, 712, 713, + 714, 715, 710, 716, 710, 712, 712, 717, 31, 718, 31, 719, 720, 718, 31, 719, + 26, 26, 721, 26, 0, 359, 0, 0, 0, 257, 362, 0, 362, 0, 362, 0, + 0, 276, 26, 26, 722, 0, 0, 0, 723, 26, 0, 0, 0, 0, 0, 359, + 0, 259, 265, 26, 276, 26, 26, 26, 0, 0, 0, 724, 0, 376, 0, 376, + 0, 0, 257, 725, 0, 359, 259, 26, 0, 26, 0, 265, 0, 26, 0, 0, + 0, 276, 0, 359, 265, 26, 26, 26, 0, 276, 0, 376, 0, 726, 0, 0, + 257, 722, 0, 727, 0, 265, 0, 259, 277, 277, 277, 280, 345, 26, 277, 277, + 728, 26, 277, 277, 277, 729, 277, 277, 277, 277, 26, 26, 730, 26, 26, 26, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976, + 1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082, + 1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147,1154,1155,1156,1161, + 1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0, 0,1267,1268,1269, + 1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, + 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, + 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0,1004,1190,1005,1191, + 1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206, 0,1022,1208,1025, + 1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035,1221, 0, 0, 0, + 1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250,1060,1246,1066,1252, + 1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0,1083,1270,1084,1271, + 1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120, + 1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1093,1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 949,1134,1010,1195,1050,1236,1090, - 1277,1341,1368,1340,1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, - 0, 0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, - 987,1172, 0, 0,1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, - 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248, - 1091,1278,1092,1279,1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, - 0, 0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10, - 1425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0,1314,1427, 5,1434,1438,1443, 0,1450, 0,1455,1461,1514, 0, 0, 0, + 0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339, + 1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177,1018,1204,1055,1241, + 1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0,1031,1217,1321,1348, + 1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197, + 1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263, + 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130, 982,1167,1337,1364, + 1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5,1434,1438,1443, 0, + 1450, 0,1455,1461,1514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1446,1458, + 1468,1476,1480,1486,1517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1489,1503, + 1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522, 0, 0, 0, 0, + 1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1534, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1556, 0, 0, + 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567, 0, 0, 0, 0, + 1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549, 0, 0,1570,1571, + 1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559, 0, 0,1572,1573, + 1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0,1543,1565, 0, 0, + 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1620, 0, 0, + 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1614,1615,1616,1617, + 1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1628, + 1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1630,1631,1632, + 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0,1639, 0, 0,1638, + 1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1642,1644, + 1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1645, 0, 0, 0, + 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648,1649, 0,1647,1650, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1651,1653, + 1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1654, 0, + 1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662, 0, 0, 0, 0, + 1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1658, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0,1674, 0, 0, 0, + 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671, 0, 0, 0, 0, + 1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1667, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0,1677, 0,1678, 0, + 1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1682, + 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, + 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170, + 1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185, + 1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213, + 1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224, + 1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249, + 1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259, + 1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393, + 1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295, + 1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,1293,1305, 0,1394, + 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345, + 1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, + 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198, + 1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401, + 1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410, + 1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,1112,1300, 0, 0, + 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719, + 1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0,1435,1436,1733,1735, + 1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755, + 1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774, + 1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0,1451,1452,1781,1783, + 1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790, 0,1459, 0,1791, + 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812, + 1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24,1493, 27,1499, 28, + 1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724, + 1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760, + 1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817, + 1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825,1429,1428,1426, 12, + 1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829,1433, 13,1437, 14, + 1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515,1445,1444,1442, 15, + 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518,1457,1456,1454, 17, + 1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830,1449, 16,1460, 18, + 1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1446,1458,1468,1476,1480,1486,1517, 0, 0, 0, + 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0, 0,1841, 0, 0, + 1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847, 0,1848, 0, 0, + 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0,1855,1856, 0, 0, + 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0,1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520, - 1521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, - 0, 0, 0,1522, 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, - 0, 0, 0,1567, 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, - 0, 0,1568,1569, 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, - 0, 0,1527,1549, 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555, - 1535,1557,1537,1559, 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563, - 1542,1564, 0, 0,1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607, - 1609,1608,1610, 0, 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, + 1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0, 0, 0,1871,1872, + 1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0, - 1624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, - 0, 0,1635, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0, - 1641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, - 0, 0, 0,1648,1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, - 0, 0, 0,1662, 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, - 0,1665,1673, 0,1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, - 0, 0, 0,1671, 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1675, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1676, 0,1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, + 1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0,1883, 0,1884, 0, + 1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890, 0,1891, 0, 0, + 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897, 0,1898,1899, 0, + 1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0,1910, 0,1911, 0, + 1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917, 0,1918, 0, 0, + 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924, 0,1925,1926, 0, + 1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929,1930,1931,1932, 0, + 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, + 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, + 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, + 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, + 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, + 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, + 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, + 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, + 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, + 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, + 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, + 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, + 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, + 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, + 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, + 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, + 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, + 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525, 544, 551, 552, 556, + 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0, 0, 0, 793, 794, + 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, + 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, + 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, + 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, + 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, + 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, + 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, + 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, + 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, + 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, + 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916, 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, - 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152, - 1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, - 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205, - 1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216, - 1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385, - 1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256, - 1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282, - 1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289, - 1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311, - 1123,1312,1186,1260,1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132, - 1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377, - 1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355, - 1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357, - 1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404, - 1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297, - 1117,1306,1116,1304,1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705, - 1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731, - 1730,1732, 0, 0,1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741, - 1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768, - 1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779, - 1778,1780, 0, 0,1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788, - 1786,1789,1787,1790, 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798, - 1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22, - 1479, 23,1485, 24,1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710, - 1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746, - 1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803, - 1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474, - 1465, 0,1473,1825,1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484, - 1466, 0,1483,1829,1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, - 0, 0,1492,1515,1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25, - 1497,1498,1506,1518,1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512, - 1519, 0,1511,1830,1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, + 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603, + 1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589, + 1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582, + 1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1937, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0, + 1939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 20, 0, 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0, - 1840, 0, 0, 0, 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0, - 1843, 0,1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0, - 1846, 0, 0,1847, 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0, - 1853,1854, 0, 0,1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0, - 1861,1862, 0, 0,1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, - 0, 0, 0, 0, 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0, - 1881, 0,1882, 0,1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, - 0,1889, 0,1890, 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894, - 1895, 0,1896,1897, 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0, - 1876, 0, 0, 0, 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0, - 1908, 0,1909, 0,1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, - 0,1916, 0,1917, 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921, - 1922, 0,1923,1924, 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0, - 1903, 0, 0,1929,1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, - 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, - 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, - 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, - 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, - 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, - 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, - 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, - 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, - 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, - 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, - 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, - 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, - 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, - 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, - 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, - 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, - 256, 435, 383, 729, 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, - 0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, - 0, 735, 743, 0, 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, - 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, - 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, - 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, - 716, 717, 733, 735, 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, - 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, - 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, - 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, - 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, - 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, - 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, - 66, 883, 892, 916, 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580, - 1581,1583,1584, 0,1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595, - 1596, 0,1598,1599,1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954, - 1955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, - 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, - 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, - 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, - 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, - 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, - 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, - 249, 246, 251, 39, 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, - 301, 264, 41, 266, 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, - 283, 284, 285, 286, 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, - 300, 300, 45, 852, 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, - 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, - 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, - 365, 367, 364, 50, 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, - 387, 382, 614, 78, 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, - 405, 401, 407, 55, 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, - 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, - 442, 443, 864, 436, 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, - 465, 464, 59, 467, 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, - 488, 489, 872, 873, 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, - 513, 874, 515, 875, 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, - 882, 530, 531, 531, 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, - 886, 887, 556, 559, 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, - 72, 891, 577, 73, 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, - 76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, - 79, 617, 252, 902, 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, - 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, - 905, 907, 906, 81, 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, - 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, - 682, 912, 685, 686, 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, - 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, - 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, - 279, 780, 923, 925, 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, - 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, - 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, + 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1943, + 1944, 0, 0, 0, 0, 0, 0,1945, 0,1946, 0, 0, 0, 0, 0, 0, + 0, 0,1947, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1950, 0,1949,1951, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1953, + 1952, 0,1954, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1957, 0, 0, 0, + 0, 0, 0, 0, 0,1958,1961,1959,1965,1960,1962,1964,1963, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1967,1966,1968, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1969,1970,1971,1972,1973,1974,1975, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1976, + 1977,1978,1980,1979,1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, + 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, + 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, + 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, + 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, + 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, + 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39, 40, 253, 255, 255, + 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266, 270, 272, 271, 841, + 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286, 43, 843, 44, 289, + 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852, 894, 302, 304, 46, + 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324, 325, 324, 328, 329, + 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, + 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50, 369, 371, 851, 376, + 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78, 388, 389, 390, 394, + 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55, 408, 409, 410, 413, + 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861, 840, 862, 426, 863, + 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436, 449, 450, 58, 454, + 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467, 470, 469, 472, 828, + 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873, 495, 497, 60, 498, + 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875, 518, 844, 520, 876, + 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531, 533, 66, 534, 67, + 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559, 70, 561, 562, 563, + 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73, 581, 579, 582, 893, + 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898, 602, 605, 607, 899, + 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902, 903, 854, 855, 621, + 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, + 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81, 653, 654, 656, 911, + 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669, 668, 671, 670, 674, + 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686, 87, 689, 36, 913, + 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, + 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, + 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925, 92, 93, 785, 926, + 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, + 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, + 821, 935, 0, 0, }; static const int16_t _hb_ucd_i16[92] = @@ -4403,12 +4615,12 @@ _hb_ucd_i16[92] = static inline uint_fast8_t _hb_ucd_gc (unsigned u) { - return u<1114110u?_hb_ucd_u8[6808+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + return u<1114110u?_hb_ucd_u8[6472+(((_hb_ucd_u8[816+(((_hb_ucd_u16[((_hb_ucd_u8[272+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15u))])<<4)+((u>>1>>3)&15u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; } static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[8800+(((_hb_ucd_u8[8244+(((_hb_ucd_u8[7784+(((_hb_ucd_u8[7432+(((_hb_ucd_u8[7186+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + return u<125259u?_hb_ucd_u8[8504+(((_hb_ucd_u8[7936+(((_hb_ucd_u8[7460+(((_hb_ucd_u8[7100+(((_hb_ucd_u8[6854+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -4418,55 +4630,55 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9692+(((_hb_ucd_u8[9460+(((_hb_ucd_u8[9364+(((_hb_ucd_b4(9300+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9396+(((_hb_ucd_u8[9164+(((_hb_ucd_u8[9068+(((_hb_ucd_b4(9004+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[11126+(((_hb_ucd_u16[4040+(((_hb_ucd_u16[2048+(((_hb_ucd_u8[10390+(((_hb_ucd_u8[9940+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; + return u<918000u?_hb_ucd_u8[10398+(((_hb_ucd_u16[3952+(((_hb_ucd_u16[2624+(((_hb_ucd_u8[9870+(((_hb_ucd_u8[9644+(u>>3>>2>>3>>4)])<<4)+((u>>3>>2>>3)&15u))])<<3)+((u>>3>>2)&7u))])<<2)+((u>>3)&3u))])<<3)+((u)&7u))]:2; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6748+(((_hb_ucd_u8[13952+(((_hb_ucd_u8[13570+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102u?_hb_ucd_u16[6244+(((_hb_ucd_u8[16628+(((_hb_ucd_u8[16246+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; } #else static const uint8_t -_hb_ucd_u8[13386] = +_hb_ucd_u8[13730] = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 7, 11, 12, 12, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 21, 21, 21, 21, 23, 7, 7, - 7, 24, 21, 21, 21, 25, 26, 27, 21, 28, 29, 30, 31, 32, 33, 34, + 14, 15, 16, 17, 18, 19, 20, 7, 21, 22, 22, 22, 23, 24, 7, 7, + 7, 25, 22, 22, 22, 26, 27, 28, 22, 29, 30, 31, 32, 33, 34, 35, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 35, 21, 36, - 7, 7, 7, 7, 37, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 38, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 21, 22, 36, + 7, 7, 7, 7, 37, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 38, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, @@ -4486,30 +4698,30 @@ _hb_ucd_u8[13386] = 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100, 34, 34, 34, 34,101,102, 34, 34,103,104,105,106,107,108, 34, 34,109,110,111,112,113,114,115,116,117,118, 34, 34, 34,119, - 120,121,122,123,124,125,126,127, 34,128,129,111,130,131,132,133, - 134,135,136,137,138,139,140,111,141,142,111,143,144,145,146,111, - 147,148,149,150,151,152,153,111,154,155,156,157,111,158,159,160, - 34, 34, 34, 34, 34, 34, 34, 34,161, 34, 34,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,162, - 34, 34, 34, 34, 34, 34, 34, 34,163,111,111,111,111,111,111,111, + 120,121,122,123,124,125,126,127, 34,128,129,130,131,132,133,134, + 135,136,137,138,139,140,141,142,143,144,111,145,146,147,148,111, + 149,150,151,152,153,154,155,156,157,158,159,160,111,161,162,163, + 34, 34, 34, 34, 34, 34, 34, 34,164, 34, 34,111,111,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,165, + 34, 34, 34, 34, 34, 34, 34, 34,166, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111, 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111, 34, 34, 34, 34, 34,111,111,111, - 34, 34, 34, 34,164,165,166, 34,111,111,111,111,167,168,169,170, + 111,111,167,111,111,111,111,111,111,111,111,111,111,111,111,111, + 34, 34, 34, 34,168,169,170, 34,111,111,171,111,172,173,174,175, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111, 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,119, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111, 34,171,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,172, 67, - 67, 67,173,174,175,130, 65,111,176,177,178,179,180,181,182,183, - 67, 67, 67, 67,184,185,111,111,111,111,111,111,111,111,186,111, - 187,188,189,111,111,190,111,111,111,191,111,111,111,111,111, 34, - 34,192,193,111,111,111,111,111,130,194,195,111, 34,196,111,111, - 67, 67,197, 67, 67,111, 67,198, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67,199,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111, + 111,111,111,111,111,111,111,111, 34,176,111,111,111,111,111,111, + 111,111,111,111,111,111,111,111, 67,177, 67, 67, 67, 67,178, 67, + 67, 67,179,180,181,131, 65,111,182,183,184,185,186,187,188,189, + 67, 67, 67, 67,190,191,111,111,111,111,111,111,111,111,192,111, + 193,194,195,111,111,196,111,111,111,197,111,198,111,111,111, 34, + 34,199,200,111,111,111,111,111,131,201,202,111, 34,203,111,111, + 67, 67,204, 67, 67,111, 67,205, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67,177,111,111,111,111,111,111,111,111, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111, - 200,111,188,188,111,111,111,111,111,111,111,111,111,111,111,111, + 206,111,194,194,111,111,111,111,111,111,111,111,111,111,111,111, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, @@ -4544,8 +4756,8 @@ _hb_ucd_u8[13386] = 36, 36, 36, 36, 36, 64, 43, 43, 43, 43, 40, 21, 2, 40, 69, 20, 36, 36, 36, 43, 43, 69, 43, 43, 43, 43, 69, 43, 69, 43, 43, 43, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 64, 43, 43, 2, - 36, 36, 36, 36, 74, 36, 36, 36, 59, 59, 59, 59, 43, 43, 43, 43, - 36, 36, 36, 36, 75, 43, 43, 43, 43, 76, 43, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 74, 36, 36, 36, 59, 59, 59, 75, 43, 43, 43, 43, + 36, 36, 36, 36, 76, 43, 43, 43, 43, 75, 43, 43, 43, 43, 43, 43, 43, 77, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 65, 78, 79, 43, 43, 43, 77, 78, 79, 78, 64, 43, 43, 43, 36, 36, 36, 36, 36, 43, 2, 7, 7, 7, 7, 7, 80, 36, 36, 36, 36, 36, 36, 36, @@ -4590,130 +4802,135 @@ _hb_ucd_u8[13386] = 36, 43, 77, 78, 78, 78, 78, 81, 36, 43, 97, 2, 2, 2, 2, 2, 36, 43, 43, 43, 43, 43, 43, 43, 36, 36, 43, 79, 43, 43, 43, 78, 78, 78, 78, 77, 79, 43, 43, 43, 43, 43, 2, 80, 2, 60, 64, 43, - 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 98, 2, 56, 43, 76, - 36, 75, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 36, 36, 36, 36, + 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 98, 2, 56, 43, 75, + 36, 76, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 36, 36, 36, 36, 36, 36, 36, 36, 64, 36, 36, 36, 43, 77, 78, 79, 77, 78, 78, 78, 78, 77, 78, 78, 79, 43, 43, 43, 61, 61, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 27, 27, 61, 36, 36, 36, 64, 77, 79, 43, 2, 36, 36, 82, 77, 43, 43, 43, 43, 77, 77, 79, 43, 43, 43, 77, 78, 78, 79, 43, 43, 43, 43, 43, 43, 2, 2, 2, 80, 2, 2, 2, 2, 43, 43, 43, 43, 43, 43, 43, 99, 43, 43, 81, 36, 36, 36, 36, 36, - 36, 36, 77, 43, 43, 77, 77, 78, 78, 77, 81, 36, 36, 36, 36, 36, + 36, 36, 77, 43, 43, 77, 77, 78, 78, 77, 81, 36, 36, 36, 36, 2, 89, 61, 61, 61, 61, 47, 43, 43, 43, 43, 61, 61, 61, 61, 21, 2, 43, 81, 36, 36, 36, 36, 36, 36, 82, 43, 43, 78, 43, 79, 43, 36, 36, 36, 36, 77, 43, 78, 79, 79, 43, 78, 78, 78, 78, 78, 2, 2, 36, 36, 78, 78, 78, 78, 43, 43, 43, 43, 78, 43, 43, 57, 2, 2, 7, 7, 7, 7, 7, 7, 86, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 43, 57, 43, 43, 43, 43, 43, 43, 77, 43, 43, 43, 65, 36, 64, 36, - 36, 36, 65, 82, 43, 36, 36, 36, 16, 16, 16, 16, 16, 16, 40, 40, - 40, 40, 40, 40, 40, 44, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, - 16, 16, 16, 16, 16,100, 40, 40, 32, 32, 32, 16, 16, 16, 16, 32, - 16, 16, 16, 16, 11, 11, 11, 11, 16, 16, 16, 16, 34, 11, 11, 11, - 16, 16, 16, 16,101,101,101,101, 16, 16, 16, 16, 11, 11,102,103, - 41, 16, 16, 16, 11, 11,102, 41, 16, 16, 16, 16, 11, 11,104, 41, - 105,105,105,105,105,106, 59, 59, 51, 51, 51, 2,107,108,107,108, - 2, 2, 2, 2,109, 59, 59,110, 2, 2, 2, 2,111,112, 2,113, - 114, 2,115,116, 2, 2, 2, 2, 2, 9,114, 2, 2, 2, 2,117, - 59, 59, 59, 59, 59, 59, 59, 59,118, 40, 27, 27, 27, 8,115,119, - 27, 27, 27, 27, 27, 8,115, 94, 20, 20, 20, 20, 20, 20, 20, 20, - 43, 43, 43, 43, 43, 43,120, 48, 99, 48, 99, 43, 43, 43, 43, 43, - 61,121, 61,122, 61, 34, 11, 16, 11, 32,122, 61, 46, 11, 11, 61, - 61, 61,121,121,121, 11, 11,123, 11, 11, 35, 36, 39, 61, 16, 11, - 8, 8, 46, 16, 16, 26, 61,124, 95, 95, 95, 95, 95, 95, 95, 95, - 95,125,126, 95,127, 61, 61, 61, 8, 8,128, 61, 61, 8, 61, 61, - 128, 26, 61,128, 61, 61, 61,128, 61, 61, 61, 61, 61, 61, 61, 8, - 61,128,128, 61, 61, 61, 61, 61, 61, 61, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 61, 61, 61, 61, 4, 4, 61, 61, - 8, 61, 61, 61,129,130, 61, 61, 61, 61, 61, 61, 61, 61,128, 61, - 61, 61, 61, 61, 61, 26, 8, 8, 8, 8, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 8, 8, 8, 61, 61, 61, 61, 61, 61, 61, - 27, 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, - 61, 61, 61, 26, 61, 61, 61, 61, 26, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 8, 8, 8, 8, 61, 61, 61, 61, 61, 61, 61, 26, - 61, 61, 61, 61, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, - 27, 27, 61, 61, 61, 61, 61, 61, 8, 8,115,131, 8, 8, 8, 8, - 8, 8, 8, 4, 4, 4, 4, 4, 8,115,132,132,132,132,132,132, - 132,132,132,132,131, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, - 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,128, 26, 8, 8,128, 61, - 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, - 32, 32,124, 61, 61,122, 34,133, 43, 32, 16, 16, 50, 2, 90, 2, - 36, 36, 36, 36, 36, 36, 36, 75, 2, 2, 2, 2, 2, 2, 2, 56, - 2,107,107, 2,111,112,107, 2, 2, 2, 2, 6, 2, 98,107, 2, - 107, 4, 4, 4, 4, 2, 2, 80, 2, 2, 2, 2, 2, 51, 2, 2, - 98,134, 2, 2, 2, 2, 2, 2, 61, 2,135,132,132,132,136, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 1, 2,137,138, 4, 4, 4, 4, - 4, 61, 4, 4, 4, 4,139, 94,140, 95, 95, 95, 95, 43, 43, 78, - 141, 40, 40, 61, 95,142, 58, 61, 72, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 64,143,144, 63, 36, 36, 36, 36, 36, 58, 40, 63, - 61, 27, 27, 61, 61, 61, 61, 61, 27, 27, 27, 27, 27, 61, 61, 61, - 61, 61, 61, 61, 27, 27, 27, 27,145, 27, 27, 27, 27, 27, 27, 27, - 36, 36, 75, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,146, 2, - 32, 32, 32, 32, 32, 32, 32, 64, 48,147, 43, 43, 43, 43, 43, 80, - 32, 32, 32, 32, 32, 32, 40, 43, 36, 36, 36, 95, 95, 95, 95, 95, - 43, 2, 2, 2, 2, 2, 2, 2, 41, 41, 41,144, 40, 40, 40, 40, - 41, 32, 32, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, - 44, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,148, 34, 35, - 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, - 11, 11, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 34, 16, 16, 16, - 32, 16, 16, 32, 32, 16, 16, 16, 16, 40,149, 35, 40, 35, 36, 36, - 36, 65, 36, 65, 36, 64, 36, 36, 36, 82, 79, 77, 61, 61, 43, 43, - 27, 27, 27, 61,150, 61, 61, 61, 36, 36, 2, 2, 2, 2, 2, 2, - 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 78, 78, 78, 78, 78, 78, - 78, 78, 43, 43, 43, 43, 43, 2, 43, 36, 36, 36, 2, 66, 66, 64, - 36, 36, 36, 43, 43, 43, 43, 2, 36, 36, 36, 64, 43, 43, 43, 43, - 43, 78, 78, 78, 78, 78, 78, 97, 36, 64, 78, 43, 43, 78, 43, 78, - 97, 2, 2, 2, 2, 2, 2, 80, 7, 7, 7, 7, 7, 7, 7, 2, - 36, 36, 64, 63, 36, 36, 36, 36, 36, 36, 36, 36, 64, 43, 43, 77, - 79, 77, 79, 43, 43, 43, 43, 43, 36, 64, 36, 36, 36, 36, 77, 78, - 7, 7, 7, 7, 7, 7, 2, 2, 63, 36, 36, 71, 61, 82, 77, 36, - 65, 43, 65, 64, 65, 36, 36, 43, 36, 36, 36, 36, 36, 36, 75, 2, - 36, 36, 36, 36, 36, 82, 43, 78, 2, 75,151, 43, 43, 43, 43, 43, - 16, 16, 16, 16, 16,103, 40, 40, 16, 16, 16, 16,100, 41, 41, 41, - 36, 82, 79, 78, 77, 97, 79, 43,152,152,152,152,152,152,152,152, - 153,153,153,153,153,153,153,153, 16, 16, 16, 16, 16, 16, 35, 65, - 36, 36, 36, 36,154, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, - 41, 74, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,132, - 36, 36, 36, 36, 36, 36, 36, 71, 36, 36, 36, 36, 36, 36,150, 61, - 2, 2, 2,135,116, 2, 2, 2, 6,155,156,132,132,132,132,132, - 132,132,116,135,116, 2,113,157, 2, 2, 2, 2,139,132,132,116, - 2,158, 8, 8, 60, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36,159, - 2, 2, 3, 2, 4, 5, 6, 2, 16, 16, 16, 16, 16, 17, 18,115, - 116, 4, 2, 36, 36, 36, 36, 36, 63, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 40, 20,160, 53, 20, 26, 8,128, 61, - 61, 61, 61, 61,161, 59, 61, 61, 2, 2, 2, 90, 27, 27, 27, 27, - 27, 27, 27, 84, 61, 61, 61, 61, 95, 95,127, 27, 84, 61, 61, 61, - 61, 61, 61, 61, 61, 27, 61, 61, 61, 61, 61, 61, 61, 61, 47, 43, - 162,162,162,162,162,162,162,162,163, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 87, 36,138, 36, 36, 36, 36, 95, 95, 95, - 36, 36, 36, 36, 36, 36, 36, 58,164, 95, 95, 95, 95, 95, 95, 95, - 11, 11, 11, 32, 16, 16, 16, 16, 36, 36, 36, 58, 27, 27, 27, 27, - 36, 36, 36, 71,145, 27, 27, 27, 36, 36, 36,165, 27, 27, 27, 27, - 36, 36, 36, 36, 36,165, 27, 27, 36, 36, 36, 27, 27, 27, 27, 30, - 36, 36, 36, 36, 36, 36, 27, 36, 64, 43, 43, 43, 43, 43, 43, 43, - 36, 36, 36, 36, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36,165, 30, - 36, 36, 36, 36, 36, 36,165, 27, 36, 36, 36, 36, 72, 36, 36, 36, - 36, 36, 64, 43, 43,163, 27, 27, 36, 36, 36, 36, 58, 2, 2, 2, - 36, 36, 36, 36, 27, 27, 27, 27, 16, 16, 16, 16, 16, 27, 27, 27, - 36, 36, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 64,166, 51, - 27, 27, 27, 87, 36, 36, 36, 36,163, 27, 30, 2, 2, 2, 2, 2, - 36, 43, 43, 2, 2, 2, 2, 2, 36, 36,165, 27, 27, 27, 27, 27, - 79, 81, 36, 36, 36, 36, 36, 36, 43, 43, 43, 57, 2, 2, 2, 2, - 2, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 7, 7, 7, - 65, 64, 65, 36, 36, 36, 36, 64, 78, 79, 43, 77, 79, 57, 73, 2, - 2, 43, 43, 43, 43, 43, 67, 59, 36, 36, 36, 64, 43, 43, 79, 43, - 43, 43, 43, 7, 7, 7, 7, 7, 2, 2, 82, 81, 36, 36, 36, 36, - 36, 64, 2, 36, 36, 36, 36, 36, 36, 82, 78, 43, 43, 43, 43, 77, - 81, 36, 58, 2, 56, 43, 57, 79, 7, 7, 7, 7, 7, 58, 58, 2, - 90, 27, 27, 27, 27, 27, 27, 27, 36, 36, 36, 36, 36, 36, 78, 79, - 43, 78, 77, 43, 2, 2, 2, 65, 36, 36, 36, 36, 36, 36, 36, 64, - 77, 78, 78, 78, 78, 78, 78, 78, 36, 36, 36, 82, 78, 78, 81, 36, - 36, 78, 78, 43, 43, 43, 43, 43, 36, 36, 82, 78, 43, 43, 43, 43, - 78, 43, 77, 65, 36, 58, 2, 2, 7, 7, 7, 7, 7, 2, 2, 65, - 78, 79, 43, 43, 77, 77, 78, 79, 77, 43, 36, 66, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 82, 78, 43, 43, 43, 78, 78, 43, 79, - 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 43, - 78, 79, 43, 43, 43, 77, 79, 79, 57, 2, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 64, 79, 78, 43, 43, 43, 79, 58, 2, 2, 2, + 16, 16, 16, 16, 34, 16, 16, 16, 43, 57, 43, 43, 43, 43, 43, 43, + 77, 43, 43, 43, 65, 36, 64, 36, 36, 36, 65, 82, 43, 36, 36, 36, + 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 44, 16, 16, + 16, 16, 16, 16, 44, 16, 16, 16, 16, 16, 16, 16, 16,100, 40, 40, + 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, + 16, 16, 16, 16, 34, 11, 11, 11, 16, 16, 16, 16,101,101,101,101, + 16, 16, 16, 16, 11, 11,102,103, 41, 16, 16, 16, 11, 11,102, 41, + 16, 16, 16, 16, 11, 11,104, 41,105,105,105,105,105,106, 59, 59, + 51, 51, 51, 2,107,108,107,108, 2, 2, 2, 2,109, 59, 59,110, + 2, 2, 2, 2,111,112, 2,113,114, 2,115,116, 2, 2, 2, 2, + 2, 9,114, 2, 2, 2, 2,117, 59, 59, 59, 59, 59, 59, 59, 59, + 118, 40, 27, 27, 27, 8,115,119, 27, 27, 27, 27, 27, 8,115, 94, + 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43,120, 48, + 99, 48, 99, 43, 43, 43, 43, 43, 61,121, 61,122, 61, 34, 11, 16, + 11, 32,122, 61, 46, 11, 11, 61, 61, 61,121,121,121, 11, 11,123, + 11, 11, 35, 36, 39, 61, 16, 11, 8, 8, 46, 16, 16, 26, 61,124, + 95, 95, 95, 95, 95, 95, 95, 95, 95,125,126, 95,127, 61, 61, 61, + 8, 8,128, 61, 61, 8, 61, 61,128, 26, 61,128, 61, 61, 61,128, + 61, 61, 61, 61, 61, 61, 61, 8, 61,128,128, 61, 61, 61, 61, 61, + 61, 61, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 61, 61, 61, 61, 4, 4, 61, 61, 8, 61, 61, 61,129,130, 61, 61, + 61, 61, 61, 61, 61, 61,128, 61, 61, 61, 61, 61, 61, 26, 8, 8, + 8, 8, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, + 8, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, 27, 27, 27, 61, 61, + 61, 61, 61, 61, 61, 27, 27, 27, 61, 61, 61, 26, 61, 61, 61, 61, + 26, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, 8, 8, + 61, 61, 61, 61, 61, 61, 61, 26, 61, 61, 61, 61, 4, 4, 4, 4, + 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, + 8, 8,115,131, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, + 8,115,132,132,132,132,132,132,132,132,132,132,131, 8, 8, 8, + 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, + 8, 8,128, 26, 8, 8,128, 61, 32, 11, 32, 34, 34, 34, 34, 11, + 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,124, 61, 61,122, 34,133, + 43, 32, 16, 16, 50, 2, 90, 2, 36, 36, 36, 36, 36, 36, 36, 76, + 2, 2, 2, 2, 2, 2, 2, 56, 2,107,107, 2,111,112,107, 2, + 2, 2, 2, 6, 2, 98,107, 2,107, 4, 4, 4, 4, 2, 2, 80, + 2, 2, 2, 2, 2, 51, 2, 2, 98,134, 2, 2, 2, 2, 2, 2, + 61, 2,135,132,132,132,136, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 1, 2,137,138, 4, 4, 4, 4, 4, 61, 4, 4, 4, 4,139, 94, + 140, 95, 95, 95, 95, 43, 43, 78,141, 40, 40, 61, 95,142, 58, 61, + 72, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64,143,144, 63, + 36, 36, 36, 36, 36, 58, 40, 63, 61, 27, 27, 61, 61, 61, 61, 61, + 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, 27, + 145, 27, 27, 27, 27, 27, 27, 27, 36, 36, 76, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36,146, 2, 32, 32, 32, 32, 32, 32, 32, 64, + 48,147, 43, 43, 43, 43, 43, 80, 32, 32, 32, 32, 32, 32, 40, 43, + 36, 36, 36, 95, 95, 95, 95, 95, 43, 2, 2, 2, 2, 2, 2, 2, + 41, 41, 41,144, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, + 16, 32, 32, 32, 32, 32, 32, 32, 44, 16, 16, 16, 34, 34, 34, 32, + 32, 32, 32, 32, 42,148, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, + 32, 32, 11, 11, 34, 34, 32, 16, 32, 16, 16, 32, 32, 32, 11, 11, + 11, 40,149, 35, 40, 35, 36, 36, 36, 65, 36, 65, 36, 64, 36, 36, + 36, 82, 79, 77, 61, 61, 43, 43, 27, 27, 27, 61,150, 61, 61, 61, + 36, 36, 2, 2, 2, 2, 2, 2, 78, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 78, 78, 78, 78, 78, 78, 78, 78, 43, 43, 43, 43, 43, 2, + 43, 36, 36, 36, 2, 66, 66, 64, 36, 36, 36, 43, 43, 43, 43, 2, + 36, 36, 36, 64, 43, 43, 43, 43, 43, 78, 78, 78, 78, 78, 78, 97, + 36, 64, 78, 43, 43, 78, 43, 78, 97, 2, 2, 2, 2, 2, 2, 80, + 7, 7, 7, 7, 7, 7, 7, 2, 36, 36, 64, 63, 36, 36, 36, 36, + 36, 36, 36, 36, 64, 43, 43, 77, 79, 77, 79, 43, 43, 43, 43, 43, + 36, 64, 36, 36, 36, 36, 77, 78, 7, 7, 7, 7, 7, 7, 2, 2, + 63, 36, 36, 71, 61, 82, 77, 36, 65, 43, 65, 64, 65, 36, 36, 43, + 36, 36, 36, 36, 36, 36, 76, 2, 36, 36, 36, 36, 36, 82, 43, 78, + 2, 76,151, 43, 43, 43, 43, 43, 16, 16, 16, 16, 16,103, 40, 40, + 16, 16, 16, 16,100, 41, 41, 41, 36, 82, 79, 78, 77, 97, 79, 43, + 152,152,152,152,152,152,152,152,153,153,153,153,153,153,153,153, + 16, 16, 16, 16, 16, 16, 35, 65, 36, 36, 36, 36,154, 36, 36, 36, + 36, 41, 41, 41, 41, 41, 41, 41, 41, 74, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36,132, 36, 36, 36, 36, 36, 36, 36, 71, + 36, 36, 36, 36, 36, 36,150, 61, 2, 2, 2,135,116, 2, 2, 2, + 6,155,156,132,132,132,132,132,132,132,116,135,116, 2,113,157, + 2, 2, 2, 2,139,132,132,116, 2,158, 8, 8, 60, 2, 2, 2, + 36, 36, 36, 36, 36, 36, 36,159, 2, 2, 3, 2, 4, 5, 6, 2, + 16, 16, 16, 16, 16, 17, 18,115,116, 4, 2, 36, 36, 36, 36, 36, + 63, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, + 20,160, 53, 20, 26, 8,128, 61, 61, 61, 61, 61,161, 59, 61, 61, + 2, 2, 2, 90, 27, 27, 27, 27, 27, 27, 27, 84, 61, 61, 61, 61, + 95, 95,127, 27, 84, 61, 61, 61, 61, 61, 61, 61, 61, 27, 61, 61, + 61, 61, 61, 61, 61, 61, 47, 43,162,162,162,162,162,162,162,162, + 163, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 87, 36, + 138, 36, 36, 36, 36, 95, 95, 95, 36, 36, 36, 36, 36, 36, 36, 58, + 164, 95, 95, 95, 95, 95, 95, 95, 11, 11, 11, 32, 16, 16, 16, 16, + 36, 36, 36, 58, 27, 27, 27, 27, 36, 36, 36, 71,145, 27, 27, 27, + 36, 36, 36,165, 27, 27, 27, 27, 36, 36, 36, 36, 36,165, 27, 27, + 36, 36, 36, 27, 27, 27, 27, 30, 36, 36, 36, 36, 36, 36, 27, 36, + 64, 43, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36,165, 30, 36, 36, 36, 36, 36, 36,165, 27, + 36, 36, 36, 36, 72, 36, 36, 36, 36, 36, 64, 43, 43,163, 27, 27, + 36, 36, 36, 36, 58, 2, 2, 2, 36, 36, 36, 36, 27, 27, 27, 27, + 16, 16, 16, 16, 16, 27, 27, 27, 36, 36, 43, 43, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 36, 36, 63, 11, 11, 11, 11,166, 43, 43,141, + 16, 16, 16, 16, 16, 16, 16, 8, 36, 36, 36, 36, 36, 64,167, 51, + 36, 36, 36, 36, 36, 36, 43, 43, 27, 27, 27, 87, 36, 36, 36, 36, + 163, 27, 30, 2, 2, 2, 2, 2, 36, 43, 43, 2, 2, 2, 2, 2, + 36, 36,165, 27, 27, 27, 27, 27, 79, 81, 36, 36, 36, 36, 36, 36, + 43, 43, 43, 57, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 7, 7, 7, 7, 7, 65, 64, 65, 36, 36, 36, 36, 64, + 78, 79, 43, 77, 79, 57, 73, 2, 2, 43, 43, 43, 43, 43, 67, 59, + 36, 36, 36, 64, 43, 43, 79, 43, 43, 43, 43, 7, 7, 7, 7, 7, + 2, 2, 82, 81, 36, 36, 36, 36, 36, 64, 2, 36, 36, 36, 36, 36, + 36, 82, 78, 43, 43, 43, 43, 77, 81, 36, 58, 2, 56, 43, 57, 79, + 7, 7, 7, 7, 7, 58, 58, 2, 90, 27, 27, 27, 27, 27, 27, 27, + 36, 36, 36, 36, 36, 36, 78, 79, 43, 78, 77, 43, 2, 2, 2, 65, + 36, 36, 36, 36, 36, 36, 36, 64, 77, 78, 78, 78, 78, 78, 78, 78, + 36, 36, 36, 82, 78, 78, 81, 36, 36, 78, 78, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 78, 79, 43, 43, 43, 78, 78, 78, 78, 78, 78, 77, + 65, 65, 2, 2, 2, 2, 2, 2, 56, 43, 43, 43, 43, 43, 43, 43, + 36, 36, 82, 78, 43, 43, 43, 43, 78, 43, 77, 65, 36, 58, 2, 2, + 7, 7, 7, 7, 7, 2, 2, 65, 78, 79, 43, 43, 77, 77, 78, 79, + 77, 43, 36, 66, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 82, + 78, 43, 43, 43, 78, 78, 43, 79, 57, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 36, 36, 43, 43, 78, 79, 43, 43, 43, 77, 79, 79, + 57, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 79, 78, + 43, 43, 43, 79, 58, 2, 2, 2, 36, 36, 36, 36, 36, 36, 64, 79, 78, 43, 43, 79, 43, 43, 43, 43, 7, 7, 7, 7, 7, 27, 2, 89, 43, 43, 43, 43, 79, 57, 2, 2, 27, 27, 27, 27, 27, 27, 27, 87, 78, 78, 78, 78, 78, 79, 77, 65, 81, 79, 2, 2, 2, 2, 2, 2, @@ -4721,39 +4938,41 @@ _hb_ucd_u8[13386] = 78, 78, 78, 78, 78, 78, 78, 78, 64, 43, 43, 43, 43, 65, 36, 36, 36, 64, 43, 43, 77, 64, 43, 57, 2, 2, 2, 56, 43, 43, 43, 43, 64, 43, 43, 77, 79, 43, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, - 43, 43, 43, 77, 43, 2, 66, 2, 43, 43, 43, 43, 43, 43, 43, 79, - 58, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, + 43, 43, 43, 77, 43, 2, 66, 2, 58, 2, 2, 2, 2, 2, 2, 2, + 43, 43, 43, 43, 43, 43, 43, 79, 2, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 77, 43, 43, 43, 77, 43, 79, 43, 43, 43, 43, 43, 43, 43, 43, 64, 43, 43, 43, 43, 36, 36, 36, 36, 36, 78, 78, 78, 43, 77, 79, 79, 36, 36, 36, 36, 36, 64, 77, 97, 2, 2, 2, 2, 43, 82, 36, 36, 36, 36, 36, 36, 36, 36, 78, 43, 43, 43, 43, 78, - 77, 57, 2, 2, 2, 2, 2, 2, 27, 27, 84, 61, 61, 61, 53, 20, - 150, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 21, - 65, 36, 36, 64, 43, 43, 43, 43, 43, 43, 57, 2, 2, 2, 2, 2, - 43, 43, 43, 57, 2, 2, 61, 61, 40, 40, 89, 61, 61, 61, 61, 61, - 7, 7, 7, 7, 7,167, 27, 27, 27, 87, 36, 36, 36, 36, 36, 36, - 27, 27, 27, 30, 2, 2, 2, 2, 82, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 79, 43, 68, 40, 40, 40, 40, 40, 40, - 40, 80, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 47, 57, - 61, 61,168, 79, 43, 61,168, 78, 78,169, 59, 59, 59, 76, 43, 43, - 43, 70, 47, 43, 43, 43, 61, 61, 61, 61, 61, 61, 61, 43, 43, 61, - 61, 43, 70, 61, 61, 61, 61, 61, 11, 11, 11, 11, 11, 16, 16, 16, - 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, - 11, 11, 11, 16, 16, 16, 16, 16, 31, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, - 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, - 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, - 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, - 16, 33, 16, 16, 16, 32, 16, 7, 43, 43, 43, 70, 61, 47, 43, 43, - 43, 43, 43, 43, 43, 43, 70, 61, 61, 61, 47, 61, 61, 61, 61, 61, - 61, 61, 70, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 56, 43, 43, - 16, 16, 16, 16, 16, 39, 16, 16, 43, 43, 43, 68, 40, 40, 40, 40, - 7, 7, 7, 7, 7, 7, 7, 71, 36, 36, 36, 36, 36, 36, 36, 43, - 36, 36, 36, 36, 36, 36, 43, 43, 7, 7, 7, 7, 7, 7, 7,170, - 36, 36, 36, 36, 36, 75, 43, 43, 16, 16, 43, 43, 43, 68, 40, 40, - 27, 27, 27, 27, 27, 27,145, 27,171, 27, 27, 27, 27, 27, 27, 27, + 77, 57, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 43, 43, 43, + 27, 27, 84, 61, 61, 61, 53, 20,150, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 21, 65, 36, 36, 64, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 78, 79, 43, + 43, 43, 57, 2, 2, 2, 2, 2, 43, 43, 43, 57, 2, 2, 61, 61, + 40, 40, 89, 61, 61, 61, 61, 61, 7, 7, 7, 7, 7,168, 27, 27, + 27, 87, 36, 36, 36, 36, 36, 36, 40, 63, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 76,146, 2, 27, 27, 27, 30, 2, 2, 2, 2, + 82, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, + 43, 68, 40, 40, 40, 40, 40, 40, 40, 80, 43, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 47, 57, 61, 61,169, 79, 43, 61,169, 78, + 78,170, 59, 59, 59, 75, 43, 43, 43, 70, 47, 43, 43, 43, 61, 61, + 61, 61, 61, 61, 61, 43, 43, 61, 61, 43, 70, 61, 61, 61, 61, 61, + 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, + 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, + 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, + 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, + 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 16, 7, + 43, 43, 43, 70, 61, 47, 43, 43, 43, 43, 43, 43, 43, 43, 70, 61, + 61, 61, 47, 61, 61, 61, 61, 61, 61, 61, 70, 21, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 56, 43, 43, 16, 16, 16, 16, 16, 39, 16, 16, + 43, 43, 43, 68, 40, 40, 40, 40, 7, 7, 7, 7, 7, 7, 7, 71, + 7, 7, 7, 7, 7, 7, 7,171, 36, 36, 36, 36, 36, 76, 43, 43, + 172, 7, 7, 7, 7, 7, 7, 85, 16, 16, 43, 43, 43, 68, 40, 40, + 27, 27, 27, 27, 27, 27,145, 27,173, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,145, 27, 27, 27, 27, 27, 27, 84, 61, 61, 61, 61, 61, 61, 25, 41, 41, 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, @@ -4764,8 +4983,8 @@ _hb_ucd_u8[13386] = 6, 5, 9, 21, 25, 9, 26, 12, 11, 11, 9, 6, 5, 21, 17, 17, 17, 26, 26, 23, 23, 12, 17, 12, 21, 12, 12, 21, 7, 21, 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, - 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 21, 1, 24, 7, 7, 6, - 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 10, 7, 7, 10, 23, 7, + 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 21, 1, 24, 7, 1, 12, + 7, 6, 12, 10, 10, 10, 10, 12, 21, 6, 10, 7, 7, 10, 23, 7, 15, 26, 13, 21, 13, 7, 15, 7, 12, 23, 21, 26, 21, 15, 17, 7, 29, 7, 7, 22, 18, 18, 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, 5, 6, 8, 8, 8, 24, 5, 24, 9, 24, 29, 29, 29, 1, 20, 19, @@ -4776,247 +4995,250 @@ _hb_ucd_u8[13386] = 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 7, 1, 25, 24, 26, 1, 2, 2, 12, 15, - 21, 14, 7, 15, 12, 17, 13, 15, 26, 10, 10, 1, 13, 23, 23, 15, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, - 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 21, 14, 7, 15, 9, 12, 12, 17, 13, 15, 26, 10, 10, 1, 13, 23, + 7, 13, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, + 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, - 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 35, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, 0, 0, - 40, 41, 42, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, 6, 7, - 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, 16, 18, 16, 19, - 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, 0, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, 0, 0, - 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 0, - 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, - 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, 0, 0, 0, 55, - 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, 62, 63, 0, 0, - 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, - 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, 0, 0, 0, 0, - 0, 0, 74, 0, 0, 0, 0, 0, 75, 76, 0, 77, 78, 0, 0, 79, - 80, 0, 81, 62, 0, 82, 83, 0, 0, 84, 85, 86, 0, 0, 0, 87, - 0, 88, 0, 0, 51, 89, 51, 0, 90, 0, 91, 0, 0, 0, 80, 0, - 0, 0, 92, 93, 0, 94, 95, 96, 97, 0, 0, 0, 0, 0, 51, 0, - 0, 0, 0, 98, 99, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 0, - 0,101,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,103, 0, 0, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105,106, 0, 0,107, - 0, 0, 0, 0, 0, 0,108, 0,109, 0,102, 0, 0, 0, 0, 0, - 110,111, 0, 0, 0, 0, 0, 0, 0,112, 0, 0, 0, 0, 0, 0, - 0,113, 0,114, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, - 7, 0, 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, - 0, 0, 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, - 0, 0, 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, - 0, 0, 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, - 0, 35, 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, - 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, - 0, 0, 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, - 0, 0, 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, - 0, 52, 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, - 0, 0, 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, - 0, 61, 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, - 0, 67, 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, - 77, 78, 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, - 0, 0, 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, - 85, 0, 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, - 0, 88, 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, - 33, 0, 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, - 93, 0, 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, - 98, 0, 0, 0, 99, 0, 0, 0, 0,100,101, 93, 0, 0,102, 0, - 0, 0, 84, 0, 0,103, 0, 0, 0,104,105, 0, 0,106,107, 0, - 0, 0, 0, 0, 0,108, 0, 0,109, 0, 0, 0, 0,110, 33, 0, - 111,112,113, 35, 0, 0,114, 0, 0, 0,115, 0, 0, 0, 0, 0, - 0,116, 0, 0,117, 0, 0, 0, 0,118, 88, 0, 0, 0, 0, 0, - 57, 0, 0, 0, 0, 52,119, 0, 0, 0, 0,120, 0, 0,121, 0, - 0, 0, 0,119, 0, 0,122, 0, 0, 0, 0, 0, 0,123, 0, 0, - 0,124, 0, 0, 0,125, 0,126, 0, 0, 0, 0,127,128,129, 0, - 130, 0,131, 0, 0, 0,132,133,134, 0, 77, 0, 0, 0, 0, 0, - 35, 0, 0, 0,135, 0, 0, 0,136, 0, 0,137, 0, 0,138, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, - 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, - 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, - 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, - 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, - 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, - 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 0, - 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, - 35, 1, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, - 0, 59, 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, - 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, - 68, 0, 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, - 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, - 0, 0, 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, - 83, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, - 15, 86, 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, - 0, 0, 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, - 0, 0, 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, - 21, 92, 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99, - 100, 4, 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, - 0, 61, 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, - 0, 38, 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, - 0, 0, 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, - 0,107, 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, - 0,108, 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, + 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, + 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, + 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, + 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, + 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, + 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, + 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, + 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, + 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, + 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, 0, 78, + 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, 86, 87, + 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, 93, 0, + 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, 0, 0, + 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, 0,102, + 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104,105, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, 0, 0, + 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, 0, 0, + 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, 0,118, + 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, + 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, + 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, + 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, 28, 29, + 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, 33, 0, + 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, + 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 43, + 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, + 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, + 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 0, + 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, 52, 0, + 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, 0, 68, + 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, 0, 0, + 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, 0, 0, + 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, 52, 0, + 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, 57, 0, + 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, 0, 91, + 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, 0, 0, + 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, + 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0,103, 0, + 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107,108, 0, + 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, 33, 0, + 112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0,117, 0, + 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, 88, 0, + 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, 0,122, + 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, 0, 0, + 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, 0,128, + 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0,134,135, + 136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, 0, 0, + 138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, + 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 19, 1, + 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, 29, 30, + 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, 37, 0, + 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, 43, 36, + 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, 0, 38, + 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, 0, 0, + 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, 0, 0, + 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, 0, 60, + 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, + 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 69, + 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, 0, 78, + 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, 0, 62, + 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, + 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, 36, 10, + 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, + 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 87, 9, + 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, 93, 1, + 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, 58, 0, + 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0, + 101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, + 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, 78, 0, + 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, 1, 14, + 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, 0, 0, + 109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, 0, 38, - 1, 58, 1, 58, 0, 0, 63, 89, 0, 0,115, 0, 0, 0, 55, 0, - 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, 0, 79, 0, 61, - 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, 0, 0, 8, 91, - 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, 0,117, 0,118, - 119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, 38, 50, 38, 58, - 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, 87, 0, 0, 0, - 0, 1, 0, 0, 0,123, 4,122, 0, 0, 0, 1,124, 0, 0, 0, - 0, 0,230,230,230,230,230,232,220,220,220,220,232,216,220,220, - 220,220,220,202,202,220,220,220,220,202,202,220,220,220, 1, 1, - 1, 1, 1,220,220,220,220,230,230,230,230,240,230,220,220,220, - 230,230,230,220,220, 0,230,230,230,220,220,220,220,230,232,220, - 220,230,233,234,234,233,234,234,233,230, 0, 0, 0,230, 0,220, - 230,230,230,230,220,230,230,230,222,220,230,230,220,220,230,222, - 228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, - 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, 0, 0, - 0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,220,230, - 230,220, 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230,230, 0, - 220,230,230,220, 0, 0, 0, 36, 0, 0,230,220,230,230,220,220, - 230,220,220,230,220,230,220,230,230, 0, 0,220, 0, 0,230,230, - 0,230, 0,230,230,230,230,230, 0, 0, 0,220,220,220,230,220, - 220,220,230,230, 0,220, 27, 28, 29,230, 7, 0, 0, 0, 0, 9, - 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0, 0, 84, - 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0,103,103, - 9, 0,107,107,107,107,118,118, 9, 0,122,122,122,122,220,220, - 0, 0, 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0,132, 0, - 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230, 9, 0, - 230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, - 0, 0, 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220,220, 0, - 0, 0,230, 0, 0,220,230,220, 0,220,230,230,230, 0, 0, 0, - 9, 9, 0, 0, 7, 0,230, 0, 1, 1, 1, 0, 0, 0,230,234, - 214,220,202,230,230,230,230,230,232,228,228,220,218,230,233,220, - 230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230,220,230, - 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, 0, 0, - 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, 0,220, - 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, 0, 0, - 230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, - 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, 0,226, - 216,216,216,216,216, 0,220,220,220, 0,232,232,220,230,230,230, - 7, 0, 16, 17, 17, 33, 17, 49, 17, 17, 84, 97,135,145, 26, 17, + 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0,115, 0, + 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, + 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, + 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, + 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, + 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, + 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, 4,122, + 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230,230,232, + 220,220,220,220,232,216,220,220,220,220,220,202,202,220,220,220, + 220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220,220,230, + 230,230,230,240,230,220,220,220,230,230,230,220,220, 0,230,230, + 230,220,220,220,220,230,232,220,220,230,233,234,234,233,234,234, + 233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230,230,230, + 222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0,230,220, + 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, + 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, 0, 0, + 230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, 0, 36, + 0, 0,230,220,230,230,220,220,230,220,220,230,220,230,220,230, + 230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230,230,230, + 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, 27, 28, + 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230,230, 0, + 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, + 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107,118,118, + 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, 0,216, + 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130,130,130, + 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, 0, 0, + 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, 0,228, + 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220,230,220, + 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0,230, 0, + 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230,230,230, + 232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, 1, 1, + 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228,232,222, + 224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230,220, 0, + 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, 0,230, + 220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, 0, 7, + 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, 0,216, + 216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0,220,220, + 220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 33, 17, 49, + 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, + 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, + 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, + 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, + 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, 3, 3, + 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, + 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, + 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, + 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, + 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, + 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, + 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, + 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, 0, 0, + 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, 14, 0, + 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 61, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, 0, 4, + 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, 0, 8, + 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, + 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, 0, 18, + 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, 0, 1, + 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, 1, 0, + 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, 1, 1, + 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, 0, 1, + 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, 9, 36, + 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, 21, 21, + 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, 0, 0, + 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, 8, 9, + 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, 8, 21, + 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 3, 3, 3, 3, 3, 3, + 3, 15, 3, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17,177, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, - 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, - 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, - 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, - 3, 3, 25, 3, 3, 3, 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, - 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, - 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, - 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, - 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, - 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, - 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, - 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, - 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, - 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, - 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, - 0, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, - 0, 0, 0, 0, 0, 59, 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, - 0, 3, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 2, 3, 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, - 0, 0, 0, 1, 1, 0, 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, - 8, 9, 10, 11, 12, 0, 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, - 17, 0, 0, 0, 1, 0, 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, - 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, - 0, 0, 22, 0, 0, 0, 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, - 0, 0, 8, 21, 27, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, - 29, 30, 0, 31, 32, 20, 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, - 5, 0, 0, 0, 33, 9, 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, - 34, 1, 35, 21, 21, 21, 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, - 0, 0, 1, 0, 1, 0, 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, - 40, 0, 8, 21, 21, 21, 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, - 1, 8, 21, 21, 21, 9, 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, - 1, 44, 0, 0, 0, 45, 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, - 9, 0, 1, 0, 1, 1, 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, - 0, 0, 0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 3, 3, 3, 3, 3, 3, 3, 15, 3, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 18, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 17, 17, 18, 17, 19, 20, 21, 22, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 25, 25, 26, 27, 28, 29, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 0, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 17, + 18, 17, 19, 20, 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 24, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 25, 25, 26, 27, + 28, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53, 31, + 31, 31, 31, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 57, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 58, 31, 31, 31, + 59, 60, 61, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 64, 65, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 66, 67, 68, 31, 31, 31, 31, 69, 31, 31, 31, 31, 31, + 31, 31, 17, 70, 71, 72, 17, 17, 73, 74, 31, 75, 76, 77, 78, 79, + 80, 31, 81, 82, 17, 83, 17, 17, 17, 17, 31, 31, 23, 23, 23, 23, + 23, 23, 23, 84, 31, 31, 31, 31, 23, 84, 31, 31, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 52, 53, 31, 31, 31, 31, 54, 55, 55, 56, 31, - 31, 31, 31, 31, 31, 31, 57, 58, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 59, 60, 31, 61, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 64, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 65, 66, 67, 31, 31, - 31, 31, 68, 31, 31, 31, 31, 31, 31, 31, 31, 69, 70, 71, 17, 17, - 72, 73, 31, 74, 75, 76, 77, 78, 79, 31, 80, 81, 17, 82, 17, 17, - 17, 17, 31, 31, 23, 23, 23, 23, 23, 23, 23, 83, 31, 31, 31, 31, - 23, 83, 31, 31, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 84, 0, 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, - 4, 5, 6, 7, 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, - 7, 8, 9, 10, 11, 11, 12, 11, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 19, 27, 28, 29, 30, 30, 31, 31, 32, 32, - 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 40, 41, 41, - 42, 42, 42, 43, 44, 44, 45, 46, 47, 47, 47, 47, 48, 48, 48, 48, - 48, 48, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 53, - 54, 55, 56, 56, 57, 58, 59, 51, 60, 61, 62, 63, 64, 65, 66, 7, - 67, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 7, 4, 4, 4, 4, - 77, 77, 77, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 85, 85, 85, 85, 0, 0, 0, 0, 86, 87, 88, 88, - 89, 90, 48, 91, 0, 0, 92, 92, 92, 92, 92, 93, 94, 95, 96, 97, - 98, 47, 99,100,101,102, 0,103,104,105, 0, 0, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0,106,106,106,106, - 106,106,106,106,106,106,106,107,108,108,108,108,108, 11,109,110, - 111, 4,112, 4,113,114,115,116,117,118,119,120,121,122,123,124, - 125,126, 50,127, 47, 47, 47, 47, 47, 47, 47, 47,128,128,128,128, - 128,128,128,128,128,128,128,128, 92, 92, 92, 92, 92, 92, 92, 92, - 129,130, 19, 19, 19, 19, 19, 19,131, 19, 19, 19,132,133, 19,134, - 135,136,137,101,138,138,138,138, 0, 77,139,140,128,128,141,142, - 143,144,145,146,147,148,149,150,151,152,153,153,154,154,154,154, - 154,154, 4, 4,155,156,157,158,159,160,161,162,163,164,165,166, - 167,168,169,169,170,170,171,171,172,172,128,128, 19, 19,173,174, - 175,176,177,178,179,179,180,181,182,183,184,185,186,186,187,188, - 189,190,128,128,191,191,192,192,128,128,193,193,194,195,196,196, - 197,197,128,128,198,198,199,199,200,200,201,201,202,203,204,205, - 28, 28,128,128,206,207,208,208,209,210,211,211,128,128,212,212, - 213,213,214, 34,215,215,215,215,215,215,215,215,215,215,215,215, - 215,215,128,128,128,128,128,128,128,128,216,216,217,217,217,217, - 217,217,217,217,217,217,128,128,128,128,128,128,218,218,218,218, - 218,218,218,218,218,218,128,128,128,128,128,128,110,110,110,110, - 110,110,110,110,110,219,220,221,222,222,222,222,223,223,223,223, - 224,224,224,225,226,226,226,226,226,226,226,226,226,226,226,226, - 227,227,227,227,227,227,227,227,226,226,128,128,128,128,128,128, - 128,128,104,104,228,229,229,229,230,231,232,232,232,232,232,232, - 128,128,128,128,233,233,234, 0,128,128,128,128,128,128,128,128, - 7,235, 0, 0, 0, 0, 0, 0, 0,236,237, 0, 77, 77, 0, 0, - 0, 0,128,128,238,238,238,238,238,238,238,238,238,238,238,238, - 128,128,128,128,128,128,128,128, 4, 4,128,128,239, 11, 11, 11, - 240,240,128,128,128,128,241,242,128,128,128,128,128,128,243,243, - 128,128,128,128,128,128,128,128,128,128, 48, 48,244,244,244,244, - 245,245,128,128, 0, 0, 0, 0, 0, 0,128,128, 19, 19, 19, 19, - 128,128,128,128,246, 0,128,128, 0, 0, 0, 0, 92, 92,128,128, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 85, 0, 0, 1, + 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, + 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 11, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 19, 27, + 28, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, + 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 42, 43, 44, 44, 45, 46, + 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 49, 50, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 51, + 60, 61, 62, 63, 64, 65, 66, 7, 67, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 7, 4, 4, 4, 4, 77, 77, 77, 77, 78, 79, 80, 81, + 82, 83, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, + 0, 0, 0, 0, 86, 87, 88, 88, 89, 90, 48, 91, 0, 0, 92, 92, + 92, 92, 92, 93, 94, 95, 96, 97, 98, 47, 99,100,101,102, 0,103, + 104,105, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 0,106,106,106,106,106,106,106,106,106,106,106,107, + 108,108,108,108,108, 11,109,110,111, 4,112, 4,113,114,115,116, + 117,118,119,120,121,122,123,124,125,126, 50,127, 47, 47, 47, 47, + 47, 47, 47, 47,128,128,128,128,128,128,128,128,128,128,128,128, + 92, 92, 92, 92, 92, 92, 92, 92,129,130, 19, 19, 19, 19, 19, 19, + 131, 19, 19, 19,132,133, 19,134,135,136,137,101,138,138,138,138, + 0, 77,139,140,128,128,141,142,143,144,145,146,147,148,149,150, + 151,152,153,154,155,155,155,155,155,155, 4, 4,156,157,158,159, + 160,161,162,163,164,165,166,167,168,169,170,170,171,171,172,172, + 173,174,174,174, 19, 19,175,176,177,178,179,180,181,181,182,183, + 184,185,186,187,188,188,189,190,191,192,193,193,194,194,195,195, + 128,128,196,196,197,198,199,200,201,201,128,128,202,202,203,203, + 204,204,205,205,206,207,208,209, 28, 28,210,210,211,212,213,213, + 214,215,216,216,128,128,217,217,218,218,219, 34,220,220,220,220, + 220,220,220,220,220,220,220,220,220,220,128,128,128,128,128,128, + 128,128,221,221,222,222,222,222,222,222,222,222,223,223,223,223, + 223,223,223,223,223,223,128,128,128,128,128,128,128,128,128,128, + 224,224,128,128,110,110,110,110,110,110,110,110,110,225,226,227, + 228,228,228,228,128,128,128,128,229,229,128,128,230,230,230,230, + 231,231,231,232,233,233,233,233,233,233,233,233,233,233,233,233, + 234,234,234,234,234,234,234,234,233,233,128,128,128,128,128,128, + 128,128,104,104,235,236,236,236,237,238,239,239,239,239,239,239, + 128,128,128,128,240,240,241, 0,128,128,128,128, 0, 0, 0, 0, + 7,242, 0, 0, 0, 0, 0, 0, 0,243,244, 0, 77, 77, 0, 0, + 0, 0,128,128,245,245,245,245,245,245,245,245,245,245,245,245, + 128,128,128,128,128,128,128,128, 4, 4,128,128,246, 11, 11, 11, + 247,247,128,128,128,128,248,249,128,128,128,128,128,128,250,250, + 128,128,251,251,128,128,128,128,128,128, 48, 48,252,252,252,252, + 253,253,128,128, 0, 0, 0, 0, 0, 0,128,128, 19, 19, 19, 19, + 128,128,128,128,254, 0,128,128, 0, 0, 0, 0, 92, 92,128,128, 128,128,128,128, 0, 0,128,128, 7, 7, 7, 7, 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, 8, 9, @@ -5056,30 +5278,32 @@ _hb_ucd_u8[13386] = 137,137,138,138,138,138,139, 0,140,140,140,141,141,142,142,142, 143,143,144,144,144,144,144,144,145,145,145,145,145,146,146,146, 147,147,147,148,148,148,148,148,149,149,149,150,150,150,150,151, - 151,151,151,151,152,152,152,152,153,153,153,153,154,154,155,155, - 156,156,156,156,156,156,157,157,158,158,159,159,159,159,159,159, - 160,160,161,161,161,161,161,161,162,162,162,162,162,162,163,163, - 164,164,164,164,165,165,165,165,166,166,166,166,167,167,168,168, - 169,169,169,169,170,170,170,170,171,171,171,171,172,172,172,172, - 173,173,173,173,173,173,173,174,175,175,175,176,176,176,176,177, - 177,177,177,178,178,178,179,179,180,180,180,180,181,181,181,181, - 181,182,182,182,183,183,183,183,183,184,184,184,185,185,185,185, - 185,185,186, 43,187,187,187,187,188,188,188,189,189,189,189,189, - 190,190,190,191,190,190,190,190,192,192,192,192,193,193,193,193, - 194,194,194,194,195,195,195,195,195,195, 66, 66,196,196,196,196, - 197,197,197,197,198,198,198,198,199,199,199,199,200,200,200,200, - 201,201,201,201,202,202,202,202,202,203,203,203,203,203,203, 55, - 204,204,204,204,205,205,205,205,205,205,205,206,206,206,206,206, - 207,207,207,207,207,207,208,208,208,208,208,208,209,209,209,209, - 210,210,210,210,110,110,110,110,211,211,211,211,212,212,212,212, - 213,213,213,213,214,214,214,214,215,215,215,216,216,216,216,216, - 216,217,217,217,218,218,218,218,219,219,219,219,220,220,220,220, - 220,220,221, 94,222,222,222,222,223,223,223,223,224, 99, 99, 99, - 99, 99, 99, 99, 99, 99,102,225, 99,226,102,227,227,227,227,227, - 228,228,228,228,228,228, 0, 0, 8, 0, 0, 0, 0, 0,229,230, - 231, 0,232, 0,233,233,233,233, 91, 91, 91, 13,234,234,234,234, - 235,235,235,235,236,236,236,236,237,237,237,237,238,238,238,238, - 239,239,239,239,240, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, + 151,151,151,151,152,152,152,152,153,153,153,153,154,154,154,154, + 155,155,156,156,157,157,157,157,157,157,158,158,159,159,160,160, + 160,160,160,160,161,161,162,162,162,162,162,162,163,163,163,163, + 163,163,164,164,165,165,165,165,166,166,166,166,167,167,167,167, + 168,168,169,169,170,170,170,170,171,171,171,171,172,172,172,172, + 173,173,173,173,174,174,174,174,175,175,175,175,176, 21, 21, 21, + 177,177,177,178,178,178,178,179,179,179,179,180,180,180,181,181, + 182,182,182,182,183,183,183,183,183,184,184,184,185,185,185,185, + 185,186,186,186,187,187,187,187,187,187,188, 43,189,189,189,189, + 190,190,190,191,191,191,191,191,192,192,192,193,192,192,192,192, + 194,194,194,194,195,195,195,195,196,196,196,196,197,197,197,197, + 198,198,198,198,198,198, 66, 66,199,199,199,199,199, 49, 49, 49, + 200,200,200,200,201,201,201,201,202,202,202,202,203,203,203,203, + 204,204,204,204,205,205,205,205,205,206,206,206,206,206,206, 55, + 207,207,207,207,208,208,208,208,209,209,209,209,209,209,209,210, + 210,210,210,210,211,211,211,211,211,211,212,212,212,212,212,212, + 213,213,213,213,214,214,214,214,110,110,110,110,215,215,215,215, + 216,216,216,216,217,217,217,217,218,218,218,218,219,219,219,219, + 220,220,220,221,221,221,221,221,221,222,222,222,223,223,223,223, + 224,224,224,224,225,225,225,225,226,226,226,226,226,226,227, 94, + 228,228,228,228,229,229,229,229,230, 99, 99, 99, 99, 99, 99, 99, + 99, 99,102,231, 99,232,102,233,233,233,233,233,234,234,234,234, + 234,234, 0, 0, 8, 0, 0, 0, 0, 0,235,236,237, 0,238, 0, + 239,239,239,239, 91, 91, 91, 13,240,240,240,240,241,241,241,241, + 242,242,242,242,243,243,243,243,244,244,244,244,245,245,245,245, + 246,246,246,246,247, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 8, 10, 8, 11, 8, 8, 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, 14, 14, @@ -5123,98 +5347,102 @@ _hb_ucd_u8[13386] = 163,163,163,163,164,164,164,164,165,165,165,165,166,166,166,166, 167,167,167,167,168,168,168,168,169,169,169,169,170,170,170,170, 171,171,171,171,172,172,172,172,173,173,173,173,174,174,174,174, - 174,174,174,175,176,176,176,176,177,177,177,177,178,178,178,178, + 175,175,175,175,176,176,176,176,177, 20, 20, 20,178,178,178,178, 179,179,179,179,180,180,180,180,181,181,181,181,182,182,182,182, 183,183,183,183,184,184,184,184,185,185,185,185,186,186,186,186, - 187, 45, 45, 45,188,188,188,188,189,189,189,189,190,190,190,190, - 191,191,191,191,191,191,192,191,193,193,193,193,194,194,194,194, + 187,187,187,187,188,188,188,188,189, 45, 45, 45,190,190,190,190, + 191,191,191,191,192,192,192,192,193,193,193,193,193,193,194,193, 195,195,195,195,196,196,196,196,197,197,197,197,198,198,198,198, 199,199,199,199,200,200,200,200,201,201,201,201,202,202,202,202, 203,203,203,203,204,204,204,204,205,205,205,205,206,206,206,206, 207,207,207,207,208,208,208,208,209,209,209,209,210,210,210,210, 211,211,211,211,212,212,212,212,213,213,213,213,214,214,214,214, 215,215,215,215,216,216,216,216,217,217,217,217,218,218,218,218, - 219,219,219,219,220,220,220,220,221,221,221,221,222,223,223,223, - 224,224,224,224,223,223,223,223,225,106,106,106,226,106,106,106, - 106,227,109,109,228,228,228,228,229,229,229,229, 0,230, 86, 0, - 0, 0,230, 7, 82,138, 7, 0, 0, 0,231, 86,232,232,232,232, - 233,233,233,233,234,234,234,234,235,235,235,235,236,236,236,236, - 237,237,237,237,238,238,238,238,239, 0, 0, 0, 0, 0, 0, 0, - 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, - 19, 0, 0, 0, 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, - 0, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, - 55, 55, 55, 55, 6, 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, - 4, 4, 4, 4, 4, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, - 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, - 1, 1, 3, 3, 1, 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, - 64, 64, 64, 64, 90, 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, - 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, - 5, 5, 5, 5, 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, - 22, 22, 22, 22, 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, - 36, 36, 36, 36, 24, 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, - 25, 25, 25, 25, 25, 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, - 8, 8, 8, 8, 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, - 29, 29, 29, 29, 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, - 35, 35, 35, 0, 0, 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, - 44, 0, 0, 0, 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, - 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, - 52, 52, 52, 52, 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, - 62, 62, 62, 62, 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, - 73, 73, 73, 73, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 1, 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, - 19, 9, 9, 9, 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, - 19, 19, 19, 9, 0, 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, - 27, 27, 27, 27, 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, - 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, - 0, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, - 12, 12, 12, 0, 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, - 79, 79, 79, 79, 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, - 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, - 84, 84, 84, 0, 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, - 19, 9, 19, 19, 19, 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, - 3, 3, 0, 0, 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, - 49, 49, 49, 49, 0, 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, - 42, 42, 42, 42, 41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53, - 59, 59, 59, 59, 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50, - 135,135,135,135,106,106,106,106,104,104,104,104,161,161,161,161, + 219,219,219,219,220,220,220,220,221,221,221,221,222,222,222,222, + 223,223,223,223,224,224,224,224,225,225,225,225,226,226,226,226, + 227,227,227,227,228,229,229,229,230,230,230,230,229,229,229,229, + 231,106,106,106,232,106,106,106,106,233,109,109,234,234,234,234, + 235,235,235,235, 0,236, 86, 0, 0, 0,236, 7, 82,138, 7, 0, + 0, 0,237, 86,238,238,238,238,239,239,239,239,240,240,240,240, + 241,241,241,241,242,242,242,242,243,243,243,243,244,244,244,244, + 245,245,245,245,246, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, + 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, + 9, 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, 55, 55, + 6, 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, 4, 4, + 4, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 0, 3, 3, + 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, + 1, 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, 64, 64, 64, 64, + 90, 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, 7, 7, 7, 7, + 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, + 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, 22, 22, 22, 22, + 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, 36, 36, + 24, 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, 25, 25, 25, 25, + 25, 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, 8, 8, 8, 8, + 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 29, 29, 29, 29, + 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 0, + 0, 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, 44, 0, 0, 0, + 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, 32, 32, 0, 0, + 32, 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 52, 52, 52, 52, + 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, 62, 62, 62, 62, + 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 73, 73, 73, 73, + 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, + 1, 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, + 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, + 0, 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, + 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, 0, 13, 0, 13, + 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 0, 15, 15, 15, + 15, 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, 12, 0, + 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, + 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, 69, 69, 69, 69, + 69, 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, 84, 84, 84, 0, + 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, 19, 9, 19, 19, + 19, 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, 0, 0, + 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, 49, 49, + 0, 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, 42, 42, + 41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, 59, 59, + 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135,135,135, + 106,106,106,106,104,104,104,104,161,161,161,161,170,170,170,170, 110,110,110,110, 47, 47, 47, 47, 81, 81, 81, 81,120,120,120,120, 116,116,116,116,128,128,128,128, 66, 66, 66, 66, 72, 72, 72, 72, 98, 98, 98, 98, 97, 97, 97, 97, 57, 57, 57, 57, 88, 88, 88, 88, 117,117,117,117,112,112,112,112, 78, 78, 78, 78, 83, 83, 83, 83, 82, 82, 82, 82,122,122,122,122, 89, 89, 89, 89,130,130,130,130, - 144,144,144,144,156,156,156,156,156, 3, 3, 3,147,147,147,147, - 148,148,148,148,158,158,158,158,153,153,153,153,149,149,149,149, - 94, 94, 94, 94, 85, 85, 85, 85,101,101,101,101, 96, 96, 96, 96, - 111,111,111,111,100,100,100,100,100, 36, 36, 36,108,108,108,108, - 129,129,129,129,109,109,109,109,107,107,107,107,107,107,107, 1, - 137,137,137,137,124,124,124,124,123,123,123,123,114,114,114,114, - 102,102,102,102,126,126,126,126,142,142,142,142,125,125,125,125, - 154,154,154,154,150,150,150,150,141,141,141,141,140,140,140,140, - 121,121,121,121,133,133,133,133,134,134,134,134,138,138,138,138, - 143,143,143,143,145,145,145,145,163,163,163,163, 63, 63, 63, 63, - 157,157,157,157, 80, 80, 80, 80,127,127,127,127,115,115,115,115, - 159,159,159,159,103,103,103,103,119,119,119,119,146,146,146,146, - 99, 99, 99, 99,136,139, 13, 13,155,155,155,155,136,136,136,136, - 17, 15, 15, 15, 17, 17, 15, 15, 15, 17, 17, 17,139,139,139,139, - 105,105,105,105, 0, 0, 0, 1, 0, 0, 1, 1,131,131,131,131, - 151,151,151,151,160,160,160,160,152,152,152,152,164,164,164,164, - 113,113,113,113,132,132,132,132, 15, 0, 0, 0, 0, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, - 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 144,144,144,144,165,165,165,165,156,156,156,156,156,156, 3, 3, + 147,147,147,147,148,148,148,148,158,158,158,158,153,153,153,153, + 149,149,149,149, 94, 94, 94, 94, 85, 85, 85, 85,101,101,101,101, + 96, 96, 96, 96,111,111,111,111,100,100,100,100,100, 36, 36, 36, + 108,108,108,108,129,129,129,129,109,109,109,109,107,107,107,107, + 107,107,107, 1,171,171,171,171,137,137,137,137,124,124,124,124, + 123,123,123,123,114,114,114,114,102,102,102,102,126,126,126,126, + 142,142,142,142,125,125,125,125,154,154,154,154,150,150,150,150, + 141,141,141,141,140,140,140,140,121,121,121,121,169,169,169,169, + 133,133,133,133,134,134,134,134,138,138,138,138,143,143,143,143, + 145,145,145,145,163,163,163,163, 63, 63, 63, 63,157,157,157,157, + 80, 80, 80, 80,127,127,127,127,166,166,166,166,115,115,115,115, + 159,159,159,159,103,103,103,103,119,119,119,119,167,167,167,167, + 146,146,146,146, 99, 99, 99, 99,136,139, 13, 13,155,155,155,155, + 136,136,136,136, 17, 15, 15, 15, 17, 17, 15, 15, 15, 17, 17, 17, + 139,139,139,139,105,105,105,105, 0, 0, 0, 1, 0, 0, 1, 1, + 131,131,131,131,151,151,151,151,160,160,160,160,152,152,152,152, + 164,164,164,164,168,168,168,168,113,113,113,113,132,132,132,132, + 15, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, + 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 16, 17, 9, 9, 9, 9, 18, 9, 9, 9, 9, 9, 19, 20, 21, 9, + 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 23, 9, 9, 9, 9, 9, 24, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -5223,60 +5451,66 @@ _hb_ucd_u8[13386] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, - 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, - 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, + 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, + 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 45, - 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, - 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, - 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, - 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, - 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, + 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, + 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, + 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, - 0, 0, 0,105,106, 0,107, 0, 0, 0,108, 0,109, 0,110, 0, - 111,112,113, 0,114, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118,119, - 120,121, 0,122,123,124,125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,129,130,131,132,133, - 134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149, - 150,151,152,153,154,155,156,157, 0, 0, 0,158,159,160,161, 0, + 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100, + 101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, + 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0, + 115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,162,163, 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, + 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, + 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,165, 0, + 0, 0,128,129,130,131,132,133,134,135,136,137,138,139,140,141, + 142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157, + 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162, 0, + 163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, 0, 0, + 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,169, - 170, 0, 0, 0, 0,171,172, 0, 0, 0,173,174,175,176,177,178, - 179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194, - 195,196,197,198,199,200,201,202,203,204,205,206, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0,170, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 0, 0, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178,179, 0, + 0, 0,180,181,182,183,184,185,186,187,188,189,190,191,192,193, + 194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, + 210,211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, + 3, 4, }; static const uint16_t -_hb_ucd_u16[4920] = +_hb_ucd_u16[5080] = { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -5303,82 +5537,85 @@ _hb_ucd_u16[4920] = 47, 47, 165, 166, 167, 47, 47, 47, 47, 47, 47, 47, 47, 168, 146, 146, 47, 169, 47, 47, 47, 170, 171, 172, 160, 160, 173, 174, 32, 32, 32, 32, 175, 47, 47, 176, 177, 122, 178, 179, 180, 47, 181, 61, 47, 47, 182, 183, - 47, 47, 184, 185, 186, 61, 47, 187, 11, 9, 9, 9, 66, 188, 189, 190, - 11, 11, 191, 27, 27, 27, 192, 193, 11, 194, 27, 27, 32, 32, 32, 32, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 195, 13, 13, 13, 13, 13, 13, - 196, 196, 196, 196, 196, 197, 196, 11, 198, 198, 198, 199, 200, 201, 201, 200, - 202, 203, 204, 205, 206, 207, 208, 209, 210, 27, 211, 211, 211, 212, 213, 32, - 214, 215, 216, 217, 218, 145, 219, 219, 220, 221, 222, 146, 223, 224, 146, 225, - 226, 226, 226, 226, 226, 226, 226, 226, 227, 146, 228, 146, 146, 146, 146, 229, - 146, 230, 226, 231, 146, 232, 233, 146, 146, 146, 146, 146, 146, 146, 145, 145, - 145, 234, 146, 146, 146, 146, 235, 145, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 236, 237, 146, 146, 238, 146, 146, 146, 146, 146, 146, 239, 146, - 146, 146, 146, 146, 146, 146, 240, 241, 145, 242, 146, 146, 243, 226, 244, 226, - 245, 246, 226, 226, 226, 247, 226, 248, 146, 146, 146, 226, 249, 146, 146, 146, - 9, 9, 9, 11, 11, 11, 250, 251, 13, 13, 13, 13, 13, 13, 252, 253, - 11, 11, 11, 47, 47, 47, 254, 255, 47, 47, 47, 47, 47, 47, 32, 32, - 256, 257, 258, 259, 260, 261, 262, 262, 263, 264, 265, 266, 267, 47, 47, 47, - 47, 268, 148, 47, 47, 47, 47, 269, 47, 270, 47, 47, 146, 146, 146, 47, - 146, 146, 271, 146, 272, 273, 146, 146, 271, 146, 146, 273, 146, 146, 146, 146, - 47, 47, 47, 47, 146, 146, 146, 146, 47, 274, 47, 47, 47, 47, 47, 47, - 47, 146, 146, 146, 146, 47, 47, 187, 275, 47, 61, 47, 13, 13, 276, 277, - 13, 278, 47, 47, 47, 47, 279, 280, 31, 281, 282, 283, 13, 13, 13, 284, - 285, 286, 287, 288, 289, 290, 11, 291, 292, 47, 293, 294, 47, 47, 47, 295, - 296, 47, 47, 297, 298, 160, 32, 299, 61, 47, 300, 47, 301, 302, 47, 47, - 72, 47, 47, 303, 304, 305, 306, 61, 47, 47, 307, 308, 309, 310, 47, 311, - 47, 47, 47, 312, 58, 313, 314, 315, 47, 47, 47, 11, 11, 316, 317, 11, - 11, 11, 11, 11, 47, 47, 318, 160, 319, 319, 319, 319, 319, 319, 319, 319, - 320, 320, 320, 320, 320, 320, 320, 320, 11, 321, 322, 47, 47, 47, 47, 47, - 47, 47, 47, 323, 31, 324, 47, 47, 47, 47, 47, 325, 146, 47, 47, 47, - 47, 47, 47, 47, 326, 146, 146, 327, 32, 328, 32, 329, 330, 331, 332, 47, - 47, 47, 47, 47, 47, 47, 47, 333, 334, 2, 3, 4, 5, 335, 336, 337, - 47, 338, 47, 47, 47, 47, 339, 340, 341, 145, 145, 342, 219, 219, 219, 343, - 344, 146, 146, 146, 146, 146, 146, 345, 346, 346, 346, 346, 346, 346, 346, 346, - 47, 47, 47, 47, 47, 47, 347, 145, 47, 47, 348, 47, 349, 47, 47, 60, - 47, 350, 47, 47, 47, 351, 219, 219, 9, 9, 147, 11, 11, 47, 47, 47, - 47, 47, 160, 9, 9, 147, 11, 11, 47, 47, 47, 47, 47, 47, 350, 9, - 9, 352, 11, 11, 11, 11, 11, 11, 27, 27, 27, 27, 27, 27, 27, 27, - 47, 47, 47, 47, 47, 353, 47, 354, 47, 47, 355, 145, 145, 145, 47, 356, - 47, 357, 47, 350, 66, 66, 66, 66, 47, 47, 47, 358, 145, 145, 145, 145, - 359, 47, 47, 360, 145, 66, 47, 361, 47, 362, 145, 145, 363, 47, 364, 66, - 47, 47, 47, 365, 47, 366, 47, 366, 47, 365, 144, 145, 145, 145, 145, 145, - 9, 9, 9, 9, 11, 11, 11, 367, 47, 47, 368, 160, 160, 160, 160, 160, - 145, 145, 145, 145, 145, 145, 145, 145, 47, 47, 369, 47, 47, 47, 47, 143, - 47, 362, 370, 47, 60, 371, 66, 47, 372, 66, 66, 47, 373, 145, 47, 47, - 374, 47, 47, 360, 375, 376, 377, 378, 180, 47, 47, 379, 380, 47, 47, 160, - 97, 47, 381, 382, 383, 47, 47, 384, 180, 47, 47, 385, 386, 387, 388, 145, - 47, 47, 389, 390, 359, 32, 32, 32, 47, 47, 365, 47, 47, 391, 172, 160, - 92, 47, 47, 113, 392, 393, 394, 32, 47, 47, 47, 395, 396, 397, 47, 47, - 47, 47, 47, 398, 399, 160, 160, 160, 47, 47, 400, 401, 402, 403, 32, 32, - 47, 47, 47, 404, 405, 160, 66, 66, 47, 47, 406, 407, 160, 160, 160, 160, - 47, 143, 408, 409, 47, 47, 47, 47, 47, 47, 389, 410, 66, 66, 66, 66, - 9, 9, 9, 9, 11, 11, 128, 411, 47, 47, 47, 412, 413, 160, 160, 160, - 47, 47, 47, 47, 47, 414, 415, 416, 417, 47, 47, 418, 419, 420, 47, 47, - 421, 422, 66, 47, 47, 47, 47, 47, 66, 66, 66, 66, 66, 66, 66, 66, - 47, 47, 400, 423, 424, 128, 145, 425, 47, 156, 426, 427, 32, 32, 32, 32, - 47, 47, 47, 359, 428, 160, 47, 47, 429, 430, 160, 160, 160, 160, 160, 160, - 47, 47, 47, 47, 47, 47, 47, 431, 432, 47, 47, 433, 434, 160, 160, 160, - 47, 47, 47, 47, 145, 435, 436, 437, 219, 219, 219, 219, 219, 219, 219, 66, - 47, 47, 47, 47, 47, 47, 47, 424, 47, 47, 47, 208, 438, 32, 32, 32, - 47, 47, 47, 47, 47, 47, 305, 47, 47, 47, 47, 47, 160, 47, 47, 439, - 47, 47, 47, 440, 441, 442, 443, 47, 9, 9, 9, 9, 9, 9, 11, 11, - 145, 444, 66, 66, 66, 66, 66, 66, 47, 47, 47, 47, 391, 445, 416, 416, - 446, 447, 27, 27, 27, 27, 448, 416, 47, 449, 208, 208, 208, 208, 208, 208, - 32, 32, 32, 32, 32, 146, 146, 146, 146, 146, 146, 146, 146, 146, 450, 451, - 452, 146, 453, 146, 146, 146, 146, 146, 146, 146, 146, 146, 454, 146, 146, 146, - 9, 455, 11, 456, 457, 11, 196, 9, 458, 459, 9, 460, 11, 9, 455, 11, - 456, 457, 11, 196, 9, 458, 459, 9, 460, 11, 9, 455, 11, 456, 457, 11, - 196, 9, 458, 459, 9, 460, 11, 9, 455, 11, 196, 9, 461, 462, 463, 464, - 11, 465, 9, 466, 467, 468, 469, 11, 470, 9, 471, 11, 472, 160, 160, 160, - 32, 32, 32, 473, 32, 32, 474, 475, 476, 477, 32, 32, 32, 32, 32, 32, - 478, 11, 11, 11, 11, 11, 11, 11, 32, 32, 32, 27, 27, 27, 27, 27, - 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 47, 479, 480, 146, 146, 146, - 47, 47, 481, 32, 47, 47, 482, 483, 47, 47, 47, 47, 47, 47, 484, 160, - 47, 47, 47, 47, 355, 32, 32, 32, 9, 9, 458, 11, 485, 305, 66, 66, - 145, 145, 486, 487, 145, 145, 145, 145, 145, 145, 488, 145, 145, 145, 145, 145, - 47, 47, 47, 47, 47, 47, 47, 226, 489, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 490, 146, 146, 146, 146, 146, 146, 146, 160, - 208, 208, 208, 208, 208, 208, 208, 208, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 184, 185, 186, 61, 47, 187, 188, 9, 9, 9, 66, 189, 190, 191, + 11, 11, 192, 27, 27, 27, 193, 194, 11, 195, 27, 27, 32, 32, 32, 32, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 196, 13, 13, 13, 13, 13, 13, + 197, 197, 197, 197, 197, 198, 197, 11, 199, 199, 199, 200, 201, 202, 202, 201, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 27, 212, 212, 212, 213, 214, 32, + 215, 216, 217, 218, 219, 145, 220, 220, 221, 222, 223, 146, 224, 225, 146, 226, + 227, 227, 227, 227, 227, 227, 227, 227, 228, 146, 229, 146, 146, 146, 146, 230, + 146, 231, 227, 232, 146, 233, 234, 146, 146, 146, 146, 146, 146, 146, 145, 145, + 145, 235, 146, 146, 146, 146, 236, 145, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 237, 238, 146, 146, 239, 146, 146, 146, 146, 146, 146, 240, 146, + 146, 146, 146, 146, 146, 146, 241, 242, 145, 243, 146, 146, 244, 227, 245, 227, + 246, 247, 227, 227, 227, 248, 227, 249, 146, 146, 146, 227, 250, 146, 146, 146, + 9, 9, 9, 11, 11, 11, 251, 252, 13, 13, 13, 13, 13, 13, 253, 254, + 11, 11, 11, 47, 47, 47, 255, 256, 47, 47, 47, 47, 47, 47, 32, 32, + 257, 258, 259, 260, 261, 262, 263, 263, 264, 265, 266, 267, 268, 47, 47, 47, + 47, 269, 148, 47, 47, 47, 47, 270, 47, 271, 47, 47, 146, 146, 146, 47, + 146, 146, 272, 146, 273, 274, 146, 146, 272, 146, 146, 274, 146, 146, 146, 146, + 47, 47, 47, 47, 146, 146, 146, 146, 47, 275, 47, 47, 47, 47, 47, 47, + 47, 146, 146, 146, 146, 47, 47, 187, 276, 47, 61, 47, 13, 13, 277, 278, + 13, 279, 47, 47, 47, 47, 280, 281, 31, 282, 283, 284, 13, 13, 13, 285, + 286, 287, 288, 289, 290, 291, 9, 292, 293, 47, 294, 295, 47, 47, 47, 296, + 297, 47, 47, 298, 299, 160, 32, 300, 61, 47, 301, 47, 302, 303, 47, 47, + 72, 47, 47, 304, 305, 306, 307, 61, 47, 47, 308, 309, 310, 311, 47, 312, + 47, 47, 47, 313, 58, 314, 315, 316, 47, 47, 47, 11, 11, 317, 318, 11, + 11, 11, 11, 11, 47, 47, 319, 160, 320, 320, 320, 320, 320, 320, 320, 320, + 321, 321, 321, 321, 321, 321, 321, 321, 11, 322, 323, 47, 47, 47, 47, 47, + 47, 47, 47, 324, 31, 325, 47, 47, 47, 47, 47, 326, 146, 47, 47, 47, + 47, 47, 47, 47, 327, 146, 146, 328, 32, 329, 32, 330, 331, 332, 333, 47, + 47, 47, 47, 47, 47, 47, 47, 334, 335, 2, 3, 4, 5, 336, 337, 338, + 47, 339, 47, 47, 47, 47, 340, 341, 342, 145, 145, 343, 220, 220, 220, 344, + 345, 146, 146, 146, 146, 146, 146, 346, 347, 347, 347, 347, 347, 347, 347, 347, + 47, 47, 47, 47, 47, 47, 348, 145, 47, 47, 349, 47, 350, 47, 47, 60, + 47, 351, 47, 47, 47, 352, 220, 220, 9, 9, 147, 11, 11, 47, 47, 47, + 47, 47, 160, 9, 9, 147, 11, 11, 47, 47, 47, 47, 47, 47, 351, 9, + 9, 353, 11, 11, 47, 47, 47, 47, 27, 27, 27, 27, 27, 27, 27, 27, + 47, 47, 47, 47, 47, 354, 47, 355, 47, 47, 356, 145, 145, 145, 47, 357, + 47, 358, 47, 351, 66, 66, 66, 66, 47, 47, 47, 359, 145, 145, 145, 145, + 360, 47, 47, 361, 145, 66, 47, 362, 47, 363, 145, 145, 364, 47, 365, 66, + 47, 47, 47, 366, 47, 367, 47, 367, 47, 366, 144, 145, 145, 145, 145, 145, + 9, 9, 9, 9, 11, 11, 11, 368, 47, 47, 369, 160, 370, 9, 371, 11, + 372, 227, 227, 227, 227, 227, 227, 227, 145, 145, 145, 145, 145, 145, 145, 145, + 47, 47, 373, 47, 47, 47, 47, 374, 47, 363, 375, 47, 60, 376, 66, 47, + 377, 66, 66, 47, 378, 145, 47, 47, 379, 47, 47, 361, 380, 381, 382, 383, + 180, 47, 47, 384, 385, 47, 47, 160, 97, 47, 386, 387, 388, 47, 47, 389, + 180, 47, 47, 390, 391, 392, 393, 145, 47, 47, 394, 395, 360, 32, 32, 32, + 47, 47, 366, 47, 47, 396, 172, 160, 92, 47, 47, 113, 397, 398, 399, 32, + 47, 47, 47, 400, 401, 402, 403, 32, 47, 47, 47, 404, 405, 406, 47, 47, + 47, 47, 47, 407, 408, 160, 160, 160, 47, 47, 409, 410, 411, 412, 32, 32, + 47, 47, 47, 413, 414, 160, 66, 66, 47, 47, 415, 416, 160, 160, 160, 160, + 47, 417, 418, 419, 47, 47, 47, 47, 47, 47, 394, 420, 66, 66, 66, 66, + 9, 9, 9, 9, 11, 11, 128, 421, 47, 47, 47, 422, 423, 160, 160, 160, + 47, 47, 47, 47, 47, 424, 425, 426, 427, 47, 47, 428, 429, 430, 47, 47, + 431, 432, 66, 47, 47, 47, 47, 47, 66, 66, 66, 66, 66, 66, 66, 66, + 47, 47, 47, 47, 47, 47, 433, 160, 47, 47, 409, 434, 433, 128, 145, 435, + 47, 156, 436, 437, 32, 32, 32, 32, 47, 47, 47, 360, 438, 160, 47, 47, + 439, 440, 160, 160, 160, 160, 160, 160, 47, 47, 47, 47, 47, 47, 47, 441, + 442, 47, 47, 443, 444, 445, 32, 32, 47, 47, 47, 47, 145, 446, 447, 448, + 220, 220, 220, 220, 220, 220, 220, 66, 47, 47, 47, 47, 47, 47, 47, 433, + 47, 47, 47, 209, 449, 32, 47, 47, 47, 450, 451, 160, 160, 160, 160, 160, + 47, 47, 47, 47, 47, 47, 306, 47, 47, 47, 47, 47, 160, 47, 47, 452, + 47, 47, 47, 453, 454, 455, 456, 47, 27, 27, 27, 27, 457, 47, 458, 160, + 9, 9, 9, 9, 9, 9, 11, 11, 145, 459, 66, 66, 66, 66, 66, 66, + 47, 47, 47, 47, 396, 460, 426, 426, 461, 462, 27, 27, 27, 27, 463, 426, + 47, 464, 209, 209, 209, 209, 209, 209, 146, 146, 146, 146, 146, 146, 146, 160, + 32, 32, 32, 32, 32, 146, 146, 146, 146, 146, 146, 146, 146, 146, 465, 466, + 467, 146, 468, 146, 146, 146, 146, 146, 146, 146, 146, 146, 469, 146, 146, 146, + 9, 470, 11, 471, 472, 11, 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, + 471, 472, 11, 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, 471, 472, 11, + 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, 197, 9, 476, 477, 478, 479, + 11, 480, 9, 481, 482, 483, 484, 11, 485, 9, 486, 11, 487, 160, 160, 160, + 32, 32, 32, 488, 32, 32, 489, 490, 491, 492, 32, 32, 32, 32, 32, 32, + 493, 11, 11, 11, 11, 11, 11, 11, 32, 32, 32, 27, 27, 27, 27, 27, + 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 47, 494, 495, 146, 146, 146, + 47, 47, 450, 32, 47, 47, 374, 496, 47, 47, 47, 47, 47, 47, 497, 160, + 47, 47, 47, 47, 47, 47, 450, 498, 47, 47, 47, 47, 356, 32, 32, 32, + 9, 9, 473, 11, 499, 306, 66, 66, 145, 145, 500, 501, 145, 145, 145, 145, + 145, 145, 502, 145, 145, 145, 145, 145, 47, 47, 47, 47, 47, 47, 47, 227, + 503, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 504, + 209, 209, 209, 209, 209, 209, 209, 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147, @@ -5541,16 +5778,23 @@ _hb_ucd_u16[4920] = 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0, 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599, 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954,1955, 0, 0, 0, + 0,1936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1937, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1938, 0,1939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1943,1944, 0, 0, 0, 0, 0, 0,1945, 0,1946, 0, 0, + 0, 0, 0, 0, 0, 0,1947, 0, 0,1948, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1950, 0,1949, + 1951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1953,1952, 0,1954, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1955,1956, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1957, 0, 0, 0, 0, 0, 0, 0, 0,1958,1961,1959,1965,1960,1962,1964, + 1963, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1967,1966,1968, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1969,1970,1971,1972,1973,1974,1975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1976,1977,1978,1980,1979,1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, @@ -5601,12 +5845,12 @@ _hb_ucd_i16[92] = static inline uint_fast8_t _hb_ucd_gc (unsigned u) { - return u<1114112u?_hb_ucd_u8[5096+(((_hb_ucd_u8[1168+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + return u<1114112u?_hb_ucd_u8[5208+(((_hb_ucd_u8[1168+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; } static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[7054+(((_hb_ucd_u8[6498+(((_hb_ucd_u8[6038+(((_hb_ucd_u8[5686+(((_hb_ucd_u8[5440+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + return u<125259u?_hb_ucd_u8[7206+(((_hb_ucd_u8[6638+(((_hb_ucd_u8[6162+(((_hb_ucd_u8[5802+(((_hb_ucd_u8[5556+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -5616,17 +5860,17 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7946+(((_hb_ucd_u8[7714+(((_hb_ucd_u8[7618+(((_hb_ucd_b4(7554+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[8098+(((_hb_ucd_u8[7866+(((_hb_ucd_u8[7770+(((_hb_ucd_b4(7706+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918016u?_hb_ucd_u8[11244+(((_hb_ucd_u8[10280+(((_hb_ucd_u8[9292+(((_hb_ucd_u8[8612+(((_hb_ucd_u8[8308+(((_hb_ucd_u8[8194+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15u))])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; + return u<918016u?_hb_ucd_u8[11464+(((_hb_ucd_u8[10472+(((_hb_ucd_u8[9452+(((_hb_ucd_u8[8764+(((_hb_ucd_u8[8460+(((_hb_ucd_u8[8346+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15u))])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[1608+(((_hb_ucd_u8[12586+(((_hb_ucd_u8[12204+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102u?_hb_ucd_u16[1656+(((_hb_ucd_u8[12834+(((_hb_ucd_u8[12452+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; } #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh index e607e8ca8290d..4bc8d64c28f8a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh @@ -7,13 +7,13 @@ * on file with this header: * * # emoji-data.txt - * # Date: 2023-02-01, 02:22:54 GMT - * # © 2023 Unicode®, Inc. + * # Date: 2024-05-01, 21:25:24 GMT + * # © 2024 Unicode®, Inc. * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. - * # For terms of use, see https://www.unicode.org/terms_of_use.html + * # For terms of use and license, see https://www.unicode.org/terms_of_use.html * # * # Emoji Data for UTS #51 - * # Used with Emoji Version 15.1 and subsequent minor revisions (if any) + * # Used with Emoji Version 16.0 and subsequent minor revisions (if any) * # * # For documentation and usage, see https://www.unicode.org/reports/tr51 */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-utf.hh b/src/java.desktop/share/native/libharfbuzz/hb-utf.hh index 9175df265b9d1..7fd3bf8828b21 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-utf.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-utf.hh @@ -458,19 +458,21 @@ struct hb_ascii_t template static inline const typename utf_t::codepoint_t * hb_utf_offset_to_pointer (const typename utf_t::codepoint_t *start, + const typename utf_t::codepoint_t *text, + unsigned text_len, signed offset) { hb_codepoint_t unicode; while (offset-- > 0) start = utf_t::next (start, - start + utf_t::max_len, + text + text_len, &unicode, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT); while (offset++ < 0) start = utf_t::prev (start, - start - utf_t::max_len, + text, &unicode, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-vector.hh b/src/java.desktop/share/native/libharfbuzz/hb-vector.hh index 001789a3037b4..7e755818ddd3f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-vector.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-vector.hh @@ -37,6 +37,8 @@ template struct hb_vector_t { + static constexpr bool realloc_move = true; + typedef Type item_t; static constexpr unsigned item_size = hb_static_size (Type); using array_t = typename std::conditional, hb_array_t>::type; @@ -51,32 +53,29 @@ struct hb_vector_t } template - hb_vector_t (const Iterable &o) : hb_vector_t () + explicit hb_vector_t (const Iterable &o) : hb_vector_t () { - auto iter = hb_iter (o); - if (iter.is_random_access_iterator || iter.has_fast_len) - alloc (hb_len (iter), true); - hb_copy (iter, *this); + extend (o); } hb_vector_t (const hb_vector_t &o) : hb_vector_t () { - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o.as_array ()); } hb_vector_t (array_t o) : hb_vector_t () { - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o); } hb_vector_t (c_array_t o) : hb_vector_t () { - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o); } - hb_vector_t (hb_vector_t &&o) + hb_vector_t (hb_vector_t &&o) noexcept { allocated = o.allocated; length = o.length; @@ -85,6 +84,35 @@ struct hb_vector_t } ~hb_vector_t () { fini (); } + template + void extend (const Iterable &o) + { + auto iter = hb_iter (o); + if (iter.is_random_access_iterator || iter.has_fast_len) + alloc (hb_len (iter), true); + while (iter) + { + if (unlikely (!alloc (length + 1))) + return; + unsigned room = allocated - length; + for (unsigned i = 0; i < room && iter; i++) + push_has_room (*iter++); + } + } + void extend (array_t o) + { + alloc (length + o.length); + if (unlikely (in_error ())) return; + copy_array (o); + } + void extend (c_array_t o) + { + alloc (length + o.length); + if (unlikely (in_error ())) return; + copy_array (o); + } + public: int allocated = 0; /* < 0 means allocation failed. */ unsigned int length = 0; @@ -120,7 +148,7 @@ struct hb_vector_t resize (0); } - friend void swap (hb_vector_t& a, hb_vector_t& b) + friend void swap (hb_vector_t& a, hb_vector_t& b) noexcept { hb_swap (a.allocated, b.allocated); hb_swap (a.length, b.length); @@ -130,14 +158,15 @@ struct hb_vector_t hb_vector_t& operator = (const hb_vector_t &o) { reset (); - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return *this; + length = 0; copy_array (o.as_array ()); return *this; } - hb_vector_t& operator = (hb_vector_t &&o) + hb_vector_t& operator = (hb_vector_t &&o) noexcept { hb_swap (*this, o); return *this; @@ -216,6 +245,10 @@ struct hb_vector_t // reference to it. return std::addressof (Crap (Type)); + return push_has_room (std::forward (args)...); + } + template Type *push_has_room (Args&&... args) + { /* Emplace. */ Type *p = std::addressof (arrayZ[length++]); return new (p) Type (std::forward (args)...); @@ -268,10 +301,9 @@ struct hb_vector_t } return new_array; } - /* Specialization for hb_vector_t> to speed up. */ + /* Specialization for types that can be moved using realloc(). */ template ) || - hb_is_same (T, hb_array_t ))> + hb_enable_if (T::realloc_move)> Type * realloc_vector (unsigned new_allocated, hb_priority<1>) { @@ -310,18 +342,23 @@ struct hb_vector_t length = size; } + template + void + copy_array (hb_array_t other) + { + assert ((int) (length + other.length) <= allocated); + hb_memcpy ((void *) (arrayZ + length), (const void *) other.arrayZ, other.length * item_size); + length += other.length; + } template void copy_array (hb_array_t other) { - length = other.length; - if (!HB_OPTIMIZE_SIZE_VAL && sizeof (T) >= sizeof (long long)) - /* This runs faster because of alignment. */ - for (unsigned i = 0; i < length; i++) - arrayZ[i] = other.arrayZ[i]; - else - hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size); + assert ((int) (length + other.length) <= allocated); + hb_memcpy ((void *) (arrayZ + length), (const void *) other.arrayZ, other.length * item_size); + length += other.length; } template other) { - length = 0; - while (length < other.length) - { - length++; - new (std::addressof (arrayZ[length - 1])) Type (other.arrayZ[length - 1]); - } + assert ((int) (length + other.length) <= allocated); + for (unsigned i = 0; i < other.length; i++) + new (std::addressof (arrayZ[length + i])) Type (other.arrayZ[i]); + length += other.length; } template other) { - length = 0; - while (length < other.length) + assert ((int) (length + other.length) <= allocated); + for (unsigned i = 0; i < other.length; i++) { - length++; - new (std::addressof (arrayZ[length - 1])) Type (); - arrayZ[length - 1] = other.arrayZ[length - 1]; + new (std::addressof (arrayZ[length + i])) Type (); + arrayZ[length + i] = other.arrayZ[i]; } + length += other.length; } void @@ -431,6 +466,15 @@ struct hb_vector_t return true; } + bool alloc_exact (unsigned int size) + { + return alloc (size, true); + } + + void clear () + { + resize (0); + } bool resize (int size_, bool initialize = true, bool exact = false) { @@ -496,7 +540,7 @@ struct hb_vector_t shrink_vector (size); if (shrink_memory) - alloc (size, true); /* To force shrinking memory if needed. */ + alloc_exact (size); /* To force shrinking memory if needed. */ } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-version.h b/src/java.desktop/share/native/libharfbuzz/hb-version.h index 3627da3bf0ce7..01edf174350b7 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-version.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-version.h @@ -41,26 +41,26 @@ HB_BEGIN_DECLS * * The major component of the library version available at compile-time. */ -#define HB_VERSION_MAJOR 8 +#define HB_VERSION_MAJOR 10 /** * HB_VERSION_MINOR: * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 2 +#define HB_VERSION_MINOR 4 /** * HB_VERSION_MICRO: * * The micro component of the library version available at compile-time. */ -#define HB_VERSION_MICRO 2 +#define HB_VERSION_MICRO 0 /** * HB_VERSION_STRING: * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "8.2.2" +#define HB_VERSION_STRING "10.4.0" /** * HB_VERSION_ATLEAST: diff --git a/src/java.desktop/share/native/libharfbuzz/hb.hh b/src/java.desktop/share/native/libharfbuzz/hb.hh index 65d2dd58a2039..fee1c9cd663bb 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb.hh @@ -64,6 +64,7 @@ #pragma GCC diagnostic error "-Wbitwise-instead-of-logical" #pragma GCC diagnostic error "-Wcast-align" #pragma GCC diagnostic error "-Wcast-function-type" +#pragma GCC diagnostic error "-Wcast-function-type-strict" #pragma GCC diagnostic error "-Wconstant-conversion" #pragma GCC diagnostic error "-Wcomma" #pragma GCC diagnostic error "-Wdelete-non-virtual-dtor" @@ -83,6 +84,7 @@ #pragma GCC diagnostic error "-Wredundant-decls" #pragma GCC diagnostic error "-Wreorder" #pragma GCC diagnostic error "-Wsign-compare" +#pragma GCC diagnostic error "-Wstrict-flex-arrays" #pragma GCC diagnostic error "-Wstrict-prototypes" #pragma GCC diagnostic error "-Wstring-conversion" #pragma GCC diagnostic error "-Wswitch-enum" @@ -129,6 +131,7 @@ #pragma GCC diagnostic ignored "-Wclass-memaccess" #pragma GCC diagnostic ignored "-Wcast-function-type-strict" // https://github.com/harfbuzz/harfbuzz/pull/3859#issuecomment-1295409126 #pragma GCC diagnostic ignored "-Wdangling-reference" // https://github.com/harfbuzz/harfbuzz/issues/4043 +#pragma GCC diagnostic ignored "-Wdangling-pointer" // Trigerred by hb_decycler_node_t(). #pragma GCC diagnostic ignored "-Wformat-nonliteral" #pragma GCC diagnostic ignored "-Wformat-zero-length" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" @@ -177,6 +180,11 @@ #define HB_EXTERN __declspec (dllexport) extern #endif +// https://github.com/harfbuzz/harfbuzz/pull/4619 +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS 1 +#endif + #include "hb.h" #define HB_H_IN #include "hb-ot.h" @@ -212,6 +220,12 @@ #include #endif +#ifndef PRId32 +# define PRId32 "d" +# define PRIu32 "u" +# define PRIx32 "x" +#endif + #define HB_PASTE1(a,b) a##b #define HB_PASTE(a,b) HB_PASTE1(a,b) @@ -268,7 +282,9 @@ extern "C" void hb_free_impl(void *ptr); #define __attribute__(x) #endif -#if defined(__GNUC__) && (__GNUC__ >= 3) +#if defined(__MINGW32__) && (__GNUC__ >= 3) +#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (gnu_printf, format_idx, arg_idx))) +#elif defined(__GNUC__) && (__GNUC__ >= 3) #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) #else #define HB_PRINTF_FUNC(format_idx, arg_idx) From 025da55defb4428a0cbc75b24842513011f1220d Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 2 Apr 2025 11:27:59 +0000 Subject: [PATCH 116/846] 8348598: Update Libpng to 1.6.47 Reviewed-by: phh Backport-of: 6b82b42a2116900b2125e03c1ffa0824d6062757 --- .../java.desktop/lib/Awt2dLibraries.gmk | 2 +- src/java.desktop/share/legal/libpng.md | 7 +- .../native/libsplashscreen/libpng/CHANGES | 55 + .../native/libsplashscreen/libpng/LICENSE | 4 +- .../native/libsplashscreen/libpng/README | 4 +- .../share/native/libsplashscreen/libpng/png.c | 1401 ++++--------- .../share/native/libsplashscreen/libpng/png.h | 143 +- .../native/libsplashscreen/libpng/pngconf.h | 10 +- .../native/libsplashscreen/libpng/pngerror.c | 35 +- .../native/libsplashscreen/libpng/pngget.c | 308 ++- .../native/libsplashscreen/libpng/pnginfo.h | 52 +- .../libsplashscreen/libpng/pnglibconf.h | 4 +- .../native/libsplashscreen/libpng/pngmem.c | 37 +- .../native/libsplashscreen/libpng/pngpread.c | 204 +- .../native/libsplashscreen/libpng/pngpriv.h | 467 ++--- .../native/libsplashscreen/libpng/pngread.c | 351 +--- .../native/libsplashscreen/libpng/pngrtran.c | 337 +-- .../native/libsplashscreen/libpng/pngrutil.c | 1866 +++++++++-------- .../native/libsplashscreen/libpng/pngset.c | 295 ++- .../native/libsplashscreen/libpng/pngstruct.h | 96 +- 20 files changed, 2694 insertions(+), 2984 deletions(-) diff --git a/make/modules/java.desktop/lib/Awt2dLibraries.gmk b/make/modules/java.desktop/lib/Awt2dLibraries.gmk index eef8ae5990b1e..4ac1ea6acb943 100644 --- a/make/modules/java.desktop/lib/Awt2dLibraries.gmk +++ b/make/modules/java.desktop/lib/Awt2dLibraries.gmk @@ -773,7 +773,7 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false) maybe-uninitialized shift-negative-value implicit-fallthrough \ unused-function, \ DISABLED_WARNINGS_clang := incompatible-pointer-types sign-compare \ - deprecated-declarations null-pointer-subtraction deprecated-non-prototype $(LIBZ_DISABLED_WARNINGS_CLANG), \ + deprecated-declarations null-pointer-subtraction deprecated-non-prototype unused-function $(LIBZ_DISABLED_WARNINGS_CLANG), \ DISABLED_WARNINGS_microsoft := 4018 4244 4267, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ diff --git a/src/java.desktop/share/legal/libpng.md b/src/java.desktop/share/legal/libpng.md index cbffed8133209..d43ccf2e8e49e 100644 --- a/src/java.desktop/share/legal/libpng.md +++ b/src/java.desktop/share/legal/libpng.md @@ -1,4 +1,4 @@ -## libpng v1.6.43 +## libpng v1.6.47 ### libpng License
@@ -9,8 +9,8 @@ COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
 PNG Reference Library License version 2
 ---------------------------------------
 
-Copyright (C) 1995-2024 The PNG Reference Library Authors.
-Copyright (C) 2018-2024 Cosmin Truta
+Copyright (c) 1995-2025 The PNG Reference Library Authors.
+Copyright (C) 2018-2025 Cosmin Truta
 Copyright (C) 1998-2018 Glenn Randers-Pehrson
 Copyright (C) 1996-1997 Andreas Dilger
 Copyright (C) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -170,6 +170,7 @@ Authors, for copyright and licensing purposes.
  * James Yu
  * John Bowler
  * Kevin Bracey
+ * Lucas Chollet
  * Magnus Holmgren
  * Mandar Sahastrabuddhe
  * Mans Rullgard
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES b/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
index 441b57ecf1ab2..834b5e19277a4 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
@@ -6196,6 +6196,61 @@ Version 1.6.43 [February 23, 2024]
     consistency verification and text linting.
   Added version consistency verification to pngtest.c also.
 
+Version 1.6.44 [September 12, 2024]
+  Hardened calculations in chroma handling to prevent overflows, and
+    relaxed a constraint in cHRM validation to accomodate the standard
+    ACES AP1 set of color primaries.
+    (Contributed by John Bowler)
+  Removed the ASM implementation of ARM Neon optimizations and updated
+    the build accordingly. Only the remaining C implementation shall be
+    used from now on, thus ensuring the support of the PAC/BTI security
+    features on ARM64.
+    (Contributed by Ross Burton and John Bowler)
+  Fixed the pickup of the PNG_HARDWARE_OPTIMIZATIONS option in the
+    CMake build on FreeBSD/amd64. This is an important performance fix
+    on this platform.
+  Applied various fixes and improvements to the CMake build.
+    (Contributed by Eric Riff, Benjamin Buch and Erik Scholz)
+  Added fuzzing targets for the simplified read API.
+    (Contributed by Mikhail Khachayants)
+  Fixed a build error involving pngtest.c under a custom config.
+    This was a regression introduced in a code cleanup in libpng-1.6.43.
+    (Contributed by Ben Wagner)
+  Fixed and improved the config files for AppVeyor CI and Travis CI.
+
+Version 1.6.45 [January 7, 2025]
+  Added support for the cICP chunk.
+    (Contributed by Lucas Chollet and John Bowler)
+  Adjusted and improved various checks in colorspace calculations.
+    (Contributed by John Bowler)
+  Rearranged the write order of colorspace chunks for better conformance
+    with the PNG v3 draft specification.
+    (Contributed by John Bowler)
+  Raised the minimum required CMake version from 3.6 to 3.14.
+  Forked off a development branch for libpng version 1.8.
+
+Version 1.6.46 [January 23, 2025]
+  Added support for the mDCV and cLLI chunks.
+    (Contributed by John Bowler)
+  Fixed a build issue affecting C89 compilers.
+    This was a regression introduced in libpng-1.6.45.
+    (Contributed by John Bowler)
+  Added makefile.c89, specifically for testing C89 compilers.
+  Cleaned up contrib/pngminus: corrected an old typo, removed an old
+    workaround, and updated the CMake file.
+
+Version 1.6.47 [February 18, 2025]
+  Modified the behaviour of colorspace chunks in order to adhere
+    to the new precedence rules formulated in the latest draft of
+    the PNG Specification.
+    (Contributed by John Bowler)
+  Fixed a latent bug in `png_write_iCCP`.
+    This would have been a read-beyond-end-of-malloc vulnerability,
+    introduced early in the libpng-1.6.0 development, yet (fortunately!)
+    it was inaccessible before the above-mentioned modification of the
+    colorspace precedence rules, due to pre-existing colorspace checks.
+    (Reported by Bob Friesenhahn; fixed by John Bowler)
+
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
 Subscription is required; visit
 https://lists.sourceforge.net/lists/listinfo/png-mng-implement
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE b/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE
index 25f298f0fcfd8..ea6df986cb6a7 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE
@@ -4,8 +4,8 @@ COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
 PNG Reference Library License version 2
 ---------------------------------------
 
- * Copyright (c) 1995-2024 The PNG Reference Library Authors.
- * Copyright (c) 2018-2024 Cosmin Truta.
+ * Copyright (c) 1995-2025 The PNG Reference Library Authors.
+ * Copyright (c) 2018-2025 Cosmin Truta.
  * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
  * Copyright (c) 1996-1997 Andreas Dilger.
  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/README b/src/java.desktop/share/native/libsplashscreen/libpng/README
index a6ca3ae9f9406..57952fb215aef 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/README
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/README
@@ -1,4 +1,4 @@
-README for libpng version 1.6.43
+README for libpng version 1.6.47
 ================================
 
 See the note about version numbers near the top of `png.h`.
@@ -157,8 +157,6 @@ Files included in this distribution
                           "PNG: The Definitive Guide" by Greg Roelofs,
                           O'Reilly, 1999
         libtests/     =>  Test programs
-        oss-fuzz/     =>  Files used by the OSS-Fuzz project for fuzz-testing
-                          libpng
         pngexif/      =>  Program to inspect the EXIF information in PNG files
         pngminim/     =>  Minimal decoder, encoder, and progressive decoder
                           programs demonstrating the use of pngusr.dfa
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/png.c b/src/java.desktop/share/native/libsplashscreen/libpng/png.c
index 232dff876c793..7b6de2f8ec3a7 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/png.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/png.c
@@ -29,7 +29,7 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Copyright (c) 2018-2024 Cosmin Truta
+ * Copyright (c) 2018-2025 Cosmin Truta
  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
  * Copyright (c) 1996-1997 Andreas Dilger
  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -42,7 +42,34 @@
 #include "pngpriv.h"
 
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_43 Your_png_h_is_not_version_1_6_43;
+typedef png_libpng_version_1_6_47 Your_png_h_is_not_version_1_6_47;
+
+/* Sanity check the chunks definitions - PNG_KNOWN_CHUNKS from pngpriv.h and the
+ * corresponding macro definitions.  This causes a compile time failure if
+ * something is wrong but generates no code.
+ *
+ * (1) The first check is that the PNG_CHUNK(cHNK, index) 'index' values must
+ * increment from 0 to the last value.
+ */
+#define PNG_CHUNK(cHNK, index) != (index) || ((index)+1)
+
+#if 0 PNG_KNOWN_CHUNKS < 0
+#  error PNG_KNOWN_CHUNKS chunk definitions are not in order
+#endif
+
+#undef PNG_CHUNK
+
+/* (2) The chunk name macros, png_cHNK, must all be valid and defined.  Since
+ * this is a preprocessor test undefined pp-tokens come out as zero and will
+ * fail this test.
+ */
+#define PNG_CHUNK(cHNK, index) !PNG_CHUNK_NAME_VALID(png_ ## cHNK) ||
+
+#if PNG_KNOWN_CHUNKS 0
+#  error png_cHNK not defined for some known cHNK
+#endif
+
+#undef PNG_CHUNK
 
 /* Tells libpng that we have already handled the first "num_bytes" bytes
  * of the PNG file signature.  If the PNG data is embedded into another
@@ -270,21 +297,23 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
     */
    memset(&create_struct, 0, (sizeof create_struct));
 
-   /* Added at libpng-1.2.6 */
 #  ifdef PNG_USER_LIMITS_SUPPORTED
       create_struct.user_width_max = PNG_USER_WIDTH_MAX;
       create_struct.user_height_max = PNG_USER_HEIGHT_MAX;
 
 #     ifdef PNG_USER_CHUNK_CACHE_MAX
-      /* Added at libpng-1.2.43 and 1.4.0 */
       create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
 #     endif
 
-#     ifdef PNG_USER_CHUNK_MALLOC_MAX
-      /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists
-       * in png_struct regardless.
-       */
+#     if PNG_USER_CHUNK_MALLOC_MAX > 0 /* default to compile-time limit */
       create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
+
+      /* No compile-time limit, so initialize to the system limit: */
+#     elif defined PNG_MAX_MALLOC_64K /* legacy system limit */
+      create_struct.user_chunk_malloc_max = 65536U;
+
+#     else /* modern system limit SIZE_MAX (C99) */
+      create_struct.user_chunk_malloc_max = PNG_SIZE_MAX;
 #     endif
 #  endif
 
@@ -626,13 +655,6 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
    /* Free any eXIf entry */
    if (((mask & PNG_FREE_EXIF) & info_ptr->free_me) != 0)
    {
-# ifdef PNG_READ_eXIf_SUPPORTED
-      if (info_ptr->eXIf_buf)
-      {
-         png_free(png_ptr, info_ptr->eXIf_buf);
-         info_ptr->eXIf_buf = NULL;
-      }
-# endif
       if (info_ptr->exif)
       {
          png_free(png_ptr, info_ptr->exif);
@@ -822,8 +844,8 @@ png_get_copyright(png_const_structrp png_ptr)
    return PNG_STRING_COPYRIGHT
 #else
    return PNG_STRING_NEWLINE \
-      "libpng version 1.6.43" PNG_STRING_NEWLINE \
-      "Copyright (c) 2018-2024 Cosmin Truta" PNG_STRING_NEWLINE \
+      "libpng version 1.6.47" PNG_STRING_NEWLINE \
+      "Copyright (c) 2018-2025 Cosmin Truta" PNG_STRING_NEWLINE \
       "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \
       PNG_STRING_NEWLINE \
       "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
@@ -1067,210 +1089,132 @@ png_zstream_error(png_structrp png_ptr, int ret)
    }
 }
 
-/* png_convert_size: a PNGAPI but no longer in png.h, so deleted
- * at libpng 1.5.5!
- */
-
-/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
-#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
-static int
-png_colorspace_check_gamma(png_const_structrp png_ptr,
-    png_colorspacerp colorspace, png_fixed_point gAMA, int from)
-   /* This is called to check a new gamma value against an existing one.  The
-    * routine returns false if the new gamma value should not be written.
-    *
-    * 'from' says where the new gamma value comes from:
-    *
-    *    0: the new gamma value is the libpng estimate for an ICC profile
-    *    1: the new gamma value comes from a gAMA chunk
-    *    2: the new gamma value comes from an sRGB chunk
-    */
+#ifdef PNG_COLORSPACE_SUPPORTED
+static png_int_32
+png_fp_add(png_int_32 addend0, png_int_32 addend1, int *error)
 {
-   png_fixed_point gtest;
-
-   if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
-       (png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) == 0  ||
-      png_gamma_significant(gtest) != 0))
+   /* Safely add two fixed point values setting an error flag and returning 0.5
+    * on overflow.
+    * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore
+    * relying on addition of two positive values producing a negative one is not
+    * safe.
+    */
+   if (addend0 > 0)
    {
-      /* Either this is an sRGB image, in which case the calculated gamma
-       * approximation should match, or this is an image with a profile and the
-       * value libpng calculates for the gamma of the profile does not match the
-       * value recorded in the file.  The former, sRGB, case is an error, the
-       * latter is just a warning.
-       */
-      if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
-      {
-         png_chunk_report(png_ptr, "gamma value does not match sRGB",
-             PNG_CHUNK_ERROR);
-         /* Do not overwrite an sRGB value */
-         return from == 2;
-      }
-
-      else /* sRGB tag not involved */
-      {
-         png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
-             PNG_CHUNK_WARNING);
-         return from == 1;
-      }
+      if (0x7fffffff - addend0 >= addend1)
+         return addend0+addend1;
    }
-
-   return 1;
-}
-
-void /* PRIVATE */
-png_colorspace_set_gamma(png_const_structrp png_ptr,
-    png_colorspacerp colorspace, png_fixed_point gAMA)
-{
-   /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
-    * occur.  Since the fixed point representation is asymmetrical it is
-    * possible for 1/gamma to overflow the limit of 21474 and this means the
-    * gamma value must be at least 5/100000 and hence at most 20000.0.  For
-    * safety the limits here are a little narrower.  The values are 0.00016 to
-    * 6250.0, which are truly ridiculous gamma values (and will produce
-    * displays that are all black or all white.)
-    *
-    * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk
-    * handling code, which only required the value to be >0.
-    */
-   png_const_charp errmsg;
-
-   if (gAMA < 16 || gAMA > 625000000)
-      errmsg = "gamma value out of range";
-
-#  ifdef PNG_READ_gAMA_SUPPORTED
-   /* Allow the application to set the gamma value more than once */
-   else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
-      (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0)
-      errmsg = "duplicate";
-#  endif
-
-   /* Do nothing if the colorspace is already invalid */
-   else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
-      return;
-
-   else
+   else if (addend0 < 0)
    {
-      if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA,
-          1/*from gAMA*/) != 0)
-      {
-         /* Store this gamma value. */
-         colorspace->gamma = gAMA;
-         colorspace->flags |=
-            (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA);
-      }
-
-      /* At present if the check_gamma test fails the gamma of the colorspace is
-       * not updated however the colorspace is not invalidated.  This
-       * corresponds to the case where the existing gamma comes from an sRGB
-       * chunk or profile.  An error message has already been output.
-       */
-      return;
+      if (-0x7fffffff - addend0 <= addend1)
+         return addend0+addend1;
    }
+   else
+      return addend1;
 
-   /* Error exit - errmsg has been set. */
-   colorspace->flags |= PNG_COLORSPACE_INVALID;
-   png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR);
+   *error = 1;
+   return PNG_FP_1/2;
 }
 
-void /* PRIVATE */
-png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr)
+static png_int_32
+png_fp_sub(png_int_32 addend0, png_int_32 addend1, int *error)
 {
-   if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
+   /* As above but calculate addend0-addend1. */
+   if (addend1 > 0)
    {
-      /* Everything is invalid */
-      info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB|
-         PNG_INFO_iCCP);
-
-#     ifdef PNG_COLORSPACE_SUPPORTED
-      /* Clean up the iCCP profile now if it won't be used. */
-      png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/);
-#     else
-      PNG_UNUSED(png_ptr)
-#     endif
+      if (-0x7fffffff + addend1 <= addend0)
+         return addend0-addend1;
    }
-
-   else
+   else if (addend1 < 0)
    {
-#     ifdef PNG_COLORSPACE_SUPPORTED
-      /* Leave the INFO_iCCP flag set if the pngset.c code has already set
-       * it; this allows a PNG to contain a profile which matches sRGB and
-       * yet still have that profile retrievable by the application.
-       */
-      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0)
-         info_ptr->valid |= PNG_INFO_sRGB;
-
-      else
-         info_ptr->valid &= ~PNG_INFO_sRGB;
-
-      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
-         info_ptr->valid |= PNG_INFO_cHRM;
-
-      else
-         info_ptr->valid &= ~PNG_INFO_cHRM;
-#     endif
-
-      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0)
-         info_ptr->valid |= PNG_INFO_gAMA;
-
-      else
-         info_ptr->valid &= ~PNG_INFO_gAMA;
+      if (0x7fffffff + addend1 >= addend0)
+         return addend0-addend1;
    }
+   else
+      return addend0;
+
+   *error = 1;
+   return PNG_FP_1/2;
 }
 
-#ifdef PNG_READ_SUPPORTED
-void /* PRIVATE */
-png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr)
+static int
+png_safe_add(png_int_32 *addend0_and_result, png_int_32 addend1,
+      png_int_32 addend2)
 {
-   if (info_ptr == NULL) /* reduce code size; check here not in the caller */
-      return;
-
-   info_ptr->colorspace = png_ptr->colorspace;
-   png_colorspace_sync_info(png_ptr, info_ptr);
+   /* Safely add three integers.  Returns 0 on success, 1 on overflow.  Does not
+    * set the result on overflow.
+    */
+   int error = 0;
+   int result = png_fp_add(*addend0_and_result,
+                           png_fp_add(addend1, addend2, &error),
+                           &error);
+   if (!error) *addend0_and_result = result;
+   return error;
 }
-#endif
-#endif /* GAMMA */
 
-#ifdef PNG_COLORSPACE_SUPPORTED
 /* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
  * cHRM, as opposed to using chromaticities.  These internal APIs return
  * non-zero on a parameter error.  The X, Y and Z values are required to be
  * positive and less than 1.0.
  */
-static int
+int /* PRIVATE */
 png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)
 {
-   png_int_32 d, dwhite, whiteX, whiteY;
+   /* NOTE: returns 0 on success, 1 means error. */
+   png_int_32 d, dred, dgreen, dblue, dwhite, whiteX, whiteY;
 
-   d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z;
-   if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0)
+   /* 'd' in each of the blocks below is just X+Y+Z for each component,
+    * x, y and z are X,Y,Z/(X+Y+Z).
+    */
+   d = XYZ->red_X;
+   if (png_safe_add(&d, XYZ->red_Y, XYZ->red_Z))
       return 1;
-   if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0)
+   dred = d;
+   if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, dred) == 0)
+      return 1;
+   if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, dred) == 0)
       return 1;
-   dwhite = d;
-   whiteX = XYZ->red_X;
-   whiteY = XYZ->red_Y;
 
-   d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z;
-   if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0)
+   d = XYZ->green_X;
+   if (png_safe_add(&d, XYZ->green_Y, XYZ->green_Z))
       return 1;
-   if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0)
+   dgreen = d;
+   if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, dgreen) == 0)
+      return 1;
+   if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, dgreen) == 0)
       return 1;
-   dwhite += d;
-   whiteX += XYZ->green_X;
-   whiteY += XYZ->green_Y;
 
-   d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z;
-   if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0)
+   d = XYZ->blue_X;
+   if (png_safe_add(&d, XYZ->blue_Y, XYZ->blue_Z))
+      return 1;
+   dblue = d;
+   if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, dblue) == 0)
       return 1;
-   if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0)
+   if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, dblue) == 0)
       return 1;
-   dwhite += d;
-   whiteX += XYZ->blue_X;
-   whiteY += XYZ->blue_Y;
 
-   /* The reference white is simply the sum of the end-point (X,Y,Z) vectors,
-    * thus:
+   /* The reference white is simply the sum of the end-point (X,Y,Z) vectors so
+    * the fillowing calculates (X+Y+Z) of the reference white (media white,
+    * encoding white) itself:
     */
+   d = dblue;
+   if (png_safe_add(&d, dred, dgreen))
+      return 1;
+   dwhite = d;
+
+   /* Find the white X,Y values from the sum of the red, green and blue X,Y
+    * values.
+    */
+   d = XYZ->red_X;
+   if (png_safe_add(&d, XYZ->green_X, XYZ->blue_X))
+      return 1;
+   whiteX = d;
+
+   d = XYZ->red_Y;
+   if (png_safe_add(&d, XYZ->green_Y, XYZ->blue_Y))
+      return 1;
+   whiteY = d;
+
    if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0)
       return 1;
    if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0)
@@ -1279,9 +1223,10 @@ png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)
    return 0;
 }
 
-static int
+int /* PRIVATE */
 png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
 {
+   /* NOTE: returns 0 on success, 1 means error. */
    png_fixed_point red_inverse, green_inverse, blue_scale;
    png_fixed_point left, right, denominator;
 
@@ -1289,15 +1234,24 @@ png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
     * have end points with 0 tristimulus values (these are impossible end
     * points, but they are used to cover the possible colors).  We check
     * xy->whitey against 5, not 0, to avoid a possible integer overflow.
+    *
+    * The limits here will *not* accept ACES AP0, where bluey is -7700
+    * (-0.0770) because the PNG spec itself requires the xy values to be
+    * unsigned.  whitey is also required to be 5 or more to avoid overflow.
+    *
+    * Instead the upper limits have been relaxed to accomodate ACES AP1 where
+    * redz ends up as -600 (-0.006).  ProPhotoRGB was already "in range."
+    * The new limit accomodates the AP0 and AP1 ranges for z but not AP0 redy.
     */
-   if (xy->redx   < 0 || xy->redx > PNG_FP_1) return 1;
-   if (xy->redy   < 0 || xy->redy > PNG_FP_1-xy->redx) return 1;
-   if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1;
-   if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1;
-   if (xy->bluex  < 0 || xy->bluex > PNG_FP_1) return 1;
-   if (xy->bluey  < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1;
-   if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1;
-   if (xy->whitey < 5 || xy->whitey > PNG_FP_1-xy->whitex) return 1;
+   const png_fixed_point fpLimit = PNG_FP_1+(PNG_FP_1/10);
+   if (xy->redx   < 0 || xy->redx > fpLimit) return 1;
+   if (xy->redy   < 0 || xy->redy > fpLimit-xy->redx) return 1;
+   if (xy->greenx < 0 || xy->greenx > fpLimit) return 1;
+   if (xy->greeny < 0 || xy->greeny > fpLimit-xy->greenx) return 1;
+   if (xy->bluex  < 0 || xy->bluex > fpLimit) return 1;
+   if (xy->bluey  < 0 || xy->bluey > fpLimit-xy->bluex) return 1;
+   if (xy->whitex < 0 || xy->whitex > fpLimit) return 1;
+   if (xy->whitey < 5 || xy->whitey > fpLimit-xy->whitex) return 1;
 
    /* The reverse calculation is more difficult because the original tristimulus
     * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
@@ -1442,18 +1396,23 @@ png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
     *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
     *
     * Accuracy:
-    * The input values have 5 decimal digits of accuracy.  The values are all in
-    * the range 0 < value < 1, so simple products are in the same range but may
-    * need up to 10 decimal digits to preserve the original precision and avoid
-    * underflow.  Because we are using a 32-bit signed representation we cannot
-    * match this; the best is a little over 9 decimal digits, less than 10.
+    * The input values have 5 decimal digits of accuracy.
+    *
+    * In the previous implementation the values were all in the range 0 < value
+    * < 1, so simple products are in the same range but may need up to 10
+    * decimal digits to preserve the original precision and avoid underflow.
+    * Because we are using a 32-bit signed representation we cannot match this;
+    * the best is a little over 9 decimal digits, less than 10.
+    *
+    * This range has now been extended to allow values up to 1.1, or 110,000 in
+    * fixed point.
     *
     * The approach used here is to preserve the maximum precision within the
     * signed representation.  Because the red-scale calculation above uses the
-    * difference between two products of values that must be in the range -1..+1
-    * it is sufficient to divide the product by 7; ceil(100,000/32767*2).  The
-    * factor is irrelevant in the calculation because it is applied to both
-    * numerator and denominator.
+    * difference between two products of values that must be in the range
+    * -1.1..+1.1 it is sufficient to divide the product by 8;
+    * ceil(121,000/32767*2).  The factor is irrelevant in the calculation
+    * because it is applied to both numerator and denominator.
     *
     * Note that the values of the differences of the products of the
     * chromaticities in the above equations tend to be small, for example for
@@ -1475,49 +1434,64 @@ png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
     *  Adobe Wide Gamut RGB
     *    0.258728243040113 0.724682314948566 0.016589442011321
     */
-   /* By the argument, above overflow should be impossible here. The return
-    * value of 2 indicates an internal error to the caller.
-    */
-   if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0)
-      return 2;
-   if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0)
-      return 2;
-   denominator = left - right;
-
-   /* Now find the red numerator. */
-   if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)
-      return 2;
-   if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0)
-      return 2;
-
-   /* Overflow is possible here and it indicates an extreme set of PNG cHRM
-    * chunk values.  This calculation actually returns the reciprocal of the
-    * scale value because this allows us to delay the multiplication of white-y
-    * into the denominator, which tends to produce a small number.
-    */
-   if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 ||
-       red_inverse <= xy->whitey /* r+g+b scales = white scale */)
-      return 1;
+   {
+      int error = 0;
 
-   /* Similarly for green_inverse: */
-   if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0)
-      return 2;
-   if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)
-      return 2;
-   if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 ||
-       green_inverse <= xy->whitey)
-      return 1;
+      /* By the argument above overflow should be impossible here, however the
+       * code now simply returns a failure code.  The xy subtracts in the
+       * arguments to png_muldiv are *not* checked for overflow because the
+       * checks at the start guarantee they are in the range 0..110000 and
+       * png_fixed_point is a 32-bit signed number.
+       */
+      if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 8) == 0)
+         return 1;
+      if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 8) ==
+            0)
+         return 1;
+      denominator = png_fp_sub(left, right, &error);
+      if (error) return 1;
 
-   /* And the blue scale, the checks above guarantee this can't overflow but it
-    * can still produce 0 for extreme cHRM values.
-    */
-   blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) -
-       png_reciprocal(green_inverse);
-   if (blue_scale <= 0)
-      return 1;
+      /* Now find the red numerator. */
+      if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 8) == 0)
+         return 1;
+      if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 8) ==
+            0)
+         return 1;
 
+      /* Overflow is possible here and it indicates an extreme set of PNG cHRM
+       * chunk values.  This calculation actually returns the reciprocal of the
+       * scale value because this allows us to delay the multiplication of
+       * white-y into the denominator, which tends to produce a small number.
+       */
+      if (png_muldiv(&red_inverse, xy->whitey, denominator,
+                     png_fp_sub(left, right, &error)) == 0 || error ||
+          red_inverse <= xy->whitey /* r+g+b scales = white scale */)
+         return 1;
 
-   /* And fill in the png_XYZ: */
+      /* Similarly for green_inverse: */
+      if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 8) == 0)
+         return 1;
+      if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 8) == 0)
+         return 1;
+      if (png_muldiv(&green_inverse, xy->whitey, denominator,
+                     png_fp_sub(left, right, &error)) == 0 || error ||
+          green_inverse <= xy->whitey)
+         return 1;
+
+      /* And the blue scale, the checks above guarantee this can't overflow but
+       * it can still produce 0 for extreme cHRM values.
+       */
+      blue_scale = png_fp_sub(png_fp_sub(png_reciprocal(xy->whitey),
+                                         png_reciprocal(red_inverse), &error),
+                              png_reciprocal(green_inverse), &error);
+      if (error || blue_scale <= 0)
+         return 1;
+   }
+
+   /* And fill in the png_XYZ.  Again the subtracts are safe because of the
+    * checks on the xy values at the start (the subtracts just calculate the
+    * corresponding z values.)
+    */
    if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0)
       return 1;
    if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0)
@@ -1544,250 +1518,9 @@ png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
 
    return 0; /*success*/
 }
+#endif /* COLORSPACE */
 
-static int
-png_XYZ_normalize(png_XYZ *XYZ)
-{
-   png_int_32 Y;
-
-   if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 ||
-      XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 ||
-      XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0)
-      return 1;
-
-   /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1.
-    * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore
-    * relying on addition of two positive values producing a negative one is not
-    * safe.
-    */
-   Y = XYZ->red_Y;
-   if (0x7fffffff - Y < XYZ->green_X)
-      return 1;
-   Y += XYZ->green_Y;
-   if (0x7fffffff - Y < XYZ->blue_X)
-      return 1;
-   Y += XYZ->blue_Y;
-
-   if (Y != PNG_FP_1)
-   {
-      if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0)
-         return 1;
-      if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0)
-         return 1;
-      if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0)
-         return 1;
-
-      if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0)
-         return 1;
-      if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0)
-         return 1;
-      if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0)
-         return 1;
-
-      if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0)
-         return 1;
-      if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0)
-         return 1;
-      if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0)
-         return 1;
-   }
-
-   return 0;
-}
-
-static int
-png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta)
-{
-   /* Allow an error of +/-0.01 (absolute value) on each chromaticity */
-   if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) ||
-       PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) ||
-       PNG_OUT_OF_RANGE(xy1->redx,   xy2->redx,  delta) ||
-       PNG_OUT_OF_RANGE(xy1->redy,   xy2->redy,  delta) ||
-       PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) ||
-       PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) ||
-       PNG_OUT_OF_RANGE(xy1->bluex,  xy2->bluex, delta) ||
-       PNG_OUT_OF_RANGE(xy1->bluey,  xy2->bluey, delta))
-      return 0;
-   return 1;
-}
-
-/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM
- * chunk chromaticities.  Earlier checks used to simply look for the overflow
- * condition (where the determinant of the matrix to solve for XYZ ends up zero
- * because the chromaticity values are not all distinct.)  Despite this it is
- * theoretically possible to produce chromaticities that are apparently valid
- * but that rapidly degrade to invalid, potentially crashing, sets because of
- * arithmetic inaccuracies when calculations are performed on them.  The new
- * check is to round-trip xy -> XYZ -> xy and then check that the result is
- * within a small percentage of the original.
- */
-static int
-png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy)
-{
-   int result;
-   png_xy xy_test;
-
-   /* As a side-effect this routine also returns the XYZ endpoints. */
-   result = png_XYZ_from_xy(XYZ, xy);
-   if (result != 0)
-      return result;
-
-   result = png_xy_from_XYZ(&xy_test, XYZ);
-   if (result != 0)
-      return result;
-
-   if (png_colorspace_endpoints_match(xy, &xy_test,
-       5/*actually, the math is pretty accurate*/) != 0)
-      return 0;
-
-   /* Too much slip */
-   return 1;
-}
-
-/* This is the check going the other way.  The XYZ is modified to normalize it
- * (another side-effect) and the xy chromaticities are returned.
- */
-static int
-png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ)
-{
-   int result;
-   png_XYZ XYZtemp;
-
-   result = png_XYZ_normalize(XYZ);
-   if (result != 0)
-      return result;
-
-   result = png_xy_from_XYZ(xy, XYZ);
-   if (result != 0)
-      return result;
-
-   XYZtemp = *XYZ;
-   return png_colorspace_check_xy(&XYZtemp, xy);
-}
-
-/* Used to check for an endpoint match against sRGB */
-static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
-{
-   /* color      x       y */
-   /* red   */ 64000, 33000,
-   /* green */ 30000, 60000,
-   /* blue  */ 15000,  6000,
-   /* white */ 31270, 32900
-};
-
-static int
-png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
-    png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
-    int preferred)
-{
-   if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
-      return 0;
-
-   /* The consistency check is performed on the chromaticities; this factors out
-    * variations because of the normalization (or not) of the end point Y
-    * values.
-    */
-   if (preferred < 2 &&
-       (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
-   {
-      /* The end points must be reasonably close to any we already have.  The
-       * following allows an error of up to +/-.001
-       */
-      if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy,
-          100) == 0)
-      {
-         colorspace->flags |= PNG_COLORSPACE_INVALID;
-         png_benign_error(png_ptr, "inconsistent chromaticities");
-         return 0; /* failed */
-      }
-
-      /* Only overwrite with preferred values */
-      if (preferred == 0)
-         return 1; /* ok, but no change */
-   }
-
-   colorspace->end_points_xy = *xy;
-   colorspace->end_points_XYZ = *XYZ;
-   colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS;
-
-   /* The end points are normally quoted to two decimal digits, so allow +/-0.01
-    * on this test.
-    */
-   if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0)
-      colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB;
-
-   else
-      colorspace->flags &= PNG_COLORSPACE_CANCEL(
-         PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
-
-   return 2; /* ok and changed */
-}
-
-int /* PRIVATE */
-png_colorspace_set_chromaticities(png_const_structrp png_ptr,
-    png_colorspacerp colorspace, const png_xy *xy, int preferred)
-{
-   /* We must check the end points to ensure they are reasonable - in the past
-    * color management systems have crashed as a result of getting bogus
-    * colorant values, while this isn't the fault of libpng it is the
-    * responsibility of libpng because PNG carries the bomb and libpng is in a
-    * position to protect against it.
-    */
-   png_XYZ XYZ;
-
-   switch (png_colorspace_check_xy(&XYZ, xy))
-   {
-      case 0: /* success */
-         return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
-             preferred);
-
-      case 1:
-         /* We can't invert the chromaticities so we can't produce value XYZ
-          * values.  Likely as not a color management system will fail too.
-          */
-         colorspace->flags |= PNG_COLORSPACE_INVALID;
-         png_benign_error(png_ptr, "invalid chromaticities");
-         break;
-
-      default:
-         /* libpng is broken; this should be a warning but if it happens we
-          * want error reports so for the moment it is an error.
-          */
-         colorspace->flags |= PNG_COLORSPACE_INVALID;
-         png_error(png_ptr, "internal error checking chromaticities");
-   }
-
-   return 0; /* failed */
-}
-
-int /* PRIVATE */
-png_colorspace_set_endpoints(png_const_structrp png_ptr,
-    png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
-{
-   png_XYZ XYZ = *XYZ_in;
-   png_xy xy;
-
-   switch (png_colorspace_check_XYZ(&xy, &XYZ))
-   {
-      case 0:
-         return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
-             preferred);
-
-      case 1:
-         /* End points are invalid. */
-         colorspace->flags |= PNG_COLORSPACE_INVALID;
-         png_benign_error(png_ptr, "invalid end points");
-         break;
-
-      default:
-         colorspace->flags |= PNG_COLORSPACE_INVALID;
-         png_error(png_ptr, "internal error checking chromaticities");
-   }
-
-   return 0; /* failed */
-}
-
-#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED)
+#ifdef PNG_iCCP_SUPPORTED
 /* Error message generation */
 static char
 png_icc_tag_char(png_uint_32 byte)
@@ -1827,15 +1560,12 @@ is_ICC_signature(png_alloc_size_t it)
 }
 
 static int
-png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
-    png_const_charp name, png_alloc_size_t value, png_const_charp reason)
+png_icc_profile_error(png_const_structrp png_ptr, png_const_charp name,
+   png_alloc_size_t value, png_const_charp reason)
 {
    size_t pos;
    char message[196]; /* see below for calculation */
 
-   if (colorspace != NULL)
-      colorspace->flags |= PNG_COLORSPACE_INVALID;
-
    pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */
    pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */
    pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */
@@ -1862,109 +1592,13 @@ png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
    pos = png_safecat(message, (sizeof message), pos, reason);
    PNG_UNUSED(pos)
 
-   /* This is recoverable, but make it unconditionally an app_error on write to
-    * avoid writing invalid ICC profiles into PNG files (i.e., we handle them
-    * on read, with a warning, but on write unless the app turns off
-    * application errors the PNG won't be written.)
-    */
-   png_chunk_report(png_ptr, message,
-       (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
+   png_chunk_benign_error(png_ptr, message);
 
    return 0;
 }
-#endif /* sRGB || iCCP */
-
-#ifdef PNG_sRGB_SUPPORTED
-int /* PRIVATE */
-png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
-    int intent)
-{
-   /* sRGB sets known gamma, end points and (from the chunk) intent. */
-   /* IMPORTANT: these are not necessarily the values found in an ICC profile
-    * because ICC profiles store values adapted to a D50 environment; it is
-    * expected that the ICC profile mediaWhitePointTag will be D50; see the
-    * checks and code elsewhere to understand this better.
-    *
-    * These XYZ values, which are accurate to 5dp, produce rgb to gray
-    * coefficients of (6968,23435,2366), which are reduced (because they add up
-    * to 32769 not 32768) to (6968,23434,2366).  These are the values that
-    * libpng has traditionally used (and are the best values given the 15bit
-    * algorithm used by the rgb to gray code.)
-    */
-   static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */
-   {
-      /* color      X      Y      Z */
-      /* red   */ 41239, 21264,  1933,
-      /* green */ 35758, 71517, 11919,
-      /* blue  */ 18048,  7219, 95053
-   };
-
-   /* Do nothing if the colorspace is already invalidated. */
-   if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
-      return 0;
-
-   /* Check the intent, then check for existing settings.  It is valid for the
-    * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must
-    * be consistent with the correct values.  If, however, this function is
-    * called below because an iCCP chunk matches sRGB then it is quite
-    * conceivable that an older app recorded incorrect gAMA and cHRM because of
-    * an incorrect calculation based on the values in the profile - this does
-    * *not* invalidate the profile (though it still produces an error, which can
-    * be ignored.)
-    */
-   if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
-      return png_icc_profile_error(png_ptr, colorspace, "sRGB",
-          (png_alloc_size_t)intent, "invalid sRGB rendering intent");
-
-   if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
-       colorspace->rendering_intent != intent)
-      return png_icc_profile_error(png_ptr, colorspace, "sRGB",
-         (png_alloc_size_t)intent, "inconsistent rendering intents");
-
-   if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
-   {
-      png_benign_error(png_ptr, "duplicate sRGB information ignored");
-      return 0;
-   }
-
-   /* If the standard sRGB cHRM chunk does not match the one from the PNG file
-    * warn but overwrite the value with the correct one.
-    */
-   if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
-       !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
-       100))
-      png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
-         PNG_CHUNK_ERROR);
-
-   /* This check is just done for the error reporting - the routine always
-    * returns true when the 'from' argument corresponds to sRGB (2).
-    */
-   (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
-       2/*from sRGB*/);
-
-   /* intent: bugs in GCC force 'int' to be used as the parameter type. */
-   colorspace->rendering_intent = (png_uint_16)intent;
-   colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT;
-
-   /* endpoints */
-   colorspace->end_points_xy = sRGB_xy;
-   colorspace->end_points_XYZ = sRGB_XYZ;
-   colorspace->flags |=
-      (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
-
-   /* gamma */
-   colorspace->gamma = PNG_GAMMA_sRGB_INVERSE;
-   colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA;
-
-   /* Finally record that we have an sRGB profile */
-   colorspace->flags |=
-      (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB);
-
-   return 1; /* set */
-}
-#endif /* sRGB */
+#endif /* iCCP */
 
-#ifdef PNG_iCCP_SUPPORTED
+#ifdef PNG_READ_iCCP_SUPPORTED
 /* Encoded value of D50 as an ICC XYZNumber.  From the ICC 2010 spec the value
  * is XYZ(0.9642,1.0,0.8249), which scales to:
  *
@@ -1974,21 +1608,19 @@ static const png_byte D50_nCIEXYZ[12] =
    { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
 
 static int /* bool */
-icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
-    png_const_charp name, png_uint_32 profile_length)
+icc_check_length(png_const_structrp png_ptr, png_const_charp name,
+   png_uint_32 profile_length)
 {
    if (profile_length < 132)
-      return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
-          "too short");
+      return png_icc_profile_error(png_ptr, name, profile_length, "too short");
    return 1;
 }
 
-#ifdef PNG_READ_iCCP_SUPPORTED
 int /* PRIVATE */
-png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
-    png_const_charp name, png_uint_32 profile_length)
+png_icc_check_length(png_const_structrp png_ptr, png_const_charp name,
+   png_uint_32 profile_length)
 {
-   if (!icc_check_length(png_ptr, colorspace, name, profile_length))
+   if (!icc_check_length(png_ptr, name, profile_length))
       return 0;
 
    /* This needs to be here because the 'normal' check is in
@@ -1997,30 +1629,17 @@ png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
     * the caller supplies the profile buffer so libpng doesn't allocate it.  See
     * the call to icc_check_length below (the write case).
     */
-#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
-      else if (png_ptr->user_chunk_malloc_max > 0 &&
-               png_ptr->user_chunk_malloc_max < profile_length)
-         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
-             "exceeds application limits");
-#  elif PNG_USER_CHUNK_MALLOC_MAX > 0
-      else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length)
-         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
-             "exceeds libpng limits");
-#  else /* !SET_USER_LIMITS */
-      /* This will get compiled out on all 32-bit and better systems. */
-      else if (PNG_SIZE_MAX < profile_length)
-         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
-             "exceeds system limits");
-#  endif /* !SET_USER_LIMITS */
+   if (profile_length > png_chunk_max(png_ptr))
+      return png_icc_profile_error(png_ptr, name, profile_length,
+            "profile too long");
 
    return 1;
 }
-#endif /* READ_iCCP */
 
 int /* PRIVATE */
-png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
-    png_const_charp name, png_uint_32 profile_length,
-    png_const_bytep profile/* first 132 bytes only */, int color_type)
+png_icc_check_header(png_const_structrp png_ptr, png_const_charp name,
+   png_uint_32 profile_length,
+   png_const_bytep profile/* first 132 bytes only */, int color_type)
 {
    png_uint_32 temp;
 
@@ -2031,18 +1650,18 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
     */
    temp = png_get_uint_32(profile);
    if (temp != profile_length)
-      return png_icc_profile_error(png_ptr, colorspace, name, temp,
+      return png_icc_profile_error(png_ptr, name, temp,
           "length does not match profile");
 
    temp = (png_uint_32) (*(profile+8));
    if (temp > 3 && (profile_length & 3))
-      return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+      return png_icc_profile_error(png_ptr, name, profile_length,
           "invalid length");
 
    temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
    if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
       profile_length < 132+12*temp) /* truncated tag table */
-      return png_icc_profile_error(png_ptr, colorspace, name, temp,
+      return png_icc_profile_error(png_ptr, name, temp,
           "tag count too large");
 
    /* The 'intent' must be valid or we can't store it, ICC limits the intent to
@@ -2050,14 +1669,14 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
     */
    temp = png_get_uint_32(profile+64);
    if (temp >= 0xffff) /* The ICC limit */
-      return png_icc_profile_error(png_ptr, colorspace, name, temp,
+      return png_icc_profile_error(png_ptr, name, temp,
           "invalid rendering intent");
 
    /* This is just a warning because the profile may be valid in future
     * versions.
     */
    if (temp >= PNG_sRGB_INTENT_LAST)
-      (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+      (void)png_icc_profile_error(png_ptr, name, temp,
           "intent outside defined range");
 
    /* At this point the tag table can't be checked because it hasn't necessarily
@@ -2074,7 +1693,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
     */
    temp = png_get_uint_32(profile+36); /* signature 'ascp' */
    if (temp != 0x61637370)
-      return png_icc_profile_error(png_ptr, colorspace, name, temp,
+      return png_icc_profile_error(png_ptr, name, temp,
           "invalid signature");
 
    /* Currently the PCS illuminant/adopted white point (the computational
@@ -2085,7 +1704,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
     * following is just a warning.
     */
    if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
-      (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
+      (void)png_icc_profile_error(png_ptr, name, 0/*no tag value*/,
           "PCS illuminant is not D50");
 
    /* The PNG spec requires this:
@@ -2113,18 +1732,18 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
    {
       case 0x52474220: /* 'RGB ' */
          if ((color_type & PNG_COLOR_MASK_COLOR) == 0)
-            return png_icc_profile_error(png_ptr, colorspace, name, temp,
+            return png_icc_profile_error(png_ptr, name, temp,
                 "RGB color space not permitted on grayscale PNG");
          break;
 
       case 0x47524159: /* 'GRAY' */
          if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
-            return png_icc_profile_error(png_ptr, colorspace, name, temp,
+            return png_icc_profile_error(png_ptr, name, temp,
                 "Gray color space not permitted on RGB PNG");
          break;
 
       default:
-         return png_icc_profile_error(png_ptr, colorspace, name, temp,
+         return png_icc_profile_error(png_ptr, name, temp,
              "invalid ICC profile color space");
    }
 
@@ -2149,7 +1768,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
 
       case 0x61627374: /* 'abst' */
          /* May not be embedded in an image */
-         return png_icc_profile_error(png_ptr, colorspace, name, temp,
+         return png_icc_profile_error(png_ptr, name, temp,
              "invalid embedded Abstract ICC profile");
 
       case 0x6c696e6b: /* 'link' */
@@ -2159,7 +1778,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
           * therefore a DeviceLink profile should not be found embedded in a
           * PNG.
           */
-         return png_icc_profile_error(png_ptr, colorspace, name, temp,
+         return png_icc_profile_error(png_ptr, name, temp,
              "unexpected DeviceLink ICC profile class");
 
       case 0x6e6d636c: /* 'nmcl' */
@@ -2167,7 +1786,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
           * contain an AToB0 tag that is open to misinterpretation.  Almost
           * certainly it will fail the tests below.
           */
-         (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+         (void)png_icc_profile_error(png_ptr, name, temp,
              "unexpected NamedColor ICC profile class");
          break;
 
@@ -2177,7 +1796,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
           * tag content to ensure they are backward compatible with one of the
           * understood profiles.
           */
-         (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+         (void)png_icc_profile_error(png_ptr, name, temp,
              "unrecognized ICC profile class");
          break;
    }
@@ -2193,7 +1812,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
          break;
 
       default:
-         return png_icc_profile_error(png_ptr, colorspace, name, temp,
+         return png_icc_profile_error(png_ptr, name, temp,
              "unexpected ICC PCS encoding");
    }
 
@@ -2201,9 +1820,9 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
 }
 
 int /* PRIVATE */
-png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
-    png_const_charp name, png_uint_32 profile_length,
-    png_const_bytep profile /* header plus whole tag table */)
+png_icc_check_tag_table(png_const_structrp png_ptr, png_const_charp name,
+   png_uint_32 profile_length,
+   png_const_bytep profile /* header plus whole tag table */)
 {
    png_uint_32 tag_count = png_get_uint_32(profile+128);
    png_uint_32 itag;
@@ -2229,7 +1848,7 @@ png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
        * profile.
        */
       if (tag_start > profile_length || tag_length > profile_length - tag_start)
-         return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
+         return png_icc_profile_error(png_ptr, name, tag_id,
              "ICC profile tag outside profile");
 
       if ((tag_start & 3) != 0)
@@ -2238,307 +1857,132 @@ png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
           * only a warning here because libpng does not care about the
           * alignment.
           */
-         (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
+         (void)png_icc_profile_error(png_ptr, name, tag_id,
              "ICC profile tag start not a multiple of 4");
       }
    }
 
    return 1; /* success, maybe with warnings */
 }
+#endif /* READ_iCCP */
 
-#ifdef PNG_sRGB_SUPPORTED
-#if PNG_sRGB_PROFILE_CHECKS >= 0
-/* Information about the known ICC sRGB profiles */
-static const struct
-{
-   png_uint_32 adler, crc, length;
-   png_uint_32 md5[4];
-   png_byte    have_md5;
-   png_byte    is_broken;
-   png_uint_16 intent;
-
-#  define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0)
-#  define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\
-      { adler, crc, length, md5, broke, intent },
-
-} png_sRGB_checks[] =
-{
-   /* This data comes from contrib/tools/checksum-icc run on downloads of
-    * all four ICC sRGB profiles from www.color.org.
-    */
-   /* adler32, crc32, MD5[4], intent, date, length, file-name */
-   PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
-       PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
-       "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
-
-   /* ICC sRGB v2 perceptual no black-compensation: */
-   PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
-       PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
-       "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
-
-   PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
-       PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
-       "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
-
-   /* ICC sRGB v4 perceptual */
-   PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
-       PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
-       "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
-
-   /* The following profiles have no known MD5 checksum. If there is a match
-    * on the (empty) MD5 the other fields are used to attempt a match and
-    * a warning is produced.  The first two of these profiles have a 'cprt' tag
-    * which suggests that they were also made by Hewlett Packard.
-    */
-   PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
-       PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
-       "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
-
-   /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
-    * match the D50 PCS illuminant in the header (it is in fact the D65 values,
-    * so the white point is recorded as the un-adapted value.)  The profiles
-    * below only differ in one byte - the intent - and are basically the same as
-    * the previous profile except for the mediaWhitePointTag error and a missing
-    * chromaticAdaptationTag.
-    */
-   PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
-       PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
-       "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
-
-   PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
-       PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
-       "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
-};
-
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+#if (defined PNG_READ_mDCV_SUPPORTED) || (defined PNG_READ_cHRM_SUPPORTED)
 static int
-png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
-    png_const_bytep profile, uLong adler)
+have_chromaticities(png_const_structrp png_ptr)
 {
-   /* The quick check is to verify just the MD5 signature and trust the
-    * rest of the data.  Because the profile has already been verified for
-    * correctness this is safe.  png_colorspace_set_sRGB will check the 'intent'
-    * field too, so if the profile has been edited with an intent not defined
-    * by sRGB (but maybe defined by a later ICC specification) the read of
-    * the profile will fail at that point.
+   /* Handle new PNGv3 chunks and the precedence rules to determine whether
+    * png_struct::chromaticities must be processed.  Only required for RGB to
+    * gray.
+    *
+    * mDCV: this is the mastering colour space and it is independent of the
+    *       encoding so it needs to be used regardless of the encoded space.
+    *
+    * cICP: first in priority but not yet implemented - the chromaticities come
+    *       from the 'primaries'.
+    *
+    * iCCP: not supported by libpng (so ignored)
+    *
+    * sRGB: the defaults match sRGB
+    *
+    * cHRM: calculate the coefficients
     */
+#  ifdef PNG_READ_mDCV_SUPPORTED
+      if (png_has_chunk(png_ptr, mDCV))
+         return 1;
+#     define check_chromaticities 1
+#  endif /*mDCV*/
 
-   png_uint_32 length = 0;
-   png_uint_32 intent = 0x10000; /* invalid */
-#if PNG_sRGB_PROFILE_CHECKS > 1
-   uLong crc = 0; /* the value for 0 length data */
-#endif
-   unsigned int i;
-
-#ifdef PNG_SET_OPTION_SUPPORTED
-   /* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to "on" */
-   if (((png_ptr->options >> PNG_SKIP_sRGB_CHECK_PROFILE) & 3) ==
-               PNG_OPTION_ON)
-      return 0;
-#endif
-
-   for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i)
-   {
-      if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] &&
-         png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] &&
-         png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] &&
-         png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3])
-      {
-         /* This may be one of the old HP profiles without an MD5, in that
-          * case we can only use the length and Adler32 (note that these
-          * are not used by default if there is an MD5!)
-          */
-#        if PNG_sRGB_PROFILE_CHECKS == 0
-            if (png_sRGB_checks[i].have_md5 != 0)
-               return 1+png_sRGB_checks[i].is_broken;
-#        endif
-
-         /* Profile is unsigned or more checks have been configured in. */
-         if (length == 0)
-         {
-            length = png_get_uint_32(profile);
-            intent = png_get_uint_32(profile+64);
-         }
-
-         /* Length *and* intent must match */
-         if (length == (png_uint_32) png_sRGB_checks[i].length &&
-            intent == (png_uint_32) png_sRGB_checks[i].intent)
-         {
-            /* Now calculate the adler32 if not done already. */
-            if (adler == 0)
-            {
-               adler = adler32(0, NULL, 0);
-               adler = adler32(adler, profile, length);
-            }
-
-            if (adler == png_sRGB_checks[i].adler)
-            {
-               /* These basic checks suggest that the data has not been
-                * modified, but if the check level is more than 1 perform
-                * our own crc32 checksum on the data.
-                */
-#              if PNG_sRGB_PROFILE_CHECKS > 1
-                  if (crc == 0)
-                  {
-                     crc = crc32(0, NULL, 0);
-                     crc = crc32(crc, profile, length);
-                  }
-
-                  /* So this check must pass for the 'return' below to happen.
-                   */
-                  if (crc == png_sRGB_checks[i].crc)
-#              endif
-               {
-                  if (png_sRGB_checks[i].is_broken != 0)
-                  {
-                     /* These profiles are known to have bad data that may cause
-                      * problems if they are used, therefore attempt to
-                      * discourage their use, skip the 'have_md5' warning below,
-                      * which is made irrelevant by this error.
-                      */
-                     png_chunk_report(png_ptr, "known incorrect sRGB profile",
-                         PNG_CHUNK_ERROR);
-                  }
-
-                  /* Warn that this being done; this isn't even an error since
-                   * the profile is perfectly valid, but it would be nice if
-                   * people used the up-to-date ones.
-                   */
-                  else if (png_sRGB_checks[i].have_md5 == 0)
-                  {
-                     png_chunk_report(png_ptr,
-                         "out-of-date sRGB profile with no signature",
-                         PNG_CHUNK_WARNING);
-                  }
+#  ifdef PNG_READ_sRGB_SUPPORTED
+      if (png_has_chunk(png_ptr, sRGB))
+         return 0;
+#  endif /*sRGB*/
 
-                  return 1+png_sRGB_checks[i].is_broken;
-               }
-            }
-
-# if PNG_sRGB_PROFILE_CHECKS > 0
-         /* The signature matched, but the profile had been changed in some
-          * way.  This probably indicates a data error or uninformed hacking.
-          * Fall through to "no match".
-          */
-         png_chunk_report(png_ptr,
-             "Not recognizing known sRGB profile that has been edited",
-             PNG_CHUNK_WARNING);
-         break;
-# endif
-         }
-      }
-   }
+#  ifdef PNG_READ_cHRM_SUPPORTED
+      if (png_has_chunk(png_ptr, cHRM))
+         return 1;
+#     define check_chromaticities 1
+#  endif /*cHRM*/
 
-   return 0; /* no match */
+   return 0; /* sRGB defaults */
 }
+#endif /* READ_mDCV || READ_cHRM */
 
 void /* PRIVATE */
-png_icc_set_sRGB(png_const_structrp png_ptr,
-    png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
+png_set_rgb_coefficients(png_structrp png_ptr)
 {
-   /* Is this profile one of the known ICC sRGB profiles?  If it is, just set
-    * the sRGB information.
+   /* Set the rgb_to_gray coefficients from the colorspace if available.  Note
+    * that '_set' means that png_rgb_to_gray was called **and** it successfully
+    * set up the coefficients.
     */
-   if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0)
-      (void)png_colorspace_set_sRGB(png_ptr, colorspace,
-         (int)/*already checked*/png_get_uint_32(profile+64));
-}
-#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
-#endif /* sRGB */
-
-int /* PRIVATE */
-png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
-    png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
-    int color_type)
-{
-   if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
-      return 0;
-
-   if (icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
-       png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
-           color_type) != 0 &&
-       png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
-           profile) != 0)
+   if (png_ptr->rgb_to_gray_coefficients_set == 0)
    {
-#     if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
-         /* If no sRGB support, don't try storing sRGB information */
-         png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
-#     endif
-      return 1;
-   }
+#  if check_chromaticities
+      png_XYZ xyz;
 
-   /* Failure case */
-   return 0;
-}
-#endif /* iCCP */
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-void /* PRIVATE */
-png_colorspace_set_rgb_coefficients(png_structrp png_ptr)
-{
-   /* Set the rgb_to_gray coefficients from the colorspace. */
-   if (png_ptr->rgb_to_gray_coefficients_set == 0 &&
-      (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
-   {
-      /* png_set_background has not been called, get the coefficients from the Y
-       * values of the colorspace colorants.
-       */
-      png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y;
-      png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y;
-      png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y;
-      png_fixed_point total = r+g+b;
-
-      if (total > 0 &&
-         r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 &&
-         g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 &&
-         b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 &&
-         r+g+b <= 32769)
+      if (have_chromaticities(png_ptr) &&
+          png_XYZ_from_xy(&xyz, &png_ptr->chromaticities) == 0)
       {
-         /* We allow 0 coefficients here.  r+g+b may be 32769 if two or
-          * all of the coefficients were rounded up.  Handle this by
-          * reducing the *largest* coefficient by 1; this matches the
-          * approach used for the default coefficients in pngrtran.c
+         /* png_set_rgb_to_gray has not set the coefficients, get them from the
+          * Y * values of the colorspace colorants.
           */
-         int add = 0;
+         png_fixed_point r = xyz.red_Y;
+         png_fixed_point g = xyz.green_Y;
+         png_fixed_point b = xyz.blue_Y;
+         png_fixed_point total = r+g+b;
+
+         if (total > 0 &&
+            r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 &&
+            g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 &&
+            b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 &&
+            r+g+b <= 32769)
+         {
+            /* We allow 0 coefficients here.  r+g+b may be 32769 if two or
+             * all of the coefficients were rounded up.  Handle this by
+             * reducing the *largest* coefficient by 1; this matches the
+             * approach used for the default coefficients in pngrtran.c
+             */
+            int add = 0;
 
-         if (r+g+b > 32768)
-            add = -1;
-         else if (r+g+b < 32768)
-            add = 1;
+            if (r+g+b > 32768)
+               add = -1;
+            else if (r+g+b < 32768)
+               add = 1;
 
-         if (add != 0)
-         {
-            if (g >= r && g >= b)
-               g += add;
-            else if (r >= g && r >= b)
-               r += add;
-            else
-               b += add;
-         }
+            if (add != 0)
+            {
+               if (g >= r && g >= b)
+                  g += add;
+               else if (r >= g && r >= b)
+                  r += add;
+               else
+                  b += add;
+            }
 
-         /* Check for an internal error. */
-         if (r+g+b != 32768)
-            png_error(png_ptr,
-                "internal error handling cHRM coefficients");
+            /* Check for an internal error. */
+            if (r+g+b != 32768)
+               png_error(png_ptr,
+                   "internal error handling cHRM coefficients");
 
-         else
-         {
-            png_ptr->rgb_to_gray_red_coeff   = (png_uint_16)r;
-            png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
+            else
+            {
+               png_ptr->rgb_to_gray_red_coeff   = (png_uint_16)r;
+               png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
+            }
          }
       }
-
-      /* This is a png_error at present even though it could be ignored -
-       * it should never happen, but it is important that if it does, the
-       * bug is fixed.
-       */
       else
-         png_error(png_ptr, "internal error handling cHRM->XYZ");
+#  endif /* check_chromaticities */
+      {
+         /* Use the historical REC 709 (etc) values: */
+         png_ptr->rgb_to_gray_red_coeff   = 6968;
+         png_ptr->rgb_to_gray_green_coeff = 23434;
+         /* png_ptr->rgb_to_gray_blue_coeff  = 2366; */
+      }
    }
 }
 #endif /* READ_RGB_TO_GRAY */
 
-#endif /* COLORSPACE */
-
 void /* PRIVATE */
 png_check_IHDR(png_const_structrp png_ptr,
     png_uint_32 width, png_uint_32 height, int bit_depth,
@@ -3320,7 +2764,27 @@ png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
 }
 #endif
 
-#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
+   !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
+   (defined(PNG_cLLI_SUPPORTED) || defined(PNG_mDCV_SUPPORTED))
+png_uint_32
+png_fixed_ITU(png_const_structrp png_ptr, double fp, png_const_charp text)
+{
+   double r = floor(10000 * fp + .5);
+
+   if (r > 2147483647. || r < 0)
+      png_fixed_error(png_ptr, text);
+
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+   PNG_UNUSED(text)
+#  endif
+
+   return (png_uint_32)r;
+}
+#endif
+
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\
     defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
 /* muldiv functions */
 /* This API takes signed arguments and rounds the result to the nearest
@@ -3328,7 +2792,7 @@ png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
  * the nearest .00001).  Overflow and divide by zero are signalled in
  * the result, a boolean - true on success, false on overflow.
  */
-int
+int /* PRIVATE */
 png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
     png_int_32 divisor)
 {
@@ -3442,27 +2906,7 @@ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
 
    return 0;
 }
-#endif /* READ_GAMMA || INCH_CONVERSIONS */
-
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
-/* The following is for when the caller doesn't much care about the
- * result.
- */
-png_fixed_point
-png_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times,
-    png_int_32 divisor)
-{
-   png_fixed_point result;
-
-   if (png_muldiv(&result, a, times, divisor) != 0)
-      return result;
-
-   png_warning(png_ptr, "fixed point overflow ignored");
-   return 0;
-}
-#endif
 
-#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */
 /* Calculate a reciprocal, return 0 on div-by-zero or overflow. */
 png_fixed_point
 png_reciprocal(png_fixed_point a)
@@ -3481,26 +2925,38 @@ png_reciprocal(png_fixed_point a)
 
    return 0; /* error/overflow */
 }
+#endif /* READ_GAMMA || COLORSPACE || INCH_CONVERSIONS || READ_pHYS */
 
+#ifdef PNG_READ_GAMMA_SUPPORTED
 /* This is the shared test on whether a gamma value is 'significant' - whether
  * it is worth doing gamma correction.
  */
 int /* PRIVATE */
 png_gamma_significant(png_fixed_point gamma_val)
 {
+   /* sRGB:       1/2.2 == 0.4545(45)
+    * AdobeRGB:   1/(2+51/256) ~= 0.45471 5dp
+    *
+    * So the correction from AdobeRGB to sRGB (output) is:
+    *
+    *    2.2/(2+51/256) == 1.00035524
+    *
+    * I.e. vanishly small (<4E-4) but still detectable in 16-bit linear (+/-
+    * 23).  Note that the Adobe choice seems to be something intended to give an
+    * exact number with 8 binary fractional digits - it is the closest to 2.2
+    * that is possible a base 2 .8p representation.
+    */
    return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED ||
        gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED;
 }
-#endif
 
-#ifdef PNG_READ_GAMMA_SUPPORTED
-#ifdef PNG_16BIT_SUPPORTED
+#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED
 /* A local convenience routine. */
 static png_fixed_point
 png_product2(png_fixed_point a, png_fixed_point b)
 {
-   /* The required result is 1/a * 1/b; the following preserves accuracy. */
-#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+   /* The required result is a * b; the following preserves accuracy. */
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED /* Should now be unused */
    double r = a * 1E-5;
    r *= b;
    r = floor(r+.5);
@@ -3516,9 +2972,8 @@ png_product2(png_fixed_point a, png_fixed_point b)
 
    return 0; /* overflow */
 }
-#endif /* 16BIT */
+#endif /* FLOATING_ARITHMETIC */
 
-/* The inverse of the above. */
 png_fixed_point
 png_reciprocal2(png_fixed_point a, png_fixed_point b)
 {
@@ -4171,10 +3626,27 @@ png_destroy_gamma_table(png_structrp png_ptr)
  * tables, we don't make a full table if we are reducing to 8-bit in
  * the future.  Note also how the gamma_16 tables are segmented so that
  * we don't need to allocate > 64K chunks for a full 16-bit table.
+ *
+ * TODO: move this to pngrtran.c and make it static.  Better yet create
+ * pngcolor.c and put all the PNG_COLORSPACE stuff in there.
  */
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+#  define GAMMA_TRANSFORMS 1 /* #ifdef CSE */
+#else
+#  define GAMMA_TRANSFORMS 0
+#endif
+
 void /* PRIVATE */
 png_build_gamma_table(png_structrp png_ptr, int bit_depth)
 {
+   png_fixed_point file_gamma, screen_gamma;
+   png_fixed_point correction;
+#  if GAMMA_TRANSFORMS
+      png_fixed_point file_to_linear, linear_to_screen;
+#  endif
+
    png_debug(1, "in png_build_gamma_table");
 
    /* Remove any existing table; this copes with multiple calls to
@@ -4189,27 +3661,44 @@ png_build_gamma_table(png_structrp png_ptr, int bit_depth)
       png_destroy_gamma_table(png_ptr);
    }
 
+   /* The following fields are set, finally, in png_init_read_transformations.
+    * If file_gamma is 0 (unset) nothing can be done otherwise if screen_gamma
+    * is 0 (unset) there is no gamma correction but to/from linear is possible.
+    */
+   file_gamma = png_ptr->file_gamma;
+   screen_gamma = png_ptr->screen_gamma;
+#  if GAMMA_TRANSFORMS
+      file_to_linear = png_reciprocal(file_gamma);
+#  endif
+
+   if (screen_gamma > 0)
+   {
+#     if GAMMA_TRANSFORMS
+         linear_to_screen = png_reciprocal(screen_gamma);
+#     endif
+      correction = png_reciprocal2(screen_gamma, file_gamma);
+   }
+   else /* screen gamma unknown */
+   {
+#     if GAMMA_TRANSFORMS
+         linear_to_screen = file_gamma;
+#     endif
+      correction = PNG_FP_1;
+   }
+
    if (bit_depth <= 8)
    {
-      png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
-          png_ptr->screen_gamma > 0 ?
-          png_reciprocal2(png_ptr->colorspace.gamma,
-          png_ptr->screen_gamma) : PNG_FP_1);
+      png_build_8bit_table(png_ptr, &png_ptr->gamma_table, correction);
 
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
-   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
-   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+#if GAMMA_TRANSFORMS
       if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
       {
-         png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
-             png_reciprocal(png_ptr->colorspace.gamma));
+         png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, file_to_linear);
 
          png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
-             png_ptr->screen_gamma > 0 ?
-             png_reciprocal(png_ptr->screen_gamma) :
-             png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+            linear_to_screen);
       }
-#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+#endif /* GAMMA_TRANSFORMS */
    }
 #ifdef PNG_16BIT_SUPPORTED
    else
@@ -4275,32 +3764,26 @@ png_build_gamma_table(png_structrp png_ptr, int bit_depth)
        * reduced to 8 bits.
        */
       if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
-          png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
-          png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
-          png_ptr->screen_gamma) : PNG_FP_1);
-
+         png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
+            png_reciprocal(correction));
       else
-          png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
-          png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
-          png_ptr->screen_gamma) : PNG_FP_1);
+         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
+            correction);
 
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
-   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
-   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+#  if GAMMA_TRANSFORMS
       if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
       {
          png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
-             png_reciprocal(png_ptr->colorspace.gamma));
+            file_to_linear);
 
          /* Notice that the '16 from 1' table should be full precision, however
           * the lookup on this table still uses gamma_shift, so it can't be.
           * TODO: fix this.
           */
          png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
-             png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
-             png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+            linear_to_screen);
       }
-#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+#endif /* GAMMA_TRANSFORMS */
    }
 #endif /* 16BIT */
 }
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/png.h b/src/java.desktop/share/native/libsplashscreen/libpng/png.h
index 9f61a773c1ddb..ede12c34fe607 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/png.h
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/png.h
@@ -29,9 +29,9 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * libpng version 1.6.43
+ * libpng version 1.6.47
  *
- * Copyright (c) 2018-2024 Cosmin Truta
+ * Copyright (c) 2018-2025 Cosmin Truta
  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
  * Copyright (c) 1996-1997 Andreas Dilger
  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -43,7 +43,7 @@
  *   libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
  *   libpng versions 0.97, January 1998, through 1.6.35, July 2018:
  *     Glenn Randers-Pehrson
- *   libpng versions 1.6.36, December 2018, through 1.6.43, February 2024:
+ *   libpng versions 1.6.36, December 2018, through 1.6.47, February 2025:
  *     Cosmin Truta
  *   See also "Contributing Authors", below.
  */
@@ -55,8 +55,8 @@
  * PNG Reference Library License version 2
  * ---------------------------------------
  *
- *  * Copyright (c) 1995-2024 The PNG Reference Library Authors.
- *  * Copyright (c) 2018-2024 Cosmin Truta.
+ *  * Copyright (c) 1995-2025 The PNG Reference Library Authors.
+ *  * Copyright (c) 2018-2025 Cosmin Truta.
  *  * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
  *  * Copyright (c) 1996-1997 Andreas Dilger.
  *  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -267,7 +267,7 @@
  *    ...
  *    1.5.30                  15    10530  15.so.15.30[.0]
  *    ...
- *    1.6.43                  16    10643  16.so.16.43[.0]
+ *    1.6.47                  16    10647  16.so.16.47[.0]
  *
  *    Henceforth the source version will match the shared-library major and
  *    minor numbers; the shared-library major version number will be used for
@@ -303,7 +303,7 @@
  */
 
 /* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.43"
+#define PNG_LIBPNG_VER_STRING "1.6.47"
 #define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n"
 
 /* The versions of shared library builds should stay in sync, going forward */
@@ -314,18 +314,18 @@
 /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
 #define PNG_LIBPNG_VER_MAJOR   1
 #define PNG_LIBPNG_VER_MINOR   6
-#define PNG_LIBPNG_VER_RELEASE 43
+#define PNG_LIBPNG_VER_RELEASE 47
 
 /* This should be zero for a public release, or non-zero for a
  * development version.
  */
-#define PNG_LIBPNG_VER_BUILD  0
+#define PNG_LIBPNG_VER_BUILD 0
 
 /* Release Status */
-#define PNG_LIBPNG_BUILD_ALPHA    1
-#define PNG_LIBPNG_BUILD_BETA     2
-#define PNG_LIBPNG_BUILD_RC       3
-#define PNG_LIBPNG_BUILD_STABLE   4
+#define PNG_LIBPNG_BUILD_ALPHA               1
+#define PNG_LIBPNG_BUILD_BETA                2
+#define PNG_LIBPNG_BUILD_RC                  3
+#define PNG_LIBPNG_BUILD_STABLE              4
 #define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
 
 /* Release-Specific Flags */
@@ -345,7 +345,7 @@
  * From version 1.0.1 it is:
  * XXYYZZ, where XX=major, YY=minor, ZZ=release
  */
-#define PNG_LIBPNG_VER 10643 /* 1.6.43 */
+#define PNG_LIBPNG_VER 10647 /* 1.6.47 */
 
 /* Library configuration: these options cannot be changed after
  * the library has been built.
@@ -455,7 +455,7 @@ extern "C" {
 /* This triggers a compiler error in png.c, if png.c and png.h
  * do not agree upon the version number.
  */
-typedef char* png_libpng_version_1_6_43;
+typedef char* png_libpng_version_1_6_47;
 
 /* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
  *
@@ -773,6 +773,21 @@ typedef png_unknown_chunk * * png_unknown_chunkpp;
 #define PNG_INFO_sCAL 0x4000U  /* ESR, 1.0.6 */
 #define PNG_INFO_IDAT 0x8000U  /* ESR, 1.0.6 */
 #define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */
+#define PNG_INFO_cICP 0x20000U /* PNGv3: 1.6.45 */
+#define PNG_INFO_cLLI 0x40000U /* PNGv3: 1.6.45 */
+#define PNG_INFO_mDCV 0x80000U /* PNGv3: 1.6.45 */
+/* APNG: these chunks are stored as unknown, these flags are never set
+ * however they are provided as a convenience for implementors of APNG and
+ * avoids any merge conflicts.
+ *
+ * Private chunks: these chunk names violate the chunk name recommendations
+ * because the chunk definitions have no signature and because the private
+ * chunks with these names have been reserved.  Private definitions should
+ * avoid them.
+ */
+#define PNG_INFO_acTL 0x100000U /* PNGv3: 1.6.45: unknown */
+#define PNG_INFO_fcTL 0x200000U /* PNGv3: 1.6.45: unknown */
+#define PNG_INFO_fdAT 0x400000U /* PNGv3: 1.6.45: unknown */
 
 /* This is used for the transformation routines, as some of them
  * change these values for the row.  It also should enable using
@@ -852,7 +867,7 @@ typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp,
  * your compiler.  This may be very difficult - try using a different compiler
  * to build the library!
  */
-PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef);
+PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), (jmp_buf, int), typedef);
 #endif
 
 /* Transform masks for the high-level interface */
@@ -2002,6 +2017,46 @@ PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr,
     png_fixed_point int_blue_Z))
 #endif
 
+#ifdef PNG_cICP_SUPPORTED
+PNG_EXPORT(250, png_uint_32, png_get_cICP, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr, png_bytep colour_primaries,
+    png_bytep transfer_function, png_bytep matrix_coefficients,
+    png_bytep video_full_range_flag));
+#endif
+
+#ifdef PNG_cICP_SUPPORTED
+PNG_EXPORT(251, void, png_set_cICP, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_byte colour_primaries,
+    png_byte transfer_function, png_byte matrix_coefficients,
+    png_byte video_full_range_flag));
+#endif
+
+#ifdef PNG_cLLI_SUPPORTED
+PNG_FP_EXPORT(252, png_uint_32, png_get_cLLI, (png_const_structrp png_ptr,
+         png_const_inforp info_ptr, double *maximum_content_light_level,
+         double *maximum_frame_average_light_level))
+PNG_FIXED_EXPORT(253, png_uint_32, png_get_cLLI_fixed,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr,
+    /* The values below are in cd/m2 (nits) and are scaled by 10,000; not
+     * 100,000 as in the case of png_fixed_point.
+     */
+    png_uint_32p maximum_content_light_level_scaled_by_10000,
+    png_uint_32p maximum_frame_average_light_level_scaled_by_10000))
+#endif
+
+#ifdef PNG_cLLI_SUPPORTED
+PNG_FP_EXPORT(254, void, png_set_cLLI, (png_const_structrp png_ptr,
+         png_inforp info_ptr, double maximum_content_light_level,
+         double maximum_frame_average_light_level))
+PNG_FIXED_EXPORT(255, void, png_set_cLLI_fixed, (png_const_structrp png_ptr,
+    png_inforp info_ptr,
+    /* The values below are in cd/m2 (nits) and are scaled by 10,000; not
+     * 100,000 as in the case of png_fixed_point.
+     */
+    png_uint_32 maximum_content_light_level_scaled_by_10000,
+    png_uint_32 maximum_frame_average_light_level_scaled_by_10000))
+#endif
+
 #ifdef PNG_eXIf_SUPPORTED
 PNG_EXPORT(246, png_uint_32, png_get_eXIf, (png_const_structrp png_ptr,
     png_inforp info_ptr, png_bytep *exif));
@@ -2046,6 +2101,60 @@ PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr,
     int color_type, int interlace_method, int compression_method,
     int filter_method));
 
+#ifdef PNG_mDCV_SUPPORTED
+PNG_FP_EXPORT(256, png_uint_32, png_get_mDCV, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr,
+    /* The chromaticities of the mastering display.  As cHRM, but independent of
+     * the encoding endpoints in cHRM, or cICP, or iCCP.  These values will
+     * always be in the range 0 to 1.3107.
+     */
+    double *white_x, double *white_y, double *red_x, double *red_y,
+    double *green_x, double *green_y, double *blue_x, double *blue_y,
+    /* Mastering display luminance in cd/m2 (nits). */
+    double *mastering_display_maximum_luminance,
+    double *mastering_display_minimum_luminance))
+
+PNG_FIXED_EXPORT(257, png_uint_32, png_get_mDCV_fixed,
+    (png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_fixed_point *int_white_x, png_fixed_point *int_white_y,
+    png_fixed_point *int_red_x, png_fixed_point *int_red_y,
+    png_fixed_point *int_green_x, png_fixed_point *int_green_y,
+    png_fixed_point *int_blue_x, png_fixed_point *int_blue_y,
+    /* Mastering display luminance in cd/m2 (nits) multiplied (scaled) by
+     * 10,000.
+     */
+    png_uint_32p mastering_display_maximum_luminance_scaled_by_10000,
+    png_uint_32p mastering_display_minimum_luminance_scaled_by_10000))
+#endif
+
+#ifdef PNG_mDCV_SUPPORTED
+PNG_FP_EXPORT(258, void, png_set_mDCV, (png_const_structrp png_ptr,
+    png_inforp info_ptr,
+    /* The chromaticities of the mastering display.  As cHRM, but independent of
+     * the encoding endpoints in cHRM, or cICP, or iCCP.
+     */
+    double white_x, double white_y, double red_x, double red_y, double green_x,
+    double green_y, double blue_x, double blue_y,
+    /* Mastering display luminance in cd/m2 (nits). */
+    double mastering_display_maximum_luminance,
+    double mastering_display_minimum_luminance))
+
+PNG_FIXED_EXPORT(259, void, png_set_mDCV_fixed, (png_const_structrp png_ptr,
+    png_inforp info_ptr,
+    /* The admissible range of these values is not the full range of a PNG
+     * fixed point value.  Negative values cannot be encoded and the maximum
+     * value is about 1.3 */
+    png_fixed_point int_white_x, png_fixed_point int_white_y,
+    png_fixed_point int_red_x, png_fixed_point int_red_y,
+    png_fixed_point int_green_x, png_fixed_point int_green_y,
+    png_fixed_point int_blue_x, png_fixed_point int_blue_y,
+    /* These are PNG unsigned 4 byte values: 31-bit unsigned values.  The MSB
+     * must be zero.
+     */
+    png_uint_32 mastering_display_maximum_luminance_scaled_by_10000,
+    png_uint_32 mastering_display_minimum_luminance_scaled_by_10000))
+#endif
+
 #ifdef PNG_oFFs_SUPPORTED
 PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr,
    png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
@@ -3266,7 +3375,7 @@ PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option,
  * one to use is one more than this.)
  */
 #ifdef PNG_EXPORT_LAST_ORDINAL
-  PNG_EXPORT_LAST_ORDINAL(249);
+  PNG_EXPORT_LAST_ORDINAL(259);
 #endif
 
 #ifdef __cplusplus
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h b/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
index b3b441b1122c2..70bca6fa1c90c 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
@@ -29,9 +29,9 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * libpng version 1.6.43
+ * libpng version 1.6.47
  *
- * Copyright (c) 2018-2024 Cosmin Truta
+ * Copyright (c) 2018-2025 Cosmin Truta
  * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
  * Copyright (c) 1996-1997 Andreas Dilger
  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -116,7 +116,7 @@
 
 /* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect
  * against legacy (pre ISOC90) compilers that did not understand function
- * prototypes.  It is not required for modern C compilers.
+ * prototypes.  [Deprecated.]
  */
 #ifndef PNGARG
 #  define PNGARG(arglist) arglist
@@ -326,7 +326,7 @@
 
 #ifndef PNG_EXPORTA
 #  define PNG_EXPORTA(ordinal, type, name, args, attributes) \
-      PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), PNGARG(args), \
+      PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), args, \
       PNG_LINKAGE_API attributes)
 #endif
 
@@ -344,7 +344,7 @@
 #endif
 
 #ifndef PNG_CALLBACK
-#  define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args)
+#  define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) args
 #endif
 
 /* Support for compiler specific function attributes.  These are used
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c
index ea8dd1721972c..ea0103331d347 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c
@@ -48,13 +48,14 @@
 
 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
 
-static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,
-    png_const_charp error_message)),PNG_NORETURN);
+static PNG_FUNCTION(void /* PRIVATE */,
+png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
+    PNG_NORETURN);
 
 #ifdef PNG_WARNINGS_SUPPORTED
 static void /* PRIVATE */
-png_default_warning PNGARG((png_const_structrp png_ptr,
-    png_const_charp warning_message));
+png_default_warning(png_const_structrp png_ptr,
+    png_const_charp warning_message);
 #endif /* WARNINGS */
 
 /* This function is called whenever there is a fatal error.  This function
@@ -963,23 +964,37 @@ png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
 int /* PRIVATE */
 png_safe_execute(png_imagep image, int (*function)(png_voidp), png_voidp arg)
 {
-   png_voidp saved_error_buf = image->opaque->error_buf;
+   const png_voidp saved_error_buf = image->opaque->error_buf;
    jmp_buf safe_jmpbuf;
-   int result;
 
    /* Safely execute function(arg), with png_error returning back here. */
    if (setjmp(safe_jmpbuf) == 0)
    {
+      int result;
+
       image->opaque->error_buf = safe_jmpbuf;
       result = function(arg);
       image->opaque->error_buf = saved_error_buf;
-      return result;
+
+      if (result)
+         return 1; /* success */
    }
 
-   /* On png_error, return via longjmp, pop the jmpbuf, and free the image. */
+   /* The function failed either because of a caught png_error and a regular
+    * return of false above or because of an uncaught png_error from the
+    * function itself.  Ensure that the error_buf is always set back to the
+    * value saved above:
+    */
    image->opaque->error_buf = saved_error_buf;
-   png_image_free(image);
-   return 0;
+
+   /* On the final false return, when about to return control to the caller, the
+    * image is freed (png_image_free does this check but it is duplicated here
+    * for clarity:
+    */
+   if (saved_error_buf == NULL)
+      png_image_free(image);
+
+   return 0; /* failure */
 }
 #endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */
 #endif /* READ || WRITE */
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c
index 41e0a5abc3a8d..d67adbae247a9 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c
@@ -409,7 +409,13 @@ png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns)
     * Notice that this can overflow - a warning is output and 0 is
     * returned.
     */
-   return png_muldiv_warn(png_ptr, microns, 500, 127);
+   png_fixed_point result;
+
+   if (png_muldiv(&result, microns, 500, 127) != 0)
+      return result;
+
+   png_warning(png_ptr, "fixed point overflow ignored");
+   return 0;
 }
 
 png_fixed_point PNGAPI
@@ -419,7 +425,7 @@ png_get_x_offset_inches_fixed(png_const_structrp png_ptr,
    return png_fixed_inches_from_microns(png_ptr,
        png_get_x_offset_microns(png_ptr, info_ptr));
 }
-#endif
+#endif /* FIXED_POINT */
 
 #ifdef PNG_FIXED_POINT_SUPPORTED
 png_fixed_point PNGAPI
@@ -547,44 +553,31 @@ png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
 #  ifdef PNG_FLOATING_POINT_SUPPORTED
 png_uint_32 PNGAPI
 png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
-    double *white_x, double *white_y, double *red_x, double *red_y,
-    double *green_x, double *green_y, double *blue_x, double *blue_y)
+    double *whitex, double *whitey, double *redx, double *redy,
+    double *greenx, double *greeny, double *bluex, double *bluey)
 {
    png_debug1(1, "in %s retrieval function", "cHRM");
 
-   /* Quiet API change: this code used to only return the end points if a cHRM
-    * chunk was present, but the end points can also come from iCCP or sRGB
-    * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and
-    * the png_set_ APIs merely check that set end points are mutually
-    * consistent.
-    */
+   /* PNGv3: this just returns the values store from the cHRM, if any. */
    if (png_ptr != NULL && info_ptr != NULL &&
-      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+       (info_ptr->valid & PNG_INFO_cHRM) != 0)
    {
-      if (white_x != NULL)
-         *white_x = png_float(png_ptr,
-             info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
-      if (white_y != NULL)
-         *white_y = png_float(png_ptr,
-             info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
-      if (red_x != NULL)
-         *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
-             "cHRM red X");
-      if (red_y != NULL)
-         *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
-             "cHRM red Y");
-      if (green_x != NULL)
-         *green_x = png_float(png_ptr,
-             info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
-      if (green_y != NULL)
-         *green_y = png_float(png_ptr,
-             info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
-      if (blue_x != NULL)
-         *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
-             "cHRM blue X");
-      if (blue_y != NULL)
-         *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
-             "cHRM blue Y");
+      if (whitex != NULL)
+         *whitex = png_float(png_ptr, info_ptr->cHRM.whitex, "cHRM wx");
+      if (whitey != NULL)
+         *whitey = png_float(png_ptr, info_ptr->cHRM.whitey, "cHRM wy");
+      if (redx   != NULL)
+         *redx   = png_float(png_ptr, info_ptr->cHRM.redx,   "cHRM rx");
+      if (redy   != NULL)
+         *redy   = png_float(png_ptr, info_ptr->cHRM.redy,   "cHRM ry");
+      if (greenx != NULL)
+         *greenx = png_float(png_ptr, info_ptr->cHRM.greenx, "cHRM gx");
+      if (greeny != NULL)
+         *greeny = png_float(png_ptr, info_ptr->cHRM.greeny, "cHRM gy");
+      if (bluex  != NULL)
+         *bluex  = png_float(png_ptr, info_ptr->cHRM.bluex,  "cHRM bx");
+      if (bluey  != NULL)
+         *bluey  = png_float(png_ptr, info_ptr->cHRM.bluey,  "cHRM by");
       return PNG_INFO_cHRM;
    }
 
@@ -597,38 +590,31 @@ png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
     double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
     double *blue_Z)
 {
+   png_XYZ XYZ;
    png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
 
    if (png_ptr != NULL && info_ptr != NULL &&
-       (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+       (info_ptr->valid & PNG_INFO_cHRM) != 0 &&
+       png_XYZ_from_xy(&XYZ, &info_ptr->cHRM) == 0)
    {
       if (red_X != NULL)
-         *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
-             "cHRM red X");
+         *red_X = png_float(png_ptr, XYZ.red_X, "cHRM red X");
       if (red_Y != NULL)
-         *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
-             "cHRM red Y");
+         *red_Y = png_float(png_ptr, XYZ.red_Y, "cHRM red Y");
       if (red_Z != NULL)
-         *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
-             "cHRM red Z");
+         *red_Z = png_float(png_ptr, XYZ.red_Z, "cHRM red Z");
       if (green_X != NULL)
-         *green_X = png_float(png_ptr,
-             info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
+         *green_X = png_float(png_ptr, XYZ.green_X, "cHRM green X");
       if (green_Y != NULL)
-         *green_Y = png_float(png_ptr,
-             info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
+         *green_Y = png_float(png_ptr, XYZ.green_Y, "cHRM green Y");
       if (green_Z != NULL)
-         *green_Z = png_float(png_ptr,
-             info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
+         *green_Z = png_float(png_ptr, XYZ.green_Z, "cHRM green Z");
       if (blue_X != NULL)
-         *blue_X = png_float(png_ptr,
-             info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
+         *blue_X = png_float(png_ptr, XYZ.blue_X, "cHRM blue X");
       if (blue_Y != NULL)
-         *blue_Y = png_float(png_ptr,
-             info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
+         *blue_Y = png_float(png_ptr, XYZ.blue_Y, "cHRM blue Y");
       if (blue_Z != NULL)
-         *blue_Z = png_float(png_ptr,
-             info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
+         *blue_Z = png_float(png_ptr, XYZ.blue_Z, "cHRM blue Z");
       return PNG_INFO_cHRM;
    }
 
@@ -645,29 +631,22 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
     png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
     png_fixed_point *int_blue_Z)
 {
+   png_XYZ XYZ;
    png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
 
    if (png_ptr != NULL && info_ptr != NULL &&
-      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+       (info_ptr->valid & PNG_INFO_cHRM) != 0U &&
+       png_XYZ_from_xy(&XYZ, &info_ptr->cHRM) == 0)
    {
-      if (int_red_X != NULL)
-         *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X;
-      if (int_red_Y != NULL)
-         *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y;
-      if (int_red_Z != NULL)
-         *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z;
-      if (int_green_X != NULL)
-         *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X;
-      if (int_green_Y != NULL)
-         *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y;
-      if (int_green_Z != NULL)
-         *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z;
-      if (int_blue_X != NULL)
-         *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X;
-      if (int_blue_Y != NULL)
-         *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y;
-      if (int_blue_Z != NULL)
-         *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z;
+      if (int_red_X != NULL) *int_red_X = XYZ.red_X;
+      if (int_red_Y != NULL) *int_red_Y = XYZ.red_Y;
+      if (int_red_Z != NULL) *int_red_Z = XYZ.red_Z;
+      if (int_green_X != NULL) *int_green_X = XYZ.green_X;
+      if (int_green_Y != NULL) *int_green_Y = XYZ.green_Y;
+      if (int_green_Z != NULL) *int_green_Z = XYZ.green_Z;
+      if (int_blue_X != NULL) *int_blue_X = XYZ.blue_X;
+      if (int_blue_Y != NULL) *int_blue_Y = XYZ.blue_Y;
+      if (int_blue_Z != NULL) *int_blue_Z = XYZ.blue_Z;
       return PNG_INFO_cHRM;
    }
 
@@ -676,31 +655,24 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
 
 png_uint_32 PNGAPI
 png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
-    png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
-    png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
-    png_fixed_point *blue_x, png_fixed_point *blue_y)
+    png_fixed_point *whitex, png_fixed_point *whitey, png_fixed_point *redx,
+    png_fixed_point *redy, png_fixed_point *greenx, png_fixed_point *greeny,
+    png_fixed_point *bluex, png_fixed_point *bluey)
 {
    png_debug1(1, "in %s retrieval function", "cHRM");
 
+   /* PNGv3: this just returns the values store from the cHRM, if any. */
    if (png_ptr != NULL && info_ptr != NULL &&
-      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+       (info_ptr->valid & PNG_INFO_cHRM) != 0)
    {
-      if (white_x != NULL)
-         *white_x = info_ptr->colorspace.end_points_xy.whitex;
-      if (white_y != NULL)
-         *white_y = info_ptr->colorspace.end_points_xy.whitey;
-      if (red_x != NULL)
-         *red_x = info_ptr->colorspace.end_points_xy.redx;
-      if (red_y != NULL)
-         *red_y = info_ptr->colorspace.end_points_xy.redy;
-      if (green_x != NULL)
-         *green_x = info_ptr->colorspace.end_points_xy.greenx;
-      if (green_y != NULL)
-         *green_y = info_ptr->colorspace.end_points_xy.greeny;
-      if (blue_x != NULL)
-         *blue_x = info_ptr->colorspace.end_points_xy.bluex;
-      if (blue_y != NULL)
-         *blue_y = info_ptr->colorspace.end_points_xy.bluey;
+      if (whitex != NULL) *whitex = info_ptr->cHRM.whitex;
+      if (whitey != NULL) *whitey = info_ptr->cHRM.whitey;
+      if (redx   != NULL) *redx   = info_ptr->cHRM.redx;
+      if (redy   != NULL) *redy   = info_ptr->cHRM.redy;
+      if (greenx != NULL) *greenx = info_ptr->cHRM.greenx;
+      if (greeny != NULL) *greeny = info_ptr->cHRM.greeny;
+      if (bluex  != NULL) *bluex  = info_ptr->cHRM.bluex;
+      if (bluey  != NULL) *bluey  = info_ptr->cHRM.bluey;
       return PNG_INFO_cHRM;
    }
 
@@ -717,11 +689,11 @@ png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
 {
    png_debug1(1, "in %s retrieval function", "gAMA");
 
+   /* PNGv3 compatibility: only report gAMA if it is really present. */
    if (png_ptr != NULL && info_ptr != NULL &&
-       (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
-       file_gamma != NULL)
+       (info_ptr->valid & PNG_INFO_gAMA) != 0)
    {
-      *file_gamma = info_ptr->colorspace.gamma;
+      if (file_gamma != NULL) *file_gamma = info_ptr->gamma;
       return PNG_INFO_gAMA;
    }
 
@@ -736,12 +708,13 @@ png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
 {
    png_debug1(1, "in %s retrieval function", "gAMA(float)");
 
+   /* PNGv3 compatibility: only report gAMA if it is really present. */
    if (png_ptr != NULL && info_ptr != NULL &&
-      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
-      file_gamma != NULL)
+       (info_ptr->valid & PNG_INFO_gAMA) != 0)
    {
-      *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
-          "png_get_gAMA");
+      if (file_gamma != NULL)
+         *file_gamma = png_float(png_ptr, info_ptr->gamma, "gAMA");
+
       return PNG_INFO_gAMA;
    }
 
@@ -758,9 +731,10 @@ png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr,
    png_debug1(1, "in %s retrieval function", "sRGB");
 
    if (png_ptr != NULL && info_ptr != NULL &&
-      (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL)
+      (info_ptr->valid & PNG_INFO_sRGB) != 0)
    {
-      *file_srgb_intent = info_ptr->colorspace.rendering_intent;
+      if (file_srgb_intent != NULL)
+         *file_srgb_intent = info_ptr->rendering_intent;
       return PNG_INFO_sRGB;
    }
 
@@ -813,6 +787,136 @@ png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
 }
 #endif
 
+#ifdef PNG_cICP_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cICP(png_const_structrp png_ptr,
+             png_const_inforp info_ptr, png_bytep colour_primaries,
+             png_bytep transfer_function, png_bytep matrix_coefficients,
+             png_bytep video_full_range_flag)
+{
+    png_debug1(1, "in %s retrieval function", "cICP");
+
+    if (png_ptr != NULL && info_ptr != NULL &&
+        (info_ptr->valid & PNG_INFO_cICP) != 0 &&
+        colour_primaries != NULL && transfer_function != NULL &&
+        matrix_coefficients != NULL && video_full_range_flag != NULL)
+    {
+        *colour_primaries = info_ptr->cicp_colour_primaries;
+        *transfer_function = info_ptr->cicp_transfer_function;
+        *matrix_coefficients = info_ptr->cicp_matrix_coefficients;
+        *video_full_range_flag = info_ptr->cicp_video_full_range_flag;
+        return (PNG_INFO_cICP);
+    }
+
+    return 0;
+}
+#endif
+
+#ifdef PNG_cLLI_SUPPORTED
+#  ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cLLI_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_uint_32p maxCLL,
+    png_uint_32p maxFALL)
+{
+   png_debug1(1, "in %s retrieval function", "cLLI");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_cLLI) != 0)
+   {
+      if (maxCLL != NULL) *maxCLL = info_ptr->maxCLL;
+      if (maxFALL != NULL) *maxFALL = info_ptr->maxFALL;
+      return PNG_INFO_cLLI;
+   }
+
+   return 0;
+}
+#  endif
+
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cLLI(png_const_structrp png_ptr, png_const_inforp info_ptr,
+      double *maxCLL, double *maxFALL)
+{
+   png_debug1(1, "in %s retrieval function", "cLLI(float)");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_cLLI) != 0)
+   {
+      if (maxCLL != NULL) *maxCLL = info_ptr->maxCLL * .0001;
+      if (maxFALL != NULL) *maxFALL = info_ptr->maxFALL * .0001;
+      return PNG_INFO_cLLI;
+   }
+
+   return 0;
+}
+#  endif
+#endif /* cLLI */
+
+#ifdef PNG_mDCV_SUPPORTED
+#  ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_mDCV_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_fixed_point *white_x, png_fixed_point *white_y,
+    png_fixed_point *red_x, png_fixed_point *red_y,
+    png_fixed_point *green_x, png_fixed_point *green_y,
+    png_fixed_point *blue_x, png_fixed_point *blue_y,
+    png_uint_32p mastering_maxDL, png_uint_32p mastering_minDL)
+{
+   png_debug1(1, "in %s retrieval function", "mDCV");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_mDCV) != 0)
+   {
+      if (white_x != NULL) *white_x = info_ptr->mastering_white_x * 2;
+      if (white_y != NULL) *white_y = info_ptr->mastering_white_y * 2;
+      if (red_x != NULL) *red_x = info_ptr->mastering_red_x * 2;
+      if (red_y != NULL) *red_y = info_ptr->mastering_red_y * 2;
+      if (green_x != NULL) *green_x = info_ptr->mastering_green_x * 2;
+      if (green_y != NULL) *green_y = info_ptr->mastering_green_y * 2;
+      if (blue_x != NULL) *blue_x = info_ptr->mastering_blue_x * 2;
+      if (blue_y != NULL) *blue_y = info_ptr->mastering_blue_y * 2;
+      if (mastering_maxDL != NULL) *mastering_maxDL = info_ptr->mastering_maxDL;
+      if (mastering_minDL != NULL) *mastering_minDL = info_ptr->mastering_minDL;
+      return PNG_INFO_mDCV;
+   }
+
+   return 0;
+}
+#  endif
+
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_mDCV(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    double *white_x, double *white_y, double *red_x, double *red_y,
+    double *green_x, double *green_y, double *blue_x, double *blue_y,
+    double *mastering_maxDL, double *mastering_minDL)
+{
+   png_debug1(1, "in %s retrieval function", "mDCV(float)");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_mDCV) != 0)
+   {
+      if (white_x != NULL) *white_x = info_ptr->mastering_white_x * .00002;
+      if (white_y != NULL) *white_y = info_ptr->mastering_white_y * .00002;
+      if (red_x != NULL) *red_x = info_ptr->mastering_red_x * .00002;
+      if (red_y != NULL) *red_y = info_ptr->mastering_red_y * .00002;
+      if (green_x != NULL) *green_x = info_ptr->mastering_green_x * .00002;
+      if (green_y != NULL) *green_y = info_ptr->mastering_green_y * .00002;
+      if (blue_x != NULL) *blue_x = info_ptr->mastering_blue_x * .00002;
+      if (blue_y != NULL) *blue_y = info_ptr->mastering_blue_y * .00002;
+      if (mastering_maxDL != NULL)
+         *mastering_maxDL = info_ptr->mastering_maxDL * .0001;
+      if (mastering_minDL != NULL)
+         *mastering_minDL = info_ptr->mastering_minDL * .0001;
+      return PNG_INFO_mDCV;
+   }
+
+   return 0;
+}
+#  endif /* FLOATING_POINT */
+#endif /* mDCV */
+
 #ifdef PNG_eXIf_SUPPORTED
 png_uint_32 PNGAPI
 png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pnginfo.h b/src/java.desktop/share/native/libsplashscreen/libpng/pnginfo.h
index d241eaebffbbc..bc6ed3d09c97e 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pnginfo.h
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pnginfo.h
@@ -115,18 +115,12 @@ struct png_info_def
     * and initialize the appropriate fields below.
     */
 
-#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
-   /* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are
-    * defined.  When COLORSPACE is switched on all the colorspace-defining
-    * chunks should be enabled, when GAMMA is switched on all the gamma-defining
-    * chunks should be enabled.  If this is not done it becomes possible to read
-    * inconsistent PNG files and assign a probably incorrect interpretation to
-    * the information.  (In other words, by carefully choosing which chunks to
-    * recognize the system configuration can select an interpretation for PNG
-    * files containing ambiguous data and this will result in inconsistent
-    * behavior between different libpng builds!)
-    */
-   png_colorspace colorspace;
+#ifdef PNG_cICP_SUPPORTED
+   /* cICP chunk data */
+   png_byte cicp_colour_primaries;
+   png_byte cicp_transfer_function;
+   png_byte cicp_matrix_coefficients;
+   png_byte cicp_video_full_range_flag;
 #endif
 
 #ifdef PNG_iCCP_SUPPORTED
@@ -136,6 +130,24 @@ struct png_info_def
    png_uint_32 iccp_proflen;  /* ICC profile data length */
 #endif
 
+#ifdef PNG_cLLI_SUPPORTED
+   png_uint_32 maxCLL;  /* cd/m2 (nits) * 10,000 */
+   png_uint_32 maxFALL;
+#endif
+
+#ifdef PNG_mDCV_SUPPORTED
+   png_uint_16 mastering_red_x;  /* CIE (xy) x * 50,000 */
+   png_uint_16 mastering_red_y;
+   png_uint_16 mastering_green_x;
+   png_uint_16 mastering_green_y;
+   png_uint_16 mastering_blue_x;
+   png_uint_16 mastering_blue_y;
+   png_uint_16 mastering_white_x;
+   png_uint_16 mastering_white_y;
+   png_uint_32 mastering_maxDL; /* cd/m2 (nits) * 10,000 */
+   png_uint_32 mastering_minDL;
+#endif
+
 #ifdef PNG_TEXT_SUPPORTED
    /* The tEXt, and zTXt chunks contain human-readable textual data in
     * uncompressed, compressed, and optionally compressed forms, respectively.
@@ -214,11 +226,8 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
 #endif
 
 #ifdef PNG_eXIf_SUPPORTED
-   int num_exif;  /* Added at libpng-1.6.31 */
+   png_uint_32 num_exif;  /* Added at libpng-1.6.31 */
    png_bytep exif;
-# ifdef PNG_READ_eXIf_SUPPORTED
-   png_bytep eXIf_buf;  /* Added at libpng-1.6.32 */
-# endif
 #endif
 
 #ifdef PNG_hIST_SUPPORTED
@@ -291,5 +300,16 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
    png_bytepp row_pointers;        /* the image bits */
 #endif
 
+#ifdef PNG_cHRM_SUPPORTED
+   png_xy cHRM;
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+   png_fixed_point gamma;
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+   int rendering_intent;
+#endif
 };
 #endif /* PNGINFO_H */
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h b/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
index e238ccdb9a4d9..906f855db0e5f 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
@@ -31,9 +31,9 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  */
-/* libpng version 1.6.43 */
+/* libpng version 1.6.47 */
 
-/* Copyright (c) 2018-2023 Cosmin Truta */
+/* Copyright (c) 2018-2025 Cosmin Truta */
 /* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */
 
 /* This code is released under the libpng license. */
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngmem.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngmem.c
index d5ad0735f37b2..ba9eb4df402b7 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngmem.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngmem.c
@@ -101,30 +101,29 @@ png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
     * to implement a user memory handler.  This checks to be sure it isn't
     * called with big numbers.
     */
-#ifndef PNG_USER_MEM_SUPPORTED
-   PNG_UNUSED(png_ptr)
-#endif
+#  ifdef PNG_MAX_MALLOC_64K
+      /* This is support for legacy systems which had segmented addressing
+       * limiting the maximum allocation size to 65536.  It takes precedence
+       * over PNG_SIZE_MAX which is set to 65535 on true 16-bit systems.
+       *
+       * TODO: libpng-1.8: finally remove both cases.
+       */
+      if (size > 65536U) return NULL;
+#  endif
 
-   /* Some compilers complain that this is always true.  However, it
-    * can be false when integer overflow happens.
+   /* This is checked too because the system malloc call below takes a (size_t).
     */
-   if (size > 0 && size <= PNG_SIZE_MAX
-#     ifdef PNG_MAX_MALLOC_64K
-         && size <= 65536U
-#     endif
-      )
-   {
-#ifdef PNG_USER_MEM_SUPPORTED
+   if (size > PNG_SIZE_MAX) return NULL;
+
+#  ifdef PNG_USER_MEM_SUPPORTED
       if (png_ptr != NULL && png_ptr->malloc_fn != NULL)
          return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);
+#  else
+      PNG_UNUSED(png_ptr)
+#  endif
 
-      else
-#endif
-         return malloc((size_t)size); /* checked for truncation above */
-   }
-
-   else
-      return NULL;
+   /* Use the system malloc */
+   return malloc((size_t)/*SAFE*/size); /* checked for truncation above */
 }
 
 #if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngpread.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngpread.c
index 816631cae189b..86d0c7aaa6447 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngpread.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngpread.c
@@ -60,6 +60,21 @@ if (png_ptr->push_length + 4 > png_ptr->buffer_size) \
 if (png_ptr->buffer_size < N) \
    { png_push_save_buffer(png_ptr); return; }
 
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+/* Arrays to facilitate interlacing - use pass (0 - 6) as index. */
+
+/* Start of interlace block */
+static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+/* Offset to next interlace block */
+static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+/* Start of interlace block in the y direction */
+static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+/* Offset to next interlace block in the y direction */
+static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+
+/* TODO: Move these arrays to a common utility module to avoid duplication. */
+#endif
+
 void PNGAPI
 png_process_data(png_structrp png_ptr, png_inforp info_ptr,
     png_bytep buffer, size_t buffer_size)
@@ -207,17 +222,8 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
     */
    if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
    {
-      png_byte chunk_length[4];
-      png_byte chunk_tag[4];
-
       PNG_PUSH_SAVE_BUFFER_IF_LT(8)
-      png_push_fill_buffer(png_ptr, chunk_length, 4);
-      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
-      png_reset_crc(png_ptr);
-      png_crc_read(png_ptr, chunk_tag, 4);
-      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
-      png_check_chunk_name(png_ptr, png_ptr->chunk_name);
-      png_check_chunk_length(png_ptr, png_ptr->push_length);
+      png_ptr->push_length = png_read_chunk_header(png_ptr);
       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    }
 
@@ -258,13 +264,13 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
          png_error(png_ptr, "Invalid IHDR length");
 
       PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
+      png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length);
    }
 
    else if (chunk_name == png_IEND)
    {
       PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
+      png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length);
 
       png_ptr->process_mode = PNG_READ_DONE_MODE;
       png_push_have_end(png_ptr, info_ptr);
@@ -281,12 +287,6 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
    }
 #endif
 
-   else if (chunk_name == png_PLTE)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
    else if (chunk_name == png_IDAT)
    {
       png_ptr->idat_size = png_ptr->push_length;
@@ -299,155 +299,10 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
       return;
    }
 
-#ifdef PNG_READ_gAMA_SUPPORTED
-   else if (png_ptr->chunk_name == png_gAMA)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_sBIT_SUPPORTED
-   else if (png_ptr->chunk_name == png_sBIT)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_cHRM_SUPPORTED
-   else if (png_ptr->chunk_name == png_cHRM)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_eXIf_SUPPORTED
-   else if (png_ptr->chunk_name == png_eXIf)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_eXIf(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_sRGB_SUPPORTED
-   else if (chunk_name == png_sRGB)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_iCCP_SUPPORTED
-   else if (png_ptr->chunk_name == png_iCCP)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_sPLT_SUPPORTED
-   else if (chunk_name == png_sPLT)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_tRNS_SUPPORTED
-   else if (chunk_name == png_tRNS)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_bKGD_SUPPORTED
-   else if (chunk_name == png_bKGD)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_hIST_SUPPORTED
-   else if (chunk_name == png_hIST)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_pHYs_SUPPORTED
-   else if (chunk_name == png_pHYs)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_oFFs_SUPPORTED
-   else if (chunk_name == png_oFFs)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
-   }
-#endif
-
-#ifdef PNG_READ_pCAL_SUPPORTED
-   else if (chunk_name == png_pCAL)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_sCAL_SUPPORTED
-   else if (chunk_name == png_sCAL)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_tIME_SUPPORTED
-   else if (chunk_name == png_tIME)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_tEXt_SUPPORTED
-   else if (chunk_name == png_tEXt)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_zTXt_SUPPORTED
-   else if (chunk_name == png_zTXt)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
-   }
-
-#endif
-#ifdef PNG_READ_iTXt_SUPPORTED
-   else if (chunk_name == png_iTXt)
-   {
-      PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
-   }
-#endif
-
    else
    {
       PNG_PUSH_SAVE_BUFFER_IF_FULL
-      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
-          PNG_HANDLE_CHUNK_AS_DEFAULT);
+      png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length);
    }
 
    png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
@@ -1004,27 +859,6 @@ png_push_process_row(png_structrp png_ptr)
 void /* PRIVATE */
 png_read_push_finish_row(png_structrp png_ptr)
 {
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
-   /* Start of interlace block */
-   static const png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
-
-   /* Offset to next interlace block */
-   static const png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
-
-   /* Start of interlace block in the y direction */
-   static const png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
-
-   /* Offset to next interlace block in the y direction */
-   static const png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
-
-   /* Height of interlace block.  This is not currently used - if you need
-    * it, uncomment it here and in png.h
-   static const png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
-   */
-#endif
-
    png_ptr->row_number++;
    if (png_ptr->row_number < png_ptr->num_rows)
       return;
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h b/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h
index 18424542b00bf..25bac4b9e69b4 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h
@@ -168,47 +168,6 @@
     * callbacks to do this.
     */
 #  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon
-
-   /* By default the 'intrinsics' code in arm/filter_neon_intrinsics.c is used
-    * if possible - if __ARM_NEON__ is set and the compiler version is not known
-    * to be broken.  This is controlled by PNG_ARM_NEON_IMPLEMENTATION which can
-    * be:
-    *
-    *    1  The intrinsics code (the default with __ARM_NEON__)
-    *    2  The hand coded assembler (the default without __ARM_NEON__)
-    *
-    * It is possible to set PNG_ARM_NEON_IMPLEMENTATION in CPPFLAGS, however
-    * this is *NOT* supported and may cease to work even after a minor revision
-    * to libpng.  It *is* valid to do this for testing purposes, e.g. speed
-    * testing or a new compiler, but the results should be communicated to the
-    * libpng implementation list for incorporation in the next minor release.
-    */
-#  ifndef PNG_ARM_NEON_IMPLEMENTATION
-#     if defined(__ARM_NEON__) || defined(__ARM_NEON)
-#        if defined(__clang__)
-            /* At present it is unknown by the libpng developers which versions
-             * of clang support the intrinsics, however some or perhaps all
-             * versions do not work with the assembler so this may be
-             * irrelevant, so just use the default (do nothing here.)
-             */
-#        elif defined(__GNUC__)
-            /* GCC 4.5.4 NEON support is known to be broken.  4.6.3 is known to
-             * work, so if this *is* GCC, or G++, look for a version >4.5
-             */
-#           if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)
-#              define PNG_ARM_NEON_IMPLEMENTATION 2
-#           endif /* no GNUC support */
-#        endif /* __GNUC__ */
-#     else /* !defined __ARM_NEON__ */
-         /* The 'intrinsics' code simply won't compile without this -mfpu=neon:
-          */
-#        if !defined(__aarch64__) && !defined(_M_ARM64)
-            /* The assembler code currently does not work on ARM64 */
-#          define PNG_ARM_NEON_IMPLEMENTATION 2
-#        endif /* __aarch64__ */
-#     endif /* __ARM_NEON__ */
-#  endif /* !PNG_ARM_NEON_IMPLEMENTATION */
-
 #  ifndef PNG_ARM_NEON_IMPLEMENTATION
       /* Use the intrinsics code by default. */
 #     define PNG_ARM_NEON_IMPLEMENTATION 1
@@ -741,7 +700,7 @@
 #define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200U
 #define PNG_FLAG_CRC_CRITICAL_USE         0x0400U
 #define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800U
-#define PNG_FLAG_ASSUME_sRGB              0x1000U /* Added to libpng-1.5.4 */
+/*      PNG_FLAG_ASSUME_sRGB unused       0x1000U  * Added to libpng-1.5.4 */
 #define PNG_FLAG_OPTIMIZE_ALPHA           0x2000U /* Added to libpng-1.5.4 */
 #define PNG_FLAG_DETECT_UNINITIALIZED     0x4000U /* Added to libpng-1.5.4 */
 /* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000U */
@@ -852,6 +811,8 @@
 #ifdef PNG_FIXED_POINT_MACRO_SUPPORTED
 #define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\
     ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0))
+#define png_fixed_ITU(png_ptr, fp, s) ((fp) <= 214748 && (fp) >= 0 ?\
+    ((png_uint_32)(10000 * (fp))) : (png_fixed_error(png_ptr, s),0))
 #endif
 /* else the corresponding function is defined below, inside the scope of the
  * cplusplus test.
@@ -870,11 +831,31 @@
  *
  * PNG_32b correctly produces a value shifted by up to 24 bits, even on
  * architectures where (int) is only 16 bits.
+ *
+ * 1.6.47: PNG_32b was made into a preprocessor evaluable macro by replacing the
+ * static_cast with a promoting binary operation using a guaranteed 32-bit
+ * (minimum) unsigned value.
  */
-#define PNG_32b(b,s) ((png_uint_32)(b) << (s))
+#define PNG_32b(b,s) (((0xFFFFFFFFU)&(b)) << (s))
 #define PNG_U32(b1,b2,b3,b4) \
    (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0))
 
+/* Chunk name validation.  When using these macros all the arguments should be
+ * constants, otherwise code bloat may well occur.  The macros are provided
+ * primarily for use in #if checks.
+ *
+ * PNG_32to8 produces a byte value with the right shift; used to extract the
+ * byte value from a chunk name.
+ */
+#define PNG_32to8(cn,s) (((cn) >> (s)) & 0xffU)
+#define PNG_CN_VALID_UPPER(b) ((b) >= 65 && (b) <= 90) /* upper-case ASCII */
+#define PNG_CN_VALID_ASCII(b) PNG_CN_VALID_UPPER((b) & ~32U)
+#define PNG_CHUNK_NAME_VALID(cn) (\
+   PNG_CN_VALID_ASCII(PNG_32to8(cn,24)) && /* critical, !ancillary */\
+   PNG_CN_VALID_ASCII(PNG_32to8(cn,16)) && /* public, !privately defined */\
+   PNG_CN_VALID_UPPER(PNG_32to8(cn, 8)) && /* VALID, !reserved */\
+   PNG_CN_VALID_ASCII(PNG_32to8(cn, 0))   /* data-dependent, !copy ok */)
+
 /* Constants for known chunk types.
  *
  * MAINTAINERS: If you need to add a chunk, define the name here.
@@ -902,9 +883,14 @@
 #define png_IEND PNG_U32( 73,  69,  78,  68)
 #define png_IHDR PNG_U32( 73,  72,  68,  82)
 #define png_PLTE PNG_U32( 80,  76,  84,  69)
+#define png_acTL PNG_U32( 97,  99,  84,  76) /* PNGv3: APNG */
 #define png_bKGD PNG_U32( 98,  75,  71,  68)
 #define png_cHRM PNG_U32( 99,  72,  82,  77)
+#define png_cICP PNG_U32( 99,  73,  67,  80) /* PNGv3 */
+#define png_cLLI PNG_U32( 99,  76,  76,  73) /* PNGv3 */
 #define png_eXIf PNG_U32(101,  88,  73, 102) /* registered July 2017 */
+#define png_fcTL PNG_U32(102,  99,  84,  76) /* PNGv3: APNG */
+#define png_fdAT PNG_U32(102, 100,  65,  84) /* PNGv3: APNG */
 #define png_fRAc PNG_U32(102,  82,  65,  99) /* registered, not defined */
 #define png_gAMA PNG_U32(103,  65,  77,  65)
 #define png_gIFg PNG_U32(103,  73,  70, 103)
@@ -913,6 +899,7 @@
 #define png_hIST PNG_U32(104,  73,  83,  84)
 #define png_iCCP PNG_U32(105,  67,  67,  80)
 #define png_iTXt PNG_U32(105,  84,  88, 116)
+#define png_mDCV PNG_U32(109,  68,  67,  86) /* PNGv3 */
 #define png_oFFs PNG_U32(111,  70,  70, 115)
 #define png_pCAL PNG_U32(112,  67,  65,  76)
 #define png_pHYs PNG_U32(112,  72,  89, 115)
@@ -953,11 +940,74 @@
 #define PNG_CHUNK_RESERVED(c)     (1 & ((c) >> 13))
 #define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >>  5))
 
+/* Known chunks.  All supported chunks must be listed here.  The macro PNG_CHUNK
+ * contains the four character ASCII name by which the chunk is identified.  The
+ * macro is implemented as required to build tables or switch statements which
+ * require entries for every known chunk.  The macro also contains an index
+ * value which should be in order (this is checked in png.c).
+ *
+ * Notice that "known" does not require "SUPPORTED"; tables should be built in
+ * such a way that chunks unsupported in a build require no more than the table
+ * entry (which should be small.)  In particular function pointers for
+ * unsupported chunks should be NULL.
+ *
+ * At present these index values are not exported (not part of the public API)
+ * so can be changed at will.  For convenience the names are in lexical sort
+ * order but with the critical chunks at the start in the order of occurence in
+ * a PNG.
+ *
+ * PNG_INFO_ values do not exist for every one of these chunk handles; for
+ * example PNG_INFO_{IDAT,IEND,tEXt,iTXt,zTXt} and possibly other chunks in the
+ * future.
+ */
+#define PNG_KNOWN_CHUNKS\
+   PNG_CHUNK(IHDR,  0)\
+   PNG_CHUNK(PLTE,  1)\
+   PNG_CHUNK(IDAT,  2)\
+   PNG_CHUNK(IEND,  3)\
+   PNG_CHUNK(acTL,  4)\
+   PNG_CHUNK(bKGD,  5)\
+   PNG_CHUNK(cHRM,  6)\
+   PNG_CHUNK(cICP,  7)\
+   PNG_CHUNK(cLLI,  8)\
+   PNG_CHUNK(eXIf,  9)\
+   PNG_CHUNK(fcTL, 10)\
+   PNG_CHUNK(fdAT, 11)\
+   PNG_CHUNK(gAMA, 12)\
+   PNG_CHUNK(hIST, 13)\
+   PNG_CHUNK(iCCP, 14)\
+   PNG_CHUNK(iTXt, 15)\
+   PNG_CHUNK(mDCV, 16)\
+   PNG_CHUNK(oFFs, 17)\
+   PNG_CHUNK(pCAL, 18)\
+   PNG_CHUNK(pHYs, 19)\
+   PNG_CHUNK(sBIT, 20)\
+   PNG_CHUNK(sCAL, 21)\
+   PNG_CHUNK(sPLT, 22)\
+   PNG_CHUNK(sRGB, 23)\
+   PNG_CHUNK(tEXt, 24)\
+   PNG_CHUNK(tIME, 25)\
+   PNG_CHUNK(tRNS, 26)\
+   PNG_CHUNK(zTXt, 27)
+
 /* Gamma values (new at libpng-1.5.4): */
 #define PNG_GAMMA_MAC_OLD 151724  /* Assume '1.8' is really 2.2/1.45! */
 #define PNG_GAMMA_MAC_INVERSE 65909
 #define PNG_GAMMA_sRGB_INVERSE 45455
 
+/* gamma sanity check.  libpng cannot implement gamma transforms outside a
+ * certain limit because of its use of 16-bit fixed point intermediate values.
+ * Gamma values that are too large or too small will zap the 16-bit values all
+ * to 0 or 65535 resulting in an obvious 'bad' image.
+ *
+ * In libpng 1.6.0 the limits were changed from 0.07..3 to 0.01..100 to
+ * accommodate the optimal 16-bit gamma of 36 and its reciprocal.
+ *
+ * These are png_fixed_point integral values:
+ */
+#define PNG_LIB_GAMMA_MIN 1000
+#define PNG_LIB_GAMMA_MAX 10000000
+
 /* Almost everything below is C specific; the #defines above can be used in
  * non-C code (so long as it is C-preprocessed) the rest of this stuff cannot.
  */
@@ -1021,7 +1071,6 @@ extern "C" {
  *
  * All of these functions must be declared with PNG_INTERNAL_FUNCTION.
  */
-
 /* Zlib support */
 #define PNG_UNEXPECTED_ZLIB_RETURN (-7)
 PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret),
@@ -1040,6 +1089,7 @@ PNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr,
    !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
    (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
    defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+   defined(PNG_mDCV_SUPPORTED) || \
    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
    (defined(PNG_sCAL_SUPPORTED) && \
    defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
@@ -1047,12 +1097,38 @@ PNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr,
    double fp, png_const_charp text),PNG_EMPTY);
 #endif
 
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
+   !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
+   (defined(PNG_cLLI_SUPPORTED) || defined(PNG_mDCV_SUPPORTED))
+PNG_INTERNAL_FUNCTION(png_uint_32,png_fixed_ITU,(png_const_structrp png_ptr,
+   double fp, png_const_charp text),PNG_EMPTY);
+#endif
+
 /* Check the user version string for compatibility, returns false if the version
  * numbers aren't compatible.
  */
 PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr,
    png_const_charp user_png_ver),PNG_EMPTY);
 
+#ifdef PNG_READ_SUPPORTED /* should only be used on read */
+/* Security: read limits on the largest allocations while reading a PNG.  This
+ * avoids very large allocations caused by PNG files with damaged or altered
+ * chunk 'length' fields.
+ */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED /* run-time limit */
+#  define png_chunk_max(png_ptr) ((png_ptr)->user_chunk_malloc_max)
+
+#elif PNG_USER_CHUNK_MALLOC_MAX > 0 /* compile-time limit */
+#  define png_chunk_max(png_ptr) ((void)png_ptr, PNG_USER_CHUNK_MALLOC_MAX)
+
+#elif (defined PNG_MAX_MALLOC_64K)  /* legacy system limit */
+#  define png_chunk_max(png_ptr) ((void)png_ptr, 65536U)
+
+#else                               /* modern system limit SIZE_MAX (C99) */
+#  define png_chunk_max(png_ptr) ((void)png_ptr, PNG_SIZE_MAX)
+#endif
+#endif /* READ */
+
 /* Internal base allocator - no messages, NULL on failure to allocate.  This
  * does, however, call the application provided allocator and that could call
  * png_error (although that would be a bug in the application implementation.)
@@ -1152,9 +1228,6 @@ PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf,
 PNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr,
    png_uint_32 skip),PNG_EMPTY);
 
-/* Read the CRC from the file and compare it to the libpng calculated CRC */
-PNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY);
-
 /* Calculate the CRC over a section of data.  Note that we are only
  * passing a maximum of 64K on systems that have this as a memory limit,
  * since this is the maximum buffer size we can specify.
@@ -1200,6 +1273,26 @@ PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr,
    /* The xy value must have been previously validated */
 #endif
 
+#ifdef PNG_WRITE_cICP_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_cICP,(png_structrp png_ptr,
+    png_byte colour_primaries, png_byte transfer_function,
+    png_byte matrix_coefficients, png_byte video_full_range_flag), PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_cLLI_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_cLLI_fixed,(png_structrp png_ptr,
+   png_uint_32 maxCLL, png_uint_32 maxFALL), PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_mDCV_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_mDCV_fixed,(png_structrp png_ptr,
+   png_uint_16 red_x, png_uint_16 red_y,
+   png_uint_16 green_x, png_uint_16 green_y,
+   png_uint_16 blue_x, png_uint_16 blue_y,
+   png_uint_16 white_x, png_uint_16 white_y,
+   png_uint_32 maxDL, png_uint_32 minDL), PNG_EMPTY);
+#endif
+
 #ifdef PNG_WRITE_sRGB_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr,
     int intent),PNG_EMPTY);
@@ -1212,10 +1305,10 @@ PNG_INTERNAL_FUNCTION(void,png_write_eXIf,(png_structrp png_ptr,
 
 #ifdef PNG_WRITE_iCCP_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
-   png_const_charp name, png_const_bytep profile), PNG_EMPTY);
-   /* The profile must have been previously validated for correctness, the
-    * length comes from the first four bytes.  Only the base, deflate,
-    * compression is supported.
+   png_const_charp name, png_const_bytep profile, png_uint_32 proflen),
+   PNG_EMPTY);
+   /* Writes a previously 'set' profile.  The profile argument is **not**
+    * compressed.
     */
 #endif
 
@@ -1524,119 +1617,36 @@ PNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info,
 /* The following decodes the appropriate chunks, and does error correction,
  * then calls the appropriate callback for the chunk if it is valid.
  */
-
-/* Decode the IHDR chunk */
-PNG_INTERNAL_FUNCTION(void,png_handle_IHDR,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void,png_handle_PLTE,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void,png_handle_IEND,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-
-#ifdef PNG_READ_bKGD_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_bKGD,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_cHRM_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_eXIf_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_eXIf,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_gAMA_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_hIST_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_hIST,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_iCCP_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_iCCP,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif /* READ_iCCP */
-
-#ifdef PNG_READ_iTXt_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_iTXt,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_oFFs_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_oFFs,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_pCAL_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_pCAL,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_pHYs_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_pHYs,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_sBIT_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_sBIT,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_sCAL_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_sCAL,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_sPLT_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_sPLT,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif /* READ_sPLT */
-
-#ifdef PNG_READ_sRGB_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_sRGB,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_tEXt_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_tEXt,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_tIME_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_tIME,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_tRNS_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_tRNS,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_zTXt_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-#endif
-
-PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr,
-    png_uint_32 chunk_name),PNG_EMPTY);
-
-PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr,
-    png_uint_32 chunk_length),PNG_EMPTY);
-
-PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);
+typedef enum
+{
+   /* Result of a call to png_handle_chunk made to handle the current chunk
+    * png_struct::chunk_name on read.  Always informational, either the stream
+    * is read for the next chunk or the routine will call png_error.
+    *
+    * NOTE: order is important internally.  handled_saved and above are regarded
+    * as handling the chunk.
+    */
+   handled_error = 0,  /* bad crc or known and bad format or too long */
+   handled_discarded,  /* not saved in the unknown chunk list */
+   handled_saved,      /* saved in the unknown chunk list */
+   handled_ok          /* known, supported and handled without error */
+} png_handle_result_code;
+
+PNG_INTERNAL_FUNCTION(png_handle_result_code,png_handle_unknown,
+    (png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length, int keep),
+    PNG_EMPTY);
    /* This is the function that gets called for unknown chunks.  The 'keep'
     * argument is either non-zero for a known chunk that has been set to be
     * handled as unknown or zero for an unknown chunk.  By default the function
     * just skips the chunk or errors out if it is critical.
     */
 
+PNG_INTERNAL_FUNCTION(png_handle_result_code,png_handle_chunk,
+    (png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+   /* This handles the current chunk png_ptr->chunk_name with unread
+    * data[length] and returns one of the above result codes.
+    */
+
 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
     defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
 PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling,
@@ -1676,8 +1686,6 @@ PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr,
     png_bytep buffer, size_t buffer_length),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr),
     PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr,
-   png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr,
    png_inforp info_ptr),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr,
@@ -1690,109 +1698,28 @@ PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr,
     png_inforp info_ptr),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr),
     PNG_EMPTY);
-#  ifdef PNG_READ_tEXt_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_push_handle_tEXt,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void,png_push_read_tEXt,(png_structrp png_ptr,
-    png_inforp info_ptr),PNG_EMPTY);
-#  endif
-#  ifdef PNG_READ_zTXt_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_push_handle_zTXt,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void,png_push_read_zTXt,(png_structrp png_ptr,
-    png_inforp info_ptr),PNG_EMPTY);
-#  endif
-#  ifdef PNG_READ_iTXt_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_push_handle_iTXt,(png_structrp png_ptr,
-    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void,png_push_read_iTXt,(png_structrp png_ptr,
-    png_inforp info_ptr),PNG_EMPTY);
-#  endif
-
 #endif /* PROGRESSIVE_READ */
 
-/* Added at libpng version 1.6.0 */
-#ifdef PNG_GAMMA_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr,
-    png_colorspacerp colorspace, png_fixed_point gAMA), PNG_EMPTY);
-   /* Set the colorspace gamma with a value provided by the application or by
-    * the gAMA chunk on read.  The value will override anything set by an ICC
-    * profile.
-    */
-
-PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr,
-    png_inforp info_ptr), PNG_EMPTY);
-   /* Synchronize the info 'valid' flags with the colorspace */
-
-PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr,
-    png_inforp info_ptr), PNG_EMPTY);
-   /* Copy the png_struct colorspace to the info_struct and call the above to
-    * synchronize the flags.  Checks for NULL info_ptr and does nothing.
-    */
-#endif
-
-/* Added at libpng version 1.4.0 */
-#ifdef PNG_COLORSPACE_SUPPORTED
-/* These internal functions are for maintaining the colorspace structure within
- * a png_info or png_struct (or, indeed, both).
- */
-PNG_INTERNAL_FUNCTION(int,png_colorspace_set_chromaticities,
-   (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_xy *xy,
-    int preferred), PNG_EMPTY);
-
-PNG_INTERNAL_FUNCTION(int,png_colorspace_set_endpoints,
-   (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_XYZ *XYZ,
-    int preferred), PNG_EMPTY);
-
-#ifdef PNG_sRGB_SUPPORTED
-PNG_INTERNAL_FUNCTION(int,png_colorspace_set_sRGB,(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, int intent), PNG_EMPTY);
-   /* This does set the colorspace gAMA and cHRM values too, but doesn't set the
-    * flags to write them, if it returns false there was a problem and an error
-    * message has already been output (but the colorspace may still need to be
-    * synced to record the invalid flag).
-    */
-#endif /* sRGB */
-
 #ifdef PNG_iCCP_SUPPORTED
-PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, png_const_charp name,
-   png_uint_32 profile_length, png_const_bytep profile, int color_type),
-   PNG_EMPTY);
-   /* The 'name' is used for information only */
-
 /* Routines for checking parts of an ICC profile. */
 #ifdef PNG_READ_iCCP_SUPPORTED
 PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, png_const_charp name,
-   png_uint_32 profile_length), PNG_EMPTY);
+   png_const_charp name, png_uint_32 profile_length), PNG_EMPTY);
 #endif /* READ_iCCP */
 PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, png_const_charp name,
-   png_uint_32 profile_length,
+   png_const_charp name, png_uint_32 profile_length,
    png_const_bytep profile /* first 132 bytes only */, int color_type),
    PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, png_const_charp name,
-   png_uint_32 profile_length,
+   png_const_charp name, png_uint_32 profile_length,
    png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY);
-#ifdef PNG_sRGB_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_icc_set_sRGB,(
-   png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_bytep profile, uLong adler), PNG_EMPTY);
-   /* 'adler' is the Adler32 checksum of the uncompressed profile data. It may
-    * be zero to indicate that it is not available.  It is used, if provided,
-    * as a fast check on the profile when checking to see if it is sRGB.
-    */
-#endif
 #endif /* iCCP */
 
 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_colorspace_set_rgb_coefficients,
-   (png_structrp png_ptr), PNG_EMPTY);
-   /* Set the rgb_to_gray coefficients from the colorspace Y values */
+PNG_INTERNAL_FUNCTION(void,png_set_rgb_coefficients, (png_structrp png_ptr),
+   PNG_EMPTY);
+   /* Set the rgb_to_gray coefficients from the cHRM Y values (if unset) */
 #endif /* READ_RGB_TO_GRAY */
-#endif /* COLORSPACE */
 
 /* Added at libpng version 1.4.0 */
 PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr,
@@ -2054,8 +1981,10 @@ PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string,
    size_t size),PNG_EMPTY);
 #endif /* pCAL || sCAL */
 
-#if defined(PNG_GAMMA_SUPPORTED) ||\
-    defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
+#if defined(PNG_READ_GAMMA_SUPPORTED) ||\
+    defined(PNG_COLORSPACE_SUPPORTED) ||\
+    defined(PNG_INCH_CONVERSIONS_SUPPORTED) ||\
+    defined(PNG_READ_pHYs_SUPPORTED)
 /* Added at libpng version 1.5.0 */
 /* This is a utility to provide a*times/div (rounded) and indicate
  * if there is an overflow.  The result is a boolean - false (0)
@@ -2064,22 +1993,14 @@ PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string,
  */
 PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a,
    png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY);
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
-/* Same deal, but issue a warning on overflow and return 0. */
-PNG_INTERNAL_FUNCTION(png_fixed_point,png_muldiv_warn,
-   (png_const_structrp png_ptr, png_fixed_point a, png_int_32 multiplied_by,
-   png_int_32 divided_by),PNG_EMPTY);
-#endif
 
-#ifdef PNG_GAMMA_SUPPORTED
 /* Calculate a reciprocal - used for gamma values.  This returns
  * 0 if the argument is 0 in order to maintain an undefined value;
  * there are no warnings.
  */
 PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a),
    PNG_EMPTY);
+#endif
 
 #ifdef PNG_READ_GAMMA_SUPPORTED
 /* The same but gives a reciprocal of the product of two fixed point
@@ -2088,14 +2009,22 @@ PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a),
  */
 PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal2,(png_fixed_point a,
    png_fixed_point b),PNG_EMPTY);
-#endif
 
 /* Return true if the gamma value is significantly different from 1.0 */
 PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value),
    PNG_EMPTY);
-#endif
 
-#ifdef PNG_READ_GAMMA_SUPPORTED
+/* PNGv3: 'resolve' the file gamma according to the new PNGv3 rules for colour
+ * space information.
+ *
+ * NOTE: this uses precisely those chunks that libpng supports.  For example it
+ * doesn't use iCCP and it can only use cICP for known and manageable
+ * transforms.  For this reason a gamma specified by png_set_gamma always takes
+ * precedence.
+ */
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_resolve_file_gamma,
+   (png_const_structrp png_ptr),PNG_EMPTY);
+
 /* Internal fixed point gamma correction.  These APIs are called as
  * required to convert single values - they don't need to be fast,
  * they are not used when processing image pixel values.
@@ -2113,6 +2042,22 @@ PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr),
    PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_build_gamma_table,(png_structrp png_ptr,
    int bit_depth),PNG_EMPTY);
+#endif /* READ_GAMMA */
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+/* Set the RGB coefficients if not already set by png_set_rgb_to_gray */
+PNG_INTERNAL_FUNCTION(void,png_set_rgb_coefficients,(png_structrp png_ptr),
+   PNG_EMPTY);
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED) || defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+PNG_INTERNAL_FUNCTION(int,png_XYZ_from_xy,(png_XYZ *XYZ, const png_xy *xy),
+   PNG_EMPTY);
+#endif /* cHRM || READ_RGB_TO_GRAY */
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+PNG_INTERNAL_FUNCTION(int,png_xy_from_XYZ,(png_xy *xy, const png_XYZ *XYZ),
+   PNG_EMPTY);
 #endif
 
 /* SIMPLIFIED READ/WRITE SUPPORT */
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c
index e9e9447754523..8a6381e1b3e95 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c
@@ -29,7 +29,7 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Copyright (c) 2018-2024 Cosmin Truta
+ * Copyright (c) 2018-2025 Cosmin Truta
  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
  * Copyright (c) 1996-1997 Andreas Dilger
  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -160,14 +160,11 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr)
          png_ptr->mode |= PNG_AFTER_IDAT;
       }
 
-      /* This should be a binary subdivision search or a hash for
-       * matching the chunk name rather than a linear search.
-       */
       if (chunk_name == png_IHDR)
-         png_handle_IHDR(png_ptr, info_ptr, length);
+         png_handle_chunk(png_ptr, info_ptr, length);
 
       else if (chunk_name == png_IEND)
-         png_handle_IEND(png_ptr, info_ptr, length);
+         png_handle_chunk(png_ptr, info_ptr, length);
 
 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
       else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
@@ -184,8 +181,6 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr)
          }
       }
 #endif
-      else if (chunk_name == png_PLTE)
-         png_handle_PLTE(png_ptr, info_ptr, length);
 
       else if (chunk_name == png_IDAT)
       {
@@ -193,99 +188,8 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr)
          break;
       }
 
-#ifdef PNG_READ_bKGD_SUPPORTED
-      else if (chunk_name == png_bKGD)
-         png_handle_bKGD(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_cHRM_SUPPORTED
-      else if (chunk_name == png_cHRM)
-         png_handle_cHRM(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_eXIf_SUPPORTED
-      else if (chunk_name == png_eXIf)
-         png_handle_eXIf(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_gAMA_SUPPORTED
-      else if (chunk_name == png_gAMA)
-         png_handle_gAMA(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_hIST_SUPPORTED
-      else if (chunk_name == png_hIST)
-         png_handle_hIST(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_oFFs_SUPPORTED
-      else if (chunk_name == png_oFFs)
-         png_handle_oFFs(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_pCAL_SUPPORTED
-      else if (chunk_name == png_pCAL)
-         png_handle_pCAL(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sCAL_SUPPORTED
-      else if (chunk_name == png_sCAL)
-         png_handle_sCAL(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_pHYs_SUPPORTED
-      else if (chunk_name == png_pHYs)
-         png_handle_pHYs(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sBIT_SUPPORTED
-      else if (chunk_name == png_sBIT)
-         png_handle_sBIT(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sRGB_SUPPORTED
-      else if (chunk_name == png_sRGB)
-         png_handle_sRGB(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_iCCP_SUPPORTED
-      else if (chunk_name == png_iCCP)
-         png_handle_iCCP(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sPLT_SUPPORTED
-      else if (chunk_name == png_sPLT)
-         png_handle_sPLT(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_tEXt_SUPPORTED
-      else if (chunk_name == png_tEXt)
-         png_handle_tEXt(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_tIME_SUPPORTED
-      else if (chunk_name == png_tIME)
-         png_handle_tIME(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_tRNS_SUPPORTED
-      else if (chunk_name == png_tRNS)
-         png_handle_tRNS(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_zTXt_SUPPORTED
-      else if (chunk_name == png_zTXt)
-         png_handle_zTXt(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_iTXt_SUPPORTED
-      else if (chunk_name == png_iTXt)
-         png_handle_iTXt(png_ptr, info_ptr, length);
-#endif
-
       else
-         png_handle_unknown(png_ptr, info_ptr, length,
-             PNG_HANDLE_CHUNK_AS_DEFAULT);
+         png_handle_chunk(png_ptr, info_ptr, length);
    }
 }
 #endif /* SEQUENTIAL_READ */
@@ -830,10 +734,10 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
          png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
 
       if (chunk_name == png_IEND)
-         png_handle_IEND(png_ptr, info_ptr, length);
+         png_handle_chunk(png_ptr, info_ptr, length);
 
       else if (chunk_name == png_IHDR)
-         png_handle_IHDR(png_ptr, info_ptr, length);
+         png_handle_chunk(png_ptr, info_ptr, length);
 
       else if (info_ptr == NULL)
          png_crc_finish(png_ptr, length);
@@ -867,102 +771,9 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
 
          png_crc_finish(png_ptr, length);
       }
-      else if (chunk_name == png_PLTE)
-         png_handle_PLTE(png_ptr, info_ptr, length);
-
-#ifdef PNG_READ_bKGD_SUPPORTED
-      else if (chunk_name == png_bKGD)
-         png_handle_bKGD(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_cHRM_SUPPORTED
-      else if (chunk_name == png_cHRM)
-         png_handle_cHRM(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_eXIf_SUPPORTED
-      else if (chunk_name == png_eXIf)
-         png_handle_eXIf(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_gAMA_SUPPORTED
-      else if (chunk_name == png_gAMA)
-         png_handle_gAMA(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_hIST_SUPPORTED
-      else if (chunk_name == png_hIST)
-         png_handle_hIST(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_oFFs_SUPPORTED
-      else if (chunk_name == png_oFFs)
-         png_handle_oFFs(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_pCAL_SUPPORTED
-      else if (chunk_name == png_pCAL)
-         png_handle_pCAL(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sCAL_SUPPORTED
-      else if (chunk_name == png_sCAL)
-         png_handle_sCAL(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_pHYs_SUPPORTED
-      else if (chunk_name == png_pHYs)
-         png_handle_pHYs(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sBIT_SUPPORTED
-      else if (chunk_name == png_sBIT)
-         png_handle_sBIT(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sRGB_SUPPORTED
-      else if (chunk_name == png_sRGB)
-         png_handle_sRGB(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_iCCP_SUPPORTED
-      else if (chunk_name == png_iCCP)
-         png_handle_iCCP(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_sPLT_SUPPORTED
-      else if (chunk_name == png_sPLT)
-         png_handle_sPLT(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_tEXt_SUPPORTED
-      else if (chunk_name == png_tEXt)
-         png_handle_tEXt(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_tIME_SUPPORTED
-      else if (chunk_name == png_tIME)
-         png_handle_tIME(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_tRNS_SUPPORTED
-      else if (chunk_name == png_tRNS)
-         png_handle_tRNS(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_zTXt_SUPPORTED
-      else if (chunk_name == png_zTXt)
-         png_handle_zTXt(png_ptr, info_ptr, length);
-#endif
-
-#ifdef PNG_READ_iTXt_SUPPORTED
-      else if (chunk_name == png_iTXt)
-         png_handle_iTXt(png_ptr, info_ptr, length);
-#endif
 
       else
-         png_handle_unknown(png_ptr, info_ptr, length,
-             PNG_HANDLE_CHUNK_AS_DEFAULT);
+         png_handle_chunk(png_ptr, info_ptr, length);
    } while ((png_ptr->mode & PNG_HAVE_IEND) == 0);
 }
 #endif /* SEQUENTIAL_READ */
@@ -1413,6 +1224,31 @@ png_image_format(png_structrp png_ptr)
    return format;
 }
 
+static int
+chromaticities_match_sRGB(const png_xy *xy)
+{
+#  define sRGB_TOLERANCE 1000
+   static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
+   {
+      /* color      x       y */
+      /* red   */ 64000, 33000,
+      /* green */ 30000, 60000,
+      /* blue  */ 15000,  6000,
+      /* white */ 31270, 32900
+   };
+
+   if (PNG_OUT_OF_RANGE(xy->whitex, sRGB_xy.whitex,sRGB_TOLERANCE) ||
+       PNG_OUT_OF_RANGE(xy->whitey, sRGB_xy.whitey,sRGB_TOLERANCE) ||
+       PNG_OUT_OF_RANGE(xy->redx,   sRGB_xy.redx,  sRGB_TOLERANCE) ||
+       PNG_OUT_OF_RANGE(xy->redy,   sRGB_xy.redy,  sRGB_TOLERANCE) ||
+       PNG_OUT_OF_RANGE(xy->greenx, sRGB_xy.greenx,sRGB_TOLERANCE) ||
+       PNG_OUT_OF_RANGE(xy->greeny, sRGB_xy.greeny,sRGB_TOLERANCE) ||
+       PNG_OUT_OF_RANGE(xy->bluex,  sRGB_xy.bluex, sRGB_TOLERANCE) ||
+       PNG_OUT_OF_RANGE(xy->bluey,  sRGB_xy.bluey, sRGB_TOLERANCE))
+      return 0;
+   return 1;
+}
+
 /* Is the given gamma significantly different from sRGB?  The test is the same
  * one used in pngrtran.c when deciding whether to do gamma correction.  The
  * arithmetic optimizes the division by using the fact that the inverse of the
@@ -1421,22 +1257,44 @@ png_image_format(png_structrp png_ptr)
 static int
 png_gamma_not_sRGB(png_fixed_point g)
 {
-   if (g < PNG_FP_1)
-   {
-      /* An uninitialized gamma is assumed to be sRGB for the simplified API. */
-      if (g == 0)
-         return 0;
-
-      return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */);
-   }
+   /* 1.6.47: use the same sanity checks as used in pngrtran.c */
+   if (g < PNG_LIB_GAMMA_MIN || g > PNG_LIB_GAMMA_MAX)
+      return 0; /* Includes the uninitialized value 0 */
 
-   return 1;
+   return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */);
 }
 
 /* Do the main body of a 'png_image_begin_read' function; read the PNG file
  * header and fill in all the information.  This is executed in a safe context,
  * unlike the init routine above.
  */
+static int
+png_image_is_not_sRGB(png_const_structrp png_ptr)
+{
+   /* Does the colorspace **not** match sRGB?  The flag is only set if the
+    * answer can be determined reliably.
+    *
+    * png_struct::chromaticities always exists since the simplified API
+    * requires rgb-to-gray.  The mDCV, cICP and cHRM chunks may all set it to
+    * a non-sRGB value, so it needs to be checked but **only** if one of
+    * those chunks occured in the file.
+    */
+   /* Highest priority: check to be safe. */
+   if (png_has_chunk(png_ptr, cICP) || png_has_chunk(png_ptr, mDCV))
+      return !chromaticities_match_sRGB(&png_ptr->chromaticities);
+
+   /* If the image is marked as sRGB then it is... */
+   if (png_has_chunk(png_ptr, sRGB))
+      return 0;
+
+   /* Last stop: cHRM, must check: */
+   if (png_has_chunk(png_ptr, cHRM))
+      return !chromaticities_match_sRGB(&png_ptr->chromaticities);
+
+   /* Else default to sRGB */
+   return 0;
+}
+
 static int
 png_image_read_header(png_voidp argument)
 {
@@ -1458,17 +1316,13 @@ png_image_read_header(png_voidp argument)
 
       image->format = format;
 
-#ifdef PNG_COLORSPACE_SUPPORTED
-      /* Does the colorspace match sRGB?  If there is no color endpoint
-       * (colorant) information assume yes, otherwise require the
-       * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set.  If the
-       * colorspace has been determined to be invalid ignore it.
+      /* Greyscale images don't (typically) have colour space information and
+       * using it is pretty much impossible, so use sRGB for grayscale (it
+       * doesn't matter r==g==b so the transform is irrelevant.)
        */
-      if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags
-         & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB|
-            PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS))
+      if ((format & PNG_FORMAT_FLAG_COLOR) != 0 &&
+          png_image_is_not_sRGB(png_ptr))
          image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB;
-#endif
    }
 
    /* We need the maximum number of entries regardless of the format the
@@ -1656,21 +1510,18 @@ png_image_skip_unused_chunks(png_structrp png_ptr)
     * potential vulnerability to security problems in the unused chunks.
     *
     * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored
-    * too.  This allows the simplified API to be compiled without iCCP support,
-    * however if the support is there the chunk is still checked to detect
-    * errors (which are unfortunately quite common.)
+    * too.  This allows the simplified API to be compiled without iCCP support.
     */
    {
          static const png_byte chunks_to_process[] = {
             98,  75,  71,  68, '\0',  /* bKGD */
             99,  72,  82,  77, '\0',  /* cHRM */
+            99,  73,  67,  80, '\0',  /* cICP */
            103,  65,  77,  65, '\0',  /* gAMA */
-#        ifdef PNG_READ_iCCP_SUPPORTED
-           105,  67,  67,  80, '\0',  /* iCCP */
-#        endif
+           109,  68,  67,  86, '\0',  /* mDCV */
            115,  66,  73,  84, '\0',  /* sBIT */
            115,  82,  71,  66, '\0',  /* sRGB */
-           };
+         };
 
        /* Ignore unknown chunks and all other chunks except for the
         * IHDR, PLTE, tRNS, IDAT, and IEND chunks.
@@ -1699,7 +1550,15 @@ png_image_skip_unused_chunks(png_structrp png_ptr)
 static void
 set_file_encoding(png_image_read_control *display)
 {
-   png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma;
+   png_structrp png_ptr = display->image->opaque->png_ptr;
+   png_fixed_point g = png_resolve_file_gamma(png_ptr);
+
+   /* PNGv3: the result may be 0 however the 'default_gamma' should have been
+    * set before this is called so zero is an error:
+    */
+   if (g == 0)
+      png_error(png_ptr, "internal: default gamma not set");
+
    if (png_gamma_significant(g) != 0)
    {
       if (png_gamma_not_sRGB(g) != 0)
@@ -2187,24 +2046,18 @@ png_image_read_colormap(png_voidp argument)
    /* Default the input file gamma if required - this is necessary because
     * libpng assumes that if no gamma information is present the data is in the
     * output format, but the simplified API deduces the gamma from the input
-    * format.
+    * format.  The 'default' gamma value is also set by png_set_alpha_mode, but
+    * this is happening before any such call, so:
+    *
+    * TODO: should be an internal API and all this code should be copied into a
+    * single common gamma+colorspace file.
     */
-   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0)
-   {
-      /* Do this directly, not using the png_colorspace functions, to ensure
-       * that it happens even if the colorspace is invalid (though probably if
-       * it is the setting will be ignored)  Note that the same thing can be
-       * achieved at the application interface with png_set_gAMA.
-       */
-      if (png_ptr->bit_depth == 16 &&
-         (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
-         png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR;
-
-      else
-         png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE;
+   if (png_ptr->bit_depth == 16 &&
+      (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
+      png_ptr->default_gamma = PNG_GAMMA_LINEAR;
 
-      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
-   }
+   else
+      png_ptr->default_gamma = PNG_GAMMA_sRGB_INVERSE;
 
    /* Decide what to do based on the PNG color type of the input data.  The
     * utility function png_create_colormap_entry deals with most aspects of the
@@ -2582,6 +2435,8 @@ png_image_read_colormap(png_voidp argument)
 
             else
             {
+               const png_fixed_point gamma = png_resolve_file_gamma(png_ptr);
+
                /* Either the input or the output has no alpha channel, so there
                 * will be no non-opaque pixels in the color-map; it will just be
                 * grayscale.
@@ -2596,10 +2451,13 @@ png_image_read_colormap(png_voidp argument)
                 * this case and doing it in the palette; this will result in
                 * duplicate palette entries, but that's better than the
                 * alternative of double gamma correction.
+                *
+                * NOTE: PNGv3: check the resolved result of all the potentially
+                * different colour space chunks.
                 */
                if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
                   png_ptr->num_trans > 0) &&
-                  png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0)
+                  png_gamma_not_sRGB(gamma) != 0)
                {
                   cmap_entries = (unsigned int)make_gray_file_colormap(display);
                   data_encoding = P_FILE;
@@ -2631,8 +2489,8 @@ png_image_read_colormap(png_voidp argument)
                      if (output_encoding == P_sRGB)
                         gray = png_sRGB_table[gray]; /* now P_LINEAR */
 
-                     gray = PNG_DIV257(png_gamma_16bit_correct(gray,
-                         png_ptr->colorspace.gamma)); /* now P_FILE */
+                     gray = PNG_DIV257(png_gamma_16bit_correct(gray, gamma));
+                        /* now P_FILE */
 
                      /* And make sure the corresponding palette entry contains
                       * exactly the required sRGB value.
@@ -3763,6 +3621,12 @@ png_image_read_direct(png_voidp argument)
       /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise.
        */
       {
+         /* This is safe but should no longer be necessary as
+          * png_ptr->default_gamma should have been set after the
+          * info-before-IDAT was read in png_image_read_header.
+          *
+          * TODO: 1.8: remove this and see what happens.
+          */
          png_fixed_point input_gamma_default;
 
          if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 &&
@@ -3818,8 +3682,9 @@ png_image_read_direct(png_voidp argument)
           * yet; it's set below.  png_struct::gamma, however, is set to the
           * final value.
           */
-         if (png_muldiv(>est, output_gamma, png_ptr->colorspace.gamma,
-             PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0)
+         if (png_muldiv(>est, output_gamma,
+                  png_resolve_file_gamma(png_ptr), PNG_FP_1) != 0 &&
+             png_gamma_significant(gtest) == 0)
             do_local_background = 0;
 
          else if (mode == PNG_ALPHA_STANDARD)
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c
index a393de4b79d07..4f31f8f07bc56 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c
@@ -247,9 +247,59 @@ png_set_strip_alpha(png_structrp png_ptr)
 #endif
 
 #if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
+/* PNGv3 conformance: this private API exists to resolve the now mandatory error
+ * resolution when multiple conflicting sources of gamma or colour space
+ * information are available.
+ *
+ * Terminology (assuming power law, "gamma", encodings):
+ *    "screen" gamma: a power law imposed by the output device when digital
+ *    samples are converted to visible light output.  The EOTF - volage to
+ *    luminance on output.
+ *
+ *    "file" gamma: a power law used to encode luminance levels from the input
+ *    data (the scene or the mastering display system) into digital voltages.
+ *    The OETF - luminance to voltage on input.
+ *
+ *    gamma "correction": a power law matching the **inverse** of the overall
+ *    transfer function from input luminance levels to output levels.  The
+ *    **inverse** of the OOTF; the correction "corrects" for the OOTF by aiming
+ *    to make the overall OOTF (including the correction) linear.
+ *
+ * It is important to understand this terminology because the defined terms are
+ * scattered throughout the libpng code and it is very easy to end up with the
+ * inverse of the power law required.
+ *
+ * Variable and struct::member names:
+ *    file_gamma        OETF  how the PNG data was encoded
+ *
+ *    screen_gamma      EOTF  how the screen will decode digital levels
+ *
+ *    -- not used --    OOTF  the net effect OETF x EOTF
+ *    gamma_correction        the inverse of OOTF to make the result linear
+ *
+ * All versions of libpng require a call to "png_set_gamma" to establish the
+ * "screen" gamma, the power law representing the EOTF.  png_set_gamma may also
+ * set or default the "file" gamma; the OETF.  gamma_correction is calculated
+ * internally.
+ *
+ * The earliest libpng versions required file_gamma to be supplied to set_gamma.
+ * Later versions started allowing png_set_gamma and, later, png_set_alpha_mode,
+ * to cause defaulting from the file data.
+ *
+ * PNGv3 mandated a particular form for this defaulting, one that is compatible
+ * with what libpng did except that if libpng detected inconsistencies it marked
+ * all the chunks as "invalid".  PNGv3 effectively invalidates this prior code.
+ *
+ * Behaviour implemented below:
+ *    translate_gamma_flags(gamma, is_screen)
+ *       The libpng-1.6 API for the gamma parameters to libpng APIs
+ *       (png_set_gamma and png_set_alpha_mode at present).  This allows the
+ *       'gamma' value to be passed as a png_fixed_point number or as one of a
+ *       set of integral values for specific "well known" examples of transfer
+ *       functions.  This is compatible with PNGv3.
+ */
 static png_fixed_point
-translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
-    int is_screen)
+translate_gamma_flags(png_fixed_point output_gamma, int is_screen)
 {
    /* Check for flag values.  The main reason for having the old Mac value as a
     * flag is that it is pretty near impossible to work out what the correct
@@ -259,14 +309,6 @@ translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
    if (output_gamma == PNG_DEFAULT_sRGB ||
       output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)
    {
-      /* If there is no sRGB support this just sets the gamma to the standard
-       * sRGB value.  (This is a side effect of using this function!)
-       */
-#     ifdef PNG_READ_sRGB_SUPPORTED
-         png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;
-#     else
-         PNG_UNUSED(png_ptr)
-#     endif
       if (is_screen != 0)
          output_gamma = PNG_GAMMA_sRGB;
       else
@@ -308,6 +350,33 @@ convert_gamma_value(png_structrp png_ptr, double output_gamma)
    return (png_fixed_point)output_gamma;
 }
 #  endif
+
+static int
+unsupported_gamma(png_structrp png_ptr, png_fixed_point gamma, int warn)
+{
+   /* Validate a gamma value to ensure it is in a reasonable range.  The value
+    * is expected to be 1 or greater, but this range test allows for some
+    * viewing correction values.  The intent is to weed out the API users
+    * who might use the inverse of the gamma value accidentally!
+    *
+    * 1.6.47: apply the test in png_set_gamma as well but only warn and return
+    * false if it fires.
+    *
+    * TODO: 1.8: make this an app_error in png_set_gamma as well.
+    */
+   if (gamma < PNG_LIB_GAMMA_MIN || gamma > PNG_LIB_GAMMA_MAX)
+   {
+#     define msg "gamma out of supported range"
+      if (warn)
+         png_app_warning(png_ptr, msg);
+      else
+         png_app_error(png_ptr, msg);
+      return 1;
+#     undef msg
+   }
+
+   return 0;
+}
 #endif /* READ_ALPHA_MODE || READ_GAMMA */
 
 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
@@ -315,31 +384,29 @@ void PNGFAPI
 png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
     png_fixed_point output_gamma)
 {
-   int compose = 0;
    png_fixed_point file_gamma;
+   int compose = 0;
 
    png_debug(1, "in png_set_alpha_mode_fixed");
 
    if (png_rtran_ok(png_ptr, 0) == 0)
       return;
 
-   output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);
-
-   /* Validate the value to ensure it is in a reasonable range.  The value
-    * is expected to be 1 or greater, but this range test allows for some
-    * viewing correction values.  The intent is to weed out the API users
-    * who might use the inverse of the gamma value accidentally!
-    *
-    * In libpng 1.6.0, we changed from 0.07..3 to 0.01..100, to accommodate
-    * the optimal 16-bit gamma of 36 and its reciprocal.
-    */
-   if (output_gamma < 1000 || output_gamma > 10000000)
-      png_error(png_ptr, "output gamma out of expected range");
+   output_gamma = translate_gamma_flags(output_gamma, 1/*screen*/);
+   if (unsupported_gamma(png_ptr, output_gamma, 0/*error*/))
+      return;
 
    /* The default file gamma is the inverse of the output gamma; the output
-    * gamma may be changed below so get the file value first:
+    * gamma may be changed below so get the file value first.  The default_gamma
+    * is set here and from the simplified API (which uses a different algorithm)
+    * so don't overwrite a set value:
     */
-   file_gamma = png_reciprocal(output_gamma);
+   file_gamma = png_ptr->default_gamma;
+   if (file_gamma == 0)
+   {
+      file_gamma = png_reciprocal(output_gamma);
+      png_ptr->default_gamma = file_gamma;
+   }
 
    /* There are really 8 possibilities here, composed of any combination
     * of:
@@ -390,17 +457,7 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
          png_error(png_ptr, "invalid alpha mode");
    }
 
-   /* Only set the default gamma if the file gamma has not been set (this has
-    * the side effect that the gamma in a second call to png_set_alpha_mode will
-    * be ignored.)
-    */
-   if (png_ptr->colorspace.gamma == 0)
-   {
-      png_ptr->colorspace.gamma = file_gamma;
-      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
-   }
-
-   /* But always set the output gamma: */
+   /* Set the screen gamma values: */
    png_ptr->screen_gamma = output_gamma;
 
    /* Finally, if pre-multiplying, set the background fields to achieve the
@@ -410,7 +467,7 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
    {
       /* And obtain alpha pre-multiplication by composing on black: */
       memset(&png_ptr->background, 0, (sizeof png_ptr->background));
-      png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */
+      png_ptr->background_gamma = file_gamma; /* just in case */
       png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;
       png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
 
@@ -848,8 +905,8 @@ png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
       return;
 
    /* New in libpng-1.5.4 - reserve particular negative values as flags. */
-   scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);
-   file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);
+   scrn_gamma = translate_gamma_flags(scrn_gamma, 1/*screen*/);
+   file_gamma = translate_gamma_flags(file_gamma, 0/*file*/);
 
    /* Checking the gamma values for being >0 was added in 1.5.4 along with the
     * premultiplied alpha support; this actually hides an undocumented feature
@@ -863,17 +920,19 @@ png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
     * libpng-1.6.0.
     */
    if (file_gamma <= 0)
-      png_error(png_ptr, "invalid file gamma in png_set_gamma");
-
+      png_app_error(png_ptr, "invalid file gamma in png_set_gamma");
    if (scrn_gamma <= 0)
-      png_error(png_ptr, "invalid screen gamma in png_set_gamma");
+      png_app_error(png_ptr, "invalid screen gamma in png_set_gamma");
 
-   /* Set the gamma values unconditionally - this overrides the value in the PNG
-    * file if a gAMA chunk was present.  png_set_alpha_mode provides a
-    * different, easier, way to default the file gamma.
+   if (unsupported_gamma(png_ptr, file_gamma, 1/*warn*/) ||
+       unsupported_gamma(png_ptr, scrn_gamma, 1/*warn*/))
+      return;
+
+   /* 1.6.47: png_struct::file_gamma and png_struct::screen_gamma are now only
+    * written by this API.  This removes dependencies on the order of API calls
+    * and allows the complex gamma checks to be delayed until needed.
     */
-   png_ptr->colorspace.gamma = file_gamma;
-   png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+   png_ptr->file_gamma = file_gamma;
    png_ptr->screen_gamma = scrn_gamma;
 }
 
@@ -1051,26 +1110,9 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
          png_ptr->rgb_to_gray_coefficients_set = 1;
       }
 
-      else
-      {
-         if (red >= 0 && green >= 0)
-            png_app_warning(png_ptr,
-                "ignoring out of range rgb_to_gray coefficients");
-
-         /* Use the defaults, from the cHRM chunk if set, else the historical
-          * values which are close to the sRGB/HDTV/ITU-Rec 709 values.  See
-          * png_do_rgb_to_gray for more discussion of the values.  In this case
-          * the coefficients are not marked as 'set' and are not overwritten if
-          * something has already provided a default.
-          */
-         if (png_ptr->rgb_to_gray_red_coeff == 0 &&
-             png_ptr->rgb_to_gray_green_coeff == 0)
-         {
-            png_ptr->rgb_to_gray_red_coeff   = 6968;
-            png_ptr->rgb_to_gray_green_coeff = 23434;
-            /* png_ptr->rgb_to_gray_blue_coeff  = 2366; */
-         }
-      }
+      else if (red >= 0 && green >= 0)
+         png_app_warning(png_ptr,
+               "ignoring out of range rgb_to_gray coefficients");
    }
 }
 
@@ -1311,6 +1353,80 @@ png_init_rgb_transformations(png_structrp png_ptr)
 #endif /* READ_EXPAND && READ_BACKGROUND */
 }
 
+#ifdef PNG_READ_GAMMA_SUPPORTED
+png_fixed_point /* PRIVATE */
+png_resolve_file_gamma(png_const_structrp png_ptr)
+{
+   png_fixed_point file_gamma;
+
+   /* The file gamma is determined by these precedence rules, in this order
+    * (i.e. use the first value found):
+    *
+    *    png_set_gamma; png_struct::file_gammma if not zero, then:
+    *    png_struct::chunk_gamma if not 0 (determined the PNGv3 rules), then:
+    *    png_set_gamma; 1/png_struct::screen_gamma if not zero
+    *
+    *    0 (i.e. do no gamma handling)
+    */
+   file_gamma = png_ptr->file_gamma;
+   if (file_gamma != 0)
+      return file_gamma;
+
+   file_gamma = png_ptr->chunk_gamma;
+   if (file_gamma != 0)
+      return file_gamma;
+
+   file_gamma = png_ptr->default_gamma;
+   if (file_gamma != 0)
+      return file_gamma;
+
+   /* If png_reciprocal oveflows it returns 0 which indicates to the caller that
+    * there is no usable file gamma.  (The checks added to png_set_gamma and
+    * png_set_alpha_mode should prevent a screen_gamma which would overflow.)
+    */
+   if (png_ptr->screen_gamma != 0)
+      file_gamma = png_reciprocal(png_ptr->screen_gamma);
+
+   return file_gamma;
+}
+
+static int
+png_init_gamma_values(png_structrp png_ptr)
+{
+   /* The following temporary indicates if overall gamma correction is
+    * required.
+    */
+   int gamma_correction = 0;
+   png_fixed_point file_gamma, screen_gamma;
+
+   /* Resolve the file_gamma.  See above: if png_ptr::screen_gamma is set
+    * file_gamma will always be set here:
+    */
+   file_gamma = png_resolve_file_gamma(png_ptr);
+   screen_gamma = png_ptr->screen_gamma;
+
+   if (file_gamma > 0) /* file has been set */
+   {
+      if (screen_gamma > 0) /* screen set too */
+         gamma_correction = png_gamma_threshold(file_gamma, screen_gamma);
+
+      else
+         /* Assume the output matches the input; a long time default behavior
+          * of libpng, although the standard has nothing to say about this.
+          */
+         screen_gamma = png_reciprocal(file_gamma);
+   }
+
+   else /* both unset, prevent corrections: */
+      file_gamma = screen_gamma = PNG_FP_1;
+
+   png_ptr->file_gamma = file_gamma;
+   png_ptr->screen_gamma = screen_gamma;
+   return gamma_correction;
+
+}
+#endif /* READ_GAMMA */
+
 void /* PRIVATE */
 png_init_read_transformations(png_structrp png_ptr)
 {
@@ -1330,59 +1446,22 @@ png_init_read_transformations(png_structrp png_ptr)
     * the test needs to be performed later - here.  In addition prior to 1.5.4
     * the tests were repeated for the PALETTE color type here - this is no
     * longer necessary (and doesn't seem to have been necessary before.)
+    *
+    * PNGv3: the new mandatory precedence/priority rules for colour space chunks
+    * are handled here (by calling the above function).
+    *
+    * Turn the gamma transformation on or off as appropriate.  Notice that
+    * PNG_GAMMA just refers to the file->screen correction.  Alpha composition
+    * may independently cause gamma correction because it needs linear data
+    * (e.g. if the file has a gAMA chunk but the screen gamma hasn't been
+    * specified.)  In any case this flag may get turned off in the code
+    * immediately below if the transform can be handled outside the row loop.
     */
-   {
-      /* The following temporary indicates if overall gamma correction is
-       * required.
-       */
-      int gamma_correction = 0;
+   if (png_init_gamma_values(png_ptr) != 0)
+      png_ptr->transformations |= PNG_GAMMA;
 
-      if (png_ptr->colorspace.gamma != 0) /* has been set */
-      {
-         if (png_ptr->screen_gamma != 0) /* screen set too */
-            gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
-                png_ptr->screen_gamma);
-
-         else
-            /* Assume the output matches the input; a long time default behavior
-             * of libpng, although the standard has nothing to say about this.
-             */
-            png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma);
-      }
-
-      else if (png_ptr->screen_gamma != 0)
-         /* The converse - assume the file matches the screen, note that this
-          * perhaps undesirable default can (from 1.5.4) be changed by calling
-          * png_set_alpha_mode (even if the alpha handling mode isn't required
-          * or isn't changed from the default.)
-          */
-         png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma);
-
-      else /* neither are set */
-         /* Just in case the following prevents any processing - file and screen
-          * are both assumed to be linear and there is no way to introduce a
-          * third gamma value other than png_set_background with 'UNIQUE', and,
-          * prior to 1.5.4
-          */
-         png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1;
-
-      /* We have a gamma value now. */
-      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
-
-      /* Now turn the gamma transformation on or off as appropriate.  Notice
-       * that PNG_GAMMA just refers to the file->screen correction.  Alpha
-       * composition may independently cause gamma correction because it needs
-       * linear data (e.g. if the file has a gAMA chunk but the screen gamma
-       * hasn't been specified.)  In any case this flag may get turned off in
-       * the code immediately below if the transform can be handled outside the
-       * row loop.
-       */
-      if (gamma_correction != 0)
-         png_ptr->transformations |= PNG_GAMMA;
-
-      else
-         png_ptr->transformations &= ~PNG_GAMMA;
-   }
+   else
+      png_ptr->transformations &= ~PNG_GAMMA;
 #endif
 
    /* Certain transformations have the effect of preventing other
@@ -1454,7 +1533,7 @@ png_init_read_transformations(png_structrp png_ptr)
     * appropriately.
     */
    if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
-      png_colorspace_set_rgb_coefficients(png_ptr);
+      png_set_rgb_coefficients(png_ptr);
 #endif
 
 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
@@ -1597,10 +1676,10 @@ png_init_read_transformations(png_structrp png_ptr)
     */
    if ((png_ptr->transformations & PNG_GAMMA) != 0 ||
        ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 &&
-        (png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||
+        (png_gamma_significant(png_ptr->file_gamma) != 0 ||
          png_gamma_significant(png_ptr->screen_gamma) != 0)) ||
         ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
-         (png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||
+         (png_gamma_significant(png_ptr->file_gamma) != 0 ||
           png_gamma_significant(png_ptr->screen_gamma) != 0
 #  ifdef PNG_READ_BACKGROUND_SUPPORTED
          || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE &&
@@ -1656,8 +1735,8 @@ png_init_read_transformations(png_structrp png_ptr)
                      break;
 
                   case PNG_BACKGROUND_GAMMA_FILE:
-                     g = png_reciprocal(png_ptr->colorspace.gamma);
-                     gs = png_reciprocal2(png_ptr->colorspace.gamma,
+                     g = png_reciprocal(png_ptr->file_gamma);
+                     gs = png_reciprocal2(png_ptr->file_gamma,
                          png_ptr->screen_gamma);
                      break;
 
@@ -1765,8 +1844,8 @@ png_init_read_transformations(png_structrp png_ptr)
                   break;
 
                case PNG_BACKGROUND_GAMMA_FILE:
-                  g = png_reciprocal(png_ptr->colorspace.gamma);
-                  gs = png_reciprocal2(png_ptr->colorspace.gamma,
+                  g = png_reciprocal(png_ptr->file_gamma);
+                  gs = png_reciprocal2(png_ptr->file_gamma,
                       png_ptr->screen_gamma);
                   break;
 
@@ -2016,11 +2095,11 @@ png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
     * been called before this from png_read_update_info->png_read_start_row
     * sometimes does the gamma transform and cancels the flag.
     *
-    * TODO: this looks wrong; the info_ptr should end up with a gamma equal to
-    * the screen_gamma value.  The following probably results in weirdness if
-    * the info_ptr is used by the app after the rows have been read.
+    * TODO: this is confusing.  It only changes the result of png_get_gAMA and,
+    * yes, it does return the value that the transformed data effectively has
+    * but does any app really understand this?
     */
-   info_ptr->colorspace.gamma = png_ptr->colorspace.gamma;
+   info_ptr->gamma = png_ptr->file_gamma;
 #endif
 
    if (info_ptr->bit_depth == 16)
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c
index 5280140d12bcb..6cf466d182abb 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c
@@ -46,6 +46,26 @@
 
 #ifdef PNG_READ_SUPPORTED
 
+/* The minimum 'zlib' stream is assumed to be just the 2 byte header, 5 bytes
+ * minimum 'deflate' stream, and the 4 byte checksum.
+ */
+#define LZ77Min  (2U+5U+4U)
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+/* Arrays to facilitate interlacing - use pass (0 - 6) as index. */
+
+/* Start of interlace block */
+static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+/* Offset to next interlace block */
+static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+/* Start of interlace block in the y direction */
+static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+/* Offset to next interlace block in the y direction */
+static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+
+/* TODO: Move these arrays to a common utility module to avoid duplication. */
+#endif
+
 png_uint_32 PNGAPI
 png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf)
 {
@@ -57,30 +77,6 @@ png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf)
    return uval;
 }
 
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
-/* The following is a variation on the above for use with the fixed
- * point values used for gAMA and cHRM.  Instead of png_error it
- * issues a warning and returns (-1) - an invalid value because both
- * gAMA and cHRM use *unsigned* integers for fixed point values.
- */
-#define PNG_FIXED_ERROR (-1)
-
-static png_fixed_point /* PRIVATE */
-png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf)
-{
-   png_uint_32 uval = png_get_uint_32(buf);
-
-   if (uval <= PNG_UINT_31_MAX)
-      return (png_fixed_point)uval; /* known to be in range */
-
-   /* The caller can turn off the warning by passing NULL. */
-   if (png_ptr != NULL)
-      png_warning(png_ptr, "PNG fixed point integer out of range");
-
-   return PNG_FIXED_ERROR;
-}
-#endif
-
 #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
 /* NOTE: the read macros will obscure these definitions, so that if
  * PNG_USE_READ_MACROS is set the library will not use them internally,
@@ -177,6 +173,38 @@ png_read_sig(png_structrp png_ptr, png_inforp info_ptr)
       png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
 }
 
+/* This function is called to verify that a chunk name is valid.
+ * Do this using the bit-whacking approach from contrib/tools/pngfix.c
+ *
+ * Copied from libpng 1.7.
+ */
+static int
+check_chunk_name(png_uint_32 name)
+{
+   png_uint_32 t;
+
+   /* Remove bit 5 from all but the reserved byte; this means
+    * every 8-bit unit must be in the range 65-90 to be valid.
+    * So bit 5 must be zero, bit 6 must be set and bit 7 zero.
+    */
+   name &= ~PNG_U32(32,32,0,32);
+   t = (name & ~0x1f1f1f1fU) ^ 0x40404040U;
+
+   /* Subtract 65 for each 8-bit quantity, this must not
+    * overflow and each byte must then be in the range 0-25.
+    */
+   name -= PNG_U32(65,65,65,65);
+   t |= name;
+
+   /* Subtract 26, handling the overflow which should set the
+    * top three bits of each byte.
+    */
+   name -= PNG_U32(25,25,25,26);
+   t |= ~name;
+
+   return (t & 0xe0e0e0e0U) == 0U;
+}
+
 /* Read the chunk header (length + type name).
  * Put the type name into png_ptr->chunk_name, and return the length.
  */
@@ -184,33 +212,36 @@ png_uint_32 /* PRIVATE */
 png_read_chunk_header(png_structrp png_ptr)
 {
    png_byte buf[8];
-   png_uint_32 length;
+   png_uint_32 chunk_name, length;
 
 #ifdef PNG_IO_STATE_SUPPORTED
    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
 #endif
 
-   /* Read the length and the chunk name.
-    * This must be performed in a single I/O call.
+   /* Read the length and the chunk name.  png_struct::chunk_name is immediately
+    * updated even if they are detectably wrong.  This aids error message
+    * handling by allowing png_chunk_error to be used.
     */
    png_read_data(png_ptr, buf, 8);
    length = png_get_uint_31(png_ptr, buf);
+   png_ptr->chunk_name = chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
 
-   /* Put the chunk name into png_ptr->chunk_name. */
-   png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
+   /* Reset the crc and run it over the chunk name. */
+   png_reset_crc(png_ptr);
+   png_calculate_crc(png_ptr, buf + 4, 4);
 
    png_debug2(0, "Reading chunk typeid = 0x%lx, length = %lu",
        (unsigned long)png_ptr->chunk_name, (unsigned long)length);
 
-   /* Reset the crc and run it over the chunk name. */
-   png_reset_crc(png_ptr);
-   png_calculate_crc(png_ptr, buf + 4, 4);
+   /* Sanity check the length (first by <= 0x80) and the chunk name.  An error
+    * here indicates a broken stream and libpng has no recovery from this.
+    */
+   if (buf[0] >= 0x80U)
+      png_chunk_error(png_ptr, "bad header (invalid length)");
 
    /* Check to see if chunk name is valid. */
-   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
-
-   /* Check for too-large chunk length */
-   png_check_chunk_length(png_ptr, length);
+   if (!check_chunk_name(chunk_name))
+      png_chunk_error(png_ptr, "bad header (invalid type)");
 
 #ifdef PNG_IO_STATE_SUPPORTED
    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
@@ -230,13 +261,85 @@ png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length)
    png_calculate_crc(png_ptr, buf, length);
 }
 
+/* Compare the CRC stored in the PNG file with that calculated by libpng from
+ * the data it has read thus far.
+ */
+static int
+png_crc_error(png_structrp png_ptr, int handle_as_ancillary)
+{
+   png_byte crc_bytes[4];
+   png_uint_32 crc;
+   int need_crc = 1;
+
+   /* There are four flags two for ancillary and two for critical chunks.  The
+    * default setting of these flags is all zero.
+    *
+    * PNG_FLAG_CRC_ANCILLARY_USE
+    * PNG_FLAG_CRC_ANCILLARY_NOWARN
+    *  USE+NOWARN: no CRC calculation (implemented here), else;
+    *  NOWARN:     png_chunk_error on error (implemented in png_crc_finish)
+    *  else:       png_chunk_warning on error (implemented in png_crc_finish)
+    *              This is the default.
+    *
+    *    I.e. NOWARN without USE produces png_chunk_error.  The default setting
+    *    where neither are set does the same thing.
+    *
+    * PNG_FLAG_CRC_CRITICAL_USE
+    * PNG_FLAG_CRC_CRITICAL_IGNORE
+    *  IGNORE: no CRC calculation (implemented here), else;
+    *  USE:    png_chunk_warning on error (implemented in png_crc_finish)
+    *  else:   png_chunk_error on error (implemented in png_crc_finish)
+    *          This is the default.
+    *
+    * This arose because of original mis-implementation and has persisted for
+    * compatibility reasons.
+    *
+    * TODO: the flag names are internal so maybe this can be changed to
+    * something comprehensible.
+    */
+   if (handle_as_ancillary || PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)
+   {
+      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+         need_crc = 0;
+   }
+
+   else /* critical */
+   {
+      if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
+         need_crc = 0;
+   }
+
+#ifdef PNG_IO_STATE_SUPPORTED
+   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
+#endif
+
+   /* The chunk CRC must be serialized in a single I/O call. */
+   png_read_data(png_ptr, crc_bytes, 4);
+
+   if (need_crc != 0)
+   {
+      crc = png_get_uint_32(crc_bytes);
+      return crc != png_ptr->crc;
+   }
+
+   else
+      return 0;
+}
+
 /* Optionally skip data and then check the CRC.  Depending on whether we
  * are reading an ancillary or critical chunk, and how the program has set
  * things up, we may calculate the CRC on the data and print a message.
  * Returns '1' if there was a CRC error, '0' otherwise.
+ *
+ * There is one public version which is used in most places and another which
+ * takes the value for the 'critical' flag to check.  This allows PLTE and IEND
+ * handling code to ignore the CRC error and removes some confusing code
+ * duplication.
  */
-int /* PRIVATE */
-png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
+static int
+png_crc_finish_critical(png_structrp png_ptr, png_uint_32 skip,
+      int handle_as_ancillary)
 {
    /* The size of the local buffer for inflate is a good guess as to a
     * reasonable size to use for buffering reads from the application.
@@ -254,14 +357,24 @@ png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
       png_crc_read(png_ptr, tmpbuf, len);
    }
 
-   if (png_crc_error(png_ptr) != 0)
+   /* If 'handle_as_ancillary' has been requested and this is a critical chunk
+    * but PNG_FLAG_CRC_CRITICAL_IGNORE was set then png_read_crc did not, in
+    * fact, calculate the CRC so the ANCILLARY settings should not be used
+    * instead.
+    */
+   if (handle_as_ancillary &&
+       (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
+      handle_as_ancillary = 0;
+
+   /* TODO: this might be more comprehensible if png_crc_error was inlined here.
+    */
+   if (png_crc_error(png_ptr, handle_as_ancillary) != 0)
    {
-      if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ?
+      /* See above for the explanation of how the flags work. */
+      if (handle_as_ancillary || PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ?
           (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0 :
           (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE) != 0)
-      {
          png_chunk_warning(png_ptr, "CRC error");
-      }
 
       else
          png_chunk_error(png_ptr, "CRC error");
@@ -272,61 +385,29 @@ png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
    return 0;
 }
 
-/* Compare the CRC stored in the PNG file with that calculated by libpng from
- * the data it has read thus far.
- */
 int /* PRIVATE */
-png_crc_error(png_structrp png_ptr)
+png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
 {
-   png_byte crc_bytes[4];
-   png_uint_32 crc;
-   int need_crc = 1;
-
-   if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)
-   {
-      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
-          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
-         need_crc = 0;
-   }
-
-   else /* critical */
-   {
-      if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
-         need_crc = 0;
-   }
-
-#ifdef PNG_IO_STATE_SUPPORTED
-   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
-#endif
-
-   /* The chunk CRC must be serialized in a single I/O call. */
-   png_read_data(png_ptr, crc_bytes, 4);
-
-   if (need_crc != 0)
-   {
-      crc = png_get_uint_32(crc_bytes);
-      return crc != png_ptr->crc;
-   }
-
-   else
-      return 0;
+   return png_crc_finish_critical(png_ptr, skip, 0/*critical handling*/);
 }
 
 #if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\
     defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\
     defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\
-    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED)
+    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_eXIf_SUPPORTED) ||\
+    defined(PNG_SEQUENTIAL_READ_SUPPORTED)
 /* Manage the read buffer; this simply reallocates the buffer if it is not small
  * enough (or if it is not allocated).  The routine returns a pointer to the
  * buffer; if an error occurs and 'warn' is set the routine returns NULL, else
- * it will call png_error (via png_malloc) on failure.  (warn == 2 means
- * 'silent').
+ * it will call png_error on failure.
  */
 static png_bytep
-png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn)
+png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size)
 {
    png_bytep buffer = png_ptr->read_buffer;
 
+   if (new_size > png_chunk_max(png_ptr)) return NULL;
+
    if (buffer != NULL && new_size > png_ptr->read_buffer_size)
    {
       png_ptr->read_buffer = NULL;
@@ -341,24 +422,17 @@ png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn)
 
       if (buffer != NULL)
       {
-         memset(buffer, 0, new_size); /* just in case */
+#        ifndef PNG_NO_MEMZERO /* for detecting UIM bugs **only** */
+            memset(buffer, 0, new_size); /* just in case */
+#        endif
          png_ptr->read_buffer = buffer;
          png_ptr->read_buffer_size = new_size;
       }
-
-      else if (warn < 2) /* else silent */
-      {
-         if (warn != 0)
-             png_chunk_warning(png_ptr, "insufficient memory to read chunk");
-
-         else
-             png_chunk_error(png_ptr, "insufficient memory to read chunk");
-      }
    }
 
    return buffer;
 }
-#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */
+#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|eXIf|SEQUENTIAL_READ */
 
 /* png_inflate_claim: claim the zstream for some nefarious purpose that involves
  * decompression.  Returns Z_OK on success, else a zlib error code.  It checks
@@ -645,16 +719,7 @@ png_decompress_chunk(png_structrp png_ptr,
     * maybe a '\0' terminator too.  We have to assume that 'prefix_size' is
     * limited only by the maximum chunk size.
     */
-   png_alloc_size_t limit = PNG_SIZE_MAX;
-
-# ifdef PNG_SET_USER_LIMITS_SUPPORTED
-   if (png_ptr->user_chunk_malloc_max > 0 &&
-       png_ptr->user_chunk_malloc_max < limit)
-      limit = png_ptr->user_chunk_malloc_max;
-# elif PNG_USER_CHUNK_MALLOC_MAX > 0
-   if (PNG_USER_CHUNK_MALLOC_MAX < limit)
-      limit = PNG_USER_CHUNK_MALLOC_MAX;
-# endif
+   png_alloc_size_t limit = png_chunk_max(png_ptr);
 
    if (limit >= prefix_size + (terminate != 0))
    {
@@ -859,9 +924,9 @@ png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
 }
 #endif /* READ_iCCP */
 
+/* CHUNK HANDLING */
 /* Read and check the IDHR chunk */
-
-void /* PRIVATE */
+static png_handle_result_code
 png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    png_byte buf[13];
@@ -871,12 +936,7 @@ png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
    png_debug(1, "in png_handle_IHDR");
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) != 0)
-      png_chunk_error(png_ptr, "out of place");
-
-   /* Check the length */
-   if (length != 13)
-      png_chunk_error(png_ptr, "invalid");
+   /* Length and position are checked by the caller. */
 
    png_ptr->mode |= PNG_HAVE_IHDR;
 
@@ -930,257 +990,196 @@ png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
    png_debug1(3, "channels = %d", png_ptr->channels);
    png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
+
+   /* Rely on png_set_IHDR to completely validate the data and call png_error if
+    * it's wrong.
+    */
    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
        color_type, interlace_type, compression_type, filter_type);
+
+   return handled_ok;
+   PNG_UNUSED(length)
 }
 
 /* Read and check the palette */
-void /* PRIVATE */
+/* TODO: there are several obvious errors in this code when handling
+ * out-of-place chunks and there is much over-complexity caused by trying to
+ * patch up the problems.
+ */
+static png_handle_result_code
 png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
-   png_color palette[PNG_MAX_PALETTE_LENGTH];
-   int max_palette_length, num, i;
-#ifdef PNG_POINTER_INDEXING_SUPPORTED
-   png_colorp pal_ptr;
-#endif
+   png_const_charp errmsg = NULL;
 
    png_debug(1, "in png_handle_PLTE");
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
-   /* Moved to before the 'after IDAT' check below because otherwise duplicate
-    * PLTE chunks are potentially ignored (the spec says there shall not be more
-    * than one PLTE, the error is not treated as benign, so this check trumps
-    * the requirement that PLTE appears before IDAT.)
+   /* 1.6.47: consistency.  This used to be especially treated as a critical
+    * error even in an image which is not colour mapped, there isn't a good
+    * justification for treating some errors here one way and others another so
+    * everything uses the same logic.
     */
-   else if ((png_ptr->mode & PNG_HAVE_PLTE) != 0)
-      png_chunk_error(png_ptr, "duplicate");
+   if ((png_ptr->mode & PNG_HAVE_PLTE) != 0)
+      errmsg = "duplicate";
 
    else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
-   {
-      /* This is benign because the non-benign error happened before, when an
-       * IDAT was encountered in a color-mapped image with no PLTE.
-       */
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "out of place");
-      return;
-   }
+      errmsg = "out of place";
 
-   png_ptr->mode |= PNG_HAVE_PLTE;
+   else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
+      errmsg = "ignored in grayscale PNG";
 
-   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "ignored in grayscale PNG");
-      return;
-   }
+   else if (length > 3*PNG_MAX_PALETTE_LENGTH || (length % 3) != 0)
+      errmsg = "invalid";
 
-#ifndef PNG_READ_OPT_PLTE_SUPPORTED
-   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
-   {
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-#endif
+   /* This drops PLTE in favour of tRNS or bKGD because both of those chunks
+    * can have an effect on the rendering of the image whereas PLTE only matters
+    * in the case of an 8-bit display with a decoder which controls the palette.
+    *
+    * The alternative here is to ignore the error and store the palette anyway;
+    * destroying the tRNS will definately cause problems.
+    *
+    * NOTE: the case of PNG_COLOR_TYPE_PALETTE need not be considered because
+    * the png_handle_ routines for the three 'after PLTE' chunks tRNS, bKGD and
+    * hIST all check for a preceding PLTE in these cases.
+    */
+   else if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE &&
+            (png_has_chunk(png_ptr, tRNS) || png_has_chunk(png_ptr, bKGD)))
+      errmsg = "out of place";
 
-   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
+   else
    {
-      png_crc_finish(png_ptr, length);
-
-      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
-         png_chunk_benign_error(png_ptr, "invalid");
-
-      else
-         png_chunk_error(png_ptr, "invalid");
+      /* If the palette has 256 or fewer entries but is too large for the bit
+       * depth we don't issue an error to preserve the behavior of previous
+       * libpng versions. We silently truncate the unused extra palette entries
+       * here.
+       */
+      const unsigned max_palette_length =
+         (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
+            1U << png_ptr->bit_depth : PNG_MAX_PALETTE_LENGTH;
 
-      return;
-   }
+      /* The cast is safe because 'length' is less than
+       * 3*PNG_MAX_PALETTE_LENGTH
+       */
+      const unsigned num = (length > 3U*max_palette_length) ?
+         max_palette_length : (unsigned)length / 3U;
 
-   /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */
-   num = (int)length / 3;
+      unsigned i, j;
+      png_byte buf[3*PNG_MAX_PALETTE_LENGTH];
+      png_color palette[PNG_MAX_PALETTE_LENGTH];
 
-   /* If the palette has 256 or fewer entries but is too large for the bit
-    * depth, we don't issue an error, to preserve the behavior of previous
-    * libpng versions. We silently truncate the unused extra palette entries
-    * here.
-    */
-   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      max_palette_length = (1 << png_ptr->bit_depth);
-   else
-      max_palette_length = PNG_MAX_PALETTE_LENGTH;
+      /* Read the chunk into the buffer then read to the end of the chunk. */
+      png_crc_read(png_ptr, buf, num*3U);
+      png_crc_finish_critical(png_ptr, length - 3U*num,
+            /* Handle as ancillary if PLTE is optional: */
+            png_ptr->color_type != PNG_COLOR_TYPE_PALETTE);
 
-   if (num > max_palette_length)
-      num = max_palette_length;
+      for (i = 0U, j = 0U; i < num; i++)
+      {
+         palette[i].red = buf[j++];
+         palette[i].green = buf[j++];
+         palette[i].blue = buf[j++];
+      }
 
-#ifdef PNG_POINTER_INDEXING_SUPPORTED
-   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
-   {
-      png_byte buf[3];
+      /* A valid PLTE chunk has been read */
+      png_ptr->mode |= PNG_HAVE_PLTE;
 
-      png_crc_read(png_ptr, buf, 3);
-      pal_ptr->red = buf[0];
-      pal_ptr->green = buf[1];
-      pal_ptr->blue = buf[2];
+      /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to
+       * its own copy of the palette.  This has the side effect that when
+       * png_start_row is called (this happens after any call to
+       * png_read_update_info) the info_ptr palette gets changed.  This is
+       * extremely unexpected and confusing.
+       *
+       * REVIEW: there have been consistent bugs in the past about gamma and
+       * similar transforms to colour mapped images being useless because the
+       * modified palette cannot be accessed because of the above.
+       *
+       * CONSIDER: Fix this by not sharing the palette in this way.  But does
+       * this completely fix the problem?
+       */
+      png_set_PLTE(png_ptr, info_ptr, palette, num);
+      return handled_ok;
    }
-#else
-   for (i = 0; i < num; i++)
-   {
-      png_byte buf[3];
 
-      png_crc_read(png_ptr, buf, 3);
-      /* Don't depend upon png_color being any order */
-      palette[i].red = buf[0];
-      palette[i].green = buf[1];
-      palette[i].blue = buf[2];
-   }
-#endif
-
-   /* If we actually need the PLTE chunk (ie for a paletted image), we do
-    * whatever the normal CRC configuration tells us.  However, if we
-    * have an RGB image, the PLTE can be considered ancillary, so
-    * we will act as though it is.
-    */
-#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+   /* Here on error: errmsg is non NULL. */
    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-#endif
    {
-      png_crc_finish(png_ptr, (png_uint_32) (length - (unsigned int)num * 3));
+      png_crc_finish(png_ptr, length);
+      png_chunk_error(png_ptr, errmsg);
    }
 
-#ifndef PNG_READ_OPT_PLTE_SUPPORTED
-   else if (png_crc_error(png_ptr) != 0)  /* Only if we have a CRC error */
+   else /* not critical to this image */
    {
-      /* If we don't want to use the data from an ancillary chunk,
-       * we have two options: an error abort, or a warning and we
-       * ignore the data in this chunk (which should be OK, since
-       * it's considered ancillary for a RGB or RGBA image).
-       *
-       * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the
-       * chunk type to determine whether to check the ancillary or the critical
-       * flags.
-       */
-      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE) == 0)
-      {
-         if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) != 0)
-            return;
-
-         else
-            png_chunk_error(png_ptr, "CRC error");
-      }
-
-      /* Otherwise, we (optionally) emit a warning and use the chunk. */
-      else if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0)
-         png_chunk_warning(png_ptr, "CRC error");
+      png_crc_finish_critical(png_ptr, length, 1/*handle as ancillary*/);
+      png_chunk_benign_error(png_ptr, errmsg);
    }
-#endif
 
-   /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its
-    * own copy of the palette.  This has the side effect that when png_start_row
-    * is called (this happens after any call to png_read_update_info) the
-    * info_ptr palette gets changed.  This is extremely unexpected and
-    * confusing.
-    *
-    * Fix this by not sharing the palette in this way.
+   /* Because PNG_UNUSED(errmsg) does not work if all the uses are compiled out
+    * (this does happen).
     */
-   png_set_PLTE(png_ptr, info_ptr, palette, num);
-
-   /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before
-    * IDAT.  Prior to 1.6.0 this was not checked; instead the code merely
-    * checked the apparent validity of a tRNS chunk inserted before PLTE on a
-    * palette PNG.  1.6.0 attempts to rigorously follow the standard and
-    * therefore does a benign error if the erroneous condition is detected *and*
-    * cancels the tRNS if the benign error returns.  The alternative is to
-    * amend the standard since it would be rather hypocritical of the standards
-    * maintainers to ignore it.
-    */
-#ifdef PNG_READ_tRNS_SUPPORTED
-   if (png_ptr->num_trans > 0 ||
-       (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0))
-   {
-      /* Cancel this because otherwise it would be used if the transforms
-       * require it.  Don't cancel the 'valid' flag because this would prevent
-       * detection of duplicate chunks.
-       */
-      png_ptr->num_trans = 0;
-
-      if (info_ptr != NULL)
-         info_ptr->num_trans = 0;
-
-      png_chunk_benign_error(png_ptr, "tRNS must be after");
-   }
-#endif
-
-#ifdef PNG_READ_hIST_SUPPORTED
-   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0)
-      png_chunk_benign_error(png_ptr, "hIST must be after");
-#endif
-
-#ifdef PNG_READ_bKGD_SUPPORTED
-   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0)
-      png_chunk_benign_error(png_ptr, "bKGD must be after");
-#endif
+   return errmsg != NULL ? handled_error : handled_error;
 }
 
-void /* PRIVATE */
+/* On read the IDAT chunk is always handled specially, even if marked for
+ * unknown handling (this is allowed), so:
+ */
+#define png_handle_IDAT NULL
+
+static png_handle_result_code
 png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    png_debug(1, "in png_handle_IEND");
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0 ||
-       (png_ptr->mode & PNG_HAVE_IDAT) == 0)
-      png_chunk_error(png_ptr, "out of place");
-
    png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
 
-   png_crc_finish(png_ptr, length);
-
    if (length != 0)
       png_chunk_benign_error(png_ptr, "invalid");
 
+   png_crc_finish_critical(png_ptr, length, 1/*handle as ancillary*/);
+
+   return handled_ok;
    PNG_UNUSED(info_ptr)
 }
 
 #ifdef PNG_READ_gAMA_SUPPORTED
-void /* PRIVATE */
+static png_handle_result_code
 png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
-   png_fixed_point igamma;
+   png_uint_32 ugamma;
    png_byte buf[4];
 
    png_debug(1, "in png_handle_gAMA");
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
+   png_crc_read(png_ptr, buf, 4);
 
-   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "out of place");
-      return;
-   }
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return handled_error;
+
+   ugamma = png_get_uint_32(buf);
 
-   if (length != 4)
+   if (ugamma > PNG_UINT_31_MAX)
    {
-      png_crc_finish(png_ptr, length);
       png_chunk_benign_error(png_ptr, "invalid");
-      return;
+      return handled_error;
    }
 
-   png_crc_read(png_ptr, buf, 4);
-
-   if (png_crc_finish(png_ptr, 0) != 0)
-      return;
+   png_set_gAMA_fixed(png_ptr, info_ptr, (png_fixed_point)/*SAFE*/ugamma);
 
-   igamma = png_get_fixed_point(NULL, buf);
+#ifdef PNG_READ_GAMMA_SUPPORTED
+      /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA.  gAMA is
+       * at the end of the chain so simply check for an unset value.
+       */
+      if (png_ptr->chunk_gamma == 0)
+         png_ptr->chunk_gamma = (png_fixed_point)/*SAFE*/ugamma;
+#endif /*READ_GAMMA*/
 
-   png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma);
-   png_colorspace_sync(png_ptr, info_ptr);
+   return handled_ok;
+   PNG_UNUSED(length)
 }
+#else
+#  define png_handle_gAMA NULL
 #endif
 
 #ifdef PNG_READ_sBIT_SUPPORTED
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    unsigned int truelen, i;
@@ -1189,23 +1188,6 @@ png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
    png_debug(1, "in png_handle_sBIT");
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
-   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "out of place");
-      return;
-   }
-
-   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "duplicate");
-      return;
-   }
-
    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    {
       truelen = 3;
@@ -1218,25 +1200,25 @@ png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
       sample_depth = png_ptr->bit_depth;
    }
 
-   if (length != truelen || length > 4)
+   if (length != truelen)
    {
-      png_chunk_benign_error(png_ptr, "invalid");
       png_crc_finish(png_ptr, length);
-      return;
+      png_chunk_benign_error(png_ptr, "bad length");
+      return handled_error;
    }
 
    buf[0] = buf[1] = buf[2] = buf[3] = sample_depth;
    png_crc_read(png_ptr, buf, truelen);
 
    if (png_crc_finish(png_ptr, 0) != 0)
-      return;
+      return handled_error;
 
    for (i=0; i sample_depth)
       {
          png_chunk_benign_error(png_ptr, "invalid");
-         return;
+         return handled_error;
       }
    }
 
@@ -1248,7 +1230,7 @@ png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
       png_ptr->sig_bit.alpha = buf[3];
    }
 
-   else
+   else /* grayscale */
    {
       png_ptr->sig_bit.gray = buf[0];
       png_ptr->sig_bit.red = buf[0];
@@ -1258,133 +1240,132 @@ png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    }
 
    png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
+   return handled_ok;
 }
+#else
+#  define png_handle_sBIT NULL
 #endif
 
 #ifdef PNG_READ_cHRM_SUPPORTED
-void /* PRIVATE */
-png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+static png_int_32
+png_get_int_32_checked(png_const_bytep buf, int *error)
 {
-   png_byte buf[32];
-   png_xy xy;
+   png_uint_32 uval = png_get_uint_32(buf);
+   if ((uval & 0x80000000) == 0) /* non-negative */
+      return (png_int_32)uval;
 
-   png_debug(1, "in png_handle_cHRM");
+   uval = (uval ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */
+   if ((uval & 0x80000000) == 0) /* no overflow */
+      return -(png_int_32)uval;
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
+   /* This version of png_get_int_32 has a way of returning the error to the
+    * caller, so:
+    */
+   *error = 1;
+   return 0; /* Safe */
+}
 
-   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "out of place");
-      return;
-   }
+static png_handle_result_code /* PRIVATE */
+png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   int error = 0;
+   png_xy xy;
+   png_byte buf[32];
 
-   if (length != 32)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "invalid");
-      return;
-   }
+   png_debug(1, "in png_handle_cHRM");
 
    png_crc_read(png_ptr, buf, 32);
 
    if (png_crc_finish(png_ptr, 0) != 0)
-      return;
+      return handled_error;
+
+   xy.whitex = png_get_int_32_checked(buf +  0, &error);
+   xy.whitey = png_get_int_32_checked(buf +  4, &error);
+   xy.redx   = png_get_int_32_checked(buf +  8, &error);
+   xy.redy   = png_get_int_32_checked(buf + 12, &error);
+   xy.greenx = png_get_int_32_checked(buf + 16, &error);
+   xy.greeny = png_get_int_32_checked(buf + 20, &error);
+   xy.bluex  = png_get_int_32_checked(buf + 24, &error);
+   xy.bluey  = png_get_int_32_checked(buf + 28, &error);
 
-   xy.whitex = png_get_fixed_point(NULL, buf);
-   xy.whitey = png_get_fixed_point(NULL, buf + 4);
-   xy.redx   = png_get_fixed_point(NULL, buf + 8);
-   xy.redy   = png_get_fixed_point(NULL, buf + 12);
-   xy.greenx = png_get_fixed_point(NULL, buf + 16);
-   xy.greeny = png_get_fixed_point(NULL, buf + 20);
-   xy.bluex  = png_get_fixed_point(NULL, buf + 24);
-   xy.bluey  = png_get_fixed_point(NULL, buf + 28);
-
-   if (xy.whitex == PNG_FIXED_ERROR ||
-       xy.whitey == PNG_FIXED_ERROR ||
-       xy.redx   == PNG_FIXED_ERROR ||
-       xy.redy   == PNG_FIXED_ERROR ||
-       xy.greenx == PNG_FIXED_ERROR ||
-       xy.greeny == PNG_FIXED_ERROR ||
-       xy.bluex  == PNG_FIXED_ERROR ||
-       xy.bluey  == PNG_FIXED_ERROR)
+   if (error)
    {
-      png_chunk_benign_error(png_ptr, "invalid values");
-      return;
+      png_chunk_benign_error(png_ptr, "invalid");
+      return handled_error;
    }
 
-   /* If a colorspace error has already been output skip this chunk */
-   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
-      return;
+   /* png_set_cHRM may complain about some of the values but this doesn't matter
+    * because it was a cHRM and it did have vaguely (if, perhaps, ridiculous)
+    * values.  Ridiculousity will be checked if the values are used later.
+    */
+   png_set_cHRM_fixed(png_ptr, info_ptr, xy.whitex, xy.whitey, xy.redx, xy.redy,
+         xy.greenx, xy.greeny, xy.bluex, xy.bluey);
 
-   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0)
-   {
-      png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
-      png_colorspace_sync(png_ptr, info_ptr);
-      png_chunk_benign_error(png_ptr, "duplicate");
-      return;
-   }
+   /* We only use 'chromaticities' for RGB to gray */
+#  ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+      /* There is no need to check sRGB here, cICP is NYI and iCCP is not
+       * supported so just check mDCV.
+       */
+      if (!png_has_chunk(png_ptr, mDCV))
+      {
+         png_ptr->chromaticities = xy;
+      }
+#  endif /* READ_RGB_TO_GRAY */
 
-   png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
-   (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy,
-       1/*prefer cHRM values*/);
-   png_colorspace_sync(png_ptr, info_ptr);
+   return handled_ok;
+   PNG_UNUSED(length)
 }
+#else
+#  define png_handle_cHRM NULL
 #endif
 
 #ifdef PNG_READ_sRGB_SUPPORTED
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    png_byte intent;
 
    png_debug(1, "in png_handle_sRGB");
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
-   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "out of place");
-      return;
-   }
-
-   if (length != 1)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "invalid");
-      return;
-   }
-
    png_crc_read(png_ptr, &intent, 1);
 
    if (png_crc_finish(png_ptr, 0) != 0)
-      return;
+      return handled_error;
 
-   /* If a colorspace error has already been output skip this chunk */
-   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
-      return;
-
-   /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect
-    * this.
+   /* This checks the range of the "rendering intent" because it is specified in
+    * the PNG spec itself; the "reserved" values will result in the chunk not
+    * being accepted, just as they do with the various "reserved" values in
+    * IHDR.
     */
-   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) != 0)
+   if (intent > 3/*PNGv3 spec*/)
    {
-      png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
-      png_colorspace_sync(png_ptr, info_ptr);
-      png_chunk_benign_error(png_ptr, "too many profiles");
-      return;
+      png_chunk_benign_error(png_ptr, "invalid");
+      return handled_error;
    }
 
-   (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent);
-   png_colorspace_sync(png_ptr, info_ptr);
+   png_set_sRGB(png_ptr, info_ptr, intent);
+   /* NOTE: png_struct::chromaticities is not set here because the RGB to gray
+    * coefficients are known without a need for the chromaticities.
+    */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+      /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA.  iCCP is
+       * not supported by libpng so the only requirement is to check for cICP
+       * setting the gamma (this is NYI, but this check is safe.)
+       */
+      if (!png_has_chunk(png_ptr, cICP) || png_ptr->chunk_gamma == 0)
+         png_ptr->chunk_gamma = PNG_GAMMA_sRGB_INVERSE;
+#endif /*READ_GAMMA*/
+
+   return handled_ok;
+   PNG_UNUSED(length)
 }
+#else
+#  define png_handle_sRGB NULL
 #endif /* READ_sRGB */
 
 #ifdef PNG_READ_iCCP_SUPPORTED
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 /* Note: this does not properly handle profiles that are > 64K under DOS */
 {
@@ -1393,44 +1374,10 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
    png_debug(1, "in png_handle_iCCP");
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
-   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "out of place");
-      return;
-   }
-
-   /* Consistent with all the above colorspace handling an obviously *invalid*
-    * chunk is just ignored, so does not invalidate the color space.  An
-    * alternative is to set the 'invalid' flags at the start of this routine
-    * and only clear them in they were not set before and all the tests pass.
+   /* PNGv3: allow PNG files with both sRGB and iCCP because the PNG spec only
+    * ever said that there "should" be only one, not "shall" and the PNGv3
+    * colour chunk precedence rules give a handling for this case anyway.
     */
-
-   /* The keyword must be at least one character and there is a
-    * terminator (0) byte and the compression method byte, and the
-    * 'zlib' datastream is at least 11 bytes.
-    */
-   if (length < 14)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "too short");
-      return;
-   }
-
-   /* If a colorspace error has already been output skip this chunk */
-   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      return;
-   }
-
-   /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect
-    * this.
-    */
-   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0)
    {
       uInt read_length, keyword_length;
       char keyword[81];
@@ -1440,19 +1387,16 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
        */
       read_length = 81; /* maximum */
       if (read_length > length)
-         read_length = (uInt)length;
+         read_length = (uInt)/*SAFE*/length;
 
       png_crc_read(png_ptr, (png_bytep)keyword, read_length);
       length -= read_length;
 
-      /* The minimum 'zlib' stream is assumed to be just the 2 byte header,
-       * 5 bytes minimum 'deflate' stream, and the 4 byte checksum.
-       */
-      if (length < 11)
+      if (length < LZ77Min)
       {
          png_crc_finish(png_ptr, length);
          png_chunk_benign_error(png_ptr, "too short");
-         return;
+         return handled_error;
       }
 
       keyword_length = 0;
@@ -1489,15 +1433,14 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
                    */
                   png_uint_32 profile_length = png_get_uint_32(profile_header);
 
-                  if (png_icc_check_length(png_ptr, &png_ptr->colorspace,
-                      keyword, profile_length) != 0)
+                  if (png_icc_check_length(png_ptr, keyword, profile_length) !=
+                      0)
                   {
                      /* The length is apparently ok, so we can check the 132
                       * byte header.
                       */
-                     if (png_icc_check_header(png_ptr, &png_ptr->colorspace,
-                         keyword, profile_length, profile_header,
-                         png_ptr->color_type) != 0)
+                     if (png_icc_check_header(png_ptr, keyword, profile_length,
+                              profile_header, png_ptr->color_type) != 0)
                      {
                         /* Now read the tag table; a variable size buffer is
                          * needed at this point, allocate one for the whole
@@ -1507,7 +1450,7 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
                         png_uint_32 tag_count =
                            png_get_uint_32(profile_header + 128);
                         png_bytep profile = png_read_buffer(png_ptr,
-                            profile_length, 2/*silent*/);
+                              profile_length);
 
                         if (profile != NULL)
                         {
@@ -1526,8 +1469,7 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
                            if (size == 0)
                            {
                               if (png_icc_check_tag_table(png_ptr,
-                                  &png_ptr->colorspace, keyword, profile_length,
-                                  profile) != 0)
+                                       keyword, profile_length, profile) != 0)
                               {
                                  /* The profile has been validated for basic
                                   * security issues, so read the whole thing in.
@@ -1559,13 +1501,6 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
                                     png_crc_finish(png_ptr, length);
                                     finished = 1;
 
-# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
-                                    /* Check for a match against sRGB */
-                                    png_icc_set_sRGB(png_ptr,
-                                        &png_ptr->colorspace, profile,
-                                        png_ptr->zstream.adler);
-# endif
-
                                     /* Steal the profile for info_ptr. */
                                     if (info_ptr != NULL)
                                     {
@@ -1588,11 +1523,7 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
                                        }
 
                                        else
-                                       {
-                                          png_ptr->colorspace.flags |=
-                                             PNG_COLORSPACE_INVALID;
                                           errmsg = "out of memory";
-                                       }
                                     }
 
                                     /* else the profile remains in the read
@@ -1600,13 +1531,10 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
                                      * chunks.
                                      */
 
-                                    if (info_ptr != NULL)
-                                       png_colorspace_sync(png_ptr, info_ptr);
-
                                     if (errmsg == NULL)
                                     {
                                        png_ptr->zowner = 0;
-                                       return;
+                                       return handled_ok;
                                     }
                                  }
                                  if (errmsg == NULL)
@@ -1647,22 +1575,21 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
          errmsg = "bad keyword";
    }
 
-   else
-      errmsg = "too many profiles";
-
    /* Failure: the reason is in 'errmsg' */
    if (finished == 0)
       png_crc_finish(png_ptr, length);
 
-   png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
-   png_colorspace_sync(png_ptr, info_ptr);
    if (errmsg != NULL) /* else already output */
       png_chunk_benign_error(png_ptr, errmsg);
+
+   return handled_error;
 }
+#else
+#  define png_handle_iCCP NULL
 #endif /* READ_iCCP */
 
 #ifdef PNG_READ_sPLT_SUPPORTED
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 /* Note: this does not properly handle chunks that are > 64K under DOS */
 {
@@ -1683,43 +1610,24 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
       if (png_ptr->user_chunk_cache_max == 1)
       {
          png_crc_finish(png_ptr, length);
-         return;
+         return handled_error;
       }
 
       if (--png_ptr->user_chunk_cache_max == 1)
       {
          png_warning(png_ptr, "No space in chunk cache for sPLT");
          png_crc_finish(png_ptr, length);
-         return;
+         return handled_error;
       }
    }
 #endif
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
-   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "out of place");
-      return;
-   }
-
-#ifdef PNG_MAX_MALLOC_64K
-   if (length > 65535U)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "too large to fit in memory");
-      return;
-   }
-#endif
-
-   buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
+   buffer = png_read_buffer(png_ptr, length+1);
    if (buffer == NULL)
    {
       png_crc_finish(png_ptr, length);
       png_chunk_benign_error(png_ptr, "out of memory");
-      return;
+      return handled_error;
    }
 
 
@@ -1730,7 +1638,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    png_crc_read(png_ptr, buffer, length);
 
    if (png_crc_finish(png_ptr, skip) != 0)
-      return;
+      return handled_error;
 
    buffer[length] = 0;
 
@@ -1743,7 +1651,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    if (length < 2U || entry_start > buffer + (length - 2U))
    {
       png_warning(png_ptr, "malformed sPLT chunk");
-      return;
+      return handled_error;
    }
 
    new_palette.depth = *entry_start++;
@@ -1757,7 +1665,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    if ((data_length % (unsigned int)entry_size) != 0)
    {
       png_warning(png_ptr, "sPLT chunk has bad length");
-      return;
+      return handled_error;
    }
 
    dl = (png_uint_32)(data_length / (unsigned int)entry_size);
@@ -1766,7 +1674,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    if (dl > max_dl)
    {
       png_warning(png_ptr, "sPLT chunk too long");
-      return;
+      return handled_error;
    }
 
    new_palette.nentries = (png_int_32)(data_length / (unsigned int)entry_size);
@@ -1777,10 +1685,9 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    if (new_palette.entries == NULL)
    {
       png_warning(png_ptr, "sPLT chunk requires too much memory");
-      return;
+      return handled_error;
    }
 
-#ifdef PNG_POINTER_INDEXING_SUPPORTED
    for (i = 0; i < new_palette.nentries; i++)
    {
       pp = new_palette.entries + i;
@@ -1803,31 +1710,6 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
       pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
    }
-#else
-   pp = new_palette.entries;
-
-   for (i = 0; i < new_palette.nentries; i++)
-   {
-
-      if (new_palette.depth == 8)
-      {
-         pp[i].red   = *entry_start++;
-         pp[i].green = *entry_start++;
-         pp[i].blue  = *entry_start++;
-         pp[i].alpha = *entry_start++;
-      }
-
-      else
-      {
-         pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
-         pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
-         pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
-         pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
-      }
-
-      pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
-   }
-#endif
 
    /* Discard all chunk data except the name and stash that */
    new_palette.name = (png_charp)buffer;
@@ -1835,34 +1717,20 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
 
    png_free(png_ptr, new_palette.entries);
+   return handled_ok;
 }
+#else
+#  define png_handle_sPLT NULL
 #endif /* READ_sPLT */
 
 #ifdef PNG_READ_tRNS_SUPPORTED
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
 
    png_debug(1, "in png_handle_tRNS");
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
-   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "out of place");
-      return;
-   }
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "duplicate");
-      return;
-   }
-
    if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
    {
       png_byte buf[2];
@@ -1871,7 +1739,7 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
       {
          png_crc_finish(png_ptr, length);
          png_chunk_benign_error(png_ptr, "invalid");
-         return;
+         return handled_error;
       }
 
       png_crc_read(png_ptr, buf, 2);
@@ -1887,7 +1755,7 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
       {
          png_crc_finish(png_ptr, length);
          png_chunk_benign_error(png_ptr, "invalid");
-         return;
+         return handled_error;
       }
 
       png_crc_read(png_ptr, buf, length);
@@ -1901,10 +1769,9 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    {
       if ((png_ptr->mode & PNG_HAVE_PLTE) == 0)
       {
-         /* TODO: is this actually an error in the ISO spec? */
          png_crc_finish(png_ptr, length);
          png_chunk_benign_error(png_ptr, "out of place");
-         return;
+         return handled_error;
       }
 
       if (length > (unsigned int) png_ptr->num_palette ||
@@ -1913,7 +1780,7 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
       {
          png_crc_finish(png_ptr, length);
          png_chunk_benign_error(png_ptr, "invalid");
-         return;
+         return handled_error;
       }
 
       png_crc_read(png_ptr, readbuf, length);
@@ -1924,13 +1791,13 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    {
       png_crc_finish(png_ptr, length);
       png_chunk_benign_error(png_ptr, "invalid with alpha channel");
-      return;
+      return handled_error;
    }
 
    if (png_crc_finish(png_ptr, 0) != 0)
    {
       png_ptr->num_trans = 0;
-      return;
+      return handled_error;
    }
 
    /* TODO: this is a horrible side effect in the palette case because the
@@ -1939,11 +1806,14 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
     */
    png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
        &(png_ptr->trans_color));
+   return handled_ok;
 }
+#else
+#  define png_handle_tRNS NULL
 #endif
 
 #ifdef PNG_READ_bKGD_SUPPORTED
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    unsigned int truelen;
@@ -1952,27 +1822,17 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
    png_debug(1, "in png_handle_bKGD");
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
-   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 ||
-       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
-       (png_ptr->mode & PNG_HAVE_PLTE) == 0))
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "out of place");
-      return;
-   }
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0)
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "duplicate");
-      return;
-   }
+      if ((png_ptr->mode & PNG_HAVE_PLTE) == 0)
+      {
+         png_crc_finish(png_ptr, length);
+         png_chunk_benign_error(png_ptr, "out of place");
+         return handled_error;
+      }
 
-   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
       truelen = 1;
+   }
 
    else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
       truelen = 6;
@@ -1984,13 +1844,13 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    {
       png_crc_finish(png_ptr, length);
       png_chunk_benign_error(png_ptr, "invalid");
-      return;
+      return handled_error;
    }
 
    png_crc_read(png_ptr, buf, truelen);
 
    if (png_crc_finish(png_ptr, 0) != 0)
-      return;
+      return handled_error;
 
    /* We convert the index value into RGB components so that we can allow
     * arbitrary RGB values for background when we have transparency, and
@@ -2006,7 +1866,7 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
          if (buf[0] >= info_ptr->num_palette)
          {
             png_chunk_benign_error(png_ptr, "invalid index");
-            return;
+            return handled_error;
          }
 
          background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
@@ -2027,7 +1887,7 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
          if (buf[0] != 0 || buf[1] >= (unsigned int)(1 << png_ptr->bit_depth))
          {
             png_chunk_benign_error(png_ptr, "invalid gray level");
-            return;
+            return handled_error;
          }
       }
 
@@ -2045,7 +1905,7 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
          if (buf[0] != 0 || buf[2] != 0 || buf[4] != 0)
          {
             png_chunk_benign_error(png_ptr, "invalid color");
-            return;
+            return handled_error;
          }
       }
 
@@ -2057,75 +1917,174 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    }
 
    png_set_bKGD(png_ptr, info_ptr, &background);
+   return handled_ok;
 }
+#else
+#  define png_handle_bKGD NULL
 #endif
 
-#ifdef PNG_READ_eXIf_SUPPORTED
-void /* PRIVATE */
-png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+#ifdef PNG_READ_cICP_SUPPORTED
+static png_handle_result_code /* PRIVATE */
+png_handle_cICP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
-   unsigned int i;
+   png_byte buf[4];
 
-   png_debug(1, "in png_handle_eXIf");
+   png_debug(1, "in png_handle_cICP");
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
+   png_crc_read(png_ptr, buf, 4);
 
-   if (length < 2)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "too short");
-      return;
-   }
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return handled_error;
 
-   else if (info_ptr == NULL || (info_ptr->valid & PNG_INFO_eXIf) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "duplicate");
-      return;
-   }
+   png_set_cICP(png_ptr, info_ptr, buf[0], buf[1],  buf[2], buf[3]);
 
-   info_ptr->free_me |= PNG_FREE_EXIF;
+   /* We only use 'chromaticities' for RGB to gray */
+#  ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+      if (!png_has_chunk(png_ptr, mDCV))
+      {
+         /* TODO: png_ptr->chromaticities = chromaticities; */
+      }
+#  endif /* READ_RGB_TO_GRAY */
 
-   info_ptr->eXIf_buf = png_voidcast(png_bytep,
-             png_malloc_warn(png_ptr, length));
+#ifdef PNG_READ_GAMMA_SUPPORTED
+      /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA.  cICP is
+       * at the head so simply set the gamma if it can be determined.  If not
+       * chunk_gamma remains unchanged; sRGB and gAMA handling check it for
+       * being zero.
+       */
+      /* TODO: set png_struct::chunk_gamma when possible */
+#endif /*READ_GAMMA*/
+
+   return handled_ok;
+   PNG_UNUSED(length)
+}
+#else
+#  define png_handle_cICP NULL
+#endif
+
+#ifdef PNG_READ_cLLI_SUPPORTED
+static png_handle_result_code /* PRIVATE */
+png_handle_cLLI(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_byte buf[8];
 
-   if (info_ptr->eXIf_buf == NULL)
+   png_debug(1, "in png_handle_cLLI");
+
+   png_crc_read(png_ptr, buf, 8);
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return handled_error;
+
+   /* The error checking happens here, this puts it in just one place: */
+   png_set_cLLI_fixed(png_ptr, info_ptr, png_get_uint_32(buf),
+         png_get_uint_32(buf+4));
+   return handled_ok;
+   PNG_UNUSED(length)
+}
+#else
+#  define png_handle_cLLI NULL
+#endif
+
+#ifdef PNG_READ_mDCV_SUPPORTED
+static png_handle_result_code /* PRIVATE */
+png_handle_mDCV(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_xy chromaticities;
+   png_byte buf[24];
+
+   png_debug(1, "in png_handle_mDCV");
+
+   png_crc_read(png_ptr, buf, 24);
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return handled_error;
+
+   /* The error checking happens here, this puts it in just one place.  The
+    * odd /50000 scaling factor makes it more difficult but the (x.y) values are
+    * only two bytes so a <<1 is safe.
+    *
+    * WARNING: the PNG specification defines the cHRM chunk to **start** with
+    * the white point (x,y).  The W3C PNG v3 specification puts the white point
+    * **after* R,G,B.  The x,y values in mDCV are also scaled by 50,000 and
+    * stored in just two bytes, whereas those in cHRM are scaled by 100,000 and
+    * stored in four bytes.  This is very, very confusing.  These APIs remove
+    * the confusion by copying the existing, well established, API.
+    */
+   chromaticities.redx   = png_get_uint_16(buf+ 0U) << 1; /* red x */
+   chromaticities.redy   = png_get_uint_16(buf+ 2U) << 1; /* red y */
+   chromaticities.greenx = png_get_uint_16(buf+ 4U) << 1; /* green x */
+   chromaticities.greeny = png_get_uint_16(buf+ 6U) << 1; /* green y */
+   chromaticities.bluex  = png_get_uint_16(buf+ 8U) << 1; /* blue x */
+   chromaticities.bluey  = png_get_uint_16(buf+10U) << 1; /* blue y */
+   chromaticities.whitex = png_get_uint_16(buf+12U) << 1; /* white x */
+   chromaticities.whitey = png_get_uint_16(buf+14U) << 1; /* white y */
+
+   png_set_mDCV_fixed(png_ptr, info_ptr,
+         chromaticities.whitex, chromaticities.whitey,
+         chromaticities.redx, chromaticities.redy,
+         chromaticities.greenx, chromaticities.greeny,
+         chromaticities.bluex, chromaticities.bluey,
+         png_get_uint_32(buf+16U), /* peak luminance */
+         png_get_uint_32(buf+20U));/* minimum perceivable luminance */
+
+   /* We only use 'chromaticities' for RGB to gray */
+#  ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+      png_ptr->chromaticities = chromaticities;
+#  endif /* READ_RGB_TO_GRAY */
+
+   return handled_ok;
+   PNG_UNUSED(length)
+}
+#else
+#  define png_handle_mDCV NULL
+#endif
+
+#ifdef PNG_READ_eXIf_SUPPORTED
+static png_handle_result_code /* PRIVATE */
+png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   png_bytep buffer = NULL;
+
+   png_debug(1, "in png_handle_eXIf");
+
+   buffer = png_read_buffer(png_ptr, length);
+
+   if (buffer == NULL)
    {
       png_crc_finish(png_ptr, length);
       png_chunk_benign_error(png_ptr, "out of memory");
-      return;
+      return handled_error;
    }
 
-   for (i = 0; i < length; i++)
+   png_crc_read(png_ptr, buffer, length);
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return handled_error;
+
+   /* PNGv3: the code used to check the byte order mark at the start for MM or
+    * II, however PNGv3 states that the the first 4 bytes should be checked.
+    * The caller ensures that there are four bytes available.
+    */
    {
-      png_byte buf[1];
-      png_crc_read(png_ptr, buf, 1);
-      info_ptr->eXIf_buf[i] = buf[0];
-      if (i == 1)
+      png_uint_32 header = png_get_uint_32(buffer);
+
+      /* These numbers are copied from the PNGv3 spec: */
+      if (header != 0x49492A00 && header != 0x4D4D002A)
       {
-         if ((buf[0] != 'M' && buf[0] != 'I') ||
-             (info_ptr->eXIf_buf[0] != buf[0]))
-         {
-            png_crc_finish(png_ptr, length - 2);
-            png_chunk_benign_error(png_ptr, "incorrect byte-order specifier");
-            png_free(png_ptr, info_ptr->eXIf_buf);
-            info_ptr->eXIf_buf = NULL;
-            return;
-         }
+         png_chunk_benign_error(png_ptr, "invalid");
+         return handled_error;
       }
    }
 
-   if (png_crc_finish(png_ptr, 0) == 0)
-      png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf);
-
-   png_free(png_ptr, info_ptr->eXIf_buf);
-   info_ptr->eXIf_buf = NULL;
+   png_set_eXIf_1(png_ptr, info_ptr, length, buffer);
+   return handled_ok;
 }
+#else
+#  define png_handle_eXIf NULL
 #endif
 
 #ifdef PNG_READ_hIST_SUPPORTED
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    unsigned int num, i;
@@ -2133,25 +2092,13 @@ png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
    png_debug(1, "in png_handle_hIST");
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
-   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 ||
-       (png_ptr->mode & PNG_HAVE_PLTE) == 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "out of place");
-      return;
-   }
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "duplicate");
-      return;
-   }
-
-   num = length / 2 ;
+   /* This cast is safe because the chunk definition limits the length to a
+    * maximum of 1024 bytes.
+    *
+    * TODO: maybe use png_uint_32 anyway, not unsigned int, to reduce the
+    * casts.
+    */
+   num = (unsigned int)length / 2 ;
 
    if (length != num * 2 ||
        num != (unsigned int)png_ptr->num_palette ||
@@ -2159,7 +2106,7 @@ png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    {
       png_crc_finish(png_ptr, length);
       png_chunk_benign_error(png_ptr, "invalid");
-      return;
+      return handled_error;
    }
 
    for (i = 0; i < num; i++)
@@ -2171,14 +2118,17 @@ png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    }
 
    if (png_crc_finish(png_ptr, 0) != 0)
-      return;
+      return handled_error;
 
    png_set_hIST(png_ptr, info_ptr, readbuf);
+   return handled_ok;
 }
+#else
+#  define png_handle_hIST NULL
 #endif
 
 #ifdef PNG_READ_pHYs_SUPPORTED
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    png_byte buf[9];
@@ -2187,44 +2137,24 @@ png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
    png_debug(1, "in png_handle_pHYs");
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
-   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "out of place");
-      return;
-   }
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "duplicate");
-      return;
-   }
-
-   if (length != 9)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "invalid");
-      return;
-   }
-
    png_crc_read(png_ptr, buf, 9);
 
    if (png_crc_finish(png_ptr, 0) != 0)
-      return;
+      return handled_error;
 
    res_x = png_get_uint_32(buf);
    res_y = png_get_uint_32(buf + 4);
    unit_type = buf[8];
    png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
+   return handled_ok;
+   PNG_UNUSED(length)
 }
+#else
+#  define png_handle_pHYs NULL
 #endif
 
 #ifdef PNG_READ_oFFs_SUPPORTED
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    png_byte buf[9];
@@ -2233,45 +2163,25 @@ png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
    png_debug(1, "in png_handle_oFFs");
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
-   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "out of place");
-      return;
-   }
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "duplicate");
-      return;
-   }
-
-   if (length != 9)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "invalid");
-      return;
-   }
-
    png_crc_read(png_ptr, buf, 9);
 
    if (png_crc_finish(png_ptr, 0) != 0)
-      return;
+      return handled_error;
 
    offset_x = png_get_int_32(buf);
    offset_y = png_get_int_32(buf + 4);
    unit_type = buf[8];
    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
+   return handled_ok;
+   PNG_UNUSED(length)
 }
+#else
+#  define png_handle_oFFs NULL
 #endif
 
 #ifdef PNG_READ_pCAL_SUPPORTED
 /* Read the pCAL chunk (described in the PNG Extensions document) */
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    png_int_32 X0, X1;
@@ -2281,40 +2191,22 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    int i;
 
    png_debug(1, "in png_handle_pCAL");
-
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
-   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "out of place");
-      return;
-   }
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "duplicate");
-      return;
-   }
-
    png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)",
        length + 1);
 
-   buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
+   buffer = png_read_buffer(png_ptr, length+1);
 
    if (buffer == NULL)
    {
       png_crc_finish(png_ptr, length);
       png_chunk_benign_error(png_ptr, "out of memory");
-      return;
+      return handled_error;
    }
 
    png_crc_read(png_ptr, buffer, length);
 
    if (png_crc_finish(png_ptr, 0) != 0)
-      return;
+      return handled_error;
 
    buffer[length] = 0; /* Null terminate the last string */
 
@@ -2330,7 +2222,7 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    if (endptr - buf <= 12)
    {
       png_chunk_benign_error(png_ptr, "invalid");
-      return;
+      return handled_error;
    }
 
    png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
@@ -2350,7 +2242,7 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
        (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
    {
       png_chunk_benign_error(png_ptr, "invalid parameter count");
-      return;
+      return handled_error;
    }
 
    else if (type >= PNG_EQUATION_LAST)
@@ -2369,7 +2261,7 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    if (params == NULL)
    {
       png_chunk_benign_error(png_ptr, "out of memory");
-      return;
+      return handled_error;
    }
 
    /* Get pointers to the start of each parameter string. */
@@ -2387,20 +2279,29 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
       {
          png_free(png_ptr, params);
          png_chunk_benign_error(png_ptr, "invalid data");
-         return;
+         return handled_error;
       }
    }
 
    png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams,
        (png_charp)units, params);
 
+   /* TODO: BUG: png_set_pCAL calls png_chunk_report which, in this case, calls
+    * png_benign_error and that can error out.
+    *
+    * png_read_buffer needs to be allocated with space for both nparams and the
+    * parameter strings.  Not hard to do.
+    */
    png_free(png_ptr, params);
+   return handled_ok;
 }
+#else
+#  define png_handle_pCAL NULL
 #endif
 
 #ifdef PNG_READ_sCAL_SUPPORTED
 /* Read the sCAL chunk */
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    png_bytep buffer;
@@ -2408,55 +2309,29 @@ png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    int state;
 
    png_debug(1, "in png_handle_sCAL");
-
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
-   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "out of place");
-      return;
-   }
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "duplicate");
-      return;
-   }
-
-   /* Need unit type, width, \0, height: minimum 4 bytes */
-   else if (length < 4)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "invalid");
-      return;
-   }
-
    png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
        length + 1);
 
-   buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
+   buffer = png_read_buffer(png_ptr, length+1);
 
    if (buffer == NULL)
    {
-      png_chunk_benign_error(png_ptr, "out of memory");
       png_crc_finish(png_ptr, length);
-      return;
+      png_chunk_benign_error(png_ptr, "out of memory");
+      return handled_error;
    }
 
    png_crc_read(png_ptr, buffer, length);
    buffer[length] = 0; /* Null terminate the last string */
 
    if (png_crc_finish(png_ptr, 0) != 0)
-      return;
+      return handled_error;
 
    /* Validate the unit. */
    if (buffer[0] != 1 && buffer[0] != 2)
    {
       png_chunk_benign_error(png_ptr, "invalid unit");
-      return;
+      return handled_error;
    }
 
    /* Validate the ASCII numbers, need two ASCII numbers separated by
@@ -2485,15 +2360,22 @@ png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
          png_chunk_benign_error(png_ptr, "non-positive height");
 
       else
+      {
          /* This is the (only) success case. */
          png_set_sCAL_s(png_ptr, info_ptr, buffer[0],
              (png_charp)buffer+1, (png_charp)buffer+heighti);
+         return handled_ok;
+      }
    }
+
+   return handled_error;
 }
+#else
+#  define png_handle_sCAL NULL
 #endif
 
 #ifdef PNG_READ_tIME_SUPPORTED
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    png_byte buf[7];
@@ -2501,30 +2383,17 @@ png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
    png_debug(1, "in png_handle_tIME");
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
-   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) != 0)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "duplicate");
-      return;
-   }
-
+   /* TODO: what is this doing here?  It should be happened in pngread.c and
+    * pngpread.c, although it could be moved to png_handle_chunk below and
+    * thereby avoid some code duplication.
+    */
    if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
       png_ptr->mode |= PNG_AFTER_IDAT;
 
-   if (length != 7)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "invalid");
-      return;
-   }
-
    png_crc_read(png_ptr, buf, 7);
 
    if (png_crc_finish(png_ptr, 0) != 0)
-      return;
+      return handled_error;
 
    mod_time.second = buf[6];
    mod_time.minute = buf[5];
@@ -2534,12 +2403,16 @@ png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    mod_time.year = png_get_uint_16(buf);
 
    png_set_tIME(png_ptr, info_ptr, &mod_time);
+   return handled_ok;
+   PNG_UNUSED(length)
 }
+#else
+#  define png_handle_tIME NULL
 #endif
 
 #ifdef PNG_READ_tEXt_SUPPORTED
 /* Note: this does not properly handle chunks that are > 64K under DOS */
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    png_text  text_info;
@@ -2556,45 +2429,35 @@ png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
       if (png_ptr->user_chunk_cache_max == 1)
       {
          png_crc_finish(png_ptr, length);
-         return;
+         return handled_error;
       }
 
       if (--png_ptr->user_chunk_cache_max == 1)
       {
          png_crc_finish(png_ptr, length);
          png_chunk_benign_error(png_ptr, "no space in chunk cache");
-         return;
+         return handled_error;
       }
    }
 #endif
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
+   /* TODO: this doesn't work and shouldn't be necessary. */
    if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
       png_ptr->mode |= PNG_AFTER_IDAT;
 
-#ifdef PNG_MAX_MALLOC_64K
-   if (length > 65535U)
-   {
-      png_crc_finish(png_ptr, length);
-      png_chunk_benign_error(png_ptr, "too large to fit in memory");
-      return;
-   }
-#endif
-
-   buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);
+   buffer = png_read_buffer(png_ptr, length+1);
 
    if (buffer == NULL)
    {
+      png_crc_finish(png_ptr, length);
       png_chunk_benign_error(png_ptr, "out of memory");
-      return;
+      return handled_error;
    }
 
    png_crc_read(png_ptr, buffer, length);
 
    if (png_crc_finish(png_ptr, skip) != 0)
-      return;
+      return handled_error;
 
    key = (png_charp)buffer;
    key[length] = 0;
@@ -2613,14 +2476,19 @@ png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    text_info.text = text;
    text_info.text_length = strlen(text);
 
-   if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) != 0)
-      png_warning(png_ptr, "Insufficient memory to process text chunk");
+   if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) == 0)
+      return handled_ok;
+
+   png_chunk_benign_error(png_ptr, "out of memory");
+   return handled_error;
 }
+#else
+#  define png_handle_tEXt NULL
 #endif
 
 #ifdef PNG_READ_zTXt_SUPPORTED
 /* Note: this does not correctly handle chunks that are > 64K under DOS */
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    png_const_charp errmsg = NULL;
@@ -2635,40 +2503,39 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
       if (png_ptr->user_chunk_cache_max == 1)
       {
          png_crc_finish(png_ptr, length);
-         return;
+         return handled_error;
       }
 
       if (--png_ptr->user_chunk_cache_max == 1)
       {
          png_crc_finish(png_ptr, length);
          png_chunk_benign_error(png_ptr, "no space in chunk cache");
-         return;
+         return handled_error;
       }
    }
 #endif
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
+   /* TODO: should not be necessary. */
    if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
       png_ptr->mode |= PNG_AFTER_IDAT;
 
    /* Note, "length" is sufficient here; we won't be adding
-    * a null terminator later.
+    * a null terminator later.  The limit check in png_handle_chunk should be
+    * sufficient.
     */
-   buffer = png_read_buffer(png_ptr, length, 2/*silent*/);
+   buffer = png_read_buffer(png_ptr, length);
 
    if (buffer == NULL)
    {
       png_crc_finish(png_ptr, length);
       png_chunk_benign_error(png_ptr, "out of memory");
-      return;
+      return handled_error;
    }
 
    png_crc_read(png_ptr, buffer, length);
 
    if (png_crc_finish(png_ptr, 0) != 0)
-      return;
+      return handled_error;
 
    /* TODO: also check that the keyword contents match the spec! */
    for (keyword_length = 0;
@@ -2721,8 +2588,10 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
             text.lang = NULL;
             text.lang_key = NULL;
 
-            if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0)
-               errmsg = "insufficient memory";
+            if (png_set_text_2(png_ptr, info_ptr, &text, 1) == 0)
+               return handled_ok;
+
+            errmsg = "out of memory";
          }
       }
 
@@ -2730,14 +2599,16 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
          errmsg = png_ptr->zstream.msg;
    }
 
-   if (errmsg != NULL)
-      png_chunk_benign_error(png_ptr, errmsg);
+   png_chunk_benign_error(png_ptr, errmsg);
+   return handled_error;
 }
+#else
+#  define png_handle_zTXt NULL
 #endif
 
 #ifdef PNG_READ_iTXt_SUPPORTED
 /* Note: this does not correctly handle chunks that are > 64K under DOS */
-void /* PRIVATE */
+static png_handle_result_code /* PRIVATE */
 png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    png_const_charp errmsg = NULL;
@@ -2752,37 +2623,35 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
       if (png_ptr->user_chunk_cache_max == 1)
       {
          png_crc_finish(png_ptr, length);
-         return;
+         return handled_error;
       }
 
       if (--png_ptr->user_chunk_cache_max == 1)
       {
          png_crc_finish(png_ptr, length);
          png_chunk_benign_error(png_ptr, "no space in chunk cache");
-         return;
+         return handled_error;
       }
    }
 #endif
 
-   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
-      png_chunk_error(png_ptr, "missing IHDR");
-
+   /* TODO: should not be necessary. */
    if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
       png_ptr->mode |= PNG_AFTER_IDAT;
 
-   buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);
+   buffer = png_read_buffer(png_ptr, length+1);
 
    if (buffer == NULL)
    {
       png_crc_finish(png_ptr, length);
       png_chunk_benign_error(png_ptr, "out of memory");
-      return;
+      return handled_error;
    }
 
    png_crc_read(png_ptr, buffer, length);
 
    if (png_crc_finish(png_ptr, 0) != 0)
-      return;
+      return handled_error;
 
    /* First the keyword. */
    for (prefix_length=0;
@@ -2872,8 +2741,10 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
          text.text_length = 0;
          text.itxt_length = uncompressed_length;
 
-         if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0)
-            errmsg = "insufficient memory";
+         if (png_set_text_2(png_ptr, info_ptr, &text, 1) == 0)
+            return handled_ok;
+
+         errmsg = "out of memory";
       }
    }
 
@@ -2882,7 +2753,10 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
    if (errmsg != NULL)
       png_chunk_benign_error(png_ptr, errmsg);
+   return handled_error;
 }
+#else
+#  define png_handle_iTXt NULL
 #endif
 
 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
@@ -2890,7 +2764,7 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 static int
 png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
 {
-   png_alloc_size_t limit = PNG_SIZE_MAX;
+   const png_alloc_size_t limit = png_chunk_max(png_ptr);
 
    if (png_ptr->unknown_chunk.data != NULL)
    {
@@ -2898,16 +2772,6 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
       png_ptr->unknown_chunk.data = NULL;
    }
 
-#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
-   if (png_ptr->user_chunk_malloc_max > 0 &&
-       png_ptr->user_chunk_malloc_max < limit)
-      limit = png_ptr->user_chunk_malloc_max;
-
-#  elif PNG_USER_CHUNK_MALLOC_MAX > 0
-   if (PNG_USER_CHUNK_MALLOC_MAX < limit)
-      limit = PNG_USER_CHUNK_MALLOC_MAX;
-#  endif
-
    if (length <= limit)
    {
       PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
@@ -2946,11 +2810,11 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
 #endif /* READ_UNKNOWN_CHUNKS */
 
 /* Handle an unknown, or known but disabled, chunk */
-void /* PRIVATE */
+png_handle_result_code /*PRIVATE*/
 png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
     png_uint_32 length, int keep)
 {
-   int handled = 0; /* the chunk was handled */
+   png_handle_result_code handled = handled_discarded; /* the default */
 
    png_debug(1, "in png_handle_unknown");
 
@@ -2997,7 +2861,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
           *           error at this point unless it is to be saved.
           * positive: The chunk was handled, libpng will ignore/discard it.
           */
-         if (ret < 0)
+         if (ret < 0) /* handled_error */
             png_chunk_error(png_ptr, "error in user chunk");
 
          else if (ret == 0)
@@ -3031,7 +2895,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
 
          else /* chunk was handled */
          {
-            handled = 1;
+            handled = handled_ok;
             /* Critical chunks can be safely discarded at this point. */
             keep = PNG_HANDLE_CHUNK_NEVER;
          }
@@ -3116,7 +2980,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
              */
             png_set_unknown_chunks(png_ptr, info_ptr,
                 &png_ptr->unknown_chunk, 1);
-            handled = 1;
+            handled = handled_saved;
 #  ifdef PNG_USER_LIMITS_SUPPORTED
             break;
       }
@@ -3142,79 +3006,267 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
 #endif /* !READ_UNKNOWN_CHUNKS */
 
    /* Check for unhandled critical chunks */
-   if (handled == 0 && PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
+   if (handled < handled_saved && PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
       png_chunk_error(png_ptr, "unhandled critical chunk");
+
+   return handled;
 }
 
-/* This function is called to verify that a chunk name is valid.
- * This function can't have the "critical chunk check" incorporated
- * into it, since in the future we will need to be able to call user
- * functions to handle unknown critical chunks after we check that
- * the chunk name itself is valid.
+/* APNG handling: the minimal implementation of APNG handling in libpng 1.6
+ * requires that those significant applications which already handle APNG not
+ * get hosed.  To do this ensure the code here will have to ensure than APNG
+ * data by default (at least in 1.6) gets stored in the unknown chunk list.
+ * Maybe this can be relaxed in a few years but at present it's just the only
+ * safe way.
+ *
+ * ATM just cause unknown handling for all three chunks:
  */
+#define png_handle_acTL NULL
+#define png_handle_fcTL NULL
+#define png_handle_fdAT NULL
 
-/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is:
+/*
+ * 1.6.47: This is the new table driven interface to all the chunk handling.
  *
- * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+ * The table describes the PNG standard rules for **reading** known chunks -
+ * every chunk which has an entry in PNG_KNOWN_CHUNKS.  The table contains an
+ * entry for each PNG_INDEX_cHNK describing the rules.
+ *
+ * In this initial version the only information in the entry is the
+ * png_handle_cHNK function for the chunk in question.  When chunk support is
+ * compiled out the entry will be NULL.
  */
-
-void /* PRIVATE */
-png_check_chunk_name(png_const_structrp png_ptr, png_uint_32 chunk_name)
+static const struct
 {
-   int i;
-   png_uint_32 cn=chunk_name;
-
-   png_debug(1, "in png_check_chunk_name");
+   png_handle_result_code (*handler)(
+         png_structrp, png_inforp, png_uint_32 length);
+      /* A chunk-specific 'handler', NULL if the chunk is not supported in this
+       * build.
+       */
 
-   for (i=1; i<=4; ++i)
+   /* Crushing these values helps on modern 32-bit architectures because the
+    * pointer and the following bit fields both end up requiring 32 bits.
+    * Typically this will halve the table size.  On 64-bit architectures the
+    * table entries will typically be 8 bytes.
+    */
+   png_uint_32 max_length :12; /* Length min, max in bytes */
+   png_uint_32 min_length :8;
+      /* Length errors on critical chunks have special handling to preserve the
+       * existing behaviour in libpng 1.6.  Anciallary chunks are checked below
+       * and produce a 'benign' error.
+       */
+   png_uint_32 pos_before :4; /* PNG_HAVE_ values chunk must precede */
+   png_uint_32 pos_after  :4; /* PNG_HAVE_ values chunk must follow */
+      /* NOTE: PLTE, tRNS and bKGD require special handling which depends on
+       * the colour type of the base image.
+       */
+   png_uint_32 multiple   :1; /* Multiple occurences permitted */
+      /* This is enabled for PLTE because PLTE may, in practice, be optional */
+}
+read_chunks[PNG_INDEX_unknown] =
+{
+   /* Definitions as above but done indirectly by #define so that
+    * PNG_KNOWN_CHUNKS can be used safely to build the table in order.
+    *
+    * Each CDcHNK definition lists the values for the parameters **after**
+    * the first, 'handler', function.  'handler' is NULL when the chunk has no
+    * compiled in support.
+    */
+#  define NoCheck 0x801U      /* Do not check the maximum length */
+#  define Limit   0x802U      /* Limit to png_chunk_max bytes */
+#  define LKMin   3U+LZ77Min  /* Minimum length of keyword+LZ77 */
+
+#define hIHDR PNG_HAVE_IHDR
+#define hPLTE PNG_HAVE_PLTE
+#define hIDAT PNG_HAVE_IDAT
+   /* For the two chunks, tRNS and bKGD which can occur in PNGs without a PLTE
+    * but must occur after the PLTE use this and put the check in the handler
+    * routine for colour mapped images were PLTE is required.  Also put a check
+    * in PLTE for other image types to drop the PLTE if tRNS or bKGD have been
+    * seen.
+    */
+#define hCOL  (PNG_HAVE_PLTE|PNG_HAVE_IDAT)
+   /* Used for the decoding chunks which must be before PLTE. */
+#define aIDAT PNG_AFTER_IDAT
+
+   /* Chunks from W3C PNG v3: */
+   /*       cHNK  max_len,   min, before, after, multiple */
+#  define CDIHDR      13U,   13U,  hIHDR,     0,        0
+#  define CDPLTE  NoCheck,    0U,      0, hIHDR,        1
+      /* PLTE errors are only critical for colour-map images, consequently the
+       * hander does all the checks.
+       */
+#  define CDIDAT  NoCheck,    0U,  aIDAT, hIHDR,        1
+#  define CDIEND  NoCheck,    0U,      0, aIDAT,        0
+      /* Historically data was allowed in IEND */
+#  define CDtRNS     256U,    0U,  hIDAT, hIHDR,        0
+#  define CDcHRM      32U,   32U,   hCOL, hIHDR,        0
+#  define CDgAMA       4U,    4U,   hCOL, hIHDR,        0
+#  define CDiCCP  NoCheck, LKMin,   hCOL, hIHDR,        0
+#  define CDsBIT       4U,    1U,   hCOL, hIHDR,        0
+#  define CDsRGB       1U,    1U,   hCOL, hIHDR,        0
+#  define CDcICP       4U,    4U,   hCOL, hIHDR,        0
+#  define CDmDCV      24U,   24U,   hCOL, hIHDR,        0
+#  define CDeXIf    Limit,    4U,      0, hIHDR,        0
+#  define CDcLLI       8U,    8U,   hCOL, hIHDR,        0
+#  define CDtEXt  NoCheck,    2U,      0, hIHDR,        1
+      /* Allocates 'length+1'; checked in the handler */
+#  define CDzTXt    Limit, LKMin,      0, hIHDR,        1
+#  define CDiTXt  NoCheck,    6U,      0, hIHDR,        1
+      /* Allocates 'length+1'; checked in the handler */
+#  define CDbKGD       6U,    1U,  hIDAT, hIHDR,        0
+#  define CDhIST    1024U,    0U,  hPLTE, hIHDR,        0
+#  define CDpHYs       9U,    9U,  hIDAT, hIHDR,        0
+#  define CDsPLT  NoCheck,    3U,  hIDAT, hIHDR,        1
+      /* Allocates 'length+1'; checked in the handler */
+#  define CDtIME       7U,    7U,      0, hIHDR,        0
+#  define CDacTL       8U,    8U,  hIDAT, hIHDR,        0
+#  define CDfcTL      25U,   26U,      0, hIHDR,        1
+#  define CDfdAT    Limit,    4U,  hIDAT, hIHDR,        1
+   /* Supported chunks from PNG extensions 1.5.0, NYI so limit */
+#  define CDoFFs       9U,    9U,  hIDAT, hIHDR,        0
+#  define CDpCAL  NoCheck,   14U,  hIDAT, hIHDR,        0
+      /* Allocates 'length+1'; checked in the handler */
+#  define CDsCAL    Limit,    4U,  hIDAT, hIHDR,        0
+      /* Allocates 'length+1'; checked in the handler */
+
+#  define PNG_CHUNK(cHNK, index) { png_handle_ ## cHNK, CD ## cHNK },
+   PNG_KNOWN_CHUNKS
+#  undef PNG_CHUNK
+};
+
+
+static png_index
+png_chunk_index_from_name(png_uint_32 chunk_name)
+{
+   /* For chunk png_cHNK return PNG_INDEX_cHNK.  Return PNG_INDEX_unknown if
+    * chunk_name is not known.  Notice that in a particular build "known" does
+    * not necessarily mean "supported", although the inverse applies.
+    */
+   switch (chunk_name)
    {
-      int c = cn & 0xff;
+#     define PNG_CHUNK(cHNK, index)\
+         case png_ ## cHNK: return PNG_INDEX_ ## cHNK; /* == index */
+
+      PNG_KNOWN_CHUNKS
 
-      if (c < 65 || c > 122 || (c > 90 && c < 97))
-         png_chunk_error(png_ptr, "invalid chunk type");
+#     undef PNG_CHUNK
 
-      cn >>= 8;
+      default: return PNG_INDEX_unknown;
    }
 }
 
-void /* PRIVATE */
-png_check_chunk_length(png_const_structrp png_ptr, png_uint_32 length)
+png_handle_result_code /*PRIVATE*/
+png_handle_chunk(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
-   png_alloc_size_t limit = PNG_UINT_31_MAX;
-
-# ifdef PNG_SET_USER_LIMITS_SUPPORTED
-   if (png_ptr->user_chunk_malloc_max > 0 &&
-       png_ptr->user_chunk_malloc_max < limit)
-      limit = png_ptr->user_chunk_malloc_max;
-# elif PNG_USER_CHUNK_MALLOC_MAX > 0
-   if (PNG_USER_CHUNK_MALLOC_MAX < limit)
-      limit = PNG_USER_CHUNK_MALLOC_MAX;
-# endif
-   if (png_ptr->chunk_name == png_IDAT)
+   /* CSE: these things don't change, these autos are just to save typing and
+    * make the code more clear.
+    */
+   const png_uint_32 chunk_name = png_ptr->chunk_name;
+   const png_index chunk_index = png_chunk_index_from_name(chunk_name);
+
+   png_handle_result_code handled = handled_error;
+   png_const_charp errmsg = NULL;
+
+   /* Is this a known chunk?  If not there are no checks performed here;
+    * png_handle_unknown does the correct checks.  This means that the values
+    * for known but unsupported chunks in the above table are not used here
+    * however the chunks_seen fields in png_struct are still set.
+    */
+   if (chunk_index == PNG_INDEX_unknown ||
+       read_chunks[chunk_index].handler == NULL)
    {
-      png_alloc_size_t idat_limit = PNG_UINT_31_MAX;
-      size_t row_factor =
-         (size_t)png_ptr->width
-         * (size_t)png_ptr->channels
-         * (png_ptr->bit_depth > 8? 2: 1)
-         + 1
-         + (png_ptr->interlaced? 6: 0);
-      if (png_ptr->height > PNG_UINT_32_MAX/row_factor)
-         idat_limit = PNG_UINT_31_MAX;
-      else
-         idat_limit = png_ptr->height * row_factor;
-      row_factor = row_factor > 32566? 32566 : row_factor;
-      idat_limit += 6 + 5*(idat_limit/row_factor+1); /* zlib+deflate overhead */
-      idat_limit=idat_limit < PNG_UINT_31_MAX? idat_limit : PNG_UINT_31_MAX;
-      limit = limit < idat_limit? idat_limit : limit;
+      handled = png_handle_unknown(
+            png_ptr, info_ptr, length, PNG_HANDLE_CHUNK_AS_DEFAULT);
+   }
+
+   /* First check the position.   The first check is historical; the stream must
+    * start with IHDR and anything else causes libpng to give up immediately.
+    */
+   else if (chunk_index != PNG_INDEX_IHDR &&
+            (png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR"); /* NORETURN */
+
+   /* Before all the pos_before chunks, after all the pos_after chunks. */
+   else if (((png_ptr->mode & read_chunks[chunk_index].pos_before) != 0) ||
+            ((png_ptr->mode & read_chunks[chunk_index].pos_after) !=
+             read_chunks[chunk_index].pos_after))
+   {
+      errmsg = "out of place";
+   }
+
+   /* Now check for duplicates: duplicated critical chunks also produce a
+    * full error.
+    */
+   else if (read_chunks[chunk_index].multiple == 0 &&
+            png_file_has_chunk(png_ptr, chunk_index))
+   {
+      errmsg = "duplicate";
+   }
+
+   else if (length < read_chunks[chunk_index].min_length)
+      errmsg = "too short";
+   else
+   {
+      /* NOTE: apart from IHDR the critical chunks (PLTE, IDAT and IEND) are set
+       * up above not to do any length checks.
+       *
+       * The png_chunk_max check ensures that the variable length chunks are
+       * always checked at this point for being within the system allocation
+       * limits.
+       */
+      unsigned max_length = read_chunks[chunk_index].max_length;
+
+      switch (max_length)
+      {
+         case Limit:
+            /* png_read_chunk_header has already png_error'ed chunks with a
+             * length exceeding the 31-bit PNG limit, so just check the memory
+             * limit:
+             */
+            if (length <= png_chunk_max(png_ptr))
+               goto MeetsLimit;
+
+            errmsg = "length exceeds libpng limit";
+            break;
+
+         default:
+            if (length <= max_length)
+               goto MeetsLimit;
+
+            errmsg = "too long";
+            break;
+
+         case NoCheck:
+         MeetsLimit:
+            handled = read_chunks[chunk_index].handler(
+                  png_ptr, info_ptr, length);
+            break;
+      }
+   }
+
+   /* If there was an error or the chunk was simply skipped it is not counted as
+    * 'seen'.
+    */
+   if (errmsg != NULL)
+   {
+      if (PNG_CHUNK_CRITICAL(chunk_name)) /* stop immediately */
+         png_chunk_error(png_ptr, errmsg);
+      else /* ancillary chunk */
+      {
+         /* The chunk data is skipped: */
+         png_crc_finish(png_ptr, length);
+         png_chunk_benign_error(png_ptr, errmsg);
+      }
    }
 
-   if (length > limit)
+   else if (handled >= handled_saved)
    {
-      png_debug2(0," length = %lu, limit = %lu",
-         (unsigned long)length,(unsigned long)limit);
-      png_benign_error(png_ptr, "chunk data is too large");
+      if (chunk_index != PNG_INDEX_unknown)
+         png_file_add_chunk(png_ptr, chunk_index);
    }
+
+   return handled;
 }
 
 /* Combines the row recently read in with the existing pixels in the row.  This
@@ -3712,10 +3764,6 @@ void /* PRIVATE */
 png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
     png_uint_32 transformations /* Because these may affect the byte layout */)
 {
-   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-   /* Offset to next interlace block */
-   static const unsigned int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
    png_debug(1, "in png_do_read_interlace");
    if (row != NULL && row_info != NULL)
    {
@@ -4208,6 +4256,9 @@ png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
 
          avail_in = png_ptr->IDAT_read_size;
 
+         if (avail_in > png_chunk_max(png_ptr))
+            avail_in = (uInt)/*SAFE*/png_chunk_max(png_ptr);
+
          if (avail_in > png_ptr->idat_size)
             avail_in = (uInt)png_ptr->idat_size;
 
@@ -4215,8 +4266,13 @@ png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
           * to minimize memory usage by causing lots of re-allocs, but
           * realistically doing IDAT_read_size re-allocs is not likely to be a
           * big problem.
+          *
+          * An error here corresponds to the system being out of memory.
           */
-         buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/);
+         buffer = png_read_buffer(png_ptr, avail_in);
+
+         if (buffer == NULL)
+            png_chunk_error(png_ptr, "out of memory");
 
          png_crc_read(png_ptr, buffer, avail_in);
          png_ptr->idat_size -= avail_in;
@@ -4353,20 +4409,6 @@ png_read_finish_IDAT(png_structrp png_ptr)
 void /* PRIVATE */
 png_read_finish_row(png_structrp png_ptr)
 {
-   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
-   /* Start of interlace block */
-   static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
-   /* Offset to next interlace block */
-   static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
-   /* Start of interlace block in the y direction */
-   static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-
-   /* Offset to next interlace block in the y direction */
-   static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
-
    png_debug(1, "in png_read_finish_row");
    png_ptr->row_number++;
    if (png_ptr->row_number < png_ptr->num_rows)
@@ -4418,20 +4460,6 @@ png_read_finish_row(png_structrp png_ptr)
 void /* PRIVATE */
 png_read_start_row(png_structrp png_ptr)
 {
-   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
-   /* Start of interlace block */
-   static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
-   /* Offset to next interlace block */
-   static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
-   /* Start of interlace block in the y direction */
-   static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-
-   /* Offset to next interlace block in the y direction */
-   static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
-
    unsigned int max_pixel_depth;
    size_t row_bytes;
 
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c
index f53ab6fa1d18f..1bfd292bd4637 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c
@@ -29,7 +29,7 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Copyright (c) 2018-2024 Cosmin Truta
+ * Copyright (c) 2018-2025 Cosmin Truta
  * Copyright (c) 1998-2018 Glenn Randers-Pehrson
  * Copyright (c) 1996-1997 Andreas Dilger
  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -70,27 +70,21 @@ png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
     png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
     png_fixed_point blue_x, png_fixed_point blue_y)
 {
-   png_xy xy;
-
    png_debug1(1, "in %s storage function", "cHRM fixed");
 
    if (png_ptr == NULL || info_ptr == NULL)
       return;
 
-   xy.redx = red_x;
-   xy.redy = red_y;
-   xy.greenx = green_x;
-   xy.greeny = green_y;
-   xy.bluex = blue_x;
-   xy.bluey = blue_y;
-   xy.whitex = white_x;
-   xy.whitey = white_y;
-
-   if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy,
-       2/* override with app values*/) != 0)
-      info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
+   info_ptr->cHRM.redx = red_x;
+   info_ptr->cHRM.redy = red_y;
+   info_ptr->cHRM.greenx = green_x;
+   info_ptr->cHRM.greeny = green_y;
+   info_ptr->cHRM.bluex = blue_x;
+   info_ptr->cHRM.bluey = blue_y;
+   info_ptr->cHRM.whitex = white_x;
+   info_ptr->cHRM.whitey = white_y;
 
-   png_colorspace_sync_info(png_ptr, info_ptr);
+   info_ptr->valid |= PNG_INFO_cHRM;
 }
 
 void PNGFAPI
@@ -102,6 +96,7 @@ png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
     png_fixed_point int_blue_Z)
 {
    png_XYZ XYZ;
+   png_xy xy;
 
    png_debug1(1, "in %s storage function", "cHRM XYZ fixed");
 
@@ -118,11 +113,14 @@ png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
    XYZ.blue_Y = int_blue_Y;
    XYZ.blue_Z = int_blue_Z;
 
-   if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace,
-       &XYZ, 2) != 0)
-      info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
+   if (png_xy_from_XYZ(&xy, &XYZ) == 0)
+   {
+      info_ptr->cHRM = xy;
+      info_ptr->valid |= PNG_INFO_cHRM;
+   }
 
-   png_colorspace_sync_info(png_ptr, info_ptr);
+   else
+      png_app_error(png_ptr, "invalid cHRM XYZ");
 }
 
 #  ifdef PNG_FLOATING_POINT_SUPPORTED
@@ -162,6 +160,192 @@ png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
 
 #endif /* cHRM */
 
+#ifdef PNG_cICP_SUPPORTED
+void PNGAPI
+png_set_cICP(png_const_structrp png_ptr, png_inforp info_ptr,
+             png_byte colour_primaries, png_byte transfer_function,
+             png_byte matrix_coefficients, png_byte video_full_range_flag)
+{
+   png_debug1(1, "in %s storage function", "cICP");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->cicp_colour_primaries = colour_primaries;
+   info_ptr->cicp_transfer_function = transfer_function;
+   info_ptr->cicp_matrix_coefficients = matrix_coefficients;
+   info_ptr->cicp_video_full_range_flag = video_full_range_flag;
+
+   if (info_ptr->cicp_matrix_coefficients != 0)
+   {
+      png_warning(png_ptr, "Invalid cICP matrix coefficients");
+      return;
+   }
+
+   info_ptr->valid |= PNG_INFO_cICP;
+}
+#endif /* cICP */
+
+#ifdef PNG_cLLI_SUPPORTED
+void PNGFAPI
+png_set_cLLI_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
+    /* The values below are in cd/m2 (nits) and are scaled by 10,000; not
+     * 100,000 as in the case of png_fixed_point.
+     */
+    png_uint_32 maxCLL, png_uint_32 maxFALL)
+{
+   png_debug1(1, "in %s storage function", "cLLI");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   /* Check the light level range: */
+   if (maxCLL > 0x7FFFFFFFU || maxFALL > 0x7FFFFFFFU)
+   {
+      /* The limit is 200kcd/m2; somewhat bright but not inconceivable because
+       * human vision is said to run up to 100Mcd/m2.  The sun is about 2Gcd/m2.
+       *
+       * The reference sRGB monitor is 80cd/m2 and the limit of PQ encoding is
+       * 2kcd/m2.
+       */
+      png_chunk_report(png_ptr, "cLLI light level exceeds PNG limit",
+            PNG_CHUNK_WRITE_ERROR);
+      return;
+   }
+
+   info_ptr->maxCLL = maxCLL;
+   info_ptr->maxFALL = maxFALL;
+   info_ptr->valid |= PNG_INFO_cLLI;
+}
+
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_cLLI(png_const_structrp png_ptr, png_inforp info_ptr,
+   double maxCLL, double maxFALL)
+{
+   png_set_cLLI_fixed(png_ptr, info_ptr,
+       png_fixed_ITU(png_ptr, maxCLL, "png_set_cLLI(maxCLL)"),
+       png_fixed_ITU(png_ptr, maxFALL, "png_set_cLLI(maxFALL)"));
+}
+#  endif /* FLOATING_POINT */
+#endif /* cLLI */
+
+#ifdef PNG_mDCV_SUPPORTED
+static png_uint_16
+png_ITU_fixed_16(int *error, png_fixed_point v)
+{
+   /* Return a safe uint16_t value scaled according to the ITU H273 rules for
+    * 16-bit display chromaticities.  Functions like the corresponding
+    * png_fixed() internal function with regard to errors: it's an error on
+    * write, a chunk_benign_error on read: See the definition of
+    * png_chunk_report in pngpriv.h.
+    */
+   v /= 2; /* rounds to 0 in C: avoids insignificant arithmetic errors */
+   if (v > 65535 || v < 0)
+   {
+      *error = 1;
+      return 0;
+   }
+
+   return (png_uint_16)/*SAFE*/v;
+}
+
+void PNGAPI
+png_set_mDCV_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_fixed_point white_x, png_fixed_point white_y,
+    png_fixed_point red_x, png_fixed_point red_y,
+    png_fixed_point green_x, png_fixed_point green_y,
+    png_fixed_point blue_x, png_fixed_point blue_y,
+    png_uint_32 maxDL,
+    png_uint_32 minDL)
+{
+   png_uint_16 rx, ry, gx, gy, bx, by, wx, wy;
+   int error;
+
+   png_debug1(1, "in %s storage function", "mDCV");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   /* Check the input values to ensure they are in the expected range: */
+   error = 0;
+   rx = png_ITU_fixed_16(&error, red_x);
+   ry = png_ITU_fixed_16(&error, red_y);
+   gx = png_ITU_fixed_16(&error, green_x);
+   gy = png_ITU_fixed_16(&error, green_y);
+   bx = png_ITU_fixed_16(&error, blue_x);
+   by = png_ITU_fixed_16(&error, blue_y);
+   wx = png_ITU_fixed_16(&error, white_x);
+   wy = png_ITU_fixed_16(&error, white_y);
+
+   if (error)
+   {
+      png_chunk_report(png_ptr,
+         "mDCV chromaticities outside representable range",
+         PNG_CHUNK_WRITE_ERROR);
+      return;
+   }
+
+   /* Check the light level range: */
+   if (maxDL > 0x7FFFFFFFU || minDL > 0x7FFFFFFFU)
+   {
+      /* The limit is 200kcd/m2; somewhat bright but not inconceivable because
+       * human vision is said to run up to 100Mcd/m2.  The sun is about 2Gcd/m2.
+       *
+       * The reference sRGB monitor is 80cd/m2 and the limit of PQ encoding is
+       * 2kcd/m2.
+       */
+      png_chunk_report(png_ptr, "mDCV display light level exceeds PNG limit",
+            PNG_CHUNK_WRITE_ERROR);
+      return;
+   }
+
+   /* All values are safe, the settings are accepted.
+    *
+    * IMPLEMENTATION NOTE: in practice the values can be checked and assigned
+    * but the result is confusing if a writing app calls png_set_mDCV more than
+    * once, the second time with an invalid value.  This approach is more
+    * obviously correct at the cost of typing and a very slight machine
+    * overhead.
+    */
+   info_ptr->mastering_red_x = rx;
+   info_ptr->mastering_red_y = ry;
+   info_ptr->mastering_green_x = gx;
+   info_ptr->mastering_green_y = gy;
+   info_ptr->mastering_blue_x = bx;
+   info_ptr->mastering_blue_y = by;
+   info_ptr->mastering_white_x = wx;
+   info_ptr->mastering_white_y = wy;
+   info_ptr->mastering_maxDL = maxDL;
+   info_ptr->mastering_minDL = minDL;
+   info_ptr->valid |= PNG_INFO_mDCV;
+}
+
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_mDCV(png_const_structrp png_ptr, png_inforp info_ptr,
+    double white_x, double white_y, double red_x, double red_y, double green_x,
+    double green_y, double blue_x, double blue_y,
+    double maxDL, double minDL)
+{
+   png_set_mDCV_fixed(png_ptr, info_ptr,
+      /* The ITU approach is to scale by 50,000, not 100,000 so just divide
+       * the input values by 2 and use png_fixed:
+       */
+      png_fixed(png_ptr, white_x / 2, "png_set_mDCV(white(x))"),
+      png_fixed(png_ptr, white_y / 2, "png_set_mDCV(white(y))"),
+      png_fixed(png_ptr, red_x / 2, "png_set_mDCV(red(x))"),
+      png_fixed(png_ptr, red_y / 2, "png_set_mDCV(red(y))"),
+      png_fixed(png_ptr, green_x / 2, "png_set_mDCV(green(x))"),
+      png_fixed(png_ptr, green_y / 2, "png_set_mDCV(green(y))"),
+      png_fixed(png_ptr, blue_x / 2, "png_set_mDCV(blue(x))"),
+      png_fixed(png_ptr, blue_y / 2, "png_set_mDCV(blue(y))"),
+      png_fixed_ITU(png_ptr, maxDL, "png_set_mDCV(maxDL)"),
+      png_fixed_ITU(png_ptr, minDL, "png_set_mDCV(minDL)"));
+}
+#  endif /* FLOATING_POINT */
+#endif /* mDCV */
+
 #ifdef PNG_eXIf_SUPPORTED
 void PNGAPI
 png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
@@ -213,8 +397,8 @@ png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
    if (png_ptr == NULL || info_ptr == NULL)
       return;
 
-   png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma);
-   png_colorspace_sync_info(png_ptr, info_ptr);
+   info_ptr->gamma = file_gamma;
+   info_ptr->valid |= PNG_INFO_gAMA;
 }
 
 #  ifdef PNG_FLOATING_POINT_SUPPORTED
@@ -673,8 +857,8 @@ png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent)
    if (png_ptr == NULL || info_ptr == NULL)
       return;
 
-   (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent);
-   png_colorspace_sync_info(png_ptr, info_ptr);
+   info_ptr->rendering_intent = srgb_intent;
+   info_ptr->valid |= PNG_INFO_sRGB;
 }
 
 void PNGAPI
@@ -686,15 +870,20 @@ png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
    if (png_ptr == NULL || info_ptr == NULL)
       return;
 
-   if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace,
-       srgb_intent) != 0)
-   {
-      /* This causes the gAMA and cHRM to be written too */
-      info_ptr->colorspace.flags |=
-         PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
-   }
+   png_set_sRGB(png_ptr, info_ptr, srgb_intent);
+
+#  ifdef PNG_gAMA_SUPPORTED
+      png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE);
+#  endif /* gAMA */
 
-   png_colorspace_sync_info(png_ptr, info_ptr);
+#  ifdef PNG_cHRM_SUPPORTED
+      png_set_cHRM_fixed(png_ptr, info_ptr,
+         /* color      x       y */
+         /* white */ 31270, 32900,
+         /* red   */ 64000, 33000,
+         /* green */ 30000, 60000,
+         /* blue  */ 15000,  6000);
+#  endif /* cHRM */
 }
 #endif /* sRGB */
 
@@ -717,27 +906,6 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
    if (compression_type != PNG_COMPRESSION_TYPE_BASE)
       png_app_error(png_ptr, "Invalid iCCP compression method");
 
-   /* Set the colorspace first because this validates the profile; do not
-    * override previously set app cHRM or gAMA here (because likely as not the
-    * application knows better than libpng what the correct values are.)  Pass
-    * the info_ptr color_type field to png_colorspace_set_ICC because in the
-    * write case it has not yet been stored in png_ptr.
-    */
-   {
-      int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,
-          proflen, profile, info_ptr->color_type);
-
-      png_colorspace_sync_info(png_ptr, info_ptr);
-
-      /* Don't do any of the copying if the profile was bad, or inconsistent. */
-      if (result == 0)
-         return;
-
-      /* But do write the gAMA and cHRM chunks from the profile. */
-      info_ptr->colorspace.flags |=
-         PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
-   }
-
    length = strlen(name)+1;
    new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length));
 
@@ -1423,11 +1591,14 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
       static const png_byte chunks_to_ignore[] = {
          98,  75,  71,  68, '\0',  /* bKGD */
          99,  72,  82,  77, '\0',  /* cHRM */
+         99,  73,  67,  80, '\0',  /* cICP */
+         99,  76,  76,  73, '\0',  /* cLLI */
         101,  88,  73, 102, '\0',  /* eXIf */
         103,  65,  77,  65, '\0',  /* gAMA */
         104,  73,  83,  84, '\0',  /* hIST */
         105,  67,  67,  80, '\0',  /* iCCP */
         105,  84,  88, 116, '\0',  /* iTXt */
+        109,  68,  67,  86, '\0',  /* mDCV */
         111,  70,  70, 115, '\0',  /* oFFs */
         112,  67,  65,  76, '\0',  /* pCAL */
         112,  72,  89, 115, '\0',  /* pHYs */
@@ -1689,8 +1860,24 @@ png_set_chunk_malloc_max(png_structrp png_ptr,
 {
    png_debug(1, "in png_set_chunk_malloc_max");
 
+   /* pngstruct::user_chunk_malloc_max is initialized to a non-zero value in
+    * png.c.  This API supports '0' for unlimited, make sure the correct
+    * (unlimited) value is set here to avoid a need to check for 0 everywhere
+    * the parameter is used.
+    */
    if (png_ptr != NULL)
-      png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
+   {
+      if (user_chunk_malloc_max == 0U) /* unlimited */
+      {
+#        ifdef PNG_MAX_MALLOC_64K
+            png_ptr->user_chunk_malloc_max = 65536U;
+#        else
+            png_ptr->user_chunk_malloc_max = PNG_SIZE_MAX;
+#        endif
+      }
+      else
+         png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
+   }
 }
 #endif /* ?SET_USER_LIMITS */
 
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngstruct.h b/src/java.desktop/share/native/libsplashscreen/libpng/pngstruct.h
index f153bdec6020c..d6c446564d122 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngstruct.h
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngstruct.h
@@ -98,13 +98,7 @@ typedef struct png_compression_buffer
 
 /* Colorspace support; structures used in png_struct, png_info and in internal
  * functions to hold and communicate information about the color space.
- *
- * PNG_COLORSPACE_SUPPORTED is only required if the application will perform
- * colorspace corrections, otherwise all the colorspace information can be
- * skipped and the size of libpng can be reduced (significantly) by compiling
- * out the colorspace support.
  */
-#ifdef PNG_COLORSPACE_SUPPORTED
 /* The chromaticities of the red, green and blue colorants and the chromaticity
  * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)).
  */
@@ -125,48 +119,36 @@ typedef struct png_XYZ
    png_fixed_point green_X, green_Y, green_Z;
    png_fixed_point blue_X, blue_Y, blue_Z;
 } png_XYZ;
-#endif /* COLORSPACE */
 
-#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
-/* A colorspace is all the above plus, potentially, profile information;
- * however at present libpng does not use the profile internally so it is only
- * stored in the png_info struct (if iCCP is supported.)  The rendering intent
- * is retained here and is checked.
- *
- * The file gamma encoding information is also stored here and gamma correction
- * is done by libpng, whereas color correction must currently be done by the
- * application.
+/* Chunk index values as an enum, PNG_INDEX_unknown is also a count of the
+ * number of chunks.
  */
-typedef struct png_colorspace
+#define PNG_CHUNK(cHNK, i) PNG_INDEX_ ## cHNK = (i),
+typedef enum
 {
-#ifdef PNG_GAMMA_SUPPORTED
-   png_fixed_point gamma;        /* File gamma */
-#endif
+   PNG_KNOWN_CHUNKS
+   PNG_INDEX_unknown
+} png_index;
+#undef PNG_CHUNK
 
-#ifdef PNG_COLORSPACE_SUPPORTED
-   png_xy      end_points_xy;    /* End points as chromaticities */
-   png_XYZ     end_points_XYZ;   /* End points as CIE XYZ colorant values */
-   png_uint_16 rendering_intent; /* Rendering intent of a profile */
-#endif
-
-   /* Flags are always defined to simplify the code. */
-   png_uint_16 flags;            /* As defined below */
-} png_colorspace, * PNG_RESTRICT png_colorspacerp;
+/* Chunk flag values.  These are (png_uint_32 values) with exactly one bit set
+ * and can be combined into a flag set with bitwise 'or'.
+ *
+ * TODO: C23: convert these macros to C23 inlines (which are static).
+ */
+#define png_chunk_flag_from_index(i) (0x80000000U >> (31 - (i)))
+   /* The flag coresponding to the given png_index enum value.  This is defined
+    * for png_unknown as well (until it reaches the value 32) but this should
+    * not be relied on.
+    */
 
-typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp;
+#define png_file_has_chunk(png_ptr, i)\
+   (((png_ptr)->chunks & png_chunk_flag_from_index(i)) != 0)
+   /* The chunk has been recorded in png_struct */
 
-/* General flags for the 'flags' field */
-#define PNG_COLORSPACE_HAVE_GAMMA           0x0001
-#define PNG_COLORSPACE_HAVE_ENDPOINTS       0x0002
-#define PNG_COLORSPACE_HAVE_INTENT          0x0004
-#define PNG_COLORSPACE_FROM_gAMA            0x0008
-#define PNG_COLORSPACE_FROM_cHRM            0x0010
-#define PNG_COLORSPACE_FROM_sRGB            0x0020
-#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040
-#define PNG_COLORSPACE_MATCHES_sRGB         0x0080 /* exact match on profile */
-#define PNG_COLORSPACE_INVALID              0x8000
-#define PNG_COLORSPACE_CANCEL(flags)        (0xffff ^ (flags))
-#endif /* COLORSPACE || GAMMA */
+#define png_file_add_chunk(pnt_ptr, i)\
+   ((void)((png_ptr)->chunks |= png_chunk_flag_from_index(i)))
+   /* Record the chunk in the png_struct */
 
 struct png_struct_def
 {
@@ -238,6 +220,11 @@ struct png_struct_def
    int zlib_set_strategy;
 #endif
 
+   png_uint_32 chunks; /* PNG_CF_ for every chunk read or (NYI) written */
+#  define png_has_chunk(png_ptr, cHNK)\
+      png_file_has_chunk(png_ptr, PNG_INDEX_ ## cHNK)
+      /* Convenience accessor - use this to check for a known chunk by name */
+
    png_uint_32 width;         /* width of image in pixels */
    png_uint_32 height;        /* height of image in pixels */
    png_uint_32 num_rows;      /* number of rows in current pass */
@@ -314,9 +301,16 @@ struct png_struct_def
    png_uint_32 flush_rows;    /* number of rows written since last flush */
 #endif
 
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+   png_xy          chromaticities; /* From mDVC, cICP, [iCCP], sRGB or cHRM */
+#endif
+
 #ifdef PNG_READ_GAMMA_SUPPORTED
    int gamma_shift;      /* number of "insignificant" bits in 16-bit gamma */
-   png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */
+   png_fixed_point screen_gamma; /* screen gamma value (display exponent) */
+   png_fixed_point file_gamma;   /* file gamma value (encoding exponent) */
+   png_fixed_point chunk_gamma;  /* from cICP, iCCP, sRGB or gAMA */
+   png_fixed_point default_gamma;/* from png_set_alpha_mode */
 
    png_bytep gamma_table;     /* gamma table for 8-bit depth files */
    png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
@@ -328,7 +322,7 @@ struct png_struct_def
    png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
    png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
 #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
-#endif
+#endif /* READ_GAMMA */
 
 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
    png_color_8 sig_bit;       /* significant bits in each available channel */
@@ -378,8 +372,8 @@ struct png_struct_def
 /* To do: remove this from libpng-1.7 */
 #ifdef PNG_TIME_RFC1123_SUPPORTED
    char time_buffer[29]; /* String to hold RFC 1123 time text */
-#endif
-#endif
+#endif /* TIME_RFC1123 */
+#endif /* LIBPNG_VER < 10700 */
 
 /* New members added in libpng-1.0.6 */
 
@@ -389,8 +383,8 @@ struct png_struct_def
    png_voidp user_chunk_ptr;
 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
    png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
-#endif
-#endif
+#endif /* READ_USER_CHUNKS */
+#endif /* USER_CHUNKS */
 
 #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
    int          unknown_default; /* As PNG_HANDLE_* */
@@ -497,11 +491,5 @@ struct png_struct_def
 /* New member added in libpng-1.5.7 */
    void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info,
       png_bytep row, png_const_bytep prev_row);
-
-#ifdef PNG_READ_SUPPORTED
-#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
-   png_colorspace   colorspace;
-#endif
-#endif
 };
 #endif /* PNGSTRUCT_H */

From c98e598bc4b369abc60a876f7cfb7c78f5521cc1 Mon Sep 17 00:00:00 2001
From: Dmitry Chuyko 
Date: Wed, 2 Apr 2025 14:50:10 +0000
Subject: [PATCH 117/846] 8350412: [21u] AArch64: Ambiguous frame layout leads
 to incorrect traces in JFR

Reviewed-by: phh
---
 src/hotspot/cpu/aarch64/aarch64.ad | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad
index bf03fbe0303a4..8b758653e39e2 100644
--- a/src/hotspot/cpu/aarch64/aarch64.ad
+++ b/src/hotspot/cpu/aarch64/aarch64.ad
@@ -1761,8 +1761,8 @@ int MachCallRuntimeNode::ret_addr_offset() {
   // for real runtime callouts it will be six instructions
   // see aarch64_enc_java_to_runtime
   //   adr(rscratch2, retaddr)
+  //   str(rscratch2, Address(rthread, JavaThread::last_Java_pc_offset()));
   //   lea(rscratch1, RuntimeAddress(addr)
-  //   stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize)))
   //   blr(rscratch1)
   CodeBlob *cb = CodeCache::find_blob(_entry_point);
   if (cb) {
@@ -3755,13 +3755,12 @@ encode %{
       }
     } else {
       Label retaddr;
+      // Make the anchor frame walkable
       __ adr(rscratch2, retaddr);
+      __ str(rscratch2, Address(rthread, JavaThread::last_Java_pc_offset()));
       __ lea(rscratch1, RuntimeAddress(entry));
-      // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc()
-      __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize)));
       __ blr(rscratch1);
       __ bind(retaddr);
-      __ add(sp, sp, 2 * wordSize);
     }
     if (Compile::current()->max_vector_size() >= 16) {
       __ reinitialize_ptrue();

From bb103d7d0914f90e85eb5f87831ffef1de536072 Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Thu, 3 Apr 2025 11:39:29 +0000
Subject: [PATCH 118/846] 8298730: Refactor subsystem_file_line_contents and
 add docs and tests

Reviewed-by: phh
Backport-of: 500c3c17379fe0a62d42ba31bdcdb584b1823f60
---
 .../os/linux/cgroupSubsystem_linux.hpp        | 110 +++++-----
 .../os/linux/cgroupV1Subsystem_linux.cpp      |  13 +-
 .../os/linux/cgroupV2Subsystem_linux.cpp      |   2 +-
 src/hotspot/share/utilities/ostream.cpp       |   2 +
 src/hotspot/share/utilities/ostream.hpp       |  13 +-
 .../os/linux/test_cgroupSubsystem_linux.cpp   | 195 ++++++++++++++++++
 .../gtest/runtime/test_os_linux_cgroups.cpp   |   4 +-
 7 files changed, 278 insertions(+), 61 deletions(-)
 create mode 100644 test/hotspot/gtest/os/linux/test_cgroupSubsystem_linux.cpp

diff --git a/src/hotspot/os/linux/cgroupSubsystem_linux.hpp b/src/hotspot/os/linux/cgroupSubsystem_linux.hpp
index 24634fe861f9a..721e49bf1fcc8 100644
--- a/src/hotspot/os/linux/cgroupSubsystem_linux.hpp
+++ b/src/hotspot/os/linux/cgroupSubsystem_linux.hpp
@@ -78,71 +78,83 @@ class CgroupController: public CHeapObj {
 
 PRAGMA_DIAG_PUSH
 PRAGMA_FORMAT_NONLITERAL_IGNORED
+// Parses a subsystem's file, looking for a matching line.
+// If key is null, then the first line will be matched with scan_fmt.
+// If key isn't null, then each line will be matched, looking for something that matches "$key $scan_fmt".
+// The matching value will be assigned to returnval.
+// scan_fmt uses scanf() syntax.
+// Return value: 0 on match, OSCONTAINER_ERROR on error.
 template  int subsystem_file_line_contents(CgroupController* c,
                                               const char *filename,
-                                              const char *matchline,
+                                              const char *key,
                                               const char *scan_fmt,
                                               T returnval) {
-  FILE *fp = NULL;
-  char *p;
-  char file[MAXPATHLEN+1];
-  char buf[MAXPATHLEN+1];
-  char discard[MAXPATHLEN+1];
-  bool found_match = false;
+  if (c == nullptr) {
+    log_debug(os, container)("subsystem_file_line_contents: CgroupController* is nullptr");
+    return OSCONTAINER_ERROR;
+  }
+  if (c->subsystem_path() == nullptr) {
+    log_debug(os, container)("subsystem_file_line_contents: subsystem path is nullptr");
+    return OSCONTAINER_ERROR;
+  }
+
+  stringStream file_path;
+  file_path.print_raw(c->subsystem_path());
+  file_path.print_raw(filename);
 
-  if (c == NULL) {
-    log_debug(os, container)("subsystem_file_line_contents: CgroupController* is NULL");
+  if (file_path.size() > (MAXPATHLEN-1)) {
+    log_debug(os, container)("File path too long %s, %s", file_path.base(), filename);
     return OSCONTAINER_ERROR;
   }
-  if (c->subsystem_path() == NULL) {
-    log_debug(os, container)("subsystem_file_line_contents: subsystem path is NULL");
+  const char* absolute_path = file_path.freeze();
+  log_trace(os, container)("Path to %s is %s", filename, absolute_path);
+
+  FILE* fp = fopen(absolute_path, "r");
+  if (fp == nullptr) {
+    log_debug(os, container)("Open of file %s failed, %s", absolute_path, os::strerror(errno));
     return OSCONTAINER_ERROR;
   }
 
-  strncpy(file, c->subsystem_path(), MAXPATHLEN);
-  file[MAXPATHLEN-1] = '\0';
-  int filelen = strlen(file);
-  if ((filelen + strlen(filename)) > (MAXPATHLEN-1)) {
-    log_debug(os, container)("File path too long %s, %s", file, filename);
+  const int buf_len = MAXPATHLEN+1;
+  char buf[buf_len];
+  char* line = fgets(buf, buf_len, fp);
+  if (line == nullptr) {
+    log_debug(os, container)("Empty file %s", absolute_path);
+    fclose(fp);
     return OSCONTAINER_ERROR;
   }
-  strncat(file, filename, MAXPATHLEN-filelen);
-  log_trace(os, container)("Path to %s is %s", filename, file);
-  fp = fopen(file, "r");
-  if (fp != NULL) {
-    int err = 0;
-    while ((p = fgets(buf, MAXPATHLEN, fp)) != NULL) {
-      found_match = false;
-      if (matchline == NULL) {
-        // single-line file case
-        int matched = sscanf(p, scan_fmt, returnval);
-        found_match = (matched == 1);
-      } else {
-        // multi-line file case
-        if (strstr(p, matchline) != NULL) {
-          // discard matchline string prefix
-          int matched = sscanf(p, scan_fmt, discard, returnval);
-          found_match = (matched == 2);
-        } else {
-          continue; // substring not found
+
+  bool found_match = false;
+  if (key == nullptr) {
+    // File consists of a single line according to caller, with only a value
+    int matched = sscanf(line, scan_fmt, returnval);
+    found_match = matched == 1;
+  } else {
+    // File consists of multiple lines in a "key value"
+    // fashion, we have to find the key.
+    const int key_len = strlen(key);
+    for (; line != nullptr; line = fgets(buf, buf_len, fp)) {
+      char* key_substr = strstr(line, key);
+      char after_key = line[key_len];
+      if (key_substr == line
+          && isspace(after_key) != 0
+          && after_key != '\n') {
+        // Skip key, skip space
+        const char* value_substr = line + key_len + 1;
+        int matched = sscanf(value_substr, scan_fmt, returnval);
+        found_match = matched == 1;
+        if (found_match) {
+          break;
         }
       }
-      if (found_match) {
-        fclose(fp);
-        return 0;
-      } else {
-        err = 1;
-        log_debug(os, container)("Type %s not found in file %s", scan_fmt, file);
-      }
     }
-    if (err == 0) {
-      log_debug(os, container)("Empty file %s", file);
-    }
-  } else {
-    log_debug(os, container)("Open of file %s failed, %s", file, os::strerror(errno));
   }
-  if (fp != NULL)
-    fclose(fp);
+  fclose(fp);
+  if (found_match) {
+    return 0;
+  }
+  log_debug(os, container)("Type %s (key == %s) not found in file %s", scan_fmt,
+                           (key == nullptr ? "null" : key), absolute_path);
   return OSCONTAINER_ERROR;
 }
 PRAGMA_DIAG_POP
diff --git a/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp
index bc7d3ada7ac1a..8008994fe5fc5 100644
--- a/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp
+++ b/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp
@@ -96,10 +96,8 @@ jlong CgroupV1Subsystem::read_memory_limit_in_bytes() {
     log_trace(os, container)("Non-Hierarchical Memory Limit is: Unlimited");
     CgroupV1MemoryController* mem_controller = reinterpret_cast(_memory->controller());
     if (mem_controller->is_hierarchical()) {
-      const char* matchline = "hierarchical_memory_limit";
-      const char* format = "%s " JULONG_FORMAT;
-      GET_CONTAINER_INFO_LINE(julong, _memory->controller(), "/memory.stat", matchline,
-                             "Hierarchical Memory Limit is: " JULONG_FORMAT, format, hier_memlimit)
+      GET_CONTAINER_INFO_LINE(julong, _memory->controller(), "/memory.stat", "hierarchical_memory_limit",
+                             "Hierarchical Memory Limit is: " JULONG_FORMAT, JULONG_FORMAT, hier_memlimit)
       if (hier_memlimit >= os::Linux::physical_memory()) {
         log_trace(os, container)("Hierarchical Memory Limit is: Unlimited");
       } else {
@@ -123,9 +121,8 @@ jlong CgroupV1Subsystem::memory_and_swap_limit_in_bytes() {
     CgroupV1MemoryController* mem_controller = reinterpret_cast(_memory->controller());
     if (mem_controller->is_hierarchical()) {
       const char* matchline = "hierarchical_memsw_limit";
-      const char* format = "%s " JULONG_FORMAT;
       GET_CONTAINER_INFO_LINE(julong, _memory->controller(), "/memory.stat", matchline,
-                             "Hierarchical Memory and Swap Limit is : " JULONG_FORMAT, format, hier_memswlimit)
+                             "Hierarchical Memory and Swap Limit is : " JULONG_FORMAT, JULONG_FORMAT, hier_memswlimit)
       if (hier_memswlimit >= host_total_memsw) {
         log_trace(os, container)("Hierarchical Memory and Swap Limit is: Unlimited");
       } else {
@@ -133,7 +130,7 @@ jlong CgroupV1Subsystem::memory_and_swap_limit_in_bytes() {
         if (swappiness == 0) {
             const char* matchmemline = "hierarchical_memory_limit";
             GET_CONTAINER_INFO_LINE(julong, _memory->controller(), "/memory.stat", matchmemline,
-                             "Hierarchical Memory Limit is : " JULONG_FORMAT, format, hier_memlimit)
+                             "Hierarchical Memory Limit is : " JULONG_FORMAT, JULONG_FORMAT, hier_memlimit)
             log_trace(os, container)("Memory and Swap Limit has been reset to " JULONG_FORMAT " because swappiness is 0", hier_memlimit);
             return (jlong)hier_memlimit;
         }
@@ -286,7 +283,7 @@ int CgroupV1Subsystem::cpu_shares() {
 
 char* CgroupV1Subsystem::pids_max_val() {
   GET_CONTAINER_INFO_CPTR(cptr, _pids, "/pids.max",
-                     "Maximum number of tasks is: %s", "%s %*d", pidsmax, 1024);
+                     "Maximum number of tasks is: %s", "%1023s", pidsmax, 1024);
   return os::strdup(pidsmax);
 }
 
diff --git a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp
index 705a3a410c134..d3f47d147efd4 100644
--- a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp
+++ b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp
@@ -224,7 +224,7 @@ char* CgroupV2Controller::construct_path(char* mount_path, char *cgroup_path) {
 
 char* CgroupV2Subsystem::pids_max_val() {
   GET_CONTAINER_INFO_CPTR(cptr, _unified, "/pids.max",
-                     "Maximum number of tasks is: %s", "%1023s %*d", pidsmax, 1024);
+                     "Maximum number of tasks is: %s", "%1023s", pidsmax, 1024);
   return os::strdup(pidsmax);
 }
 
diff --git a/src/hotspot/share/utilities/ostream.cpp b/src/hotspot/share/utilities/ostream.cpp
index 4d7af94d0c369..4156bdc88fdc1 100644
--- a/src/hotspot/share/utilities/ostream.cpp
+++ b/src/hotspot/share/utilities/ostream.cpp
@@ -354,6 +354,7 @@ void stringStream::grow(size_t new_capacity) {
 }
 
 void stringStream::write(const char* s, size_t len) {
+  assert(_is_frozen == false, "Modification forbidden");
   assert(_capacity >= _written + 1, "Sanity");
   if (len == 0) {
     return;
@@ -393,6 +394,7 @@ void stringStream::zero_terminate() {
 }
 
 void stringStream::reset() {
+  assert(_is_frozen == false, "Modification forbidden");
   _written = 0; _precount = 0; _position = 0;
   _newlines = 0;
   zero_terminate();
diff --git a/src/hotspot/share/utilities/ostream.hpp b/src/hotspot/share/utilities/ostream.hpp
index d37b1bc3e8408..7fcfb8fe2f56f 100644
--- a/src/hotspot/share/utilities/ostream.hpp
+++ b/src/hotspot/share/utilities/ostream.hpp
@@ -28,6 +28,7 @@
 #include "memory/allocation.hpp"
 #include "runtime/timer.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
 
 DEBUG_ONLY(class ResourceMark;)
 
@@ -191,6 +192,7 @@ class ttyUnlocker: StackObj {
 // for writing to strings; buffer will expand automatically.
 // Buffer will always be zero-terminated.
 class stringStream : public outputStream {
+  DEBUG_ONLY(bool _is_frozen = false);
   char*  _buffer;
   size_t _written;  // Number of characters written, excluding termin. zero
   size_t _capacity;
@@ -215,9 +217,18 @@ class stringStream : public outputStream {
   // Return number of characters written into buffer, excluding terminating zero and
   // subject to truncation in static buffer mode.
   size_t      size() const { return _written; }
+  // Returns internal buffer containing the accumulated string.
+  // Returned buffer is only guaranteed to be valid as long as stream is not modified
   const char* base() const { return _buffer; }
+  // Freezes stringStream (no further modifications possible) and returns pointer to it.
+  // No-op if stream is frozen already.
+  // Returns the internal buffer containing the accumulated string.
+  const char* freeze() NOT_DEBUG(const) {
+    DEBUG_ONLY(_is_frozen = true);
+    return _buffer;
+  };
   void  reset();
-  // copy to a resource, or C-heap, array as requested
+  // Copy to a resource, or C-heap, array as requested
   char* as_string(bool c_heap = false) const;
 };
 
diff --git a/test/hotspot/gtest/os/linux/test_cgroupSubsystem_linux.cpp b/test/hotspot/gtest/os/linux/test_cgroupSubsystem_linux.cpp
new file mode 100644
index 0000000000000..cfac19185a39e
--- /dev/null
+++ b/test/hotspot/gtest/os/linux/test_cgroupSubsystem_linux.cpp
@@ -0,0 +1,195 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+
+#ifdef LINUX
+
+#include "runtime/os.hpp"
+#include "cgroupSubsystem_linux.hpp"
+#include "unittest.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+#include 
+
+
+// Utilities
+bool file_exists(const char* filename) {
+  struct stat st;
+  return os::stat(filename, &st) == 0;
+}
+
+char* temp_file(const char* prefix) {
+  const testing::TestInfo* test_info = ::testing::UnitTest::GetInstance()->current_test_info();
+  stringStream path;
+  path.print_raw(os::get_temp_directory());
+  path.print_raw(os::file_separator());
+  path.print("%s-test-jdk.pid%d.%s.%s", prefix, os::current_process_id(),
+             test_info->test_case_name(), test_info->name());
+  return path.as_string(true);
+}
+
+void delete_file(const char* filename) {
+  if (!file_exists(filename)) {
+    return;
+  }
+  int ret = remove(filename);
+  EXPECT_TRUE(ret == 0 || errno == ENOENT) << "failed to remove file '" << filename << "': "
+      << os::strerror(errno) << " (" << errno << ")";
+}
+
+class TestController : public CgroupController {
+public:
+  char* subsystem_path() override {
+    // The real subsystem is in /tmp/, generaed by temp_file()
+    return (char*)"/";
+  };
+};
+
+void fill_file(const char* path, const char* content) {
+  delete_file(path);
+  FILE* fp = os::fopen(path, "w");
+  if (fp == nullptr) {
+    return;
+  }
+  if (content != nullptr) {
+    fprintf(fp, "%s", content);
+  }
+  fclose(fp);
+}
+
+TEST(cgroupTest, SubSystemFileLineContentsMultipleLinesErrorCases) {
+  TestController my_controller{};
+  const char* test_file = temp_file("cgroups");
+  int x = 0;
+  char s[1024];
+  int err = 0;
+
+  s[0] = '\0';
+  fill_file(test_file, "foo ");
+  err = subsystem_file_line_contents(&my_controller, test_file, "foo", "%s", &s);
+  EXPECT_NE(err, 0) << "Value must not be missing in key/value case";
+
+  s[0] = '\0';
+  fill_file(test_file, "faulty_start foo bar");
+  err = subsystem_file_line_contents(&my_controller, test_file, "foo", "%s", &s);
+  EXPECT_NE(err, 0) << "Key must be at start";
+
+  s[0] = '\0';
+  fill_file(test_file, "foof bar");
+  err = subsystem_file_line_contents(&my_controller, test_file, "foo", "%s", &s);
+  EXPECT_NE(err, 0) << "Key must be exact match";
+}
+
+TEST(cgroupTest, SubSystemFileLineContentsMultipleLinesSuccessCases) {
+  TestController my_controller{};
+  const char* test_file = temp_file("cgroups");
+  int x = 0;
+  char s[1024];
+  int err = 0;
+
+  s[0] = '\0';
+  fill_file(test_file, "foo bar");
+  err = subsystem_file_line_contents(&my_controller, test_file, "foo", "%s", &s);
+  EXPECT_EQ(err, 0);
+  EXPECT_STREQ(s, "bar") << "Incorrect!";
+
+  s[0] = '\0';
+  fill_file(test_file, "foo\tbar");
+  err = subsystem_file_line_contents(&my_controller, test_file, "foo", "%s", &s);
+  EXPECT_EQ(err, 0);
+  EXPECT_STREQ(s, "bar") << "Incorrect!";
+
+  s[0] = '\0';
+  fill_file(test_file, "foof bar\nfoo car");
+  err = subsystem_file_line_contents(&my_controller, test_file, "foo", "%s", &s);
+  EXPECT_EQ(err, 0);
+  EXPECT_STREQ(s, "car");
+
+  s[0] = '\0';
+  fill_file(test_file, "foo\ttest\nfoot car");
+  err = subsystem_file_line_contents(&my_controller, test_file, "foo", "%s", &s);
+  EXPECT_EQ(err, 0);
+  EXPECT_STREQ(s, "test");
+
+  s[0] = '\0';
+  fill_file(test_file, "foo 1\nfoo car");
+  err = subsystem_file_line_contents(&my_controller, test_file, "foo", "%s", &s);
+  EXPECT_EQ(err, 0);
+  EXPECT_STREQ(s, "1");
+
+  s[0] = '\0';
+  fill_file(test_file, "max 10000");
+  err = subsystem_file_line_contents(&my_controller, test_file, nullptr, "%s %*d", &s);
+  EXPECT_EQ(err, 0);
+  EXPECT_STREQ(s, "max");
+
+  x = -3;
+  fill_file(test_file, "max 10001");
+  err = subsystem_file_line_contents(&my_controller, test_file, nullptr, "%*s %d", &x);
+  EXPECT_EQ(err, 0);
+  EXPECT_EQ(x, 10001);
+}
+
+TEST(cgroupTest, SubSystemFileLineContentsSingleLine) {
+  TestController my_controller{};
+  const char* test_file = temp_file("cgroups");
+  int x = 0;
+  char s[1024];
+  int err = 0;
+
+  fill_file(test_file, "foo");
+  err = subsystem_file_line_contents(&my_controller, test_file, nullptr, "%s", &s);
+  EXPECT_EQ(err, 0);
+  EXPECT_STREQ(s, "foo");
+
+  fill_file(test_file, "1337");
+  err = subsystem_file_line_contents(&my_controller, test_file, nullptr, "%d", &x);
+  EXPECT_EQ(err, 0);
+  EXPECT_EQ(x, 1337) << "Wrong value for x";
+
+  s[0] = '\0';
+  fill_file(test_file, "1337");
+  err = subsystem_file_line_contents(&my_controller, test_file, nullptr, "%s", &s);
+  EXPECT_EQ(err, 0);
+  EXPECT_STREQ(s, "1337");
+
+  x = -1;
+  fill_file(test_file, nullptr);
+  err = subsystem_file_line_contents(&my_controller, test_file, nullptr, "%d", &x);
+  EXPECT_NE(err, 0) << "Empty file should've failed";
+  EXPECT_EQ(x, -1) << "x was altered";
+
+  jlong y;
+  fill_file(test_file, "1337");
+  err = subsystem_file_line_contents(&my_controller, test_file, nullptr, JLONG_FORMAT, &y);
+  EXPECT_EQ(err, 0);
+  EXPECT_EQ(y, 1337) << "Wrong value for y";
+  julong z;
+  fill_file(test_file, "1337");
+  err = subsystem_file_line_contents(&my_controller, test_file, nullptr, JULONG_FORMAT, &z);
+  EXPECT_EQ(err, 0);
+  EXPECT_EQ(z, (julong)1337) << "Wrong value for z";
+}
+
+#endif // LINUX
diff --git a/test/hotspot/gtest/runtime/test_os_linux_cgroups.cpp b/test/hotspot/gtest/runtime/test_os_linux_cgroups.cpp
index 9130c0c701d9e..917dd8bc40cd9 100644
--- a/test/hotspot/gtest/runtime/test_os_linux_cgroups.cpp
+++ b/test/hotspot/gtest/runtime/test_os_linux_cgroups.cpp
@@ -36,7 +36,7 @@ typedef struct {
   const char* expected_path;
 } TestCase;
 
-TEST(os_linux_cgroup, set_cgroupv1_subsystem_path) {
+TEST(cgroupTest, set_cgroupv1_subsystem_path) {
   TestCase host = {
     "/sys/fs/cgroup/memory",                                             // mount_path
     "/",                                                                 // root_path
@@ -60,7 +60,7 @@ TEST(os_linux_cgroup, set_cgroupv1_subsystem_path) {
   }
 }
 
-TEST(os_linux_cgroup, set_cgroupv2_subsystem_path) {
+TEST(cgroupTest, set_cgroupv2_subsystem_path) {
   TestCase at_mount_root = {
     "/sys/fs/cgroup",       // mount_path
     NULL,                   // root_path, ignored

From 729b0c7aa59d7b2e53cdaa8b4a1631962951f8d8 Mon Sep 17 00:00:00 2001
From: Andrei Pangin 
Date: Fri, 4 Apr 2025 15:46:06 +0000
Subject: [PATCH 119/846] 8352649: [17u] guarantee(is_result_safe ||
 is_in_asgct()) failed inside AsyncGetCallTrace

Reviewed-by: jbachorik
---
 src/hotspot/share/code/codeCache.cpp | 7 +------
 src/hotspot/share/runtime/thread.cpp | 1 -
 src/hotspot/share/runtime/thread.hpp | 5 -----
 3 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp
index f4753fd6cfffa..0c53a0a2ec001 100644
--- a/src/hotspot/share/code/codeCache.cpp
+++ b/src/hotspot/share/code/codeCache.cpp
@@ -653,11 +653,6 @@ bool CodeCache::contains(nmethod *nm) {
   return contains((void *)nm);
 }
 
-static bool is_in_asgct() {
-  Thread* current_thread = Thread::current_or_null_safe();
-  return current_thread != NULL && current_thread->is_Java_thread() && current_thread->as_Java_thread()->in_asgct();
-}
-
 // This method is safe to call without holding the CodeCache_lock, as long as a dead CodeBlob is not
 // looked up (i.e., one that has been marked for deletion). It only depends on the _segmap to contain
 // valid indices, which it will always do, as long as the CodeBlob is not in the process of being recycled.
@@ -666,7 +661,7 @@ CodeBlob* CodeCache::find_blob(void* start) {
   // We could potentially look up non_entrant methods
   bool is_zombie = result != NULL && result->is_zombie();
   bool is_result_safe = !is_zombie || result->is_locked_by_vm() || VMError::is_error_reported();
-  guarantee(is_result_safe || is_in_asgct(), "unsafe access to zombie method");
+  guarantee(is_result_safe || Thread::current_in_asgct(), "unsafe access to zombie method");
   // When in ASGCT the previous gurantee will pass for a zombie method but we still don't want that code blob returned in order
   // to minimize the chance of accessing dead memory
   return is_result_safe ? result : NULL;
diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp
index 3905336d40f57..8e89abcd3440c 100644
--- a/src/hotspot/share/runtime/thread.cpp
+++ b/src/hotspot/share/runtime/thread.cpp
@@ -1008,7 +1008,6 @@ void JavaThread::check_for_valid_safepoint_state() {
 JavaThread::JavaThread() :
   // Initialize fields
 
-  _in_asgct(false),
   _on_thread_list(false),
   DEBUG_ONLY(_java_call_counter(0) COMMA)
   _entry_point(nullptr),
diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp
index 9c949cb3b4157..65c634dd11407 100644
--- a/src/hotspot/share/runtime/thread.hpp
+++ b/src/hotspot/share/runtime/thread.hpp
@@ -715,7 +715,6 @@ class JavaThread: public Thread {
   friend class ThreadsSMRSupport; // to access _threadObj for exiting_threads_oops_do
   friend class HandshakeState;
  private:
-  bool           _in_asgct;                      // Is set when this JavaThread is handling ASGCT call
   bool           _on_thread_list;                // Is set when this JavaThread is added to the Threads list
   OopHandle      _threadObj;                     // The Java level thread object
 
@@ -1640,10 +1639,6 @@ class JavaThread: public Thread {
   // Helper function to do vm_exit_on_initialization for osthread
   // resource allocation failure.
   static void vm_exit_on_osthread_failure(JavaThread* thread);
-
-  // AsyncGetCallTrace support
-  inline bool in_asgct(void) {return _in_asgct;}
-  inline void set_in_asgct(bool value) {_in_asgct = value;}
 };
 
 // Inline implementation of JavaThread::current

From 62c6b145614c1b6302ec8db153a7aa6dec1884bc Mon Sep 17 00:00:00 2001
From: Yuri Nesterenko 
Date: Thu, 2 Jan 2025 19:03:53 +0000
Subject: [PATCH 120/846] 8337494: Clarify JarInputStream behavior

Reviewed-by: mbalao
Backport-of: 353f6e90bec7248016b2c733bae52ed6ca06fc20
---
 .../share/classes/java/util/jar/JarFile.java         |  3 ++-
 .../share/classes/java/util/jar/JarInputStream.java  | 12 +++++++++++-
 .../share/classes/java/util/jar/JarVerifier.java     |  5 ++++-
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/src/java.base/share/classes/java/util/jar/JarFile.java b/src/java.base/share/classes/java/util/jar/JarFile.java
index 70cf99504e44a..ce4e01c7c372e 100644
--- a/src/java.base/share/classes/java/util/jar/JarFile.java
+++ b/src/java.base/share/classes/java/util/jar/JarFile.java
@@ -422,7 +422,8 @@ private Manifest getManifestFromReference() throws IOException {
                             jv = new JarVerifier(manEntry.getName(), b);
                         } else {
                             if (JarVerifier.debug != null) {
-                                JarVerifier.debug.println("Multiple MANIFEST.MF found. Treat JAR file as unsigned");
+                                JarVerifier.debug.println(
+                                        JarVerifier.MULTIPLE_MANIFEST_WARNING);
                             }
                         }
                     }
diff --git a/src/java.base/share/classes/java/util/jar/JarInputStream.java b/src/java.base/share/classes/java/util/jar/JarInputStream.java
index eb51942173230..5f90c1ab353a2 100644
--- a/src/java.base/share/classes/java/util/jar/JarInputStream.java
+++ b/src/java.base/share/classes/java/util/jar/JarInputStream.java
@@ -97,7 +97,17 @@ private JarEntry checkManifest(JarEntry e)
                 jv = new JarVerifier(e.getName(), bytes);
                 mev = new ManifestEntryVerifier(man, jv.manifestName);
             }
-            return (JarEntry)super.getNextEntry();
+            JarEntry nextEntry = (JarEntry)super.getNextEntry();
+            if (nextEntry != null &&
+                    JarFile.MANIFEST_NAME.equalsIgnoreCase(nextEntry.getName())) {
+                if (JarVerifier.debug != null) {
+                    JarVerifier.debug.println(JarVerifier.MULTIPLE_MANIFEST_WARNING);
+                }
+
+                jv = null;
+                mev = null;
+            }
+            return nextEntry;
         }
         return e;
     }
diff --git a/src/java.base/share/classes/java/util/jar/JarVerifier.java b/src/java.base/share/classes/java/util/jar/JarVerifier.java
index c9ab1ac06bfea..9185dc481fef3 100644
--- a/src/java.base/share/classes/java/util/jar/JarVerifier.java
+++ b/src/java.base/share/classes/java/util/jar/JarVerifier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,9 @@
  */
 class JarVerifier {
 
+    public static final String MULTIPLE_MANIFEST_WARNING =
+            "WARNING: Multiple MANIFEST.MF found. Treat JAR file as unsigned.";
+
     /* Are we debugging ? */
     static final Debug debug = Debug.getInstance("jar");
 

From 73aa304234f2ec17abbb640b7f2d0503cf1bfc91 Mon Sep 17 00:00:00 2001
From: Martin Balao 
Date: Mon, 17 Mar 2025 17:54:00 +0000
Subject: [PATCH 121/846] 8337692: Better TLS connection support

Reviewed-by: abakhtin
Backport-of: f06ecf8072b39ffb9eedfc629f181bd805115e0e
---
 .../com/sun/crypto/provider/RSACipher.java    |  62 +++++++---
 .../classes/sun/security/rsa/RSAPadding.java  | 109 +++++++++++++-----
 .../classes/sun/security/util/KeyUtil.java    |  32 +++--
 3 files changed, 147 insertions(+), 56 deletions(-)

diff --git a/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java b/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java
index b9438dfb30944..4c4f9a30254a3 100644
--- a/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java
+++ b/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java
@@ -385,7 +385,7 @@ private byte[] doFinal() throws BadPaddingException,
                 byte[] decryptBuffer = RSACore.convert(buffer, 0, bufOfs);
                 paddingCopy = RSACore.rsa(decryptBuffer, privateKey, false);
                 result = padding.unpad(paddingCopy);
-                if (result == null && !forTlsPremasterSecret) {
+                if (!forTlsPremasterSecret && result == null) {
                     throw new BadPaddingException
                             ("Padding error in decryption");
                 }
@@ -405,6 +405,34 @@ private byte[] doFinal() throws BadPaddingException,
         }
     }
 
+    // TLS master secret decode version of the doFinal() method.
+    private byte[] doFinalForTls(int clientVersion, int serverVersion)
+            throws BadPaddingException, IllegalBlockSizeException {
+        if (bufOfs > buffer.length) {
+            throw new IllegalBlockSizeException("Data must not be longer "
+                    + "than " + buffer.length + " bytes");
+        }
+        byte[] paddingCopy = null;
+        byte[] result = null;
+        try {
+            byte[] decryptBuffer = RSACore.convert(buffer, 0, bufOfs);
+
+            paddingCopy = RSACore.rsa(decryptBuffer, privateKey, false);
+            result = padding.unpadForTls(paddingCopy, clientVersion,
+                    serverVersion);
+
+            return result;
+        } finally {
+            Arrays.fill(buffer, 0, bufOfs, (byte)0);
+            bufOfs = 0;
+            if (paddingCopy != null
+                    && paddingCopy != buffer    // already cleaned
+                    && paddingCopy != result) { // DO NOT CLEAN, THIS IS RESULT
+                Arrays.fill(paddingCopy, (byte)0);
+            }
+        }
+    }
+
     // see JCE spec
     protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
         update(in, inOfs, inLen);
@@ -477,38 +505,34 @@ protected Key engineUnwrap(byte[] wrappedKey, String algorithm,
         byte[] encoded = null;
 
         update(wrappedKey, 0, wrappedKey.length);
-        try {
-            encoded = doFinal();
-        } catch (BadPaddingException | IllegalBlockSizeException e) {
-            // BadPaddingException cannot happen for TLS RSA unwrap.
-            // In that case, padding error is indicated by returning null.
-            // IllegalBlockSizeException cannot happen in any case,
-            // because of the length check above.
-            throw new InvalidKeyException("Unwrapping failed", e);
-        }
-
         try {
             if (isTlsRsaPremasterSecret) {
                 if (!forTlsPremasterSecret) {
                     throw new IllegalStateException(
                             "No TlsRsaPremasterSecretParameterSpec specified");
                 }
-
-                // polish the TLS premaster secret
-                encoded = KeyUtil.checkTlsPreMasterSecretKey(
-                        ((TlsRsaPremasterSecretParameterSpec) spec).getClientVersion(),
-                        ((TlsRsaPremasterSecretParameterSpec) spec).getServerVersion(),
-                        random, encoded, encoded == null);
+                TlsRsaPremasterSecretParameterSpec parameterSpec =
+                        (TlsRsaPremasterSecretParameterSpec) spec;
+                encoded = doFinalForTls(parameterSpec.getClientVersion(),
+                        parameterSpec.getServerVersion());
+            } else {
+                encoded = doFinal();
             }
-
             return ConstructKeys.constructKey(encoded, algorithm, type);
+
+        } catch (BadPaddingException | IllegalBlockSizeException e) {
+            // BadPaddingException cannot happen for TLS RSA unwrap.
+            // Neither padding error nor server version error is indicated
+            // for TLS, but a fake unwrapped value is returned.
+            // IllegalBlockSizeException cannot happen in any case,
+            // because of the length check above.
+            throw new InvalidKeyException("Unwrapping failed", e);
         } finally {
             if (encoded != null) {
                 Arrays.fill(encoded, (byte) 0);
             }
         }
     }
-
     // see JCE spec
     protected int engineGetKeySize(Key key) throws InvalidKeyException {
         RSAKey rsaKey = RSAKeyFactory.toRSAKey(key);
diff --git a/src/java.base/share/classes/sun/security/rsa/RSAPadding.java b/src/java.base/share/classes/sun/security/rsa/RSAPadding.java
index 6954c2ad7eaeb..686073ac6862f 100644
--- a/src/java.base/share/classes/sun/security/rsa/RSAPadding.java
+++ b/src/java.base/share/classes/sun/security/rsa/RSAPadding.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -322,48 +322,103 @@ private byte[] padV15(byte[] data, int ofs, int len) {
      * Note that we want to make it a constant-time operation
      */
     private byte[] unpadV15(byte[] padded) {
-        int k = 0;
-        boolean bp = false;
+        int paddedLength = padded.length;
 
-        if (padded[k++] != 0) {
-            bp = true;
-        }
-        if (padded[k++] != type) {
-            bp = true;
+        if (paddedLength < 2) {
+            return null;
         }
-        int p = 0;
-        while (k < padded.length) {
+
+        // The following check ensures that the lead byte is zero and
+        // the second byte is equivalent to the padding type.  The
+        // bp (bad padding) variable throughout this unpadding process will
+        // be updated and remain 0 if good padding, 1 if bad.
+        int p0 = padded[0];
+        int p1 = padded[1];
+        int bp = (-(p0 & 0xff) | ((p1 - type) | (type - p1))) >>> 31;
+
+        int padLen = 0;
+        int k = 2;
+        // Walk through the random, nonzero padding bytes.  For each padding
+        // byte bp and padLen will remain zero.  When the end-of-padding
+        // byte (0x00) is reached then padLen will be set to the index of the
+        // first byte of the message content.
+        while (k < paddedLength) {
             int b = padded[k++] & 0xff;
-            if ((b == 0) && (p == 0)) {
-                p = k;
-            }
-            if ((k == padded.length) && (p == 0)) {
-                bp = true;
-            }
-            if ((type == PAD_BLOCKTYPE_1) && (b != 0xff) &&
-                    (p == 0)) {
-                bp = true;
+            padLen += (k * (1 - ((-(b | padLen)) >>> 31)));
+            if (k == paddedLength) {
+                bp = bp | (1 - ((-padLen) >>> 31));
             }
+            bp = bp | (1 - (-(((type - PAD_BLOCKTYPE_1) & 0xff) |
+                    padLen | (1 - ((b - 0xff) >>> 31))) >>> 31));
         }
-        int n = padded.length - p;
-        if (n > maxDataSize) {
-            bp = true;
-        }
+        int n = paddedLength - padLen;
+        // So long as n <= maxDataSize, bp will remain zero
+        bp = bp | ((maxDataSize - n) >>> 31);
 
         // copy useless padding array for a constant-time method
-        byte[] padding = new byte[p];
-        System.arraycopy(padded, 0, padding, 0, p);
+        byte[] padding = new byte[padLen + 2];
+        for (int i = 0; i < padLen; i++) {
+            padding[i] = padded[i];
+        }
 
         byte[] data = new byte[n];
-        System.arraycopy(padded, p, data, 0, n);
+        for (int i = 0; i < n; i++) {
+            data[i] = padded[padLen + i];
+        }
 
-        if (bp) {
+        if ((bp | padding[bp]) != 0) {
+            // using the array padding here hoping that this way
+            // the compiler does not eliminate the above useless copy
             return null;
         } else {
             return data;
         }
     }
 
+    public byte[] unpadForTls(byte[] padded, int clientVersion,
+            int serverVersion) {
+        int paddedLength = padded.length;
+
+        // bp is positive if the padding is bad and 0 if it is good so far
+        int bp = (((int) padded[0] | ((int)padded[1] - PAD_BLOCKTYPE_2)) &
+                0xFFF);
+
+        int k = 2;
+        while (k < paddedLength - 49) {
+            int b = padded[k++] & 0xFF;
+            bp = bp | (1 - (-b >>> 31)); // if (padded[k] == 0) bp |= 1;
+        }
+        bp |= ((int)padded[k++] & 0xFF);
+        int encodedVersion = ((padded[k] & 0xFF) << 8) | (padded[k + 1] & 0xFF);
+
+        int bv1 = clientVersion - encodedVersion;
+        bv1 |= -bv1;
+        int bv3 = serverVersion - encodedVersion;
+        bv3 |= -bv3;
+        int bv2 = (0x301 - clientVersion);
+
+        bp |= ((bv1 & (bv2 | bv3)) >>> 28);
+
+        byte[] data = Arrays.copyOfRange(padded, paddedLength - 48,
+                paddedLength);
+        if (random == null) {
+            random = JCAUtil.getSecureRandom();
+        }
+
+        byte[] fake = new byte[48];
+        random.nextBytes(fake);
+
+        bp = (-bp >> 24);
+
+        // Now bp is 0 if the padding and version number were good and
+        // -1 otherwise.
+        for (int i = 0; i < 48; i++) {
+            data[i] = (byte)((~bp & data[i]) | (bp & fake[i]));
+        }
+
+        return data;
+    }
+
     /**
      * PKCS#1 v2.0 OAEP padding (MGF1).
      * Paragraph references refer to PKCS#1 v2.1 (June 14, 2002)
diff --git a/src/java.base/share/classes/sun/security/util/KeyUtil.java b/src/java.base/share/classes/sun/security/util/KeyUtil.java
index d5ab03e62f42f..a84aa1529a6b0 100644
--- a/src/java.base/share/classes/sun/security/util/KeyUtil.java
+++ b/src/java.base/share/classes/sun/security/util/KeyUtil.java
@@ -322,19 +322,31 @@ public static byte[] checkTlsPreMasterSecretKey(
             tmp = encoded;
         }
 
+        // At this point tmp.length is 48
         int encodedVersion =
                 ((tmp[0] & 0xFF) << 8) | (tmp[1] & 0xFF);
-        int check1 = 0;
-        int check2 = 0;
-        int check3 = 0;
-        if (clientVersion != encodedVersion) check1 = 1;
-        if (clientVersion > 0x0301) check2 = 1;
-        if (serverVersion != encodedVersion) check3 = 1;
-        if ((check1 & (check2 | check3)) == 1) {
-            return replacer;
-        } else {
-            return tmp;
+
+        // The following code is a time-constant version of
+        // if ((clientVersion != encodedVersion) ||
+        //    ((clientVersion > 0x301) && (serverVersion != encodedVersion))) {
+        //        return replacer;
+        // } else { return tmp; }
+        int check1 = (clientVersion - encodedVersion) |
+                (encodedVersion - clientVersion);
+        int check2 = 0x0301 - clientVersion;
+        int check3 = (serverVersion - encodedVersion) |
+                (encodedVersion - serverVersion);
+
+        check1 = (check1 & (check2 | check3)) >> 24;
+
+        // Now check1 is either 0 or -1
+        check2 = ~check1;
+
+        for (int i = 0; i < 48; i++) {
+            tmp[i] = (byte) ((tmp[i] & check2) | (replacer[i] & check1));
         }
+
+        return tmp;
     }
 
     /**

From 5b0a5f436fb9817d679f64302b37543bf160d43d Mon Sep 17 00:00:00 2001
From: Martin Balao 
Date: Mon, 17 Mar 2025 22:13:00 +0000
Subject: [PATCH 122/846] 8338430: Improve compiler transformations

Reviewed-by: mbaesken
Backport-of: 456be5090b6a181afb85d72ac8473e4df3398032
---
 src/hotspot/share/opto/addnode.cpp | 39 +++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/src/hotspot/share/opto/addnode.cpp b/src/hotspot/share/opto/addnode.cpp
index 35e8e2bdc1ce1..ed83e224b418c 100644
--- a/src/hotspot/share/opto/addnode.cpp
+++ b/src/hotspot/share/opto/addnode.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2025, 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
@@ -1164,6 +1164,14 @@ static bool can_overflow(const TypeInt* t, jint c) {
           (c > 0 && (java_add(t_hi, c) < t_hi)));
 }
 
+// Check if addition of a long with type 't' and a constant 'c' can overflow.
+static bool can_overflow(const TypeLong* t, jlong c) {
+  jlong t_lo = t->_lo;
+  jlong t_hi = t->_hi;
+  return ((c < 0 && (java_add(t_lo, c) > t_lo)) ||
+          (c > 0 && (java_add(t_hi, c) < t_hi)));
+}
+
 //=============================================================================
 //------------------------------Idealize---------------------------------------
 // MINs show up in range-check loop limit calculations.  Look for
@@ -1285,6 +1293,31 @@ const Type *MinINode::add_ring( const Type *t0, const Type *t1 ) const {
 //
 // Note: we assume that SubL was already replaced by an AddL, and that the stride
 // has its sign flipped: SubL(limit, stride) -> AddL(limit, -stride).
+//
+// Proof MaxL collapsed version equivalent to original (MinL version similar):
+// is_sub_con ensures that con1, con2 ∈ [min_int, 0[
+//
+// Original:
+// - AddL2 underflow => x + con2 ∈ ]max_long - min_int, max_long], ALWAYS BAILOUT as x + con1 + con2 surely fails can_overflow (*)
+// - AddL2 no underflow => x + con2 ∈ [min_long, max_long]
+//   - MaxL2 clamp => min_int
+//     - AddL1 underflow: NOT POSSIBLE: cannot underflow since min_int + con1 ∈ [2 * min_int, min_int] always > min_long
+//     - AddL1 no underflow => min_int + con1 ∈ [2 * min_int, min_int]
+//       - MaxL1 clamp => min_int (RESULT 1)
+//       - MaxL1 no clamp: NOT POSSIBLE: min_int + con1 ∈ [2 * min_int, min_int] always <= min_int, so clamp always taken
+//   - MaxL2 no clamp => x + con2 ∈ [min_int, max_long]
+//     - AddL1 underflow: NOT POSSIBLE: cannot underflow since x + con2 + con1 ∈ [2 * min_int, max_long] always > min_long
+//     - AddL1 no underflow => x + con2 + con1 ∈ [2 * min_int, max_long]
+//       - MaxL1 clamp => min_int (RESULT 2)
+//       - MaxL1 no clamp => x + con2 + con1 ∈ ]min_int, max_long] (RESULT 3)
+//
+// Collapsed:
+// - AddL2 (cannot underflow) => con2 + con1 ∈ [2 * min_int, 0]
+//   - AddL1 underflow: NOT POSSIBLE: would have bailed out at can_overflow (*)
+//   - AddL1 no underflow => x + con2 + con1 ∈ [min_long, max_long]
+//     - MaxL clamp => min_int (RESULT 1 and RESULT 2)
+//     - MaxL no clamp => x + con2 + con1 ∈ ]min_int, max_long] (RESULT 3)
+//
 Node* fold_subI_no_underflow_pattern(Node* n, PhaseGVN* phase) {
   assert(n->Opcode() == Op_MaxL || n->Opcode() == Op_MinL, "sanity");
   // Check that the two clamps have the correct values.
@@ -1314,6 +1347,10 @@ Node* fold_subI_no_underflow_pattern(Node* n, PhaseGVN* phase) {
         Node* x    = add2->in(1);
         Node* con2 = add2->in(2);
         if (is_sub_con(con2)) {
+          // Collapsed graph not equivalent if potential over/underflow -> bailing out (*)
+          if (can_overflow(phase->type(x)->is_long(), con1->get_long() + con2->get_long())) {
+            return nullptr;
+          }
           Node* new_con = phase->transform(new AddLNode(con1, con2));
           Node* new_sub = phase->transform(new AddLNode(x, new_con));
           n->set_req_X(1, new_sub, phase);

From 185fc0c9163f5f79528ebfc96d01ec76e727fc58 Mon Sep 17 00:00:00 2001
From: Alexei Voitylov 
Date: Thu, 6 Feb 2025 10:01:42 +0100
Subject: [PATCH 123/846] 8342562: Enhance Deflater operations

Reviewed-by: mbalao
Backport-of: 17f7df55fb762488c1054985830ea13840489df2
---
 .../java/util/zip/DeflaterOutputStream.java   | 44 ++++++++++++++++---
 .../java/util/zip/GZIPOutputStream.java       |  4 +-
 2 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/src/java.base/share/classes/java/util/zip/DeflaterOutputStream.java b/src/java.base/share/classes/java/util/zip/DeflaterOutputStream.java
index c856d8999b39f..c9f7807c2f277 100644
--- a/src/java.base/share/classes/java/util/zip/DeflaterOutputStream.java
+++ b/src/java.base/share/classes/java/util/zip/DeflaterOutputStream.java
@@ -40,6 +40,26 @@
  * @since 1.1
  */
 public class DeflaterOutputStream extends FilterOutputStream {
+
+    /*
+     * The default size of the output buffer
+     */
+    static final int DEFAULT_BUF_SIZE = 512;
+
+    /*
+     * When calling Deflater.deflate() with Deflater.SYNC_FLUSH or Deflater.FULL_FLUSH,
+     * the callers are expected to ensure that the size of the buffer is greater than 6.
+     * This expectation comes from the underlying zlib library which in its zlib.h
+     * states:
+     * "If deflate returns with avail_out == 0, this function must be called again
+     * with the same value of the flush parameter and more output space (updated
+     * avail_out), until the flush is complete (deflate returns with non-zero
+     * avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+     * avail_out is greater than six when the flush marker begins, in order to avoid
+     * repeated flush markers upon calling deflate() again when avail_out == 0."
+     */
+    private static final int SYNC_FLUSH_MIN_BUF_SIZE = 7;
+
     /**
      * Compressor for this stream.
      */
@@ -123,7 +143,7 @@ public DeflaterOutputStream(OutputStream out, Deflater def, int size) {
     public DeflaterOutputStream(OutputStream out,
                                 Deflater def,
                                 boolean syncFlush) {
-        this(out, def, 512, syncFlush);
+        this(out, def, DEFAULT_BUF_SIZE, syncFlush);
     }
 
 
@@ -138,7 +158,7 @@ public DeflaterOutputStream(OutputStream out,
      * @param def the compressor ("deflater")
      */
     public DeflaterOutputStream(OutputStream out, Deflater def) {
-        this(out, def, 512, false);
+        this(out, def, DEFAULT_BUF_SIZE, false);
     }
 
     boolean usesDefaultDeflater = false;
@@ -158,7 +178,7 @@ public DeflaterOutputStream(OutputStream out, Deflater def) {
      * @since 1.7
      */
     public DeflaterOutputStream(OutputStream out, boolean syncFlush) {
-        this(out, out != null ? new Deflater() : null, 512, syncFlush);
+        this(out, out != null ? new Deflater() : null, DEFAULT_BUF_SIZE, syncFlush);
         usesDefaultDeflater = true;
     }
 
@@ -181,6 +201,7 @@ public DeflaterOutputStream(OutputStream out) {
      * @param b the byte to be written
      * @throws    IOException if an I/O error has occurred
      */
+    @Override
     public void write(int b) throws IOException {
         byte[] buf = new byte[1];
         buf[0] = (byte)(b & 0xff);
@@ -195,6 +216,7 @@ public void write(int b) throws IOException {
      * @param len the length of the data
      * @throws    IOException if an I/O error has occurred
      */
+    @Override
     public void write(byte[] b, int off, int len) throws IOException {
         if (def.finished()) {
             throw new IOException("write beyond end of stream");
@@ -238,6 +260,7 @@ public void finish() throws IOException {
      * underlying stream.
      * @throws    IOException if an I/O error has occurred
      */
+    @Override
     public void close() throws IOException {
         if (!closed) {
             try {
@@ -277,13 +300,20 @@ protected void deflate() throws IOException {
      *
      * @since 1.7
      */
+    @Override
     public void flush() throws IOException {
         if (syncFlush && !def.finished()) {
             int len = 0;
-            while ((len = def.deflate(buf, 0, buf.length, Deflater.SYNC_FLUSH)) > 0)
-            {
-                out.write(buf, 0, len);
-                if (len < buf.length)
+            // For SYNC_FLUSH, the Deflater.deflate() expects the callers
+            // to use a buffer whose length is greater than 6 to avoid
+            // flush marker (5 bytes) being repeatedly output to the output buffer
+            // every time it is invoked.
+            final byte[] flushBuf = buf.length < SYNC_FLUSH_MIN_BUF_SIZE
+                    ? new byte[DEFAULT_BUF_SIZE]
+                    : buf;
+            while ((len = def.deflate(flushBuf, 0, flushBuf.length, Deflater.SYNC_FLUSH)) > 0) {
+                out.write(flushBuf, 0, len);
+                if (len < flushBuf.length)
                     break;
             }
         }
diff --git a/src/java.base/share/classes/java/util/zip/GZIPOutputStream.java b/src/java.base/share/classes/java/util/zip/GZIPOutputStream.java
index cdfac329cfa83..7dad5fe0e879f 100644
--- a/src/java.base/share/classes/java/util/zip/GZIPOutputStream.java
+++ b/src/java.base/share/classes/java/util/zip/GZIPOutputStream.java
@@ -109,7 +109,7 @@ public GZIPOutputStream(OutputStream out, int size, boolean syncFlush)
      * @throws    IOException If an I/O error has occurred.
      */
     public GZIPOutputStream(OutputStream out) throws IOException {
-        this(out, 512, false);
+        this(out, DeflaterOutputStream.DEFAULT_BUF_SIZE, false);
     }
 
     /**
@@ -131,7 +131,7 @@ public GZIPOutputStream(OutputStream out) throws IOException {
     public GZIPOutputStream(OutputStream out, boolean syncFlush)
         throws IOException
     {
-        this(out, 512, syncFlush);
+        this(out, DeflaterOutputStream.DEFAULT_BUF_SIZE, syncFlush);
     }
 
     /**

From 0a89eb2588334226531e8e25ac340eabbc00bd6d Mon Sep 17 00:00:00 2001
From: Aleksei Voitylov 
Date: Thu, 12 Dec 2024 03:14:30 +0000
Subject: [PATCH 124/846] 8343007: Enhance Buffered Image handling

Reviewed-by: yan, mbalao
Backport-of: e95aaf16aa202b49892ccb05ded783114b2d8534
---
 .../share/native/libawt/java2d/loops/Blit.c    | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/src/java.desktop/share/native/libawt/java2d/loops/Blit.c b/src/java.desktop/share/native/libawt/java2d/loops/Blit.c
index fee108b833a4d..8a41584deefe8 100644
--- a/src/java.desktop/share/native/libawt/java2d/loops/Blit.c
+++ b/src/java.desktop/share/native/libawt/java2d/loops/Blit.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -68,14 +68,30 @@ Java_sun_java2d_loops_Blit_Blit
         return;
     }
 
+    if (width <= 0 || height <= 0) {
+        return;
+    }
+
     srcInfo.bounds.x1 = srcx;
     srcInfo.bounds.y1 = srcy;
+    if (UNSAFE_TO_ADD(srcx, width) ||
+        UNSAFE_TO_ADD(srcy, height) ||
+        UNSAFE_TO_ADD(dstx, width) ||
+        UNSAFE_TO_ADD(dsty, height)) {
+        return;
+    }
+
     srcInfo.bounds.x2 = srcx + width;
     srcInfo.bounds.y2 = srcy + height;
     dstInfo.bounds.x1 = dstx;
     dstInfo.bounds.y1 = dsty;
     dstInfo.bounds.x2 = dstx + width;
     dstInfo.bounds.y2 = dsty + height;
+    if (UNSAFE_TO_SUB(srcx, dstx) ||
+        UNSAFE_TO_SUB(srcy, dsty)) {
+        return;
+    }
+
     srcx -= dstx;
     srcy -= dsty;
     SurfaceData_IntersectBounds(&dstInfo.bounds, &clipInfo.bounds);

From ff6fb92bd9721e85a6187af262f2fa77d79c7b09 Mon Sep 17 00:00:00 2001
From: Martin Balao 
Date: Wed, 19 Mar 2025 10:46:00 +0000
Subject: [PATCH 125/846] 8347847: Enhance jar file support

Reviewed-by: yan
Backport-of: 013d9f988559bc7e29449967c4d35b80d692ef11
---
 .../security/util/SignatureFileVerifier.java  | 27 ++++++++++++++-----
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java b/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java
index 05acdcb94748b..05e992f2be94e 100644
--- a/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java
+++ b/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2025, 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
@@ -525,6 +525,8 @@ private boolean verifyManifestMainAttrs(Manifest sf, ManifestDigester md)
         boolean attrsVerified = true;
         // If only weak algorithms are used.
         boolean weakAlgs = true;
+        // If only unsupported algorithms are used.
+        boolean unsupportedAlgs = true;
         // If a ATTR_DIGEST entry is found.
         boolean validEntry = false;
 
@@ -549,6 +551,7 @@ private boolean verifyManifestMainAttrs(Manifest sf, ManifestDigester md)
 
                 MessageDigest digest = getDigest(algorithm);
                 if (digest != null) {
+                    unsupportedAlgs = false;
                     ManifestDigester.Entry mde = md.getMainAttsEntry(false);
                     if (mde == null) {
                         throw new SignatureException("Manifest Main Attribute check " +
@@ -591,12 +594,22 @@ private boolean verifyManifestMainAttrs(Manifest sf, ManifestDigester md)
             }
         }
 
-        // If there were only weak algorithms entries used, throw an exception.
-        if (validEntry && weakAlgs) {
-            throw new SignatureException("Manifest Main Attribute check " +
-                    "failed (" + ATTR_DIGEST + ").  " +
-                    "Disabled algorithm(s) used: " +
-                    getWeakAlgorithms(ATTR_DIGEST));
+        if (validEntry) {
+            // If there were only weak algorithms entries used, throw an exception.
+            if (weakAlgs) {
+                throw new SignatureException(
+                        "Manifest Main Attribute check "
+                        + "failed (" + ATTR_DIGEST + ").  "
+                        + "Disabled algorithm(s) used: "
+                        + getWeakAlgorithms(ATTR_DIGEST));
+            }
+
+            // If there were only unsupported algorithms entries used, throw an exception.
+            if (unsupportedAlgs) {
+                throw new SignatureException(
+                        "Manifest Main Attribute check failed ("
+                        + ATTR_DIGEST + "). Unsupported algorithm(s) used");
+            }
         }
 
         // this method returns 'true' if either:

From 95e6cbd222732fcccc3767e5983df524b9214acb Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Mon, 7 Apr 2025 14:59:28 +0000
Subject: [PATCH 126/846] 8315871: Opensource five more Swing regression tests

Backport-of: be9cc73fcad0cac0a6f12b0f962fbe3bd8328ec9
---
 .../AncestorNotifier/4817630/bug4817630.java  | 114 ++++++++++++++++++
 .../swing/BoxLayout/4191948/bug4191948.java   |  86 +++++++++++++
 .../ComponentInputMap/4248723/bug4248723.java |  69 +++++++++++
 .../4297953/bug4297953.java                   |  42 +++++++
 .../4097723/bug4097723.java                   |  44 +++++++
 5 files changed, 355 insertions(+)
 create mode 100644 test/jdk/javax/swing/AncestorNotifier/4817630/bug4817630.java
 create mode 100644 test/jdk/javax/swing/BoxLayout/4191948/bug4191948.java
 create mode 100644 test/jdk/javax/swing/ComponentInputMap/4248723/bug4248723.java
 create mode 100644 test/jdk/javax/swing/DefaultBoundedRangeModel/4297953/bug4297953.java
 create mode 100644 test/jdk/javax/swing/DefaultButtonModel/4097723/bug4097723.java

diff --git a/test/jdk/javax/swing/AncestorNotifier/4817630/bug4817630.java b/test/jdk/javax/swing/AncestorNotifier/4817630/bug4817630.java
new file mode 100644
index 0000000000000..35c42f6e78be2
--- /dev/null
+++ b/test/jdk/javax/swing/AncestorNotifier/4817630/bug4817630.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+/*
+ *  @test
+ *  @bug 4817630
+ *  @summary AncestorEvent ancestorAdded thrown at JFrame creation, not at show()
+ *  @key headful
+ *  @run main bug4817630
+ */
+
+import java.lang.reflect.InvocationTargetException;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.SwingUtilities;
+import javax.swing.event.AncestorEvent;
+import javax.swing.event.AncestorListener;
+
+public class bug4817630 {
+
+    JFrame fr;
+
+    volatile boolean ancestorAdded = false;
+    volatile boolean passed = true;
+
+    public void init() {
+        fr = new JFrame("bug4817630");
+        JLabel label = new JLabel("Label");
+
+        label.addAncestorListener(new AncestorListener() {
+                public void ancestorAdded(AncestorEvent e) {
+                    if (!fr.isVisible()) {
+                        setPassed(false);
+                    }
+                    synchronized (bug4817630.this) {
+                        ancestorAdded = true;
+                        bug4817630.this.notifyAll();
+                    }
+                }
+                public void ancestorRemoved(AncestorEvent e) {
+                }
+                public void ancestorMoved(AncestorEvent e) {
+                }
+            });
+
+        fr.setLocationRelativeTo(null);
+        fr.getContentPane().add(label);
+        fr.pack();
+        fr.setVisible(true);
+    }
+
+    public void start() {
+        try {
+            synchronized (bug4817630.this) {
+                while (!ancestorAdded) {
+                    bug4817630.this.wait();
+                }
+            }
+        } catch(Exception e) {
+            throw new RuntimeException("Test failed because of "
+                    + e.getLocalizedMessage());
+        }
+    }
+
+    public void destroy() {
+        if (fr != null) {
+            fr.setVisible(false);
+            fr.dispose();
+        }
+        if (!isPassed()) {
+            throw new RuntimeException("ancestorAdded() method shouldn't be "
+                    + "called before the frame is shown.");
+        }
+    }
+
+    synchronized void setPassed(boolean passed) {
+        this.passed = passed;
+    }
+
+    synchronized boolean isPassed() {
+        return passed;
+    }
+
+    public static void main(String[] args) throws InterruptedException,
+            InvocationTargetException {
+        bug4817630 test = new bug4817630();
+        try {
+            SwingUtilities.invokeAndWait(test::init);
+            test.start();
+        } finally {
+            SwingUtilities.invokeAndWait(test::destroy);
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/BoxLayout/4191948/bug4191948.java b/test/jdk/javax/swing/BoxLayout/4191948/bug4191948.java
new file mode 100644
index 0000000000000..a7a1f792341ab
--- /dev/null
+++ b/test/jdk/javax/swing/BoxLayout/4191948/bug4191948.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1999, 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.
+ */
+
+/*
+ * @test
+ * @bug 4191948
+ * @summary BoxLayout doesn't ignore invisible components
+ * @key headful
+ * @run main bug4191948
+ */
+
+import java.awt.BorderLayout;
+import java.lang.reflect.InvocationTargetException;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+public class bug4191948 {
+    JFrame frame;
+    JPanel p;
+    JButton foo1;
+    JButton foo2;
+    JButton foo3;
+
+    public void init() {
+        frame = new JFrame("bug4191948");
+        p = new JPanel();
+        p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
+        foo1 = (JButton)p.add(new JButton("Foo1"));
+        foo2 = (JButton)p.add(new JButton("Foo2"));
+        foo3 = (JButton)p.add(new JButton("Foo3"));
+
+        foo2.setVisible(false);
+        frame.setLocationRelativeTo(null);
+        frame.setLayout(new BorderLayout());
+        frame.add(p, BorderLayout.CENTER);
+        frame.pack();
+        frame.setVisible(true);
+    }
+
+    public void start() {
+        try {
+            int totalWidth = p.getPreferredSize().width;
+            int foo1Width = foo1.getPreferredSize().width;
+            int foo2Width = foo2.getPreferredSize().width;
+            int foo3Width = foo3.getPreferredSize().width;
+            if (totalWidth >= (foo1Width + foo2Width + foo3Width)) {
+                throw new RuntimeException("Panel is too wide");
+            }
+        } finally {
+            if (frame != null) {
+                frame.setVisible(false);
+                frame.dispose();
+            }
+        }
+    }
+
+    public static void main(String[] args) throws InterruptedException,
+            InvocationTargetException {
+        bug4191948 test = new bug4191948();
+        SwingUtilities.invokeAndWait(test::init);
+        SwingUtilities.invokeAndWait(test::start);
+    }
+}
diff --git a/test/jdk/javax/swing/ComponentInputMap/4248723/bug4248723.java b/test/jdk/javax/swing/ComponentInputMap/4248723/bug4248723.java
new file mode 100644
index 0000000000000..0218b2fbc108f
--- /dev/null
+++ b/test/jdk/javax/swing/ComponentInputMap/4248723/bug4248723.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1999, 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.
+ */
+
+/*
+ * @test
+ * @bug 4248723
+ * @summary Tests that ComponentInputMap doesn't throw NPE when deserializing
+ * @run main bug4248723
+ */
+
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import javax.swing.ComponentInputMap;
+import javax.swing.JButton;
+import javax.swing.KeyStroke;
+
+public class bug4248723 {
+    public static Object serializeAndDeserialize(Object toWrite)
+            throws ClassNotFoundException, IOException {
+        ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+        ObjectOutputStream p = new ObjectOutputStream(ostream);
+        p.writeObject(toWrite);
+        p.flush();
+        byte[] data = ostream.toByteArray();
+        ostream.close();
+
+        ByteArrayInputStream istream = new ByteArrayInputStream(data);
+        ObjectInputStream q = new ObjectInputStream(istream);
+        Object retValue = q.readObject();
+        istream.close();
+        return retValue;
+    }
+
+    public static void main(String[] argv) {
+        ComponentInputMap cim = new ComponentInputMap(new JButton());
+        cim.put(KeyStroke.getKeyStroke(
+                KeyEvent.VK_B, InputEvent.CTRL_DOWN_MASK), "A");
+        try {
+            cim = (ComponentInputMap)serializeAndDeserialize(cim);
+        } catch (ClassNotFoundException|IOException ignore) {
+            // Should not cause test to fail so silently ignore these
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/DefaultBoundedRangeModel/4297953/bug4297953.java b/test/jdk/javax/swing/DefaultBoundedRangeModel/4297953/bug4297953.java
new file mode 100644
index 0000000000000..a19487490720b
--- /dev/null
+++ b/test/jdk/javax/swing/DefaultBoundedRangeModel/4297953/bug4297953.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+/*
+ * @test
+ * @bug 4297953
+ * @summary Tests that DefaultBoundedRangeModel doesn't zero out the
+ *          extent value when maximum changes
+ * @run main bug4297953
+ */
+
+import javax.swing.JScrollBar;
+
+public class bug4297953 {
+    public static void main(String[] args)  {
+        JScrollBar sb = new JScrollBar(JScrollBar.HORIZONTAL, 90, 10, 0, 100);
+        sb.setMaximum(80);
+        if (sb.getVisibleAmount() != 10) {
+            throw new RuntimeException("Failed: extent is " + sb.getVisibleAmount());
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/DefaultButtonModel/4097723/bug4097723.java b/test/jdk/javax/swing/DefaultButtonModel/4097723/bug4097723.java
new file mode 100644
index 0000000000000..5ffebe3e8ff28
--- /dev/null
+++ b/test/jdk/javax/swing/DefaultButtonModel/4097723/bug4097723.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1999, 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.
+ */
+
+/*
+ * @test
+ * @bug 4097723
+ * @summary Tests that method DefaultButtonModel.getGroup() exists
+ * @run main bug4097723
+ */
+
+import javax.swing.ButtonGroup;
+import javax.swing.DefaultButtonModel;
+
+public class bug4097723 {
+    public static void main(String[] argv) {
+        DefaultButtonModel dbm = new DefaultButtonModel();
+        ButtonGroup group = new ButtonGroup();
+        dbm.setGroup(group);
+        ButtonGroup g = dbm.getGroup();
+        if (g != group) {
+            throw new RuntimeException("Failure: getGroup() returned wrong thing");
+        }
+    }
+}

From 36e703ac2b22d605ea4813a7d956d0437ab303f1 Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Mon, 7 Apr 2025 15:00:57 +0000
Subject: [PATCH 127/846] 8321931: memory_swap_current_in_bytes reports 0 as
 "unlimited"

Backport-of: 7777eb5e15b9f08cdc621c84ff38c72334388b56
---
 src/hotspot/os/linux/osContainer_linux.cpp    |  2 +-
 .../containers/docker/TestContainerInfo.java  | 97 +++++++++++++++++++
 2 files changed, 98 insertions(+), 1 deletion(-)
 create mode 100644 test/hotspot/jtreg/containers/docker/TestContainerInfo.java

diff --git a/src/hotspot/os/linux/osContainer_linux.cpp b/src/hotspot/os/linux/osContainer_linux.cpp
index 52e6ab86c716c..88a9289b93972 100644
--- a/src/hotspot/os/linux/osContainer_linux.cpp
+++ b/src/hotspot/os/linux/osContainer_linux.cpp
@@ -138,7 +138,7 @@ jlong OSContainer::pids_current() {
 
 void OSContainer::print_container_helper(outputStream* st, jlong j, const char* metrics) {
   st->print("%s: ", metrics);
-  if (j > 0) {
+  if (j >= 0) {
     if (j >= 1024) {
       st->print_cr(UINT64_FORMAT " k", uint64_t(j) / 1024);
     } else {
diff --git a/test/hotspot/jtreg/containers/docker/TestContainerInfo.java b/test/hotspot/jtreg/containers/docker/TestContainerInfo.java
new file mode 100644
index 0000000000000..dadc262cd5a4e
--- /dev/null
+++ b/test/hotspot/jtreg/containers/docker/TestContainerInfo.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2024, Red Hat, Inc.
+ * 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
+ * @summary Test container info for cgroup v2
+ * @requires docker.support
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build CheckContainerized jdk.test.whitebox.WhiteBox PrintContainerInfo
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar whitebox.jar jdk.test.whitebox.WhiteBox
+ * @run driver TestContainerInfo
+ */
+import jtreg.SkippedException;
+import jdk.test.lib.containers.docker.Common;
+import jdk.test.lib.containers.docker.DockerTestUtils;
+import jdk.test.lib.containers.docker.DockerRunOptions;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+
+public class TestContainerInfo {
+    private static final String imageName = Common.imageName("container-info");
+
+    public static void main(String[] args) throws Exception {
+        if (!DockerTestUtils.canTestDocker()) {
+            return;
+        }
+
+        Common.prepareWhiteBox();
+        DockerTestUtils.buildJdkContainerImage(imageName);
+
+        try {
+            testPrintContainerInfoWithoutSwap();
+        } finally {
+            DockerTestUtils.removeDockerImage(imageName);
+        }
+    }
+
+    private static void testPrintContainerInfoWithoutSwap() throws Exception {
+        Common.logNewTestCase("Test print_container_info() - without swap");
+
+        DockerRunOptions opts = Common.newOpts(imageName, "PrintContainerInfo")
+                      .addDockerOpts("--memory=500m")
+                      .addDockerOpts("--memory-swap=500m"); // no swap
+        Common.addWhiteBoxOpts(opts);
+
+        OutputAnalyzer out = Common.run(opts);
+        checkContainerInfo(out);
+    }
+
+    private static void shouldMatchWithValue(OutputAnalyzer output, String match, String value) {
+        output.shouldContain(match);
+        String str = output.getOutput();
+        for (String s : str.split(System.lineSeparator())) {
+            if (s.contains(match)) {
+                if (!s.contains(value)) {
+                    throw new RuntimeException("memory_swap_current_in_bytes NOT " + value + "! Line was : " + s);
+                }
+            }
+        }
+    }
+
+    private static void checkContainerInfo(OutputAnalyzer out) throws Exception {
+        String str = out.getOutput();
+        if (str.contains("cgroupv2")) {
+            shouldMatchWithValue(out, "memory_swap_max_limit_in_bytes", "0");
+            shouldMatchWithValue(out, "memory_swap_current_in_bytes", "0");
+        } else {
+            throw new SkippedException("This test is cgroups v2 specific, skipped on cgroups v1");
+        }
+    }
+}

From 4d51cd82c0bcc308a5ab8ea17902d31ec1885201 Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Mon, 7 Apr 2025 15:02:31 +0000
Subject: [PATCH 128/846] 8258483: [TESTBUG] gtest
 CollectorPolicy.young_scaled_initial_ergo_vm fails if heap is too small

Backport-of: d08b5bd9f5f740d75c1acfbd644ce1c822e03833
---
 .../gtest/gc/shared/test_collectorPolicy.cpp      | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp b/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp
index dfe096248c778..6739e20cfd4d6 100644
--- a/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp
+++ b/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp
@@ -69,7 +69,7 @@ class TestGenCollectorPolicy {
       FLAG_SET_ERGO(InitialHeapSize, 100 * M);
       FLAG_SET_ERGO(OldSize, 4 * M);
       FLAG_SET_ERGO(NewSize, 1 * M);
-      FLAG_SET_ERGO(MaxNewSize, 80 * M);
+      FLAG_SET_ERGO(MaxNewSize, 40 * M);
 
       ASSERT_NO_FATAL_FAILURE(setter1->execute());
 
@@ -212,6 +212,9 @@ class TestGenCollectorPolicy {
 // depends on so many other configurable variables. These tests only try to
 // verify that there are some basic rules for NewSize honored by the policies.
 
+// Tests require at least 128M of MaxHeap
+// otherwise ergonomic is different and generation sizes might be changed.
+
 // If NewSize has been ergonomically set, the collector policy
 // should use it for min
 TEST_VM(CollectorPolicy, young_min_ergo) {
@@ -225,6 +228,9 @@ TEST_VM(CollectorPolicy, young_min_ergo) {
 // should use it for min but calculate the initial young size
 // using NewRatio.
 TEST_VM(CollectorPolicy, young_scaled_initial_ergo) {
+  if (MaxHeapSize < 128 * M) {
+      return;
+  }
   TestGenCollectorPolicy::SetNewSizeErgo setter(20 * M);
   TestGenCollectorPolicy::CheckScaledYoungInitial checker;
 
@@ -237,6 +243,9 @@ TEST_VM(CollectorPolicy, young_scaled_initial_ergo) {
 // the rest of the VM lifetime. This is an irreversible change and
 // could impact other tests so we use TEST_OTHER_VM
 TEST_OTHER_VM(CollectorPolicy, young_cmd) {
+  if (MaxHeapSize < 128 * M) {
+    return;
+  }
   // If NewSize is set on the command line, it should be used
   // for both min and initial young size if less than min heap.
   TestGenCollectorPolicy::SetNewSizeCmd setter(20 * M);
@@ -249,8 +258,8 @@ TEST_OTHER_VM(CollectorPolicy, young_cmd) {
 
   // If NewSize is set on command line, but is larger than the min
   // heap size, it should only be used for initial young size.
-  TestGenCollectorPolicy::SetNewSizeCmd setter_large(80 * M);
-  TestGenCollectorPolicy::CheckYoungInitial checker_large(80 * M);
+  TestGenCollectorPolicy::SetNewSizeCmd setter_large(40 * M);
+  TestGenCollectorPolicy::CheckYoungInitial checker_large(40 * M);
   TestGenCollectorPolicy::TestWrapper::test(&setter_large, &checker_large);
 }
 

From b7a846d9d1d434b7074b1f495222e2b3f6ca2c9a Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Mon, 7 Apr 2025 15:07:46 +0000
Subject: [PATCH 129/846] 8339300: CollectorPolicy.young_scaled_initial_ergo_vm
 gtest fails on ppc64 based platforms

Backport-of: f2c992c5af021ab0ff8429fd261314bc7e01f7df
---
 test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp b/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp
index 6739e20cfd4d6..a45d54b61f948 100644
--- a/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp
+++ b/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp
@@ -69,7 +69,7 @@ class TestGenCollectorPolicy {
       FLAG_SET_ERGO(InitialHeapSize, 100 * M);
       FLAG_SET_ERGO(OldSize, 4 * M);
       FLAG_SET_ERGO(NewSize, 1 * M);
-      FLAG_SET_ERGO(MaxNewSize, 40 * M);
+      FLAG_SET_ERGO(MaxNewSize, 50 * M);
 
       ASSERT_NO_FATAL_FAILURE(setter1->execute());
 
@@ -258,8 +258,8 @@ TEST_OTHER_VM(CollectorPolicy, young_cmd) {
 
   // If NewSize is set on command line, but is larger than the min
   // heap size, it should only be used for initial young size.
-  TestGenCollectorPolicy::SetNewSizeCmd setter_large(40 * M);
-  TestGenCollectorPolicy::CheckYoungInitial checker_large(40 * M);
+  TestGenCollectorPolicy::SetNewSizeCmd setter_large(50 * M);
+  TestGenCollectorPolicy::CheckYoungInitial checker_large(50 * M);
   TestGenCollectorPolicy::TestWrapper::test(&setter_large, &checker_large);
 }
 

From 98f87f6074ebb42bb45fcca73517132402eaac47 Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Mon, 7 Apr 2025 15:09:10 +0000
Subject: [PATCH 130/846] 8339148: Make os::Linux::active_processor_count()
 public

Backport-of: bc269de452ba2c6072529c3201059b2039210238
---
 src/hotspot/os/linux/os_linux.hpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/hotspot/os/linux/os_linux.hpp b/src/hotspot/os/linux/os_linux.hpp
index dc83208f60387..e225d521f3230 100644
--- a/src/hotspot/os/linux/os_linux.hpp
+++ b/src/hotspot/os/linux/os_linux.hpp
@@ -31,9 +31,7 @@
 static bool zero_page_read_protected() { return true; }
 
 class Linux {
-  friend class CgroupSubsystem;
   friend class os;
-  friend class OSContainer;
   friend class TestReserveMemorySpecial;
 
   static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *);
@@ -57,7 +55,6 @@ class Linux {
   static int _page_size;
 
   static julong available_memory();
-  static int active_processor_count();
 
   static void initialize_system_info();
 
@@ -107,6 +104,7 @@ class Linux {
     bool     has_steal_ticks;
   };
 
+  static int active_processor_count();
   // which_logical_cpu=-1 returns accumulated ticks for all cpus.
   static bool get_tick_information(CPUPerfTicks* pticks, int which_logical_cpu);
   static bool _stack_is_executable;

From 6c1f3dbb74b56a10ebea2e03c9ebf6351c5906a8 Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Mon, 7 Apr 2025 15:10:58 +0000
Subject: [PATCH 131/846] 8340271: Open source several AWT Robot tests

Backport-of: bc36ace72c1189dcd6d0c05d40d8c568acd89b01
---
 .../java/awt/Robot/CreateScreenCapture.java   |  81 ++++++++++++++
 test/jdk/java/awt/Robot/RobotScrollTest.java  | 101 ++++++++++++++++++
 2 files changed, 182 insertions(+)
 create mode 100644 test/jdk/java/awt/Robot/CreateScreenCapture.java
 create mode 100644 test/jdk/java/awt/Robot/RobotScrollTest.java

diff --git a/test/jdk/java/awt/Robot/CreateScreenCapture.java b/test/jdk/java/awt/Robot/CreateScreenCapture.java
new file mode 100644
index 0000000000000..8060240ba8f1d
--- /dev/null
+++ b/test/jdk/java/awt/Robot/CreateScreenCapture.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 4292503
+ * @summary OutOfMemoryError with lots of Robot.createScreenCapture
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @requires (os.family == "linux")
+ * @run main/manual CreateScreenCapture
+*/
+
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.TextArea;
+
+public class CreateScreenCapture {
+
+    static TextArea messageText;
+
+    private static final String INSTRUCTIONS = """
+         This test is linux only!
+         Once you see these instructions, run 'top' program.
+         Watch for java process.
+         The memory size used by this process should stop growing after several steps.
+         Numbers of steps test is performing are displayed in output window.
+         After 5-7 steps the size taken by the process should become stable.
+         If this happens, then test passed otherwise test failed.
+
+         Small oscillations of the memory size are, however, acceptable.""";
+
+    public static void main(String[] args) throws Exception {
+        Robot robot = new Robot();
+        PassFailJFrame passFail = new PassFailJFrame(INSTRUCTIONS);
+        Dialog dialog = new Dialog(new Frame(), "Instructions");
+        messageText = new TextArea("", 5, 80, TextArea.SCROLLBARS_BOTH);
+        dialog.add(messageText);
+        PassFailJFrame.addTestWindow(dialog);
+        PassFailJFrame.positionTestWindow(dialog, PassFailJFrame.Position.HORIZONTAL);
+        dialog.setSize(200, 300);
+        dialog.setVisible(true);
+        Rectangle rect = new Rectangle(0, 0, 1000, 1000);
+        for (int i = 0; i < 100; i++) {
+            Image image = robot.createScreenCapture(rect);
+            image.flush();
+            image = null;
+            robot.delay(200);
+            log("step #" + i);
+        }
+        passFail.awaitAndCheck();
+    }
+
+    private static void log(String messageIn) {
+        messageText.append(messageIn + "\n");
+    }
+}
+
diff --git a/test/jdk/java/awt/Robot/RobotScrollTest.java b/test/jdk/java/awt/Robot/RobotScrollTest.java
new file mode 100644
index 0000000000000..20dc9f2f4ebd9
--- /dev/null
+++ b/test/jdk/java/awt/Robot/RobotScrollTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 4374578
+ * @summary Test robot wheel scrolling of Text
+ * @requires (os.family == "Windows") | (os.family == "linux")
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @run main/manual RobotScrollTest
+*/
+
+import java.awt.Frame;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.TextArea;
+
+public class RobotScrollTest {
+
+    static TextArea ta;
+    static Robot robot;
+
+    private static final String INSTRUCTIONS = """
+         0. DON'T TOUCH ANYTHING!
+         1. This test is for Windows and Linux only.
+         2. Just sit back, and watch the Robot move the mouse to the TextArea.
+         3. Once the pointer is on the text area, the Robot will use the mouse wheel
+            to scroll the text.
+            If the text scrolled, press PASS, else, press FAIL.""";
+
+    public static void main(String[] args) throws Exception {
+        robot = new Robot();
+        robot.setAutoDelay(100);
+        PassFailJFrame passFail = new PassFailJFrame(INSTRUCTIONS);
+        createTestUI();
+        passFail.awaitAndCheck();
+    }
+
+    private static void createTestUI() {
+        Frame f = new Frame("RobotScrollTest");
+        ta = new TextArea();
+        for (int i = 0; i < 100; i++) {
+            ta.append(i + "\n");
+        }
+        f.add(ta);
+        f.setLocation(0, 400);
+        f.pack();
+        PassFailJFrame.addTestWindow(f);
+        PassFailJFrame.positionTestWindow(f, PassFailJFrame.Position.HORIZONTAL);
+        f.setVisible(true);
+        doTest();
+    }
+
+    private static void doTest() {
+        robot.waitForIdle();
+        robot.delay(1000);
+        // get loc of TextArea
+        Point taAt = ta.getLocationOnScreen();
+        // get bounds of button
+        Rectangle bounds = ta.getBounds();
+
+        // move mouse to middle of button
+        robot.mouseMove(taAt.x + bounds.width / 2,
+                        taAt.y + bounds.height / 2);
+
+        // rotate wheel a few times
+        for (int j = 1; j < 8; j++) {
+            for (int k = 0; k < 5; k++) {
+                robot.mouseWheel(j);
+            }
+
+            for (int k = 0; k < 5; k++) {
+                robot.mouseWheel(-1 * j);
+            }
+        }
+    }
+
+}
+

From 51a79187bc820cfd241c7bd65560f7c94de1655d Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Mon, 7 Apr 2025 15:12:36 +0000
Subject: [PATCH 132/846] 8340874: Open source some of the AWT Geometry/Button
 tests

Backport-of: e19c7d80f722395583fbdb4cc10dc9051c8602f2
---
 .../BadActionEventTest.java                   |  93 +++++++++++++
 .../jdk/java/awt/geom/Arc2D/Arc2DHitTest.java | 100 ++++++++++++++
 test/jdk/java/awt/geom/Arc2D/BoundsBug.java   | 123 ++++++++++++++++++
 test/jdk/java/awt/geom/Area/Translate.java    | 122 +++++++++++++++++
 4 files changed, 438 insertions(+)
 create mode 100644 test/jdk/java/awt/Button/BadActionEventTest/BadActionEventTest.java
 create mode 100644 test/jdk/java/awt/geom/Arc2D/Arc2DHitTest.java
 create mode 100644 test/jdk/java/awt/geom/Arc2D/BoundsBug.java
 create mode 100644 test/jdk/java/awt/geom/Area/Translate.java

diff --git a/test/jdk/java/awt/Button/BadActionEventTest/BadActionEventTest.java b/test/jdk/java/awt/Button/BadActionEventTest/BadActionEventTest.java
new file mode 100644
index 0000000000000..53aac7ab78751
--- /dev/null
+++ b/test/jdk/java/awt/Button/BadActionEventTest/BadActionEventTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 4530087
+ * @summary Test if double-clicking causes ActionEvent on underlying button
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @run main/manual BadActionEventTest
+ */
+
+import java.awt.Button;
+import java.awt.Color;
+import java.awt.FileDialog;
+import java.awt.Frame;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class BadActionEventTest implements ActionListener {
+    private static Button showBtn;
+    private static Button listBtn;
+
+    public static void main(String[] args) throws Exception {
+        String INSTRUCTIONS = """
+            1) Click on 'Show File Dialog' to bring up the FileDialog window.
+            (If necessary, change to a directory with files (not just directories) in it.)
+            2) Move the FileDialog so that one of the file names (again, a file, NOT a directory) in the list is
+            directly over the 'ActionListener' button.
+            3) Double-click on the file name over the button. The FileDialog will disappear.
+            4) If the 'ActionListener' button receives an ActionEvent, the test fails and a
+            message to that effect will be printed.
+            Otherwise, the test passes.
+            """;
+
+        PassFailJFrame.builder()
+            .title("Test Instructions")
+            .instructions(INSTRUCTIONS)
+            .columns(45)
+            .testUI(BadActionEventTest::createUI)
+            .logArea(2)
+            .build()
+            .awaitAndCheck();
+    }
+
+    private static Frame createUI() {
+        Frame frame = new Frame("BadActionEventTest");
+        frame.setLayout(new GridLayout(1, 2));
+        frame.setSize(400, 200);
+        showBtn = new Button("Show File Dialog");
+        listBtn = new Button("ActionListener");
+        showBtn.setSize(200, 200);
+        listBtn.setSize(200, 200);
+        showBtn.addActionListener(new BadActionEventTest());
+        listBtn.addActionListener(new BadActionEventTest());
+        frame.add(showBtn);
+        frame.add(listBtn);
+        return frame;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if (e.getSource() == showBtn) {
+            FileDialog fd = new FileDialog(new Frame());
+            fd.setVisible(true);
+        } else if (e.getSource() == listBtn) {
+            listBtn.setBackground(Color.red);
+            listBtn.setLabel("TEST FAILS!");
+            PassFailJFrame.log("*TEST FAILS!* ActionListener got ActionEvent! *TEST FAILS!*");
+        }
+    }
+}
diff --git a/test/jdk/java/awt/geom/Arc2D/Arc2DHitTest.java b/test/jdk/java/awt/geom/Arc2D/Arc2DHitTest.java
new file mode 100644
index 0000000000000..de6b39d5c6f7f
--- /dev/null
+++ b/test/jdk/java/awt/geom/Arc2D/Arc2DHitTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 4178123
+ * @summary Verifies that the Arc2D.contains(point) methods work correctly.
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @run main/manual Arc2DHitTest
+ */
+
+import java.awt.Color;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Panel;
+import java.awt.Point;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.geom.Arc2D;
+
+public class Arc2DHitTest {
+    public static void main(String[] args) throws Exception {
+        String INSTRUCTIONS = """
+            This test displays an arc figure and lets the user click on it.
+            The arc will initially be drawn in red and only when the user clicks
+            within the arc in the window it will be redrawn into green otherwise
+            it should stay red.
+
+            For convenience, the point being tested is drawn in black.  Note
+            that rounding in the arc rendering routines may cause points near
+            the boundary of the arc to render incorrectly.  Allow for a pixel
+            or two of leeway near the boundary.
+            """;
+
+        PassFailJFrame.builder()
+            .title("Test Instructions")
+            .instructions(INSTRUCTIONS)
+            .columns(40)
+            .testUI(initialize())
+            .build()
+            .awaitAndCheck();
+    }
+    private static Frame initialize() {
+        Frame f = new Frame("Arc2DHitTest");
+        ArcHitPanel panel = new ArcHitPanel();
+        f.add(panel);
+        f.setSize(300, 250);
+        return f;
+    }
+}
+
+class ArcHitPanel extends Panel {
+    private Arc2D arc;
+    private Point hit;
+    public ArcHitPanel() {
+        arc = new Arc2D.Float(10, 10, 100, 100, 0, 120, Arc2D.PIE);
+        this.addMouseListener(new MouseAdapter() {
+            public void mouseClicked(MouseEvent e) {
+                hit = e.getPoint();
+                repaint();
+            }
+        });
+    }
+
+    @Override
+    public void paint(Graphics g) {
+        Graphics2D g2 = (Graphics2D) g;
+        g2.setColor(Color.white);
+        g2.fill(g2.getClipBounds());
+        g2.setColor((hit != null && arc.contains(hit))
+            ? Color.green : Color.red);
+        g2.fill(arc);
+        if (hit != null) {
+            g2.setColor(Color.black);
+            g2.fillRect(hit.x, hit.y, 1, 1);
+        }
+    }
+}
diff --git a/test/jdk/java/awt/geom/Arc2D/BoundsBug.java b/test/jdk/java/awt/geom/Arc2D/BoundsBug.java
new file mode 100644
index 0000000000000..a17f45f9dad37
--- /dev/null
+++ b/test/jdk/java/awt/geom/Arc2D/BoundsBug.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 4197746
+ * @summary Verifies that the getBounds2D method of Arc2D returns the
+ *          correct result.
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @run main/manual BoundsBug
+ */
+
+import java.awt.Color;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Panel;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+public class BoundsBug {
+    public static void main(String[] args) throws Exception {
+        String INSTRUCTIONS = """
+            This test displays three figures and draws the outline of their
+            bounding boxes. The bounding boxes should correctly encompass
+            the 3 figures.
+
+            This test also paints two highlight rectangles at the ends of the
+            angular extents of the arc. The two highlights should correctly
+            appear at the outer circumference of the arc where the radii lines
+            from its center intersect that circumference.
+            """;
+
+        PassFailJFrame.builder()
+            .title("Test Instructions")
+            .instructions(INSTRUCTIONS)
+            .columns(40)
+            .testUI(initialize())
+            .build()
+            .awaitAndCheck();
+    }
+    private static Frame initialize() {
+        Frame f = new Frame("BoundsBug");
+        ArcPanel panel = new ArcPanel();
+        f.add(panel);
+        f.setSize(300, 250);
+        return f;
+    }
+}
+
+class ArcPanel extends Panel {
+    protected void drawPoint(Graphics2D g2, Point2D p) {
+        g2.setColor(Color.green);
+        g2.fill(new Rectangle2D.Double(p.getX() - 5, p.getY() - 5, 10, 10));
+    }
+
+    protected void drawShapeAndBounds(Graphics2D g2, Shape s) {
+        g2.setColor(Color.orange);
+        g2.fill(s);
+        g2.setColor(Color.black);
+        g2.draw(s);
+
+        Rectangle2D r = s.getBounds2D();
+        g2.setColor(Color.gray);
+        g2.draw(r);
+    }
+
+    @Override
+    public void paint(Graphics g) {
+        Graphics2D g2 = (Graphics2D)g;
+        g2.setColor(Color.white);
+        g2.fill(g.getClipBounds());
+        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+            RenderingHints.VALUE_ANTIALIAS_ON);
+
+        // Create some interesting shapes.
+        Ellipse2D ellipse = new Ellipse2D.Float(20, 40, 60, 80);
+        Arc2D arc = new Arc2D.Float(60, 40, 100, 120,
+            -30, -40, Arc2D.PIE);
+        GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
+        path.moveTo(0, 0);
+        path.lineTo(75, -25);
+        path.lineTo(25, 75);
+        path.lineTo(0, 25);
+        path.lineTo(100, 50);
+        path.lineTo(50, 0);
+        path.lineTo(25, 50);
+        path.closePath();
+        // Now draw them and their bounds rectangles.
+        drawShapeAndBounds(g2, ellipse);
+        drawShapeAndBounds(g2, arc);
+        drawPoint(g2, arc.getStartPoint());
+        drawPoint(g2, arc.getEndPoint());
+        g2.translate(180, 65);
+        drawShapeAndBounds(g2, path);
+    }
+}
diff --git a/test/jdk/java/awt/geom/Area/Translate.java b/test/jdk/java/awt/geom/Area/Translate.java
new file mode 100644
index 0000000000000..7519f1753bcf3
--- /dev/null
+++ b/test/jdk/java/awt/geom/Area/Translate.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 4183373
+ * @summary Verifies that the translated Area objects display correctly
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @run main/manual Translate
+ */
+
+import java.awt.BorderLayout;
+import java.awt.CardLayout;
+import java.awt.Color;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Panel;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Area;
+import java.awt.geom.Rectangle2D;
+
+public class Translate {
+    public static void main(String[] args) throws Exception {
+        String INSTRUCTIONS = """
+            This test displays two sets of rectangular figures. The two sets
+            should be displayed one on top of the other and should be lined
+            up vertically with each other. If the two sets of figures are
+            not directly above and below each other then the test fails
+            """;
+
+        PassFailJFrame.builder()
+            .title("Test Instructions")
+            .instructions(INSTRUCTIONS)
+            .columns(35)
+            .testUI(initialize())
+            .build()
+            .awaitAndCheck();
+    }
+    private static Frame initialize() {
+        Frame f = new Frame("Translate");
+        TranslatePanel panel = new TranslatePanel();
+        f.add(panel);
+        f.setSize(300, 250);
+        return f;
+    }
+}
+
+class TranslatePanel extends Panel {
+    private static Image bufferedImage;
+    private static Area a1, a2, a3;
+
+    public TranslatePanel() {
+        a1 = new Area(new Rectangle2D.Double(20.0, 20.0, 60.0, 60.0));
+
+        a2 = new Area((Area) a1.clone());
+        a2.subtract(new Area(new Rectangle2D.Double(30.0, 30.0, 40.0, 40.0)));
+
+        a3 = new Area((Area) a2.clone());
+        a3.add(new Area(new Rectangle2D.Double(40.0, 40.0, 20.0, 20.0)));
+
+        AffineTransform at2 = new AffineTransform();
+        at2.translate(100.0, 0.0);
+        a2.transform(at2);
+
+        AffineTransform at3 = new AffineTransform();
+        at3.translate(200.0, 0.0);
+        a3.transform(at3);
+    }
+    private void paintRects(Graphics2D g2) {
+        Rectangle clip = g2.getClipBounds();
+        g2.setColor(Color.white);
+        g2.fillRect(clip.x, clip.y, clip.width, clip.height);
+        g2.setPaint(Color.red);
+        g2.fill(a1);
+        g2.setPaint(Color.yellow);
+        g2.fill(a2);
+        g2.setPaint(Color.blue);
+        g2.fill(a3);
+    }
+
+    @Override
+    public void paint(Graphics g) {
+        if (bufferedImage == null) {
+            bufferedImage = createImage(300, 100);
+            Graphics big = bufferedImage.getGraphics();
+            // Notice that if you remove the translate() call, it works fine.
+            big.translate(-1, -1);
+            big.setClip(1, 1, 300, 100);
+            paintRects((Graphics2D)big);
+            big.translate(1, 1);
+        }
+        paintRects((Graphics2D)g);
+        g.drawImage(bufferedImage, 1, 100, this);
+        g.setColor(Color.black);
+        g.drawString("From offscreen image (with translate):", 10, 95);
+        g.drawString(" (should line up with rectangles above)", 10, 110);
+    }
+}

From c8ac6fd07f8530db57c4890133c407ef00c34b4b Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Mon, 7 Apr 2025 15:14:26 +0000
Subject: [PATCH 133/846] 8340437: Open source few more AWT Frame related tests

Backport-of: 9bd478593cc92a716151d1373f3426f1d92143bb
---
 .../awt/Frame/DisabledParentOfToplevel.java   |  99 ++++
 test/jdk/java/awt/Frame/FrameVisualTest.java  | 117 +++++
 test/jdk/java/awt/Frame/IMStatusBar.java      |  70 +++
 test/jdk/java/awt/Frame/MultiScreenTest.java  | 485 ++++++++++++++++++
 4 files changed, 771 insertions(+)
 create mode 100644 test/jdk/java/awt/Frame/DisabledParentOfToplevel.java
 create mode 100644 test/jdk/java/awt/Frame/FrameVisualTest.java
 create mode 100644 test/jdk/java/awt/Frame/IMStatusBar.java
 create mode 100644 test/jdk/java/awt/Frame/MultiScreenTest.java

diff --git a/test/jdk/java/awt/Frame/DisabledParentOfToplevel.java b/test/jdk/java/awt/Frame/DisabledParentOfToplevel.java
new file mode 100644
index 0000000000000..878809749d35a
--- /dev/null
+++ b/test/jdk/java/awt/Frame/DisabledParentOfToplevel.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.Window;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+/*
+ * @test
+ * @bug 5062118
+ * @key headful
+ * @summary Disabling of a parent should not disable Window.
+ * @run main DisabledParentOfToplevel
+ */
+
+public class DisabledParentOfToplevel {
+    private static Button okBtn;
+    private static Window ww;
+    private static Frame parentFrame;
+    private static volatile Point p;
+    private static volatile Dimension d;
+
+    public static void main(String[] args) throws Exception {
+        Robot robot = new Robot();
+        robot.setAutoDelay(100);
+        try {
+            EventQueue.invokeAndWait(() -> {
+                createAndShowUI();
+            });
+            robot.delay(1000);
+            EventQueue.invokeAndWait(() -> {
+                p = okBtn.getLocationOnScreen();
+                d = okBtn.getSize();
+            });
+            robot.mouseMove(p.x + d.width / 2, p.x + d.height / 2);
+            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+            robot.delay(500);
+            if (ww.isVisible()) {
+                throw new RuntimeException("Window is visible but should be hidden: failure.");
+            }
+        } finally {
+            EventQueue.invokeAndWait(() -> {
+                if (parentFrame != null) {
+                    parentFrame.dispose();
+                }
+            });
+        }
+    }
+
+    private static void createAndShowUI() {
+        parentFrame = new Frame("parentFrame");
+        parentFrame.setSize(100, 100);
+        parentFrame.setEnabled(false);
+        ww = new Window(parentFrame);
+        ww.setLayout(new BorderLayout());
+        okBtn = new Button("Click to Close Me");
+        ww.add(okBtn);
+        ww.setSize(250, 250);
+        ww.setLocation(110, 110);
+        okBtn.addMouseListener(new MouseAdapter() {
+            public void mousePressed(MouseEvent me) {
+                System.out.println("Pressed: close");
+                ww.setVisible(false);
+            }
+        });
+        parentFrame.setVisible(true);
+        ww.setVisible(true);
+        okBtn.requestFocus();
+    }
+}
diff --git a/test/jdk/java/awt/Frame/FrameVisualTest.java b/test/jdk/java/awt/Frame/FrameVisualTest.java
new file mode 100644
index 0000000000000..767eb0a18965c
--- /dev/null
+++ b/test/jdk/java/awt/Frame/FrameVisualTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import javax.imageio.ImageIO;
+
+/*
+ * @test
+ * @bug 4328588
+ * @key headful
+ * @summary Non-default visual on top-level Frame should work
+ * @run main FrameVisualTest
+ */
+
+public class FrameVisualTest {
+    private static GraphicsConfiguration[] gcs;
+    private static volatile Frame[] frames;
+    private static volatile int index;
+
+    private static Frame f;
+    private static Robot robot;
+    private static volatile Point p;
+    private static volatile Dimension d;
+    private static final int TOLERANCE = 5;
+
+    public static void main(String[] args) throws Exception {
+        gcs = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getConfigurations();
+        robot = new Robot();
+        robot.setAutoDelay(100);
+        try {
+            EventQueue.invokeAndWait(() -> {
+                createAndShowUI();
+            });
+            robot.delay(1000);
+            System.out.println("frames.length: "+frames.length);
+            for (index = 0; index < frames.length; index++) {
+                EventQueue.invokeAndWait(() -> {
+                    p = frames[index].getLocation();
+                    d = frames[index].getSize();
+                });
+                Rectangle rect = new Rectangle(p, d);
+                BufferedImage img = robot.createScreenCapture(rect);
+                if (chkImgBackgroundColor(img)) {
+                    try {
+                        ImageIO.write(img, "png", new File("Frame_" + index + ".png"));
+                    } catch (IOException ignored) {}
+                    throw new RuntimeException("Frame visual test failed with non-white background color");
+                }
+            }
+        } finally {
+            for (index = 0; index < frames.length; index++) {
+                EventQueue.invokeAndWait(() -> {
+                    if (frames[index] != null) {
+                        frames[index].dispose();
+                    }
+                });
+            }
+        }
+    }
+
+    private static void createAndShowUI() {
+        frames = new Frame[gcs.length];
+        for (int i = 0; i < frames.length; i++) {
+            frames[i] = new Frame("Frame w/ gc " + i, gcs[i]);
+            frames[i].setSize(100, 100);
+            frames[i].setUndecorated(true);
+            frames[i].setBackground(Color.WHITE);
+            frames[i].setVisible(true);
+        }
+    }
+
+    private static boolean chkImgBackgroundColor(BufferedImage img) {
+
+        // scan for mid-line and if it is non-white color then return true.
+        for (int x = 1; x < img.getWidth() - 1; ++x) {
+            Color c = new Color(img.getRGB(x, img.getHeight() / 2));
+            if ((c.getRed() - Color.WHITE.getRed()) > TOLERANCE &&
+                    (c.getGreen() - Color.WHITE.getGreen()) > TOLERANCE &&
+                    (c.getBlue() - Color.WHITE.getBlue()) > TOLERANCE) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
+
diff --git a/test/jdk/java/awt/Frame/IMStatusBar.java b/test/jdk/java/awt/Frame/IMStatusBar.java
new file mode 100644
index 0000000000000..7e882d01c707c
--- /dev/null
+++ b/test/jdk/java/awt/Frame/IMStatusBar.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.BorderLayout;
+import java.awt.Frame;
+import java.awt.Label;
+import java.awt.Panel;
+import java.awt.TextField;
+
+/*
+ * @test
+ * @bug 4113040
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @summary Checks that IMStatusBar does not affect Frame layout
+ * @run main/manual/othervm -Duser.language=ja -Duser.country=JP IMStatusBar
+ */
+
+public class IMStatusBar {
+
+    public static void main(String[] args) throws Exception {
+        String INSTRUCTIONS = """
+                If the window appears the right size, but then resizes so that the
+                status field overlaps the bottom label, press Fail; otherwise press Pass.
+                """;
+
+        PassFailJFrame.builder()
+                .title("IMStatusBar Instruction")
+                .instructions(INSTRUCTIONS)
+                .rows((int) INSTRUCTIONS.lines().count() + 2)
+                .columns(40)
+                .testUI(IMStatusBar::createUI)
+                .build()
+                .awaitAndCheck();
+    }
+
+    private static Frame createUI() {
+        Frame f = new Frame();
+        Panel centerPanel = new Panel();
+        f.setSize(200, 200);
+        f.setLayout(new BorderLayout());
+        f.add(new Label("Top"), BorderLayout.NORTH);
+        f.add(centerPanel, BorderLayout.CENTER);
+        f.add(new Label("Bottom"), BorderLayout.SOUTH);
+        centerPanel.setLayout(new BorderLayout());
+        centerPanel.add(new TextField("Middle"), BorderLayout.CENTER);
+        centerPanel.validate();
+        return f;
+    }
+}
diff --git a/test/jdk/java/awt/Frame/MultiScreenTest.java b/test/jdk/java/awt/Frame/MultiScreenTest.java
new file mode 100644
index 0000000000000..845f601138b74
--- /dev/null
+++ b/test/jdk/java/awt/Frame/MultiScreenTest.java
@@ -0,0 +1,485 @@
+/*
+ * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Canvas;
+import java.awt.Choice;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.FontMetrics;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Label;
+import java.awt.LayoutManager;
+import java.awt.Panel;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.TextField;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import java.awt.image.ColorModel;
+import java.awt.image.MemoryImageSource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JFrame;
+
+import jtreg.SkippedException;
+
+/*
+ * @test
+ * @bug 4312921
+ * @key multimon
+ * @library /java/awt/regtesthelpers /test/lib
+ * @build PassFailJFrame
+ * @summary Tests that no garbage is painted on primary screen with DGA
+ * @run main/manual MultiScreenTest
+ */
+
+public class MultiScreenTest {
+    static GraphicsEnvironment ge;
+    static GraphicsDevice[] gs;
+
+    public static void main(String[] args) throws Exception {
+        ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+        gs = ge.getScreenDevices();
+        if (gs.length < 2) {
+            throw new SkippedException("You have only one monitor in your system - test passed");
+        }
+        MultiScreenTest obj = new MultiScreenTest();
+        String INSTRUCTIONS =
+                "This test is to be run only on multiscreen machine. " +
+                "You have " + gs.length + " monitors in your system.\n" +
+                "Actively drag the DitherTest frames on the secondary screen and " +
+                "if you see garbage appearing on your primary screen " +
+                "test failed otherwise it passed.";;
+
+        PassFailJFrame.builder()
+                .title("MultiScreenTest Instruction")
+                .instructions(INSTRUCTIONS)
+                .rows((int) INSTRUCTIONS.lines().count() + 2)
+                .columns(40)
+                .testUI(obj::init)
+                .build()
+                .awaitAndCheck();
+    }
+
+    public List init() {
+        List list = new ArrayList<>();
+        for (int j = 0; j < gs.length; j++) {
+            GraphicsConfiguration[] gc = gs[j].getConfigurations();
+            if (gc.length > 0) {
+                for (int i = 0; i < gc.length / 2; i++) {
+                    JFrame f = new JFrame(gc[i]); //test JFrame( gc )
+                    GCCanvas c = new GCCanvas(gc[i]);//test canvas( gc )
+                    Rectangle gcBounds = gc[i].getBounds(); //test getBounds()
+                    int xoffs = gcBounds.x;
+                    int yoffs = gcBounds.y;
+
+                    f.getContentPane().add(c);
+                    f.setTitle("Screen# " + Integer.toString(j) + ", GC#" + Integer.toString(i));
+                    f.setSize(300, 200);
+                    f.setLocation(400 + xoffs, (i * 150) + yoffs);//test displaying in right location
+                    list.add(f);
+
+                    Frame ditherfs = new Frame("DitherTest GC#" + Integer.toString(i), gc[i]);
+                    ditherfs.setLayout(new BorderLayout()); //showDitherTest
+                    DitherTest ditherTest = new DitherTest(gc[i]);
+                    ditherfs.add("Center", ditherTest);
+                    ditherfs.setBounds(300, 200, 300, 200);
+                    ditherfs.setLocation(750 + xoffs, (i * 50) + yoffs);
+                    ditherfs.pack();
+                    ditherfs.show();
+                    ditherTest.start();
+                }
+            }
+        }
+        return list;
+    }
+}
+
+class GCCanvas extends Canvas {
+
+    GraphicsConfiguration gc;
+    Rectangle bounds;
+    Graphics g = this.getGraphics();
+    Dimension size = getSize();
+
+    public GCCanvas(GraphicsConfiguration gc) {
+        super(gc);
+        this.gc = gc;
+        bounds = gc.getBounds();
+    }
+
+    public void paint( Graphics _g ) {
+
+        Graphics2D g = (Graphics2D) _g;
+
+        g.drawRect(0, 0, size.width-1, size.height-1);
+        g.setColor(Color.lightGray);
+        g.draw3DRect(1, 1, size.width-3, size.height-3, true);
+
+        g.setColor(Color.red);
+        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+
+        g.drawString("HELLO!", 110, 10);
+
+        g.setColor(Color.blue);
+        g.drawString("ScreenSize="+Integer.toString(bounds.width)+"X"+
+                     Integer.toString(bounds.height), 10, 20);
+        g.setColor(Color.green);
+        g.drawString(gc.toString(), 10, 30);
+        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+
+        g.setColor(Color.orange);
+        g.fillRect(40, 20, 50, 50);
+
+        g.setColor(Color.red);
+        g.drawRect(100, 20, 30, 30);
+
+        g.setColor(Color.gray);
+        g.drawLine(220, 20, 280, 40);
+
+        g.setColor(Color.cyan);
+        g.fillArc(150, 30, 30, 30, 0, 200);
+    }
+
+    public Dimension getPreferredSize(){
+         return new Dimension(300, 200);
+    }
+}
+
+class DitherCanvas extends Canvas {
+    Image img;
+    static String calcString = "Calculating...";
+
+    GraphicsConfiguration mGC;
+
+    public DitherCanvas(GraphicsConfiguration gc) {
+        super(gc);
+        mGC = gc;
+    }
+
+    public GraphicsConfiguration getGraphicsConfig() {
+        return mGC;
+    }
+
+    public void paint(Graphics g) {
+        int w = getSize().width;
+        int h = getSize().height;
+        if (img == null) {
+            super.paint(g);
+            g.setColor(Color.black);
+            FontMetrics fm = g.getFontMetrics();
+            int x = (w - fm.stringWidth(calcString)) / 2;
+            int y = h / 2;
+            g.drawString(calcString, x, y);
+        } else {
+            g.drawImage(img, 0, 0, w, h, this);
+        }
+    }
+
+    public void update(Graphics g) {
+        paint(g);
+    }
+
+    public Dimension getMinimumSize() {
+        return new Dimension(20, 20);
+    }
+
+    public Dimension getPreferredSize() {
+        return new Dimension(200, 200);
+    }
+
+    public Image getImage() {
+        return img;
+    }
+
+    public void setImage(Image img) {
+        this.img = img;
+        paint(getGraphics());
+    }
+}
+
+class DitherTest extends Panel implements Runnable {
+    final static int NOOP = 0;
+    final static int RED = 1;
+    final static int GREEN = 2;
+    final static int BLUE = 3;
+    final static int ALPHA = 4;
+    final static int SATURATION = 5;
+
+    Thread runner;
+
+    DitherControls XControls;
+    DitherControls YControls;
+    DitherCanvas canvas;
+
+    public DitherTest(GraphicsConfiguration gc) {
+        String xspec, yspec;
+        int xvals[] = new int[2];
+        int yvals[] = new int[2];
+
+        xspec = "red";
+        yspec = "blue";
+        int xmethod = colormethod(xspec, xvals);
+        int ymethod = colormethod(yspec, yvals);
+
+        setLayout(new BorderLayout());
+        XControls = new DitherControls(this, xvals[0], xvals[1],
+                xmethod, false);
+        YControls = new DitherControls(this, yvals[0], yvals[1],
+                ymethod, true);
+        YControls.addRenderButton();
+        add("North", XControls);
+        add("South", YControls);
+        add("Center", canvas = new DitherCanvas(gc));
+    }
+
+    public void start() {
+        runner = new Thread(this);
+        runner.start();
+    }
+
+    int colormethod(String s, int vals[]) {
+        int method = NOOP;
+
+        if (s == null) {
+            s = "";
+        }
+
+        String lower = s.toLowerCase();
+        int len = 0;
+        if (lower.startsWith("red")) {
+            method = RED;
+            lower = lower.substring(3);
+        } else if (lower.startsWith("green")) {
+            method = GREEN;
+            lower = lower.substring(5);
+        } else if (lower.startsWith("blue")) {
+            method = BLUE;
+            lower = lower.substring(4);
+        } else if (lower.startsWith("alpha")) {
+            method = ALPHA;
+            lower = lower.substring(4);
+        } else if (lower.startsWith("saturation")) {
+            method = SATURATION;
+            lower = lower.substring(10);
+        }
+
+        if (method == NOOP) {
+            vals[0] = 0;
+            vals[1] = 0;
+            return method;
+        }
+
+        int begval = 0;
+        int endval = 255;
+
+        try {
+            int dash = lower.indexOf('-');
+            if (dash < 0) {
+                begval = endval = Integer.parseInt(lower);
+            } else {
+                begval = Integer.parseInt(lower.substring(0, dash));
+                endval = Integer.parseInt(lower.substring(dash + 1));
+            }
+        } catch (Exception e) {
+        }
+
+        if (begval < 0) {
+            begval = 0;
+        }
+        if (endval < 0) {
+            endval = 0;
+        }
+        if (begval > 255) {
+            begval = 255;
+        }
+        if (endval > 255) {
+            endval = 255;
+        }
+
+        vals[0] = begval;
+        vals[1] = endval;
+
+        return method;
+    }
+
+    void applymethod(int c[], int method, int step, int total, int vals[]) {
+        if (method == NOOP)
+            return;
+        int val = ((total < 2)
+                ? vals[0]
+                : vals[0] + ((vals[1] - vals[0]) * step / (total - 1)));
+        switch (method) {
+            case RED:
+                c[0] = val;
+                break;
+            case GREEN:
+                c[1] = val;
+                break;
+            case BLUE:
+                c[2] = val;
+                break;
+            case ALPHA:
+                c[3] = val;
+                break;
+            case SATURATION:
+                int max = Math.max(Math.max(c[0], c[1]), c[2]);
+                int min = max * (255 - val) / 255;
+                if (c[0] == 0) {
+                    c[0] = min;
+                }
+                if (c[1] == 0) {
+                    c[1] = min;
+                }
+                if (c[2] == 0) {
+                    c[2] = min;
+                }
+                break;
+        }
+    }
+
+    public void run() {
+        canvas.setImage(null);  // Wipe previous image
+        Image img = calculateImage();
+        synchronized (this) {
+            if (img != null && runner == Thread.currentThread()) {
+                canvas.setImage(img);
+            }
+        }
+    }
+
+    /**
+     * Calculates and returns the image.  Halts the calculation and returns
+     * null if stopped during the calculation.
+     */
+    Image calculateImage() {
+        Thread me = Thread.currentThread();
+
+        int width = canvas.getSize().width;
+        int height = canvas.getSize().height;
+        int xvals[] = new int[2];
+        int yvals[] = new int[2];
+        int xmethod = XControls.getParams(xvals);
+        int ymethod = YControls.getParams(yvals);
+        int pixels[] = new int[width * height];
+        int c[] = new int[4];
+        int index = 0;
+
+        for (int j = 0; j < height; j++) {
+            for (int i = 0; i < width; i++) {
+                c[0] = c[1] = c[2] = 0;
+                c[3] = 255;
+                if (xmethod < ymethod) {
+                    applymethod(c, xmethod, i, width, xvals);
+                    applymethod(c, ymethod, j, height, yvals);
+                } else {
+                    applymethod(c, ymethod, j, height, yvals);
+                    applymethod(c, xmethod, i, width, xvals);
+                }
+                pixels[index++] = ((c[3] << 24) |
+                        (c[0] << 16) |
+                        (c[1] << 8) |
+                        (c[2] << 0));
+
+            }
+            // Poll once per row to see if we've been told to stop.
+            if (runner != me) {
+                return null;
+            }
+        }
+
+        return createImage(new MemoryImageSource(width, height,
+                ColorModel.getRGBdefault(), pixels, 0, width));
+    }
+
+    public String getInfo() {
+        return "An interactive demonstration of dithering.";
+    }
+
+    public String[][] getParameterInfo() {
+        String[][] info = {
+                {"xaxis", "{RED, GREEN, BLUE, PINK, ORANGE, MAGENTA, CYAN, WHITE, YELLOW, GRAY, DARKGRAY}",
+                 "The color of the Y axis.  Default is RED."},
+                {"yaxis", "{RED, GREEN, BLUE, PINK, ORANGE, MAGENTA, CYAN, WHITE, YELLOW, GRAY, DARKGRAY}",
+                 "The color of the X axis.  Default is BLUE."}
+        };
+        return info;
+    }
+}
+
+class DitherControls extends Panel implements ActionListener {
+    TextField start;
+    TextField end;
+    Button button;
+    Choice choice;
+    DitherTest dt;
+
+    static LayoutManager dcLayout = new FlowLayout(FlowLayout.CENTER, 10, 5);
+
+    public DitherControls(DitherTest app, int s, int e, int type,
+                          boolean vertical) {
+        dt = app;
+        setLayout(dcLayout);
+        add(new Label(vertical ? "Vertical" : "Horizontal"));
+        add(choice = new Choice());
+        choice.addItem("Noop");
+        choice.addItem("Red");
+        choice.addItem("Green");
+        choice.addItem("Blue");
+        choice.addItem("Alpha");
+        choice.addItem("Saturation");
+        choice.select(type);
+        add(start = new TextField(Integer.toString(s), 4));
+        add(end = new TextField(Integer.toString(e), 4));
+    }
+
+    public void addRenderButton() {
+        add(button = new Button("New Image"));
+        button.addActionListener(this);
+    }
+
+    public int getParams(int vals[]) {
+        vals[0] = Integer.parseInt(start.getText());
+        vals[1] = Integer.parseInt(end.getText());
+        return choice.getSelectedIndex();
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        if (e.getSource() == button) {
+            dt.start();
+        }
+    }
+}

From 8c5fa69897ccbd920d5a1bc508f87697efc96357 Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Mon, 7 Apr 2025 15:15:34 +0000
Subject: [PATCH 134/846] 8353714: [17u] Backport of 8347740 incomplete

Reviewed-by: mbaesken
---
 test/jdk/java/io/File/createTempFile/SpecialTempFile.java | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/test/jdk/java/io/File/createTempFile/SpecialTempFile.java b/test/jdk/java/io/File/createTempFile/SpecialTempFile.java
index 532d3389da38f..a5d903cb4e2b6 100644
--- a/test/jdk/java/io/File/createTempFile/SpecialTempFile.java
+++ b/test/jdk/java/io/File/createTempFile/SpecialTempFile.java
@@ -117,10 +117,6 @@ public static void main(String[] args) throws Exception {
         // Test JDK-8013827
         String[] resvPre = { "LPT1.package.zip", "com7.4.package.zip" };
         String[] resvSuf = { ".temp", ".temp" };
-        boolean exceptionExpected =
-            !(System.getProperty("os.name").matches("^.*[11|2025]$") ||
-              new OSVersion(10, 0).compareTo(OSVersion.current()) > 0);
-        test("ReservedName", resvPre, resvSuf, exceptionExpected);
 
         System.out.println("OS name:    " + System.getProperty("os.name") + "\n" +
                            "OS version: " + OSVersion.current());

From da0dd4627474be464c4a5bcb99a6b7c8cefb4939 Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Mon, 7 Apr 2025 15:16:00 +0000
Subject: [PATCH 135/846] 8341239: Open source closed frame tests # 3

Backport-of: ff3e849b8a1de3741dcd728636e1a804996f96fe
---
 .../jdk/java/awt/Frame/FrameMenuPackTest.java |  99 +++++++++++++++++
 .../FrameResizeTest/FrameResizeTest_3.java    |  86 ++++++++++++++
 .../FrameResizeTest/FrameResizeTest_4.java    |  76 +++++++++++++
 .../FrameResizeTest/FrameResizeTest_5.java    | 105 ++++++++++++++++++
 4 files changed, 366 insertions(+)
 create mode 100644 test/jdk/java/awt/Frame/FrameMenuPackTest.java
 create mode 100644 test/jdk/java/awt/Frame/FrameResizeTest/FrameResizeTest_3.java
 create mode 100644 test/jdk/java/awt/Frame/FrameResizeTest/FrameResizeTest_4.java
 create mode 100644 test/jdk/java/awt/Frame/FrameResizeTest/FrameResizeTest_5.java

diff --git a/test/jdk/java/awt/Frame/FrameMenuPackTest.java b/test/jdk/java/awt/Frame/FrameMenuPackTest.java
new file mode 100644
index 0000000000000..c034acd8eb710
--- /dev/null
+++ b/test/jdk/java/awt/Frame/FrameMenuPackTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.BorderLayout;
+import java.awt.Frame;
+import java.awt.Label;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
+import java.awt.ScrollPane;
+import java.awt.Window;
+import java.util.List;
+
+/*
+ * @test
+ * @bug 4084766
+ * @summary Test for bug(s): 4084766
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @run main/manual FrameMenuPackTest
+ */
+
+public class FrameMenuPackTest {
+    private static final String INSTRUCTIONS = """
+            Check that both frames that appear are properly packed with
+            the scrollpane visible.
+            """;
+
+    public static void main(String[] argv) throws Exception {
+        PassFailJFrame.builder()
+                .title("FrameMenuPackTest Instructions")
+                .instructions(INSTRUCTIONS)
+                .columns(45)
+                .testUI(FrameMenuPackTest::createAndShowUI)
+                .positionTestUIRightRow()
+                .build()
+                .awaitAndCheck();
+    }
+
+    private static List createAndShowUI() {
+        // Frame without menu, packs correctly
+        PackedFrame f1 = new PackedFrame(false);
+        f1.pack();
+
+        // Frame with menu, doesn't pack right
+        PackedFrame f2 = new PackedFrame(true);
+        f2.pack();
+
+        return List.of(f1, f2);
+    }
+
+    private static class PackedFrame extends Frame {
+        public PackedFrame(boolean withMenu) {
+            super("PackedFrame");
+
+            MenuBar menubar;
+            Menu fileMenu;
+            MenuItem foo;
+            ScrollPane sp;
+
+            sp = new ScrollPane();
+            sp.add(new Label("Label in ScrollPane"));
+            System.out.println(sp.getMinimumSize());
+
+            this.setLayout(new BorderLayout());
+            this.add(sp, "Center");
+            this.add(new Label("Label in Frame"), "South");
+
+            if (withMenu) {
+                menubar = new MenuBar();
+                fileMenu = new Menu("File");
+                foo = new MenuItem("foo");
+                fileMenu.add(foo);
+                menubar.add(fileMenu);
+                this.setMenuBar(menubar);
+            }
+        }
+    }
+}
diff --git a/test/jdk/java/awt/Frame/FrameResizeTest/FrameResizeTest_3.java b/test/jdk/java/awt/Frame/FrameResizeTest/FrameResizeTest_3.java
new file mode 100644
index 0000000000000..6fdef005775a5
--- /dev/null
+++ b/test/jdk/java/awt/Frame/FrameResizeTest/FrameResizeTest_3.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Button;
+import java.awt.Frame;
+import java.awt.GridLayout;
+import java.awt.Window;
+import java.awt.event.ActionListener;
+
+/*
+ * @test
+ * @bug 4097207
+ * @summary setSize() on a Frame does not resize its content
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @run main/manual FrameResizeTest_3
+*/
+
+public class FrameResizeTest_3 {
+
+    private static final String INSTRUCTIONS = """
+            1. You would see a frame titled 'TestFrame' with 2 buttons
+               named 'setSize(500,500)' and 'setSize(400,400)'
+            2. Click any button and you would see the frame resized
+            3. If the buttons get resized along with the frame
+               (ie., to fit the frame), press Pass else press Fail.
+            """;
+
+    public static void main(String[] args) throws Exception {
+        PassFailJFrame.builder()
+                .title("FrameResizeTest_3 Instructions")
+                .instructions(INSTRUCTIONS)
+                .columns(45)
+                .logArea(6)
+                .testUI(FrameResizeTest_3::createTestUI)
+                .build()
+                .awaitAndCheck();
+    }
+
+    private static Window createTestUI() {
+        Frame frame = new Frame("TestFrame");
+        frame.setLayout(new GridLayout(2, 1));
+
+        Button butSize500 = new Button("setSize(500,500)");
+        Button butSize400 = new Button("setSize(400,400)");
+
+        ActionListener actionListener = e -> {
+            if (e.getSource() instanceof Button) {
+                if (e.getSource() == butSize500) {
+                    frame.setSize(500, 500);
+                    PassFailJFrame.log("New bounds: " + frame.getBounds());
+                } else if (e.getSource() == butSize400) {
+                    frame.setSize(400, 400);
+                    PassFailJFrame.log("New bounds: " + frame.getBounds());
+                }
+            }
+        };
+        butSize500.addActionListener(actionListener);
+        butSize400.addActionListener(actionListener);
+        frame.add(butSize500);
+        frame.add(butSize400);
+
+        frame.setSize(270, 200);
+        return frame;
+    }
+}
diff --git a/test/jdk/java/awt/Frame/FrameResizeTest/FrameResizeTest_4.java b/test/jdk/java/awt/Frame/FrameResizeTest/FrameResizeTest_4.java
new file mode 100644
index 0000000000000..4428feee3355b
--- /dev/null
+++ b/test/jdk/java/awt/Frame/FrameResizeTest/FrameResizeTest_4.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/* Note that although this test makes use of Swing classes, like JFrame and */
+/* JButton, it is really an AWT test, because it tests mechanism of sending */
+/* paint events. */
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import java.awt.BorderLayout;
+
+/*
+ * @test
+ * @bug 4174831
+ * @summary Tests that frame do not flicker on diagonal resize
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @run main/manual FrameResizeTest_4
+ */
+
+public class FrameResizeTest_4 {
+    private static final String INSTRUCTIONS = """
+          Try enlarging the frame diagonally.
+          If buttons inside frame excessively repaint themselves and flicker
+          while you enlarge frame, the test fails.
+          Otherwise, it passes.
+          """;
+
+    public static void main(String[] args) throws Exception {
+        PassFailJFrame.builder()
+                .title("FrameResizeTest_4 Instructions")
+                .instructions(INSTRUCTIONS)
+                .columns(45)
+                .testUI(FrameResizeTest_4::createTestUI)
+                .build()
+                .awaitAndCheck();
+    }
+
+    private static JFrame createTestUI() {
+        JFrame f = new JFrame("FrameResizeTest_4 Flickering Frame");
+
+        JPanel panel = new JPanel(new BorderLayout());
+        panel.add(new JButton("West"), BorderLayout.WEST);
+        panel.add(new JButton("East"), BorderLayout.EAST);
+        panel.add(new JButton("North"), BorderLayout.NORTH);
+        panel.add(new JButton("South"), BorderLayout.SOUTH);
+        panel.add(new JButton("Center"), BorderLayout.CENTER);
+        f.setContentPane(panel);
+
+        f.pack();
+        f.setBounds(100, 50, 300, 200);
+
+        return f;
+    }
+}
diff --git a/test/jdk/java/awt/Frame/FrameResizeTest/FrameResizeTest_5.java b/test/jdk/java/awt/Frame/FrameResizeTest/FrameResizeTest_5.java
new file mode 100644
index 0000000000000..5a43b755a5212
--- /dev/null
+++ b/test/jdk/java/awt/Frame/FrameResizeTest/FrameResizeTest_5.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Button;
+import java.awt.Frame;
+import java.awt.GridLayout;
+
+/*
+ * @test
+ * @summary Test to make sure non-resizable Frames can be resized with the
+ *          setSize() method.
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @run main/manual FrameResizeTest_5
+*/
+
+public class FrameResizeTest_5  {
+    private static final String INSTRUCTIONS = """
+            This tests the programmatic resizability of non-resizable Frames.
+            Even when a Frame is set to be non-resizable, it should still be
+            programmatically resizable using the setSize() method.
+
+            Initially the Frame will be resizable.  Try using the "Smaller"
+            and "Larger" buttons to verify that the Frame resizes correctly.
+            Then, click the "Toggle" button to make the Frame non-resizable.
+            Again, verify that clicking the "Larger" and "Smaller" buttons
+            causes the Frame to get larger and smaller.  If the Frame does
+            not change size, or does not re-layout correctly, the test fails.
+            """;
+
+    public static void main(String[] args) throws Exception {
+        PassFailJFrame.builder()
+                .title("FrameResizeTest_5 Instructions")
+                .instructions(INSTRUCTIONS)
+                .columns(45)
+                .logArea(6)
+                .testUI(TestFrame::new)
+                .build()
+                .awaitAndCheck();
+    }
+
+    private static class TestFrame extends Frame {
+        Button bLarger, bSmaller, bCheck, bToggle;
+
+        public TestFrame() {
+            super("Frame Resize Test");
+            setSize(200, 200);
+            bLarger = new Button("Larger");
+            bLarger.addActionListener(e -> {
+                setSize(400, 400);
+                validate();
+            });
+            bSmaller = new Button("Smaller");
+            bSmaller.addActionListener(e -> {
+                setSize(200, 100);
+                validate();
+            });
+            bCheck = new Button("Resizable?");
+            bCheck.addActionListener(e -> {
+                if (isResizable()) {
+                    PassFailJFrame.log("Frame is resizable");
+                    setResizable(true);
+                } else {
+                    PassFailJFrame.log("Frame is not resizable");
+                    setResizable(false);
+                }
+            });
+            bToggle = new Button("Toggle");
+            bToggle.addActionListener(e -> {
+                if (isResizable()) {
+                    PassFailJFrame.log("Frame is now not resizable");
+                    setResizable(false);
+                } else {
+                    PassFailJFrame.log("Frame is now resizable");
+                    setResizable(true);
+                }
+            });
+            setLayout(new GridLayout(4, 1));
+            add(bSmaller);
+            add(bLarger);
+            add(bCheck);
+            add(bToggle);
+        }
+    }
+}

From 26ff4f5f5969662f8387293466ff1c1892ff5a9e Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Mon, 7 Apr 2025 15:17:13 +0000
Subject: [PATCH 136/846] 8340625: Open source additional Component tests (part
 3)

Backport-of: ebb4759c3d2776f5e6e83f743a7891a145f8aee4
---
 .../PaintGlitchTest/PaintGlitchTest.java      | 225 +++++++++
 .../Component/ProcessEvent/ProcessEvent.java  | 455 ++++++++++++++++++
 .../SetFontOrBackground/SetBgrFnt.java        | 123 +++++
 3 files changed, 803 insertions(+)
 create mode 100644 test/jdk/java/awt/Component/PaintGlitchTest/PaintGlitchTest.java
 create mode 100644 test/jdk/java/awt/Component/ProcessEvent/ProcessEvent.java
 create mode 100644 test/jdk/java/awt/Component/SetFontOrBackground/SetBgrFnt.java

diff --git a/test/jdk/java/awt/Component/PaintGlitchTest/PaintGlitchTest.java b/test/jdk/java/awt/Component/PaintGlitchTest/PaintGlitchTest.java
new file mode 100644
index 0000000000000..867d82d326297
--- /dev/null
+++ b/test/jdk/java/awt/Component/PaintGlitchTest/PaintGlitchTest.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 4045781
+ * @summary Exposed/damaged canvases don't always update correctly
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @run main/manual PaintGlitchTest
+ */
+
+import java.awt.Button;
+import java.awt.Canvas;
+import java.awt.Checkbox;
+import java.awt.Choice;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Label;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
+import java.awt.Panel;
+import java.awt.Scrollbar;
+import java.awt.TextArea;
+import java.awt.TextField;
+import java.lang.reflect.InvocationTargetException;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollBar;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+
+public class PaintGlitchTest extends Frame {
+    static final String INSTRUCTIONS = """
+               1. Click on the 'Painting Glitch Test' window  and select from
+                  its menu a content type (text, gradient, fill,
+                  AWT components, Swing components etc.).
+               2. Select 'Modal Dialog...' to create a dialog.
+               3. Drag the dialog over the content very fast
+                  for 10 seconds or so - make sure you
+                  keep dragging while the content is painting.
+               4. Verify that the area exposed by the drag (the damaged regions)
+                  always update properly no white areas or bits of the dialog
+                  should be left after the drag operation is
+                  completed (i.e. after you let go of the mouse).
+               5. Repeat for all other content types.
+               6. If for any content type the damaged dialog is not properly
+                  repainted press Fail. Otherwise press Pass.
+            """;
+
+    public PaintGlitchTest() {
+        super("Painting Glitch Test");
+
+        TextPanel textPanel = new TextPanel();
+        GradientPanel gradientPanel = new GradientPanel();
+        ComponentPanel componentPanel = new ComponentPanel();
+        SwingPanel swingPanel = new SwingPanel();
+
+        add(textPanel);
+
+        MenuBar menubar = new MenuBar();
+        Menu testMenu = new Menu("Test");
+        testMenu.add(makeContentItem("Text Lines", textPanel) );
+        testMenu.add(makeContentItem("Gradient Fill", gradientPanel) );
+        testMenu.add(makeContentItem("AWT Components", componentPanel) );
+        testMenu.add(makeContentItem("Swing Components", swingPanel) );
+        testMenu.addSeparator();
+        MenuItem dialogItem = new MenuItem("Modal Dialog...");
+        dialogItem.addActionListener(ev -> new ObscuringDialog(PaintGlitchTest.this).show());
+        testMenu.add(dialogItem);
+        testMenu.addSeparator();
+        menubar.add(testMenu);
+
+        setMenuBar(menubar);
+        setSize(400,300);
+    }
+
+    public static void main(String args[]) throws InterruptedException,
+            InvocationTargetException {
+        PassFailJFrame.builder()
+                .title("Repaint Glitch")
+                .testUI(PaintGlitchTest::new)
+                .instructions(INSTRUCTIONS)
+                .columns(40)
+                .logArea()
+                .build()
+                .awaitAndCheck();
+    }
+
+    public MenuItem makeContentItem(String title, final Component content) {
+        MenuItem menuItem = new MenuItem(title);
+        menuItem.addActionListener(
+                ev -> {
+                    remove(0);
+                    add(content);
+                    validate();
+                }
+        );
+
+        return menuItem;
+    }
+}
+
+class GradientPanel extends Canvas {
+    public void paint(Graphics g) {
+        long ms = System.currentTimeMillis();
+        // just paint something that'll take a while
+        int x, y;
+        int width = getSize().width;
+        int height = getSize().height;
+        int step = 8;
+
+        for (x = 0; x < width; x += step) {
+            for (y = 0; y < height; y += step) {
+                int red = (255 * y) / height;
+                int green = (255 * x * y) / (width * height);
+                int blue = (255 * x) / width;
+
+                Color   color = new Color(red, green, blue);
+                g.setColor(color);
+                g.fillRect(x, y, step, step);
+            }
+        }
+        long time = System.currentTimeMillis() - ms;
+        PassFailJFrame.log("GradientPanel paint took " + time + " ms");
+    }
+
+    public Dimension getPreferredSize() {
+        return new Dimension(200,1000);
+    }
+}
+
+class TextPanel extends Canvas {
+    public void paint(Graphics g) {
+        long ms = System.currentTimeMillis();
+        Font font = new Font("SanSerif", Font.ITALIC, 12);
+
+        g.setFont(font);
+        // just paint something that'll take a while
+        int x, y;
+        int height = getHeight();
+        int step = 16;
+
+        for (x = y = 0; y < height; y += step) {
+            g.drawString(y + " : The quick brown fox jumps over the lazy dog. " +
+                    "The rain in Spain falls mainly on the plain.", x, y);
+        }
+        long time = System.currentTimeMillis() - ms;
+        PassFailJFrame.log("TextPanel paint took " + time + " ms");
+    }
+
+    public Dimension getPreferredSize() {
+        return new Dimension(640,1000);
+    }
+}
+
+class ComponentPanel extends Panel {
+    ComponentPanel() {
+        add(new Label("Label"));
+        add(new Button("Button"));
+        add(new Checkbox("Checkbox"));
+        Choice c = new Choice();
+        c.add("choice");
+        java.awt.List l = new java.awt.List();
+        l.add("list");
+        add(new Scrollbar());
+        add(new TextField("TextField"));
+        add(new TextArea("TextArea"));
+        add(new Panel());
+        add(new Canvas());
+    }
+}
+
+class SwingPanel extends JPanel {
+    SwingPanel() {
+        add(new JLabel("JLabel"));
+        add(new JButton("JButton"));
+        add(new JCheckBox("JCheckBox"));
+        JComboBox c = new JComboBox();
+        JList l = new JList();
+        add(new JScrollBar());
+        add(new JTextField("This is a JTextField with some text in it to make it longer."));
+        add(new JTextArea("This is a JTextArea with some text in it to make it longer."));
+    }
+}
+
+class ObscuringDialog extends Dialog {
+    ObscuringDialog(Frame f) {
+        super(f, "Obscuring Dialog");
+        Button ok = new Button("OK, go away");
+        ok.addActionListener(ev -> dispose());
+        add(ok);
+        pack();
+    }
+}
diff --git a/test/jdk/java/awt/Component/ProcessEvent/ProcessEvent.java b/test/jdk/java/awt/Component/ProcessEvent/ProcessEvent.java
new file mode 100644
index 0000000000000..3dfd5a0403804
--- /dev/null
+++ b/test/jdk/java/awt/Component/ProcessEvent/ProcessEvent.java
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 4292099
+ * @summary AWT Event delivery to processEvent
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @run main/manual ProcessEvent
+ */
+
+import java.awt.AWTEvent;
+import java.awt.AWTEventMulticaster;
+import java.awt.Adjustable;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.ItemSelectable;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.TextEvent;
+import java.awt.event.TextListener;
+import java.lang.reflect.InvocationTargetException;
+
+public class ProcessEvent extends Frame {
+
+    static final String INSTRUCTIONS = """
+                Press each of the four buttons for ActionEvent, AdjustmentEvent,
+                ItemEvent and TextEvent. If a message for each corresponding event
+                appears in the log area and says the event listener was
+                called, then press Pass otherwise press Fail.
+            """;
+    ActionBtn af;
+    AdjustmentBtn adjf;
+    ItemBtn itf;
+    TextBtn txtf;
+
+    public ProcessEvent() {
+        setLayout(new FlowLayout());
+        add(af = new ActionBtn());
+        af.setBackground(Color.green);
+
+        add(adjf = new AdjustmentBtn());
+        adjf.setBackground(Color.green);
+
+        add(itf = new ItemBtn());
+        itf.setBackground(Color.green);
+
+        add(txtf = new TextBtn());
+        txtf.setBackground(Color.green);
+
+        // These action listeners simply provide feedback of when
+        // the event is delivered properly.
+        af.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent ae) {
+                PassFailJFrame.log(af.getText()
+                        + ": action listener called: "
+                        + ae.toString());
+            }
+        });
+
+        adjf.addAdjustmentListener(new AdjustmentListener() {
+            public void adjustmentValueChanged(AdjustmentEvent ae) {
+                PassFailJFrame.log(adjf.getText()
+                        + ": adjustment listener called: "
+                        + ae.toString());
+            }
+        });
+
+        itf.addItemListener(new ItemListener() {
+            public void itemStateChanged(ItemEvent e) {
+                PassFailJFrame.log(itf.getText()
+                        + ": item listener called: "
+                        + e.toString());
+            }
+        });
+
+        txtf.addTextListener(new TextListener() {
+            public void textValueChanged(TextEvent e) {
+                PassFailJFrame.log(txtf.getText()
+                        + ": text listener called: "
+                        + e.toString());
+            }
+        });
+
+        pack();
+    }
+
+    public static void main(String[] args) throws InterruptedException,
+            InvocationTargetException {
+        PassFailJFrame.builder()
+                .title("Process Events Test")
+                .testUI(ProcessEvent::new)
+                .instructions(INSTRUCTIONS)
+                .columns(40)
+                .logArea()
+                .build()
+                .awaitAndCheck();
+    }
+}
+
+class ButtonComponent extends Component implements ItemSelectable, Adjustable {
+
+    transient protected TextListener textListener;
+    transient ActionListener actionListener;
+    transient AdjustmentListener adjustmentListener;
+    transient ItemListener itemListener;
+    String actionCommand = null;
+
+    String text = null;
+
+    public ButtonComponent(String label) {
+        super();
+        text = label;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public Dimension getPreferredSize() {
+        return new Dimension(200, 30);
+    }
+
+    public Dimension getMinimumSize() {
+        return getPreferredSize();
+    }
+
+    public String getActionCommand() {
+        if (actionCommand == null)
+            return getText();
+        else
+            return actionCommand;
+    }
+
+    public void setActionCommand(String ac) {
+        actionCommand = ac;
+    }
+
+    // ActionEvent listener support
+
+    public synchronized void addActionListener(ActionListener l) {
+        if (l == null) {
+            return;
+        }
+        enableEvents(AWTEvent.ACTION_EVENT_MASK);
+        actionListener = AWTEventMulticaster.add(actionListener, l);
+    }
+
+    public synchronized void removeActionListener(ActionListener l) {
+        if (l == null) {
+            return;
+        }
+        actionListener = AWTEventMulticaster.remove(actionListener, l);
+    }
+
+    // AdjustmentEvent listener support
+
+    public synchronized void addAdjustmentListener(AdjustmentListener l) {
+        if (l == null) {
+            return;
+        }
+        enableEvents(AWTEvent.ADJUSTMENT_EVENT_MASK);
+        adjustmentListener = AWTEventMulticaster.add(adjustmentListener, l);
+    }
+
+    public synchronized void removeAdjustmentListener(AdjustmentListener l) {
+        if (l == null) {
+            return;
+        }
+        adjustmentListener = AWTEventMulticaster.remove(adjustmentListener, l);
+    }
+
+    // ItemEvent listener support
+
+    public synchronized void addItemListener(ItemListener l) {
+        if (l == null) {
+            return;
+        }
+        enableEvents(AWTEvent.ITEM_EVENT_MASK);
+        itemListener = AWTEventMulticaster.add(itemListener, l);
+    }
+
+    public synchronized void removeItemListener(ItemListener l) {
+        if (l == null) {
+            return;
+        }
+        itemListener = AWTEventMulticaster.remove(itemListener, l);
+    }
+
+    // TextEvent listener support
+
+    public synchronized void addTextListener(TextListener l) {
+        if (l == null) {
+            return;
+        }
+        enableEvents(AWTEvent.TEXT_EVENT_MASK);
+        textListener = AWTEventMulticaster.add(textListener, l);
+    }
+
+    public synchronized void removeTextListener(TextListener l) {
+        if (l == null) {
+            return;
+        }
+        textListener = AWTEventMulticaster.remove(textListener, l);
+    }
+
+    // Implement the processEvent and processXXXEvent methods to
+    // handle reception and processing of the event types.
+
+    protected void processEvent(AWTEvent e) {
+        if (e instanceof ActionEvent) {
+            processActionEvent((ActionEvent) e);
+            return;
+        }
+        if (e instanceof AdjustmentEvent) {
+            processAdjustmentEvent((AdjustmentEvent) e);
+            return;
+        }
+        if (e instanceof ItemEvent) {
+            processItemEvent((ItemEvent) e);
+            return;
+        }
+        if (e instanceof TextEvent) {
+            processTextEvent((TextEvent) e);
+            return;
+        }
+        super.processEvent(e);
+    }
+
+    protected void processActionEvent(ActionEvent e) {
+        if (actionListener != null) {
+            actionListener.actionPerformed(e);
+        }
+    }
+
+    protected void processAdjustmentEvent(AdjustmentEvent e) {
+        if (adjustmentListener != null) {
+            adjustmentListener.adjustmentValueChanged(e);
+        }
+    }
+
+    protected void processItemEvent(ItemEvent e) {
+        if (itemListener != null) {
+            itemListener.itemStateChanged(e);
+        }
+    }
+
+    protected void processTextEvent(TextEvent e) {
+        if (textListener != null) {
+            textListener.textValueChanged(e);
+        }
+    }
+
+    public void paint(Graphics g) {
+        Dimension dim = getSize();
+        g.clearRect(0, 0, dim.width, dim.height);
+        g.setColor(getForeground());
+        g.drawString(text, 2, dim.height - 2);
+    }
+
+    /**
+     * Returns the selected items or null if no items are selected.
+     */
+    public Object[] getSelectedObjects() {
+        return null;
+    }
+
+    /**
+     * Gets the orientation of the adjustable object.
+     */
+    public int getOrientation() {
+        return 0;
+    }
+
+    /**
+     * Gets the minimum value of the adjustable object.
+     */
+    public int getMinimum() {
+        return 0;
+    }
+
+    /**
+     * Sets the minimum value of the adjustable object.
+     *
+     * @param min the minimum value
+     */
+    public void setMinimum(int min) {
+    }
+
+    /**
+     * Gets the maximum value of the adjustable object.
+     */
+    public int getMaximum() {
+        return 0;
+    }
+
+    /**
+     * Sets the maximum value of the adjustable object.
+     *
+     * @param max the maximum value
+     */
+    public void setMaximum(int max) {
+    }
+
+    /**
+     * Gets the unit value increment for the adjustable object.
+     */
+    public int getUnitIncrement() {
+        return 0;
+    }
+
+    /**
+     * Sets the unit value increment for the adjustable object.
+     *
+     * @param u the unit increment
+     */
+    public void setUnitIncrement(int u) {
+    }
+
+    /**
+     * Gets the block value increment for the adjustable object.
+     */
+    public int getBlockIncrement() {
+        return 0;
+    }
+
+    /**
+     * Sets the block value increment for the adjustable object.
+     *
+     * @param b the block increment
+     */
+    public void setBlockIncrement(int b) {
+    }
+
+    /**
+     * Gets the length of the propertional indicator.
+     */
+    public int getVisibleAmount() {
+        return 0;
+    }
+
+    /**
+     * Sets the length of the proportionl indicator of the
+     * adjustable object.
+     *
+     * @param v the length of the indicator
+     */
+    public void setVisibleAmount(int v) {
+    }
+
+    /**
+     * Gets the current value of the adjustable object.
+     */
+    public int getValue() {
+        return 0;
+    }
+
+    /**
+     * Sets the current value of the adjustable object. This
+     * value must be within the range defined by the minimum and
+     * maximum values for this object.
+     *
+     * @param v the current value
+     */
+    public void setValue(int v) {
+    }
+
+}
+
+class ActionBtn extends ButtonComponent {
+    public ActionBtn() {
+        super("ActionEvent");
+        addMouseListener(new MouseAdapter() {
+            public void mouseClicked(MouseEvent e) {
+                ActionEvent ae = new ActionEvent(e.getSource(),
+                        ActionEvent.ACTION_PERFORMED,
+                        getActionCommand());
+                Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ae);
+            }
+        });
+    }
+}
+
+class AdjustmentBtn extends ButtonComponent {
+    public AdjustmentBtn() {
+        super("AdjustmentEvent");
+        addMouseListener(new MouseAdapter() {
+            public void mouseClicked(MouseEvent e) {
+                AdjustmentEvent ae = new AdjustmentEvent((Adjustable) e.getSource(),
+                        AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+                        1, 1);
+                Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ae);
+            }
+        });
+    }
+}
+
+class ItemBtn extends ButtonComponent {
+    public ItemBtn() {
+        super("ItemEvent");
+        addMouseListener(new MouseAdapter() {
+            public void mouseClicked(MouseEvent e) {
+                ItemEvent ae = new ItemEvent((ItemSelectable) e.getSource(),
+                        ItemEvent.ITEM_STATE_CHANGED,
+                        e.getSource(), 1);
+                Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ae);
+            }
+        });
+    }
+}
+
+class TextBtn extends ButtonComponent {
+    public TextBtn() {
+        super("TextEvent");
+        addMouseListener(new MouseAdapter() {
+            public void mouseClicked(MouseEvent e) {
+                TextEvent ae = new TextEvent(e.getSource(),
+                        TextEvent.TEXT_VALUE_CHANGED);
+                Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ae);
+            }
+        });
+    }
+}
diff --git a/test/jdk/java/awt/Component/SetFontOrBackground/SetBgrFnt.java b/test/jdk/java/awt/Component/SetFontOrBackground/SetBgrFnt.java
new file mode 100644
index 0000000000000..02707ad578475
--- /dev/null
+++ b/test/jdk/java/awt/Component/SetFontOrBackground/SetBgrFnt.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 4906548 4921849
+ * @summary Checks that setFont and setBackground have immediate effect
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @run main/manual SetBgrFnt
+ */
+
+import java.awt.Button;
+import java.awt.Canvas;
+import java.awt.Checkbox;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.GridLayout;
+import java.awt.Label;
+import java.lang.reflect.InvocationTargetException;
+
+public class SetBgrFnt extends Frame {
+    static final String INSTRUCTIONS = """
+            1. Press a button marked 'Switch fonts'
+               fonts in three components below (a Button, a Checkbox
+               and a Label) must change immediately.
+
+            2. Press a button marked 'Switch background'
+               background of three components and canvas must change.
+               MacOS is an exception - AWT buttons on macOS so not
+               change color so on macOS only canvas, checkbox
+               and a label should change background.
+
+            If this is the behavior that you observe press Pass,
+            otherwise press Fail.
+            """;
+    Label la;
+    Button bu, bu1, bu2;
+    Checkbox cb;
+    Font font1, font2;
+    Canvas ca;
+    boolean bToggleFont = true;
+    boolean bToggleBg = true;
+
+    public SetBgrFnt() {
+        bu = new Button("Switch fonts");
+        bu1 = new Button("Switch background");
+        bu2 = new Button("I'm a button");
+        cb = new Checkbox("Checkbox I am");
+        la = new Label("I am a label");
+        ca = new Canvas();
+        font1 = new Font("Serif", Font.ITALIC, 22);
+        font2 = new Font("SansSerif", Font.PLAIN, 10);
+        la.setFont(font1);
+        cb.setFont(font1);
+        bu2.setFont(font1);
+        bu.addActionListener(ae -> {
+            if (bToggleFont) {
+                la.setFont(font2);
+                cb.setFont(font2);
+                bu2.setFont(font2);
+            } else {
+                la.setFont(font1);
+                cb.setFont(font1);
+                bu2.setFont(font1);
+            }
+            bToggleFont = !bToggleFont;
+        });
+
+        bu1.addActionListener(ae -> {
+            if (bToggleBg) {
+                ca.setBackground(Color.YELLOW);
+                setBackground(Color.YELLOW);
+            } else {
+                ca.setBackground(Color.GREEN);
+                setBackground(Color.GREEN);
+            }
+            bToggleBg = !bToggleBg;
+        });
+
+        setLayout(new GridLayout(8, 1));
+        add(bu);
+        add(bu1);
+        add(new Label());
+        add("South", la);
+        add("South", bu2);
+        add("South", cb);
+        add("South", ca);
+        pack();
+    }
+
+    public static void main(String[] args) throws InterruptedException,
+            InvocationTargetException {
+        PassFailJFrame.builder()
+                .title("Set Font and Background Test")
+                .testUI(SetBgrFnt::new)
+                .instructions(INSTRUCTIONS)
+                .columns(40)
+                .build()
+                .awaitAndCheck();
+    }
+}

From 628e1820b40c31b4634ccfe7c292a3b56df4158a Mon Sep 17 00:00:00 2001
From: Goetz Lindenmaier 
Date: Mon, 7 Apr 2025 15:19:16 +0000
Subject: [PATCH 137/846] 8340555: Open source DnD tests - Set4

Backport-of: 0dd49970428e08d35996752ba0878a97fb6f8530
---
 test/jdk/ProblemList.txt                      |   3 +
 .../DnDHTMLToOutlookTest.java                 |  82 ++++++
 .../dnd/DnDHTMLToOutlookTest/DnDSource.html   |  25 ++
 .../dnd/DnDHTMLToOutlookTest/DnDSource.java   | 142 ++++++++++
 .../awt/dnd/DragSourceMotionListenerTest.java | 242 ++++++++++++++++++
 .../java/awt/dnd/DragToAnotherScreenTest.java | 169 ++++++++++++
 test/jdk/java/awt/dnd/RejectDragTest.java     | 174 +++++++++++++
 7 files changed, 837 insertions(+)
 create mode 100644 test/jdk/java/awt/dnd/DnDHTMLToOutlookTest/DnDHTMLToOutlookTest.java
 create mode 100644 test/jdk/java/awt/dnd/DnDHTMLToOutlookTest/DnDSource.html
 create mode 100644 test/jdk/java/awt/dnd/DnDHTMLToOutlookTest/DnDSource.java
 create mode 100644 test/jdk/java/awt/dnd/DragSourceMotionListenerTest.java
 create mode 100644 test/jdk/java/awt/dnd/DragToAnotherScreenTest.java
 create mode 100644 test/jdk/java/awt/dnd/RejectDragTest.java

diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt
index fe34cc1935cf5..04c76729a9672 100644
--- a/test/jdk/ProblemList.txt
+++ b/test/jdk/ProblemList.txt
@@ -486,6 +486,9 @@ java/awt/KeyboardFocusmanager/ConsumeNextMnemonicKeyTypedTest/ConsumeNextMnemoni
 
 java/awt/Window/GetScreenLocation/GetScreenLocationTest.java 8225787 linux-x64
 java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 8266243 macosx-aarch64
+java/awt/dnd/DragSourceMotionListenerTest.java 8225131 windows-all
+java/awt/dnd/RejectDragTest.java 7124259 macosx-all
+java/awt/dnd/DnDHTMLToOutlookTest/DnDHTMLToOutlookTest.java 8027424 generic-all
 java/awt/Dialog/ChoiceModalDialogTest.java 8161475 macosx-all
 
 # Wayland related
diff --git a/test/jdk/java/awt/dnd/DnDHTMLToOutlookTest/DnDHTMLToOutlookTest.java b/test/jdk/java/awt/dnd/DnDHTMLToOutlookTest/DnDHTMLToOutlookTest.java
new file mode 100644
index 0000000000000..8a39ce537056e
--- /dev/null
+++ b/test/jdk/java/awt/dnd/DnDHTMLToOutlookTest/DnDHTMLToOutlookTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Frame;
+import java.awt.Panel;
+
+
+/*
+ * @test
+ * @bug 6392086
+ * @summary Tests dnd to another screen
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @run main/manual DnDHTMLToOutlookTest
+ */
+
+public class DnDHTMLToOutlookTest {
+
+    private static final String INSTRUCTIONS = """
+            The window contains a yellow button. Click on the button
+            to copy HTML from DnDSource.html file into the clipboard or drag
+            HTML context. Paste into or drop over the HTML capable editor in
+            external application such as Outlook, Word.
+
+            When the mouse enters the editor, cursor should change to indicate
+            that copy operation is about to happen and then release the mouse
+            button. HTML text without tags should appear inside the document.
+
+            You should be able to repeat this operation multiple times.
+            If the above is true Press PASS else FAIL.
+            """;
+
+    public static void main(String[] args) throws Exception {
+        PassFailJFrame.builder()
+                      .title("Test Instructions")
+                      .instructions(INSTRUCTIONS)
+                      .columns(40)
+                      .testUI(DnDHTMLToOutlookTest::createAndShowUI)
+                      .build()
+                      .awaitAndCheck();
+    }
+
+    private static Frame createAndShowUI() {
+        Frame frame = new Frame("DnDHTMLToOutlookTest");
+        Panel mainPanel;
+        Component dragSource;
+
+        mainPanel = new Panel();
+        mainPanel.setLayout(new BorderLayout());
+
+        mainPanel.setBackground(Color.YELLOW);
+        dragSource = new DnDSource("Drag ME (HTML)!");
+
+        mainPanel.add(dragSource, BorderLayout.CENTER);
+        frame.add(mainPanel);
+        frame.setSize(200, 200);
+        return frame;
+    }
+}
diff --git a/test/jdk/java/awt/dnd/DnDHTMLToOutlookTest/DnDSource.html b/test/jdk/java/awt/dnd/DnDHTMLToOutlookTest/DnDSource.html
new file mode 100644
index 0000000000000..0f1b9751decdb
--- /dev/null
+++ b/test/jdk/java/awt/dnd/DnDHTMLToOutlookTest/DnDSource.html
@@ -0,0 +1,25 @@
+
+
+

DnDHTMLToOutlookTest
HTML Drag & Paste problem

+

if you see the bold header above without HTML tags and without StartHTML as the first word, press PASS

diff --git a/test/jdk/java/awt/dnd/DnDHTMLToOutlookTest/DnDSource.java b/test/jdk/java/awt/dnd/DnDHTMLToOutlookTest/DnDSource.java new file mode 100644 index 0000000000000..58f17e9415c50 --- /dev/null +++ b/test/jdk/java/awt/dnd/DnDHTMLToOutlookTest/DnDSource.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.InvalidDnDOperationException; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; + +class DnDSource extends Button implements Transferable, + DragGestureListener, + DragSourceListener { + private DataFlavor m_df; + private transient int m_dropAction; + private ByteArrayInputStream m_data = null; + + DnDSource(String label) { + super(label); + setBackground(Color.yellow); + setForeground(Color.blue); + setSize(200, 120); + + try { + m_df = new DataFlavor("text/html; Class=" + InputStream.class.getName() + "; charset=UTF-8"); + } catch (Exception e) { + e.printStackTrace(); + } + + DragSource dragSource = new DragSource(); + dragSource.createDefaultDragGestureRecognizer( + this, + DnDConstants.ACTION_COPY_OR_MOVE, + this + ); + dragSource.addDragSourceListener(this); + + String dir = System.getProperty("test.src", "."); + + try { + m_data = new ByteArrayInputStream(Files.readAllBytes( + Paths.get(dir, "DnDSource.html"))); + m_data.mark(m_data.available()); + addActionListener( + new ActionListener(){ + public void actionPerformed(ActionEvent ae){ + Toolkit.getDefaultToolkit().getSystemClipboard() + .setContents( DnDSource.this, null); + } + } + ); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void dragGestureRecognized(DragGestureEvent dge) { + System.err.println("starting Drag"); + try { + dge.startDrag(null, this, this); + } catch (InvalidDnDOperationException e) { + e.printStackTrace(); + } + } + + public void dragEnter(DragSourceDragEvent dsde) { + System.err.println("[Source] dragEnter"); + } + + public void dragOver(DragSourceDragEvent dsde) { + System.err.println("[Source] dragOver"); + m_dropAction = dsde.getDropAction(); + System.out.println("m_dropAction = " + m_dropAction); + } + + public void dragExit(DragSourceEvent dsde) { + System.err.println("[Source] dragExit"); + } + + public void dragDropEnd(DragSourceDropEvent dsde) { + System.err.println("[Source] dragDropEnd"); + } + + public void dropActionChanged(DragSourceDragEvent dsde) { + System.err.println("[Source] dropActionChanged"); + m_dropAction = dsde.getDropAction(); + System.out.println("m_dropAction = " + m_dropAction); + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] {m_df}; + } + + public boolean isDataFlavorSupported(DataFlavor sdf) { + System.err.println("[Source] isDataFlavorSupported" + m_df.equals(sdf)); + return m_df.equals(sdf); + } + + public Object getTransferData(DataFlavor tdf) throws UnsupportedFlavorException { + if (!m_df.equals(tdf)) { + throw new UnsupportedFlavorException(tdf); + } + System.err.println("[Source] Ok"); + m_data.reset(); + return m_data; + } +} diff --git a/test/jdk/java/awt/dnd/DragSourceMotionListenerTest.java b/test/jdk/java/awt/dnd/DragSourceMotionListenerTest.java new file mode 100644 index 0000000000000..25bf7ef03fd1e --- /dev/null +++ b/test/jdk/java/awt/dnd/DragSourceMotionListenerTest.java @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTEvent; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.AWTEventListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/* + * @test + * @key headful + * @bug 4422345 + * @summary tests that DragSourceMotionListeners work correctly and + DragSourceEvents position is correct + */ + +public class DragSourceMotionListenerTest implements AWTEventListener { + static class TestPanel extends Panel { + final Dimension preferredDimension = new Dimension(200, 200); + public Dimension getPreferredSize() { + return preferredDimension; + } + } + + private static Frame frame; + private static final Panel source = new TestPanel(); + private static final Panel target = new TestPanel(); + private static final DragSource ds = DragSource.getDefaultDragSource(); + private static volatile CountDownLatch mouseReleaseEvent; + + static volatile boolean passedTest1 = false; + static volatile boolean passedTest2 = false; + + private static final Point testPoint1 = new Point(); + private static final Point testPoint2 = new Point(); + private static volatile Point srcPoint; + private static volatile Point dstOutsidePoint; + private static volatile Point dstInsidePoint; + + private static final Transferable t = new StringSelection("TEXT"); + private static final DragGestureListener gestureListener = e -> e.startDrag(null, t); + + private static final DragSourceAdapter sourceAdapter = new DragSourceAdapter() { + public void dragMouseMoved(DragSourceDragEvent dsde) { + if (Math.abs(dsde.getX() - testPoint1.getX()) < 5) { + passedTest1 = true; + } + } + + public void dragDropEnd(DragSourceDropEvent dsde) { + if (Math.abs(dsde.getX() - testPoint2.getX()) < 5) { + passedTest2 = true; + } + } + }; + + private static final DropTargetListener targetAdapter = new DropTargetAdapter() { + public void drop(DropTargetDropEvent e) { + e.acceptDrop(DnDConstants.ACTION_COPY); + try { + final Transferable t = e.getTransferable(); + final String str = + (String) t.getTransferData(DataFlavor.stringFlavor); + e.dropComplete(true); + } catch (Exception ex) { + ex.printStackTrace(); + e.dropComplete(false); + } + } + }; + + private static final DropTarget dropTarget = new DropTarget(target, targetAdapter); + Component clickedComponent = null; + + private void createAndShowUI() { + frame = new Frame("DragSourceMotionListenerTest"); + ds.addDragSourceListener(sourceAdapter); + ds.addDragSourceMotionListener(sourceAdapter); + ds.createDefaultDragGestureRecognizer(source, DnDConstants.ACTION_COPY, gestureListener); + target.setDropTarget(dropTarget); + + frame.setLayout(new GridLayout(1, 2)); + + frame.add(source); + frame.add(target); + + Toolkit.getDefaultToolkit() + .addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK); + frame.pack(); + frame.setVisible(true); + } + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoDelay(10); + + DragSourceMotionListenerTest dsmObj = new DragSourceMotionListenerTest(); + EventQueue.invokeAndWait(dsmObj::createAndShowUI); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + srcPoint = getPoint(source, 1); + + dstOutsidePoint = getPoint(frame, 3); + testPoint1.setLocation(dstOutsidePoint); + + dstInsidePoint = getPoint(target, 1); + testPoint2.setLocation(dstInsidePoint); + }); + robot.waitForIdle(); + + if (!dsmObj.pointInComponent(robot, srcPoint, source)) { + throw new RuntimeException("WARNING: Couldn't locate source panel."); + } + + if (!dsmObj.pointInComponent(robot, dstInsidePoint, target)) { + throw new RuntimeException("WARNING: Couldn't locate target panel."); + } + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (; !srcPoint.equals(dstOutsidePoint); + srcPoint.translate(sign(dstOutsidePoint.x - srcPoint.x), + sign(dstOutsidePoint.y - srcPoint.y))) { + robot.mouseMove(srcPoint.x, srcPoint.y); + } + + for (int i = 0; i < 10; i++) { + robot.mouseMove(srcPoint.x, srcPoint.y++); + } + + for (;!srcPoint.equals(dstInsidePoint); + srcPoint.translate(sign(dstInsidePoint.x - srcPoint.x), + sign(dstInsidePoint.y - srcPoint.y))) { + robot.mouseMove(srcPoint.x, srcPoint.y); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + robot.waitForIdle(); + robot.delay(1000); + + if (!passedTest1) { + throw new RuntimeException("Failed first test."); + } + + if (!passedTest2) { + throw new RuntimeException("Failed second test."); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static Point getPoint(Container container, int multiple) { + Point p = container.getLocationOnScreen(); + Dimension d = container.getSize(); + p.translate(multiple * d.width / 2, d.height / 2); + return p; + } + + public static int sign(int n) { + return Integer.compare(n, 0); + } + + public void eventDispatched(AWTEvent e) { + if (e.getID() == MouseEvent.MOUSE_RELEASED) { + clickedComponent = (Component)e.getSource(); + mouseReleaseEvent.countDown(); + } + } + + boolean pointInComponent(Robot robot, Point p, Component comp) throws Exception { + robot.waitForIdle(); + clickedComponent = null; + mouseReleaseEvent = new CountDownLatch(1); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + if (!mouseReleaseEvent.await(2, TimeUnit.SECONDS)) { + throw new RuntimeException("Mouse Release Event not received"); + } + + Component c = clickedComponent; + while (c != null && c != comp) { + c = c.getParent(); + } + return c == comp; + } +} diff --git a/test/jdk/java/awt/dnd/DragToAnotherScreenTest.java b/test/jdk/java/awt/dnd/DragToAnotherScreenTest.java new file mode 100644 index 0000000000000..89f18061845fe --- /dev/null +++ b/test/jdk/java/awt/dnd/DragToAnotherScreenTest.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Frame; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Label; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDropEvent; +import java.util.List; + +import javax.swing.JOptionPane; + +/* + * @test + * @bug 6179157 + * @key multimon + * @summary Tests dnd to another screen + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DragToAnotherScreenTest + */ + +public class DragToAnotherScreenTest { + private static Label label0; + private static Label label1; + private static final int HGAP = 20; + + private static final String INSTRUCTIONS = """ + The following test is applicable for Single as well + as Multi-monitor screens. + + It is a semi-automated test, the test will prompt + the user whether the drag and drop action was successful or not + and automatically PASS/FAIL the test. + + If on multi-monitor screens then please position + the drag and drop windows on different screens. + + If you can not move the mouse from the frame "Drag Source" + to the frame "Drop Target" press PASS, + else proceed to the next step. + + Drag the label "Drag me" and drop it on the + label "Drop on me". + + If you can not drag to the second label (for example + if you can not drag across screens) press FAIL. + + After the drag and drop action, the test displays + Success/Failure msg in JOptionPane. + Click on OK button and the test is configured to + automatically PASS/FAIL. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(DragToAnotherScreenTest::createAndShowUI) + .positionTestUI(DragToAnotherScreenTest::positionMultiTestUI) + .logArea(10) + .build() + .awaitAndCheck(); + } + + private static List createAndShowUI() { + PassFailJFrame.log("----- System Configuration ----"); + PassFailJFrame.log("Toolkit:" + Toolkit.getDefaultToolkit() + .getClass() + .getName()); + + GraphicsDevice[] gd = GraphicsEnvironment.getLocalGraphicsEnvironment() + .getScreenDevices(); + if (gd.length == 1) { + PassFailJFrame.log("Single Monitor"); + } else { + PassFailJFrame.log("Multi-Monitor"); + } + PassFailJFrame.log("--------------"); + PassFailJFrame.log("Test logs:\n"); + Frame frame0 = new Frame("Drag Source", gd[0].getDefaultConfiguration()); + frame0.setSize(300, 300); + label0 = new Label("Drag me"); + frame0.add(label0); + + Frame frame1 = new Frame("Drop Target", gd[(gd.length > 1 ? 1 : 0)].getDefaultConfiguration()); + frame1.setSize(300, 300); + label1 = new Label("Drop on me"); + frame1.add(label1); + + DragGestureListener dragGestureListener = dge -> dge.startDrag(null, new StringSelection(label0.getText()), null); + new DragSource().createDefaultDragGestureRecognizer(label0, + DnDConstants.ACTION_COPY, dragGestureListener); + + DropTargetAdapter dropTargetAdapter = new DropTargetAdapter() { + public void drop(DropTargetDropEvent dtde) { + Transferable t = dtde.getTransferable(); + if (t.isDataFlavorSupported(DataFlavor.stringFlavor)) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + try { + String str = (String) t.getTransferData(DataFlavor.stringFlavor); + label1.setText(str); + JOptionPane.showMessageDialog(frame0, + "getTransferData was successful", + "Test Passed", JOptionPane.PLAIN_MESSAGE); + } catch (Exception e) { + dtde.dropComplete(false); + e.printStackTrace(); + PassFailJFrame.log("getTransferData() Failed"); + JOptionPane.showMessageDialog(frame0, + "getTransferData() Failed", + "Test Failed", JOptionPane.ERROR_MESSAGE); + PassFailJFrame.forceFail("getTransferData() Failed"); + } + dtde.dropComplete(true); + } else { + dtde.rejectDrop(); + PassFailJFrame.log("stringFlavor is not supported by Transferable"); + JOptionPane.showMessageDialog(frame0, + "stringFlavor is not supported by Transferable", + "Test Failed", JOptionPane.ERROR_MESSAGE); + PassFailJFrame.forceFail("stringFlavor is not supported by Transferable"); + } + } + }; + new DropTarget(label1, dropTargetAdapter); + return List.of(frame0, frame1); + } + + private static void positionMultiTestUI(List windows, + PassFailJFrame.InstructionUI instructionUI) { + int x = instructionUI.getLocation().x + instructionUI.getSize().width + HGAP; + for (Window w : windows) { + w.setLocation(x, instructionUI.getLocation().y); + x += w.getWidth() + HGAP; + } + } +} diff --git a/test/jdk/java/awt/dnd/RejectDragTest.java b/test/jdk/java/awt/dnd/RejectDragTest.java new file mode 100644 index 0000000000000..c65612436bc38 --- /dev/null +++ b/test/jdk/java/awt/dnd/RejectDragTest.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.StringSelection; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.event.InputEvent; + +/* + * @test + * @key headful + * @bug 4407521 + * @summary Tests that DragSourceListener.dragEnter() and + DragSourceListener.dragOver() are not called after + drag rejecting, but DragSourceListener.dragExit() is. + */ + +public class RejectDragTest { + private static Frame frame; + private static Robot robot; + private static volatile boolean dragEnterCalled; + private static volatile boolean dragOverCalled; + private static volatile boolean dragExitCalledAtFirst; + private static volatile Point startPoint; + private static volatile Point endPoint; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + + EventQueue.invokeAndWait(RejectDragTest::createAndShowUI); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(RejectDragTest::addDnDListeners); + robot.waitForIdle(); + + testDnD(); + robot.waitForIdle(); + robot.delay(200); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void addDnDListeners() { + final DragSourceListener dragSourceListener = new DragSourceAdapter() { + private boolean first = true; + + public void dragEnter(DragSourceDragEvent dsde) { + first = false; + dragEnterCalled = true; + } + + public void dragExit(DragSourceEvent dse) { + if (first) { + dragExitCalledAtFirst = true; + first = false; + } + } + + public void dragDropEnd(DragSourceDropEvent dsde) { + first = false; + } + + public void dragOver(DragSourceDragEvent dsde) { + first = false; + dragOverCalled = true; + } + + public void dropActionChanged(DragSourceDragEvent dsde) { + first = false; + } + }; + + DragGestureListener dragGestureListener = + dge -> dge.startDrag(null, new StringSelection("OKAY"), + dragSourceListener); + new DragSource().createDefaultDragGestureRecognizer(frame, + DnDConstants.ACTION_COPY, + dragGestureListener); + + DropTargetAdapter dropTargetListener = new DropTargetAdapter() { + public void dragEnter(DropTargetDragEvent dtde) { + dtde.rejectDrag(); + } + + public void drop(DropTargetDropEvent dtde) { + dtde.rejectDrop(); + } + }; + + new DropTarget(frame, dropTargetListener); + } + + private static void createAndShowUI() { + frame = new Frame("RejectDragTest"); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + private static void testDnD() throws Exception { + EventQueue.invokeAndWait(() -> { + Point start = frame.getLocationOnScreen(); + start.translate(50, 50); + startPoint = start; + + Point end = new Point(start); + end.translate(150, 150); + endPoint = end; + }); + + robot.mouseMove(startPoint.x, startPoint.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (Point p = new Point(startPoint); !p.equals(endPoint); + p.translate(sign(endPoint.x - p.x), + sign(endPoint.y - p.y))) { + robot.mouseMove(p.x, p.y); + robot.delay(30); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + if (dragEnterCalled || dragOverCalled) { + throw new RuntimeException("Test failed: " + + (dragEnterCalled ? "DragSourceListener.dragEnter() was called; " : "") + + (dragOverCalled ? "DragSourceListener.dragOver() was called; " : "") + + (!dragExitCalledAtFirst ? "DragSourceListener.dragExit() was not " + + "called immediately after rejectDrag() " : "")); + } + } + + public static int sign(int n) { + return Integer.compare(n, 0); + } +} From 37dc3791a25bd773b8246a6cc54eff4dd6ab7cf9 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 7 Apr 2025 15:20:27 +0000 Subject: [PATCH 138/846] 8340967: Open source few Cursor tests - Set2 Backport-of: 92cb6331085bb6f4db091ce80d9951413541d74a --- .../BlockedWindowTest/BlockedWindowTest.java | 105 ++++++++++++++ .../CursorUpdateTest/CursorUpdateTest.java | 118 +++++++++++++++ .../CustomCursorTest/CustomCursorTest.java | 137 ++++++++++++++++++ .../JPanelCursorTest/JPanelCursorTest.java | 122 ++++++++++++++++ .../Cursor/SetCursorTest/SetCursorTest.java | 82 +++++++++++ 5 files changed, 564 insertions(+) create mode 100644 test/jdk/java/awt/Cursor/BlockedWindowTest/BlockedWindowTest.java create mode 100644 test/jdk/java/awt/Cursor/CursorUpdateTest/CursorUpdateTest.java create mode 100644 test/jdk/java/awt/Cursor/CustomCursorTest/CustomCursorTest.java create mode 100644 test/jdk/java/awt/Cursor/JPanelCursorTest/JPanelCursorTest.java create mode 100644 test/jdk/java/awt/Cursor/SetCursorTest/SetCursorTest.java diff --git a/test/jdk/java/awt/Cursor/BlockedWindowTest/BlockedWindowTest.java b/test/jdk/java/awt/Cursor/BlockedWindowTest/BlockedWindowTest.java new file mode 100644 index 0000000000000..f1313dbb74246 --- /dev/null +++ b/test/jdk/java/awt/Cursor/BlockedWindowTest/BlockedWindowTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6391547 + * @summary Test if the JTextField's cursor is changed when there is a modal dialog + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual BlockedWindowTest + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Cursor; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +class MyDialog extends Dialog implements ActionListener { + MyDialog(Frame owner) { + super(owner, "Modal dialog", true); + setBounds(owner.getX() + 150, owner.getY() + 150, 100, 100); + setLayout(new BorderLayout()); + Button b = new Button("Close"); + add(b, "South"); + b.addActionListener(this); + setVisible(true); + } + + public void actionPerformed(ActionEvent ae) { + setVisible(false); + this.dispose(); + } +} + +class MyFrame extends Frame implements ActionListener { + Dialog d; + + public MyFrame() { + super("ManualYesNoTest"); + Button b = new Button("Click here"); + TextField tf = new TextField("A text field"); + b.addActionListener(this); + setLayout(new BorderLayout()); + setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + add(b, "South"); + add(tf, "North"); + setSize(300, 300); + } + + public void actionPerformed(ActionEvent ae) { + d = new MyDialog(this); + } +} + +public class BlockedWindowTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Verify that the hand cursor is displayed over the window and + text cursor over TextField. + Click the button in the window to display a modal dialog. + Verify that default cursor is displayed over the window + and over TextField now. + Then close modal dialog and verify that hand cursor is + displayed over window and text cursor over TextField. + If so, press PASS, else press FAIL. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(BlockedWindowTest::createUI) + .build() + .awaitAndCheck(); + } + + public static MyFrame createUI() { + MyFrame f = new MyFrame(); + return f; + } +} diff --git a/test/jdk/java/awt/Cursor/CursorUpdateTest/CursorUpdateTest.java b/test/jdk/java/awt/Cursor/CursorUpdateTest/CursorUpdateTest.java new file mode 100644 index 0000000000000..33e2a3cb166a1 --- /dev/null +++ b/test/jdk/java/awt/Cursor/CursorUpdateTest/CursorUpdateTest.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 5097531 + * @summary Make sure the cursor updates correctly under certain + * circumstances even when the EDT is busy + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual CursorUpdateTest + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Graphics; + +public class CursorUpdateTest { + final static String progress = "|/-\\"; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Check the following: + 1. Cursor must be crosshair when hovering the mouse over the + blue square. + 2. Crosshair cursor must not flicker. + 3. The cursor must be "I-beam" when hovering the mouse over the + button. + 4. Click the button - it will display "Busy" message and a + rotating bar for 5 seconds. The cursor must change to + hourglass. + 5. (Windows only) While the cursor is on the button, press Alt. + The cursor must change to normal shape. Pressing Alt again + must revert it back to I-beam. + 6. Move the mouse out of the button and back onto it. The cursor + must update correctly (hourglass over the button, normal + over the frame) even when the button displays "busy". + Do not try to check (1) or (5) when the button displays + "Busy" - this is not required. + Pass if all the steps are as behave as described. Otherwise, + fail this test. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(CursorUpdateTest::createUI) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame f = new Frame(); + f.setLayout(new FlowLayout()); + Button b = new Button("Button"); + f.add(b); + b.setCursor(new Cursor(Cursor.TEXT_CURSOR)); + Component c = new MyComponent(); + f.add(c); + c.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); + b.addActionListener(e -> { + String oldLabel = b.getLabel(); + Cursor oldCursor = b.getCursor(); + b.setCursor(new Cursor(Cursor.WAIT_CURSOR)); + try { + for (int i = 0; i < 50; i++) { + b.setLabel("Busy " + progress.charAt(i % 4)); + Thread.sleep(100); + } + } catch (InterruptedException ex) { + } + b.setCursor(oldCursor); + b.setLabel(oldLabel); + }); + return f; + } +} + +class MyComponent extends Component { + public void paint(Graphics g) { + g.setColor(getBackground()); + g.fillRect(0, 0, getSize().width, getSize().height); + } + + public MyComponent() { + setBackground(Color.blue); + } + + public Dimension getPreferredSize() { + return new Dimension(100, 100); + } +} diff --git a/test/jdk/java/awt/Cursor/CustomCursorTest/CustomCursorTest.java b/test/jdk/java/awt/Cursor/CustomCursorTest/CustomCursorTest.java new file mode 100644 index 0000000000000..32c1fdc150622 --- /dev/null +++ b/test/jdk/java/awt/Cursor/CustomCursorTest/CustomCursorTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4174035 4106384 4205805 + * @summary Test for functionality of Custom Cursor + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual CustomCursorTest + */ + +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Frame; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; + +import javax.imageio.ImageIO; +import javax.swing.JFrame; +import javax.swing.JLabel; + +import static java.awt.image.BufferedImage.TYPE_INT_ARGB; + +public class CustomCursorTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + This test is for switching between a custom cursor and the + system cursor. + + 1. Click on the test window panel to change from the default + system cursor to the custom red square cursor + 2. Verify that the square cursor shows when the panel is clicked + 3. Verify that the square cursor is colored red + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(CustomCursorTest::createUI) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + JFrame f = new JFrame("Custom Cursor Test"); + CustomCursorPanel c = null; + try { + c = new CustomCursorPanel(); + } catch (IOException e) { + e.printStackTrace(); + } + + f.setIconImage(c.getImage()); + f.getContentPane().add(c); + f.setSize(400, 400); + return f; + } +} + +class CustomCursorPanel extends Panel { + Toolkit toolkit = Toolkit.getDefaultToolkit(); + Image image; + Cursor cursor; + boolean flip = false; + + public CustomCursorPanel() throws IOException { + generateRedSquareCursor(); + + image = toolkit.getImage(System.getProperty("test.classes", ".") + + java.io.File.separator + "square_cursor.gif"); + + setBackground(Color.green); + cursor = toolkit.createCustomCursor(image, new Point(0, 0), "custom"); + + JLabel c = (JLabel) add(new JLabel("click to switch between " + + "red square and default cursors")); + c.setBackground(Color.white); + c.setForeground(Color.red); + + addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + if (!flip) { + setCursor(cursor); + flip = true; + } else { + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + flip = false; + } + } + }); + } + + public Image getImage() { + return image; + } + + private static void generateRedSquareCursor() throws IOException { + Path p = Path.of(System.getProperty("test.classes", ".")); + BufferedImage bImg = new BufferedImage(35, 34, TYPE_INT_ARGB); + Graphics2D cg = bImg.createGraphics(); + cg.setColor(Color.RED); + cg.fillRect(0, 0, 35, 34); + ImageIO.write(bImg, "png", new File(p + java.io.File.separator + + "square_cursor.gif")); + } +} diff --git a/test/jdk/java/awt/Cursor/JPanelCursorTest/JPanelCursorTest.java b/test/jdk/java/awt/Cursor/JPanelCursorTest/JPanelCursorTest.java new file mode 100644 index 0000000000000..8acd622e59212 --- /dev/null +++ b/test/jdk/java/awt/Cursor/JPanelCursorTest/JPanelCursorTest.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4114073 + * @summary Test for setCursor in a JPanel when added to a JFrame's contentPane + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual JPanelCursorTest + */ + +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Graphics; + +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JSplitPane; +import javax.swing.border.BevelBorder; + +public class JPanelCursorTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + This test checks for setCursor in a JPanel when added to a + JFrame's contentPane. + + 1. Verify that the cursor in the left side of the test window + is a default cursor. + 2. Verify that the cursor changes to the crosshair cursor when + pointing over the button. + 3. Verify that the cursor changes to the hand cursor when in + the right side of the splitpane (and not on the button). + + If true, then pass the test. Otherwise, fail this test. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(JPanelCursorTest::createUI) + .build() + .awaitAndCheck(); + } + + public static JFrame createUI() { + JFrame frame = new JFrame(); + + JSplitPane j = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); + ExtJComponent pane = new ExtJComponent(); + + CursorBugPanel panel = new CursorBugPanel(); + + j.setLeftComponent(pane); + j.setRightComponent(panel); + j.setContinuousLayout(true); + + frame.getContentPane().add("Center", j); + pane.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); + frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + frame.pack(); + return frame; + } +} + +class ExtJComponent extends JComponent { + public ExtJComponent() { + super(); + setOpaque(true); + setBackground(Color.green); + setForeground(Color.red); + setBorder(new BevelBorder(BevelBorder.RAISED)); + } + public void paintComponent(Graphics g) { + g.drawString("Default", 20, 30); + } + public Dimension getPreferredSize() { + return new Dimension(100, 100); + } +} + +class CursorBugPanel extends JPanel { + public CursorBugPanel () { + // BUG: fails to set cursor for panel + setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + + // Create a button + JButton button = new JButton("Crosshair"); + + // Sets cursor for button, no problem + button.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); + add(button); + } + + public void paintComponent(Graphics g) { + g.drawString("Hand", 20, 60); + } +} diff --git a/test/jdk/java/awt/Cursor/SetCursorTest/SetCursorTest.java b/test/jdk/java/awt/Cursor/SetCursorTest/SetCursorTest.java new file mode 100644 index 0000000000000..87f028eb4f617 --- /dev/null +++ b/test/jdk/java/awt/Cursor/SetCursorTest/SetCursorTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4160080 + * @summary Test setCursor() on lightweight components when event is generated + * by a button + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual SetCursorTest + */ + +import java.awt.Cursor; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; + + +public class SetCursorTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + This test checks for the behavior of setCursor() when called in + a JFrame's JButton action event. + + 1. Click the "OK" button in the test window. + 2. Verify that the cursor changes to the waiting cursor instead + of the default system cursor. + + If true, then pass the test. Otherwise, fail this test. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(SetCursorTest::createUI) + .build() + .awaitAndCheck(); + } + + public static myFrame createUI() { + myFrame f = new myFrame(); + return f; + } +} + +class myFrame extends JFrame { + public myFrame() { + super("SetCursor With Button Test"); + setSize(200, 200); + + final JPanel p = new JPanel(); + final JButton okButton = new JButton("OK"); + okButton.addActionListener(e -> + setCursor(new Cursor(Cursor.WAIT_CURSOR))); + + p.add(okButton); + getContentPane().add(p); + } +} From 0648c86cf585a8ba128db54f585faa910433a7da Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 7 Apr 2025 15:23:32 +0000 Subject: [PATCH 139/846] 8341378: Open source few TrayIcon tests - Set8 Backport-of: b9db74a64577bf2b79570a789c91de6549a50788 --- test/jdk/ProblemList.txt | 1 + test/jdk/java/awt/TrayIcon/TrayIconTest.java | 613 +++++++++++++++++++ 2 files changed, 614 insertions(+) create mode 100644 test/jdk/java/awt/TrayIcon/TrayIconTest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 04c76729a9672..617f9e34069d1 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -220,6 +220,7 @@ java/awt/TrayIcon/TrayIconMouseTest/TrayIconMouseTest.java 8150540 windows-all java/awt/TrayIcon/TrayIconPopup/TrayIconPopupClickTest.java 8150540 windows-all,macosx-all java/awt/TrayIcon/TrayIconPopup/TrayIconPopupTest.java 8150540 windows-all java/awt/TrayIcon/PopupMenuLeakTest/PopupMenuLeakTest.java 8196440 linux-all +java/awt/TrayIcon/TrayIconTest.java 8341559 generic-all java/awt/Window/ShapedAndTranslucentWindows/SetShapeAndClick.java 8197936 macosx-all java/awt/Window/ShapedAndTranslucentWindows/SetShapeDynamicallyAndClick.java 8013450 macosx-all diff --git a/test/jdk/java/awt/TrayIcon/TrayIconTest.java b/test/jdk/java/awt/TrayIcon/TrayIconTest.java new file mode 100644 index 0000000000000..c78f6c134fed3 --- /dev/null +++ b/test/jdk/java/awt/TrayIcon/TrayIconTest.java @@ -0,0 +1,613 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Checkbox; +import java.awt.CheckboxGroup; +import java.awt.Choice; +import java.awt.Color; +import java.awt.Container; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Graphics2D; +import java.awt.GridLayout; +import java.awt.Image; +import java.awt.Insets; +import java.awt.Label; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.PopupMenu; +import java.awt.RenderingHints; +import java.awt.SystemTray; +import java.awt.TextField; +import java.awt.Toolkit; +import java.awt.TrayIcon; +import java.awt.TrayIcon.MessageType; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BufferedImage; +import java.beans.PropertyChangeEvent; +import java.util.HashMap; +import java.util.Map; +import jtreg.SkippedException; + +/* + * @test + * @key headful + * @bug 4310333 + * @library /java/awt/regtesthelpers /test/lib + * @build PassFailJFrame jtreg.SkippedException + * @summary A unit test for TrayIcon RFE + * @run main/manual TrayIconTest + */ + +public class TrayIconTest { + private static SystemTray tray; + static Frame frame = new Frame("TrayIcon Test"); + private static final String INSTRUCTIONS = """ + The test frame contains CheckboxGroup of tray icons. + A selected checkbox represents the TrayIcon (or null + TrayIcon) whose functionality is currently tested. + + If you are under Linux make sure your Application Panel has + System Tray (on Gnome it is called Notification Area). + + Perform all the cases (1-7) documented below. + + CASE 1: Testing ADD/REMOVE/PropertyChange functionality. + -------------------------------------------------------- + 1. Select null TrayIcon and pressAdd button: + - NullPointerException should be thrown. + 2. Select some of the valid TrayIcons and press Add button: + - The selected TrayIcon should appear in the SystemTray. + - PropertyChangeEvent should be fired (the property is + an array of TrayIcons added to the system tray). + 3. Press Add button again: + - IllegalArgumentException should be thrown. + - No PropertyChangeEvent should be fired. + 4. Press Remove button: + - The TrayIcon should disappear from the SystemTray. + - PropertyChangeEvent should be fired. + 5. Press Remove button again: + - It should have no effect. + - No PropertyChangeEvent should be fired. + 6. Add all the valid TrayIcons (by selecting everyone and pressing Add + button): + - All the TrayIcons should appear in the SystemTray. + - PropertyChangeEvent should be fired on each adding. + 7. Remove all the TrayIcons (again by selecting everyone and pressing + Remove): + - All the TrayIcons should disappear from the SystemTray. + - PropertyChangeEvent should be fired on each removing. + 8. Not for Windows! Remove the system tray (Notification Area) from + the desktop. Try to add some valid TrayIcon: + - AWTException should be thrown. + - No PropertyChangeEvent should be fired. + 9. Not for Windows! Add the system tray back to the desktop. Add all the + valid TrayIcons: + - All the TrayIcons should appear in the system tray. + - PropertyChangeEvent should be fired on each adding. + 11. Not for Windows! Remove the system tray from the desktop: + - All the TrayIcons should disappear. + - PropertyChangeEvent should be fired for each TrayIcon + removal. + - PropertyChangeEvent should be fired for SystemTray removal. + 12. Add the system tray and go to the next step. + - All the TrayIcons should appear again. + - PropertyChangeEvent should be fired for SystemTray addition. + - PropertyChangeEvent shouldn't be fired for TrayIcon removal. + + CASE 2: Testing RESIZE functionality. + ------------------------------------- + 1. Select some of the TrayIcons and add it. Then press resize button: + - The TrayIcon selected should be resized to fit the area it occupies. + 2. Press resize button again: + - The TrayIcon should be resized to the original size. + 3. Repeat the 1-2 steps for other TrayIcons: + - The TrayIcons should be resized appropriately. + + CASE 3: Testing EVENTS functionality + --------------------------------- + 1. Select some of the TrayIcons and add it. Select MouseEvent from the + group of checkboxes at the top-right of the test frame. + Click on the TrayIcon in the SystemTray: + - MOUSE_PRESSED MOUSE_RELEASED and MOUSE_CLICKED events should be + generated. + 2. Press mouse inside the TrayIcon dragging mouse and releasing it. + - Make sure that MOUSE_CLICKED event is not triggered. + 3. Click on the TrayIcon with different modification keys: + - there should be appropriate modifiers in the events. + 4. Keep clicking on the TrayIcon: + - there should be correct absolute coordinates in the events. + 5. Only for Windows! Focus the system tray using keyboard: + - press WIN key once to bring up the start menu then press ESC once to + close the menu the focus should be on the start button + - press TAB key for several times until you focus on the system + tray then use ARROW keys to move to the TrayIcon + - press ENTER or SPACE should trigger ACTION_PERFORMED message + make sure that mouse events are not triggered. + 6. Select MouseMotionEvent checkbox. Move mouse over the TrayIcon: + - MOUSE_MOVED event should be generated. It should contain + correct coordinates. + 7. Deselect both the checkboxes and then select AWTEventListener. + Click on the TrayIcon and then move mouse over it: + - Appropriate mouse events should be generated (catched by the + AWTEventListener). + 8. Deselect all the checkboxes and go to the following step. + + CASE 4: Testing DISPLAY MESSAGE functionality. + ---------------------------------------------- + 1. Select some of the TrayIcons and add it. Then press Display message + button: + - A balloon message should appear near the TrayIcon. + 2. After the message is displayed wait for some period: + - The message window should be closed automatically. + 3. Display the message again. Close it by pressing X in its top-right + corner: + - The message window should be closed immediately. + 4. Display the message again. Click inside it: + - The message should be closed an ACTION_PERFORMED event should be + generated with correct information and an Ok dialog should appear. + Close the dialog. + 5. Select a message type from the Type choice and display the message + again: + - It should contain an icon appropriate to the message type selected + or no icon if NONE is selected. + 6. Change the content of the Message and Caption text fields and + display the message: + - The message content should be changed in the accordance with the text + typed. + 7. Not for Windows! Type some too long or too short text for the Caption + and Message: + - The message should process the text correctly. The long text should + be cut. + 8. Not for Windows! Type null in the Message text field and display + the message: + - The message body should contain no text. + 9. Type null in the Caption text field and display the message: + - The message caption should contain no text. + 10. Type null in the both Message and Caption fields and display + the message: + - NullPointerException should be generated and no message should be + displayed. + 11. Try to hide the taskbar. Click Display message for several times. + Then restore the taskbar. Click on the TrayIcon: + - No message should appear. + Try to display the message once more: + - It should appear appropriately. + 12. Try to display the message for other TrayIcons: + - The messages should be displayed appropriately. + + CASE 5: Testing POPUP MENU functionality. + ----------------------------------------- + 1. Add some TrayIcon to the system tray. Press Set button in the + Popup menu test area. Trigger the popup menu for the TrayIcon with + the mouse: + - A popup menu should appear. Make sure it behaves properly. + - Make sure the 'duke.gif' image is animated while the popup menu is shown. + 2. Press Remove button for the popup menu and try to trigger it again: + - No popup menu should appear. + 3. Perform 1-2 steps for other TrayIcons: + - Make sure the popup menu behaves properly. + 4. Add more than one TrayIcons to the system tray. Press Set button in + the PopupMenu test area for some of the TrayIcon added. Trigger + the popup menu for this TrayIcon: + - A popup menu should appear properly. + 5. Try to set the popup menu to the same TrayIcon again: + - It should have no effect + 6. Try to set the popup menu for other TrayIcons you've added to the system + tray: + - for each one IllegalArgumentException should be thrown. + + CASE 6: Testing TOOLTIP functionality. + -------------------------------------- + 1. Type something in the Tooltip text field and press Set button. + Then move mouse cursor over the TrayIcon and wait for a second: + - A tooltip should appear containing the text typed. + 2. Show a tooltip again and keep your mouse over the TrayIcon for some period: + - The tooltip should disappear automatically. + 3. Show a tooltip again and leave the TrayIcon: + - The tooltip should disappear immediately. + 4. Type null in the Tooltip field and press set then move your + mouse to the SystemTray: + - The tooltip shouldn't appear. + 5. Type something too long in the Tooltip field and show the tooltip: + - The tooltip text should be cut. + + CASE 7: Testing ACTION functionality. + ------------------------------------- + 1. Add some TrayIcon to the system tray. Double click it with the left mouse + button: + - An ACTION_PERFORMED event should be generated. + 2. Double click the TrayIcon with the left mouse button several times: + - Several ACTION_PERFORMED events should be generated + - Make sure that the time-stamp of each event ('when' field) is increased. + + If all the above cases work as expected Press PASS else FAIL. + """; + + public static void main(String[] args) throws Exception { + if (!SystemTray.isSupported()) { + throw new SkippedException("Test not applicable as" + + " System Tray not supported"); + } + try { + PassFailJFrame.builder() + .title("TrayIconTest Instructions") + .instructions(INSTRUCTIONS) + .columns(50) + .rows(40) + .testUI(TrayIconTest::createAndShowUI) + .logArea(10) + .build() + .awaitAndCheck(); + + } finally { + EventQueue.invokeAndWait(() -> { + if (tray != null) { + //Remove any remaining tray icons before ending the test. + TrayIcon[] icons = tray.getTrayIcons(); + for (TrayIcon icon : icons) { + tray.remove(icon); + } + } + }); + } + } + + private static Frame createAndShowUI() { + final TrayIconControl ctrl = new TrayIconControl(); + frame.setLayout(new BorderLayout()); + frame.add(ctrl.cont, BorderLayout.CENTER); + frame.setBackground(Color.LIGHT_GRAY); + + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + ctrl.dispose(); + } + }); + + frame.pack(); + return frame; + } + + private static class TrayIconControl { + final String RED_ICON = "RED ICON"; + final String BLUE_ICON = "BLUE ICON"; + final String GREEN_ICON = "GREEN ICON"; + + CheckboxGroup cbg = new CheckboxGroup(); + Button addButton = new PackedButton(" Add "); + Button remButton = new PackedButton("Remove"); + Button resizeButton = new PackedButton("Resize"); + Button balloonButton = new PackedButton("Display message"); + Choice balloonChoice = new Choice(); + String[] balloonTypes = new String[] { "ERROR", "WARNING", "INFO", "NONE" }; + + TextField balloonText = new TextField( + "A TrayIcon can generate various MouseEvents and" + + " supports adding corresponding listeners to receive" + + " notification of these events. TrayIcon processes" + + " some of the events by itself. For example," + + " by default, when the right-mouse click", 70); + TextField balloonCaption = new TextField("TrayIcon", 70); + + MessageType[] typeArr = new MessageType[] { MessageType.ERROR, MessageType.WARNING, + MessageType.INFO, MessageType.NONE }; + Checkbox mouseListenerCbox = new Checkbox("MouseEvent"); + Checkbox motionListenerCbox = new Checkbox(" MouseMotionEvent"); + Checkbox awtListenerCbox = new Checkbox(" AWTEventListener"); + TextField tipText = new TextField("TrayIcon", 50); + Button tipButton = new PackedButton("Set"); + Button setPopupButton = new PackedButton("Set"); + Button remPopupButton = new PackedButton("Remove"); + + PopupMenu popupMenu = new PopupMenu(); + + Map resToObjMap = new HashMap<>(); + + Container cont = new Container(); + + TrayIconControl() { + Toolkit.getDefaultToolkit().addAWTEventListener(e -> { + if (e.getSource() instanceof TrayIcon && awtListenerCbox.getState()) { + PassFailJFrame.log(e.toString()); + } + }, MouseEvent.MOUSE_EVENT_MASK | MouseEvent.MOUSE_MOTION_EVENT_MASK | + ActionEvent.ACTION_EVENT_MASK); + + cont.setLayout(new GridLayout(4, 1)); + + Container raw1 = new Container(); + raw1.setLayout(new GridLayout(1, 4)); + cont.add(raw1); + + InsetsPanel cbgPanel = new InsetsPanel(); + cbgPanel.setLayout(new GridLayout(4, 1)); + Checkbox nullCbox = new Checkbox("null", cbg, true); + Checkbox redCbox = new Checkbox(RED_ICON, cbg, false); + Checkbox blueCbox = new Checkbox(BLUE_ICON, cbg, false); + Checkbox greenCbox = new Checkbox(GREEN_ICON, cbg, false); + cbgPanel.add(nullCbox); + cbgPanel.add(redCbox); + cbgPanel.add(blueCbox); + cbgPanel.add(greenCbox); + cbgPanel.addTo(raw1); + + InsetsPanel addremPanel = new InsetsPanel(); + addremPanel.setLayout(new BorderLayout()); + addremPanel.add(addButton.getParent(), BorderLayout.NORTH); + addremPanel.add(remButton.getParent(), BorderLayout.SOUTH); + addremPanel.addTo(raw1); + + InsetsPanel resizePanel = new InsetsPanel(); + resizePanel.add(resizeButton); + resizePanel.addTo(raw1); + + InsetsPanel lstPanel = new InsetsPanel(); + lstPanel.setLayout(new GridLayout(3, 1)); + lstPanel.add(mouseListenerCbox); + lstPanel.add(motionListenerCbox); + lstPanel.add(awtListenerCbox); + lstPanel.addTo(raw1); + + Container raw2 = new Container(); + raw2.setLayout(new BorderLayout()); + cont.add(raw2); + + InsetsPanel balloonPanel = new InsetsPanel(); + balloonPanel.setLayout(new BorderLayout()); + balloonPanel.add(balloonButton.getParent(), BorderLayout.NORTH); + Container bc = new Container(); + bc.setLayout(new FlowLayout()); + bc.add(new Label(" Type:")); + bc.add(balloonChoice); + balloonPanel.add(bc, BorderLayout.SOUTH); + balloonPanel.addTo(raw2, BorderLayout.WEST); + + InsetsPanel blnTextPanel = new InsetsPanel(); + blnTextPanel.setLayout(new GridLayout(2, 2)); + Container c1 = new Panel(); + c1.setLayout(new FlowLayout()); + blnTextPanel.add(c1); + c1.add(new Label("Message:")); + c1.add(balloonText); + + Container c2 = new Panel(); + c2.setLayout(new FlowLayout()); + blnTextPanel.add(c2); + c2.add(new Label("Caption:")); + c2.add(balloonCaption); + blnTextPanel.addTo(raw2, BorderLayout.CENTER); + + + Container raw3 = new Container(); + raw3.setLayout(new BorderLayout()); + cont.add(raw3); + + InsetsPanel popupPanel = new InsetsPanel(); + popupPanel.setLayout(new FlowLayout()); + popupPanel.add(new Label("Popup menu:")); + popupPanel.add(setPopupButton); + popupPanel.add(remPopupButton); + popupPanel.addTo(raw3); + + + Container raw4 = new Container(); + raw4.setLayout(new BorderLayout()); + cont.add(raw4); + + InsetsPanel tipPanel = new InsetsPanel(); + tipPanel.setLayout(new FlowLayout()); + tipPanel.add(new Label("Tooltip:")); + tipPanel.add(tipText); + tipPanel.add(tipButton); + tipPanel.addTo(raw4); + + addButton.addActionListener(e -> { + try { + tray.add(getCurIcon()); + } catch (NullPointerException npe) { + if (npe.getMessage() == null) { + PassFailJFrame.log("Probably wrong path to the images."); + throw npe; // if wrong images path was set + } + PassFailJFrame.log(npe.toString()); + } catch (IllegalArgumentException iae) { + PassFailJFrame.log(iae.toString()); + } catch (AWTException ise) { + PassFailJFrame.log(ise.toString()); + } + }); + remButton.addActionListener(e -> tray.remove(getCurIcon())); + + resizeButton.addActionListener( + e -> getCurIcon().setImageAutoSize(!getCurIcon().isImageAutoSize())); + + balloonButton.addActionListener(e -> { + String text = null, caption = null; + if (balloonText.getText().compareToIgnoreCase("null") != 0) { + text = balloonText.getText(); + } + if (balloonCaption.getText().compareToIgnoreCase("null") != 0) { + caption = balloonCaption.getText(); + } + try { + getCurIcon().displayMessage(caption, text, typeArr[balloonChoice.getSelectedIndex()]); + } catch (NullPointerException npe) { + PassFailJFrame.log(npe.toString()); + } + }); + + tipButton.addActionListener(e -> { + String tip = null; + if (tipText.getText().compareToIgnoreCase("null") != 0) { + tip = tipText.getText(); + } + getCurIcon().setToolTip(tip); + }); + + setPopupButton.addActionListener(e -> { + try { + getCurIcon().setPopupMenu(popupMenu); + } catch (IllegalArgumentException iae) { + PassFailJFrame.log(iae.toString()); + } + }); + + remPopupButton.addActionListener(e -> getCurIcon().setPopupMenu(null)); + for (String s: balloonTypes) { + balloonChoice.add(s); + } + + init(); + } + + void init() { + tray = SystemTray.getSystemTray(); + tray.addPropertyChangeListener("trayIcons", + e -> printPropertyChangeEvent(e)); + + tray.addPropertyChangeListener("systemTray", + e -> printPropertyChangeEvent(e)); + + configureTrayIcon(RED_ICON); + configureTrayIcon(BLUE_ICON); + configureTrayIcon(GREEN_ICON); + + for (String s: balloonTypes) { + popupMenu.add(new MenuItem(s)); + } + } + + void printPropertyChangeEvent(PropertyChangeEvent e) { + String name = e.getPropertyName(); + Object oldValue = e.getOldValue(); + Object newValue = e.getNewValue(); + + PassFailJFrame.log("PropertyChangeEvent[name=" + name + + ",oldValue=" + oldValue + ",newValue=" + newValue + "]"); + } + + void configureTrayIcon(String icon) { + Color color = Color.WHITE; + switch (icon) { + case "RED ICON" -> color = Color.RED; + case "BLUE ICON" -> color = Color.BLUE; + case "GREEN ICON" -> color = Color.GREEN; + } + Image image = createIcon(color); + TrayIcon trayIcon = new TrayIcon(image); + + trayIcon.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + if (mouseListenerCbox.getState()) + PassFailJFrame.log(e.toString()); + } + public void mouseReleased(MouseEvent e) { + if (mouseListenerCbox.getState()) + PassFailJFrame.log(e.toString()); + } + public void mouseClicked(MouseEvent e) { + if (mouseListenerCbox.getState()) + PassFailJFrame.log(e.toString()); + } + }); + trayIcon.addMouseMotionListener(new MouseMotionAdapter() { + public void mouseMoved(MouseEvent e) { + if (motionListenerCbox.getState()) + PassFailJFrame.log(e.toString()); + } + }); + trayIcon.addActionListener(e -> PassFailJFrame.log(e.toString())); + + resToObjMap.remove(icon); + resToObjMap.put(icon, trayIcon); + } + + String getCurImgName() { + return cbg.getSelectedCheckbox().getLabel(); + } + + TrayIcon getCurIcon() { + return resToObjMap.get(getCurImgName()); + } + + public void dispose() { + tray.remove(getCurIcon()); + } + + private static Image createIcon(Color color) { + BufferedImage image = new BufferedImage(16, 16, + BufferedImage.TYPE_INT_ARGB); + Graphics2D g = image.createGraphics(); + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + g.setColor(color); + g.fillRect(0, 0, 16, 16); + g.dispose(); + return image; + } + + } + + private static class InsetsPanel extends Panel { + Container parent = new Container() { + public Insets getInsets() { + return new Insets(2, 2, 2, 2); + } + }; + + InsetsPanel() { + parent.setLayout(new BorderLayout()); + setBackground(new Color(240, 240, 240)); + } + + void addTo(Container c) { + parent.add(this); + c.add(parent); + } + + void addTo(Container c, String pos) { + parent.add(this); + c.add(parent, pos); + } + } + + private static class PackedButton extends Button { + Container parent = new Container(); + PackedButton(String l) { + super(l); + parent.setLayout(new FlowLayout()); + parent.add(this); + } + } +} + From d24239bb6a1f438c048596defe6fb4c3e744f042 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 7 Apr 2025 15:26:34 +0000 Subject: [PATCH 140/846] 8340978: Open source few DnD tests - Set6 Backport-of: 32f817a46068b61d599b714a4480e3ea5d6e9050 --- test/jdk/ProblemList.txt | 1 + .../java/awt/dnd/CustomDragCursorTest.java | 289 ++++++++++++++++++ .../DnDAcceptanceTest/DnDAcceptanceTest.java | 87 ++++++ .../awt/dnd/DnDAcceptanceTest/DnDSource.java | 155 ++++++++++ .../awt/dnd/DnDAcceptanceTest/DnDTarget.java | 115 +++++++ 5 files changed, 647 insertions(+) create mode 100644 test/jdk/java/awt/dnd/CustomDragCursorTest.java create mode 100644 test/jdk/java/awt/dnd/DnDAcceptanceTest/DnDAcceptanceTest.java create mode 100644 test/jdk/java/awt/dnd/DnDAcceptanceTest/DnDSource.java create mode 100644 test/jdk/java/awt/dnd/DnDAcceptanceTest/DnDTarget.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 617f9e34069d1..ed7411e12329c 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -129,6 +129,7 @@ java/awt/dnd/MissingEventsOnModalDialog/MissingEventsOnModalDialogTest.java 8164 java/awt/dnd/URIListBetweenJVMsTest/URIListBetweenJVMsTest.java 8171510 macosx-all java/awt/dnd/DragExitBeforeDropTest.java 8242805 macosx-all java/awt/dnd/DragThresholdTest.java 8076299 macosx-all +java/awt/dnd/CustomDragCursorTest.java 8242805 macosx-all java/awt/Focus/ChoiceFocus/ChoiceFocus.java 8169103 windows-all,macosx-all java/awt/Focus/ClearLwQueueBreakTest/ClearLwQueueBreakTest.java 8198618 macosx-all java/awt/Focus/ConsumeNextKeyTypedOnModalShowTest/ConsumeNextKeyTypedOnModalShowTest.java 6986252 macosx-all diff --git a/test/jdk/java/awt/dnd/CustomDragCursorTest.java b/test/jdk/java/awt/dnd/CustomDragCursorTest.java new file mode 100644 index 0000000000000..9e5e006b31c81 --- /dev/null +++ b/test/jdk/java/awt/dnd/CustomDragCursorTest.java @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetContext; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/* + * @test + * @bug 4451328 + * @summary tests that a custom drag cursor is not changed + to the default drag cursor + * @key headful + * @run main CustomDragCursorTest + */ + +public class CustomDragCursorTest { + private static Frame frame; + private static final DragSourcePanel dragSourcePanel = new DragSourcePanel(); + private static final DropTargetPanel dropTargetPanel = new DropTargetPanel(); + + private static volatile Point srcPoint; + private static volatile Point dstPoint; + private static volatile boolean passed = true; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + EventQueue.invokeAndWait(CustomDragCursorTest::createAndShowUI); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + Point p = dragSourcePanel.getLocationOnScreen(); + Dimension d = dragSourcePanel.getSize(); + p.translate(d.width / 2, d.height / 2); + srcPoint = p; + + p = dropTargetPanel.getLocationOnScreen(); + d = dropTargetPanel.getSize(); + p.translate(d.width / 2, d.height / 2); + dstPoint = p; + }); + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (; !srcPoint.equals(dstPoint); + srcPoint.translate(sign(dstPoint.x - srcPoint.x), + sign(dstPoint.y - srcPoint.y))) { + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.delay(10); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + robot.waitForIdle(); + robot.delay(1000); + + if (!passed) { + throw new RuntimeException("Custom drag cursor changed to default."); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + frame = new Frame("CustomDragCursorTest"); + frame.setLayout(new GridLayout(2, 1)); + frame.add(dragSourcePanel); + frame.add(dropTargetPanel); + frame.setLocationRelativeTo(null); + frame.setSize(300, 400); + frame.setVisible(true); + } + + public static void failed() { + passed = false; + } + + private static int sign(int n) { + return Integer.compare(n, 0); + } + + private static class DragSourceButton extends Button implements Serializable, + Transferable, + DragGestureListener, + DragSourceListener { + private final DataFlavor dataflavor = + new DataFlavor(Button.class, "DragSourceButton"); + private final Cursor dragCursor = new Cursor(Cursor.HAND_CURSOR); + + public DragSourceButton() { + this("DragSourceButton"); + } + + public DragSourceButton(String str) { + super(str); + + DragSource ds = DragSource.getDefaultDragSource(); + ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, + this); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(dragCursor, this, this); + } + + public void dragEnter(DragSourceDragEvent dsde) { + if (!dragCursor.equals(dsde.getDragSourceContext().getCursor())) { + CustomDragCursorTest.failed(); + } + } + + public void dragExit(DragSourceEvent dse) { + if (!dragCursor.equals(dse.getDragSourceContext().getCursor())) { + CustomDragCursorTest.failed(); + } + } + + public void dragOver(DragSourceDragEvent dsde) { + if (!dragCursor.equals(dsde.getDragSourceContext().getCursor())) { + CustomDragCursorTest.failed(); + } + } + + public void dragDropEnd(DragSourceDropEvent dsde) { + if (!dragCursor.equals(dsde.getDragSourceContext().getCursor())) { + CustomDragCursorTest.failed(); + } + } + + public void dropActionChanged(DragSourceDragEvent dsde) { + if (!dragCursor.equals(dsde.getDragSourceContext().getCursor())) { + CustomDragCursorTest.failed(); + } + } + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, IOException { + + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } + + Object retObj; + + ByteArrayOutputStream baoStream = new ByteArrayOutputStream(); + ObjectOutputStream ooStream = new ObjectOutputStream(baoStream); + ooStream.writeObject(this); + + ByteArrayInputStream baiStream = new ByteArrayInputStream(baoStream.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(baiStream); + try { + retObj = ois.readObject(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + throw new RuntimeException(e.toString()); + } + + return retObj; + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { dataflavor }; + } + + public boolean isDataFlavorSupported(DataFlavor dflavor) { + return dataflavor.equals(dflavor); + } + } + + private static class DragSourcePanel extends Panel { + + final Dimension preferredDimension = new Dimension(200, 100); + + public DragSourcePanel() { + setLayout(new GridLayout(1, 1)); + add(new DragSourceButton()); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + } + + private static class DropTargetPanel extends Panel implements DropTargetListener { + + final Dimension preferredDimension = new Dimension(200, 100); + + public DropTargetPanel() { + setDropTarget(new DropTarget(this, this)); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragEnter(DropTargetDragEvent dtde) {} + + public void dragExit(DropTargetEvent dte) {} + + public void dragOver(DropTargetDragEvent dtde) {} + + public void dropActionChanged(DropTargetDragEvent dtde) {} + + public void drop(DropTargetDropEvent dtde) { + DropTargetContext dtc = dtde.getDropTargetContext(); + + if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY) != 0) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + } else { + dtde.rejectDrop(); + } + + DataFlavor[] dfs = dtde.getCurrentDataFlavors(); + Component comp = null; + + if(dfs != null && dfs.length >= 1) { + Transferable transfer = dtde.getTransferable(); + + try { + comp = (Component)transfer.getTransferData(dfs[0]); + } catch (Throwable e) { + e.printStackTrace(); + dtc.dropComplete(false); + } + } + dtc.dropComplete(true); + add(comp); + } + } +} diff --git a/test/jdk/java/awt/dnd/DnDAcceptanceTest/DnDAcceptanceTest.java b/test/jdk/java/awt/dnd/DnDAcceptanceTest/DnDAcceptanceTest.java new file mode 100644 index 0000000000000..700187f9dce49 --- /dev/null +++ b/test/jdk/java/awt/dnd/DnDAcceptanceTest/DnDAcceptanceTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Frame; +import java.awt.Panel; + +/* + * @test + * @bug 4166541 4225247 4297663 + * @summary Tests Basic DnD functionality + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DnDAcceptanceTest + */ + +public class DnDAcceptanceTest { + private static final String INSTRUCTIONS = """ + When test runs a Frame which contains a yellow button labeled + "Drag ME!" and a RED Panel will appear. + + Click on the button and drag to the red panel. + When the mouse enters the red panel + during the drag the panel should turn yellow. + + Release the mouse button, panel should turn red again and + a yellow button labeled Drag ME! should appear inside the panel. + You should be able to repeat this operation multiple times. + + If above is true press PASS, else press FAIL. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(38) + .testUI(DnDAcceptanceTest::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + Frame frame = new Frame("DnDAcceptanceTest"); + Panel mainPanel; + Component dragSource, dropTarget; + + frame.setSize(400, 400); + frame.setLayout(new BorderLayout()); + + mainPanel = new Panel(); + mainPanel.setLayout(new BorderLayout()); + + mainPanel.setBackground(Color.BLACK); + + dropTarget = new DnDTarget(Color.RED, Color.YELLOW); + dragSource = new DnDSource("Drag ME!"); + + mainPanel.add(dragSource, "North"); + mainPanel.add(dropTarget, "Center"); + frame.add(mainPanel, BorderLayout.CENTER); + frame.setAlwaysOnTop(true); + return frame; + } +} diff --git a/test/jdk/java/awt/dnd/DnDAcceptanceTest/DnDSource.java b/test/jdk/java/awt/dnd/DnDAcceptanceTest/DnDSource.java new file mode 100644 index 0000000000000..a35ccd9ee12cb --- /dev/null +++ b/test/jdk/java/awt/dnd/DnDAcceptanceTest/DnDSource.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.Container; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.MouseDragGestureRecognizer; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.InvalidDnDOperationException; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +class DnDSource extends Button implements Transferable, + DragGestureListener, + DragSourceListener { + private DataFlavor df; + private transient int dropAction; + + DnDSource(String label) { + super(label); + Toolkit.getDefaultToolkit().createDragGestureRecognizer(MouseDragGestureRecognizer.class, + DragSource.getDefaultDragSource(), + this, DnDConstants.ACTION_COPY, this); + setBackground(Color.yellow); + setForeground(Color.blue); + df = new DataFlavor(DnDSource.class, "DnDSource"); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + System.err.println("starting Drag"); + try { + dge.startDrag(null, this, this); + } catch (InvalidDnDOperationException e) { + e.printStackTrace(); + } + } + + public void dragEnter(DragSourceDragEvent dsde) { + System.err.println("[Source] dragEnter"); + dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyDrop); + } + + public void dragOver(DragSourceDragEvent dsde) { + System.err.println("[Source] dragOver"); + dropAction = dsde.getDropAction(); + System.out.println("dropAction = " + dropAction); + } + + public void dragGestureChanged(DragSourceDragEvent dsde) { + System.err.println("[Source] dragGestureChanged"); + dropAction = dsde.getDropAction(); + System.out.println("dropAction = " + dropAction); + } + + public void dragExit(DragSourceEvent dsde) { + System.err.println("[Source] dragExit"); + dsde.getDragSourceContext().setCursor(null); + } + + public void dragDropEnd(DragSourceDropEvent dsde) { + System.err.println("[Source] dragDropEnd"); + } + + public void dropActionChanged(DragSourceDragEvent dsde) { + System.err.println("[Source] dropActionChanged"); + dropAction = dsde.getDropAction(); + System.out.println("dropAction = " + dropAction); + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] {df}; + } + + public boolean isDataFlavorSupported(DataFlavor sdf) { + return df.equals(sdf); + } + + public Object getTransferData(DataFlavor tdf) throws UnsupportedFlavorException, IOException { + + Object copy = null; + + if (!df.equals(tdf)) { + throw new UnsupportedFlavorException(tdf); + } + Container parent = getParent(); + switch (dropAction) { + case DnDConstants.ACTION_COPY: + try { + copy = this.clone(); + } catch (CloneNotSupportedException e) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + + oos.writeObject(this); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bais); + try { + copy = ois.readObject(); + } catch (ClassNotFoundException cnfe) { + // do nothing + } + } + + parent.add(this); + return copy; + + case DnDConstants.ACTION_MOVE: + synchronized(this) { + if (parent != null) parent.remove(this); + } + return this; + + case DnDConstants.ACTION_LINK: + return this; + + default: + //throw new IOException("bad operation"); + return this; // workaround for: 4135456 getDropAction() always return 0 + } + } +} diff --git a/test/jdk/java/awt/dnd/DnDAcceptanceTest/DnDTarget.java b/test/jdk/java/awt/dnd/DnDAcceptanceTest/DnDTarget.java new file mode 100644 index 0000000000000..d147741f0d225 --- /dev/null +++ b/test/jdk/java/awt/dnd/DnDAcceptanceTest/DnDTarget.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.Panel; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetContext; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.io.IOException; + +class DnDTarget extends Panel implements DropTargetListener { + Color bgColor; + Color htColor; + + DnDTarget(Color bgColor, Color htColor) { + super(); + this.bgColor = bgColor; + this.htColor = htColor; + setBackground(bgColor); + setDropTarget(new DropTarget(this, this)); + } + + public void dragEnter(DropTargetDragEvent e) { + System.err.println("[Target] dragEnter"); + e.acceptDrag(DnDConstants.ACTION_COPY); + setBackground(htColor); + repaint(); + } + + public void dragOver(DropTargetDragEvent e) { + System.err.println("[Target] dragOver"); + e.acceptDrag(DnDConstants.ACTION_COPY); + } + + public void dragExit(DropTargetEvent e) { + System.err.println("[Target] dragExit"); + setBackground(bgColor); + repaint(); + } + + public void drop(DropTargetDropEvent dtde) { + System.err.println("[Target] drop"); + DropTargetContext dtc = dtde.getDropTargetContext(); + + if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY) != 0) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + } else { + dtde.rejectDrop(); + return; + } + + DataFlavor[] dfs = dtde.getCurrentDataFlavors(); + if (dfs != null && dfs.length >= 1) { + Transferable transfer = dtde.getTransferable(); + Object obj; + try { + obj = transfer.getTransferData(dfs[0]); + } catch (IOException | UnsupportedFlavorException ex) { + System.err.println(ex.getMessage()); + dtc.dropComplete(false); + return; + } + + if (obj != null) { + Button button; + try { + button = (Button) obj; + } catch (Exception e) { + System.err.println(e.getMessage()); + dtc.dropComplete(false); + return; + } + add(button); + repaint(); + } + } + setBackground(bgColor); + invalidate(); + validate(); + repaint(); + dtc.dropComplete(true); + } + + public void dropActionChanged(DropTargetDragEvent e) { + System.err.println("[Target] dropActionChanged"); + } +} From 495aa7593b3ff56fb4cdafa1d1056d11f2a74f89 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 7 Apr 2025 15:27:51 +0000 Subject: [PATCH 141/846] 8345357: test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java fails in ubuntu22.04 Backport-of: 521ed72b87d0fb1def6d94485e08be22632deef0 --- .../JRadioButton/8033699/bug8033699.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java b/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java index 9365e6ba45b25..699338c4b30f5 100644 --- a/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java +++ b/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ * @summary Incorrect radio button behavior when pressing tab key * @run main bug8033699 */ + import java.awt.KeyboardFocusManager; import java.awt.Robot; import java.awt.event.ActionListener; @@ -57,42 +58,50 @@ public class bug8033699 { public static void main(String[] args) throws Throwable { SwingUtilities.invokeAndWait(() -> { - changeLAF(); - createAndShowGUI(); + changeLAF(); + createAndShowGUI(); }); robot = new Robot(); - Thread.sleep(100); - robot.waitForIdle(); - robot.setAutoDelay(100); + robot.waitForIdle(); + robot.delay(1000); // tab key test grouped radio button runTest1(); + robot.delay(100); // tab key test non-grouped radio button runTest2(); + robot.delay(100); // shift tab key test grouped and non-grouped radio button runTest3(); + robot.delay(100); // left/up key test in grouped radio button runTest4(); + robot.delay(100); // down/right key test in grouped radio button runTest5(); + robot.delay(100); // tab from radio button in group to next component in the middle of button group layout runTest6(); + robot.delay(100); // tab to radio button in group from component in the middle of button group layout runTest7(); + robot.delay(100); // down key circle back to first button in grouped radio button runTest8(); + robot.delay(100); // Verify that ActionListener is called when a RadioButton is selected using arrow key. runTest9(); + robot.delay(100); SwingUtilities.invokeAndWait(() -> mainFrame.dispose()); } From b8887dad618cdab283b12a163893412a81effc6e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 7 Apr 2025 15:29:37 +0000 Subject: [PATCH 142/846] 8346049: jdk/test/lib/security/timestamp/TsaServer.java warnings Backport-of: 1eb54e4228ba9319ac2f980055ed366dd861ec0b --- test/lib/jdk/test/lib/security/timestamp/TsaServer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/lib/jdk/test/lib/security/timestamp/TsaServer.java b/test/lib/jdk/test/lib/security/timestamp/TsaServer.java index 9bffa1a240ff8..e103821c9b81c 100644 --- a/test/lib/jdk/test/lib/security/timestamp/TsaServer.java +++ b/test/lib/jdk/test/lib/security/timestamp/TsaServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, 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 @@ -87,7 +87,7 @@ public TsaServer(int port, KeyStore keyStore, String passphrase) * * @param handler a {@link TsaHandler} */ - public void setHandler(TsaHandler handler) { + public final void setHandler(TsaHandler handler) { server.createContext("/", handler); } @@ -113,7 +113,7 @@ public int getPort() { } @Override - public void close() throws Exception { + public void close() { stop(); } } From 7cfd95c6ee0ddd1778409e46ca9d9b90b97d622a Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 7 Apr 2025 15:31:01 +0000 Subject: [PATCH 143/846] 8281511: java/net/ipv6tests/UdpTest.java fails with checkTime failed Backport-of: ea9e3cfe03b5284ef0edc6f0eb92fcb6ffd62725 --- test/jdk/java/net/ipv6tests/TcpTest.java | 10 ++++++---- test/jdk/java/net/ipv6tests/Tests.java | 21 ++++++++------------- test/jdk/java/net/ipv6tests/UdpTest.java | 17 ++++++++++------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/test/jdk/java/net/ipv6tests/TcpTest.java b/test/jdk/java/net/ipv6tests/TcpTest.java index 3df9454237674..159f40f28868a 100644 --- a/test/jdk/java/net/ipv6tests/TcpTest.java +++ b/test/jdk/java/net/ipv6tests/TcpTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -37,6 +37,7 @@ import java.net.*; import java.io.*; +import java.util.concurrent.TimeUnit; public class TcpTest extends Tests { static ServerSocket server, server1, server2; @@ -194,13 +195,14 @@ static void test3 () throws Exception { server = new ServerSocket (0); server.setSoTimeout (5000); int port = server.getLocalPort(); - long t1 = System.currentTimeMillis(); + long t1 = System.nanoTime(); try { server.accept (); throw new RuntimeException ("accept should not have returned"); } catch (SocketTimeoutException e) {} - t1 = System.currentTimeMillis() - t1; - checkTime (t1, 5000); + t1 = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t1); + final long expectedTime = TimeUnit.SECONDS.toMillis(5); + checkIfTimeOut(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t1), expectedTime); c1 = new Socket (); c1.connect (new InetSocketAddress (ia4addr, port), 1000); diff --git a/test/jdk/java/net/ipv6tests/Tests.java b/test/jdk/java/net/ipv6tests/Tests.java index 7a6917a60382f..21cc83571ae37 100644 --- a/test/jdk/java/net/ipv6tests/Tests.java +++ b/test/jdk/java/net/ipv6tests/Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -151,19 +151,14 @@ public static void comparePackets (DatagramPacket p1, DatagramPacket p2) } } - /* check the time got is within 50% of the time expected */ - public static void checkTime (long got, long expected) { - checkTime(got, expected, expected); - } - /* check the time got is between start and end, given 50% tolerance */ - public static void checkTime(long got, long start, long end) { - dprintln("checkTime: got = " + got + " start = " + start + " end = " + end); - long upper = end + (end / 2); - long lower = start - (start / 2); - if (got > upper || got < lower) { - throw new RuntimeException("checkTime failed: got " + got - + ", expected between " + start + " and " + end); + /* check the timeout breached lower bound time rule */ + public static void checkIfTimeOut(long got, long expected) { + dprintln("checkIfTimeOut: got = " + got + " lower bound = " + expected); + + if (got < expected) { + throw new RuntimeException("checkIfTimeOut failed: got " + got + + ", expected at least " + expected ); } } diff --git a/test/jdk/java/net/ipv6tests/UdpTest.java b/test/jdk/java/net/ipv6tests/UdpTest.java index 8986af74ff456..6139db85407dd 100644 --- a/test/jdk/java/net/ipv6tests/UdpTest.java +++ b/test/jdk/java/net/ipv6tests/UdpTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -41,6 +41,7 @@ import java.net.InetAddress; import java.net.PortUnreachableException; import java.net.SocketTimeoutException; +import java.util.concurrent.TimeUnit; public class UdpTest extends Tests { static DatagramSocket c3, s1, s2, s3; @@ -138,26 +139,27 @@ static void test2 () throws Exception { s1 = new DatagramSocket (); s2 = new DatagramSocket (); s1.setSoTimeout (4000); - long t1 = System.currentTimeMillis(); + long t1 = System.nanoTime(); try { s1.receive (new DatagramPacket (new byte [128], 128)); throw new Exception ("expected receive timeout "); } catch (SocketTimeoutException e) { } - checkTime (System.currentTimeMillis() - t1, 4000); + final long expectedTime = TimeUnit.SECONDS.toMillis(4); + checkIfTimeOut(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t1), expectedTime); /* check data can be exchanged now */ simpleDataExchange (s1, ia6addr, s2, ia4addr); /* double check timeout still works */ - t1 = System.currentTimeMillis(); + t1 = System.nanoTime(); try { s1.receive (new DatagramPacket (new byte [128], 128)); throw new Exception ("expected receive timeout "); } catch (SocketTimeoutException e) { } - checkTime (System.currentTimeMillis() - t1, 4000); + checkIfTimeOut(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t1), expectedTime); /* check receive works after a delay < timeout */ @@ -174,9 +176,10 @@ public void run () { } catch (Exception e) {} } }); - t1 = System.currentTimeMillis(); + t1 = System.nanoTime(); s1.receive (new DatagramPacket (new byte [128], 128)); - checkTime (System.currentTimeMillis() - t1, 2000, 10000); + final long startTime = TimeUnit.SECONDS.toMillis(2); + checkIfTimeOut(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t1), startTime); s1.close (); s2.close (); System.out.println ("Test2: OK"); From b6b498c62b85f125b90eda5673c0162c9983651e Mon Sep 17 00:00:00 2001 From: Paul Hohensee Date: Mon, 7 Apr 2025 15:32:44 +0000 Subject: [PATCH 144/846] 8345133: Test sun/security/tools/jarsigner/TsacertOptionTest.java failed: Warning found in stdout Backport-of: 153dc6d84300e4c3446e33be820c15336cf45e72 --- test/jdk/sun/security/tools/jarsigner/TsacertOptionTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/jdk/sun/security/tools/jarsigner/TsacertOptionTest.java b/test/jdk/sun/security/tools/jarsigner/TsacertOptionTest.java index 06b5ed082f515..3655c01b5b0b9 100644 --- a/test/jdk/sun/security/tools/jarsigner/TsacertOptionTest.java +++ b/test/jdk/sun/security/tools/jarsigner/TsacertOptionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,6 +103,7 @@ void start() throws Throwable { "-alias", CA_KEY_ALIAS, "-keystore", KEYSTORE, "-storepass", PASSWORD, + "-startdate", "-1M", "-keypass", PASSWORD, "-validity", Integer.toString(VALIDITY), "-infile", "certreq", From 7a29de5fd6670bfecfd616777cb90946f338076c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 7 Apr 2025 15:37:44 +0000 Subject: [PATCH 145/846] 8271419: Refactor test code for modifying CDS archive contents Reviewed-by: mbaesken Backport-of: 84f02310310293163130dde24e30563d39f1610a --- .../cds/appcds/SharedArchiveConsistency.java | 332 ++---------------- .../lib/jdk/test/lib/cds/CDSArchiveUtils.java | 314 +++++++++++++++++ 2 files changed, 348 insertions(+), 298 deletions(-) create mode 100644 test/lib/jdk/test/lib/cds/CDSArchiveUtils.java diff --git a/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java b/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java index 0993dc74cd88b..404f3271b9e85 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java @@ -34,42 +34,12 @@ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SharedArchiveConsistency on * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SharedArchiveConsistency auto */ +import jdk.test.lib.cds.CDSArchiveUtils; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.Utils; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.FileChannel; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; -import java.nio.file.StandardOpenOption; -import static java.nio.file.StandardOpenOption.READ; -import static java.nio.file.StandardOpenOption.WRITE; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Random; -import jdk.test.whitebox.WhiteBox; public class SharedArchiveConsistency { - public static WhiteBox wb; - public static int offset_magic; // CDSFileMapHeaderBase::_magic - public static int offset_version; // CDSFileMapHeaderBase::_version - public static int offset_jvm_ident; // FileMapHeader::_jvm_ident - public static int sp_offset_crc; // CDSFileMapRegion::_crc - public static int file_header_size = -1;// total size of header, variant, need calculation - public static int CDSFileMapRegion_size; // size of CDSFileMapRegion - public static int sp_offset; // offset of CDSFileMapRegion - public static int sp_used_offset; // offset of CDSFileMapRegion::_used - public static int size_t_size; // size of size_t - public static int int_size; // size of int - public static long alignment; // MetaspaceShared::core_region_alignment - public static boolean shareAuto; // true == -Xshare:auto // false == -Xshare:on @@ -94,256 +64,14 @@ public class SharedArchiveConsistency { "The shared archive file has been truncated." }; - public static void getFileOffsetInfo() throws Exception { - wb = WhiteBox.getWhiteBox(); - offset_magic = wb.getOffsetForName("FileMapHeader::_magic"); - offset_version = wb.getOffsetForName("FileMapHeader::_version"); - offset_jvm_ident = wb.getOffsetForName("FileMapHeader::_jvm_ident"); - sp_offset_crc = wb.getOffsetForName("CDSFileMapRegion::_crc"); - try { - int nonExistOffset = wb.getOffsetForName("FileMapHeader::_non_exist_offset"); - System.exit(-1); // should fail - } catch (Exception e) { - // success - } - - sp_offset = wb.getOffsetForName("FileMapHeader::_space[0]") - offset_magic; - sp_used_offset = wb.getOffsetForName("CDSFileMapRegion::_used") - sp_offset_crc; - size_t_size = wb.getOffsetForName("size_t_size"); - CDSFileMapRegion_size = wb.getOffsetForName("CDSFileMapRegion_size"); - alignment = wb.metaspaceSharedRegionAlignment(); - } - - public static int getFileHeaderSize(FileChannel fc) throws Exception { - if (file_header_size != -1) { - return file_header_size; - } - // this is not real header size, it is struct size - int_size = wb.getOffsetForName("int_size"); - file_header_size = wb.getOffsetForName("file_header_size"); - System.out.println("file_header_size = " + file_header_size); - file_header_size = (int)align_up_page(file_header_size); - System.out.println("file_header_size (aligned to page) = " + file_header_size); - return file_header_size; - } - - public static long align_up_page(long l) throws Exception { - // wb is obtained in getFileOffsetInfo() which is called first in main() else we should call - // WhiteBox.getWhiteBox() here first. - int pageSize = wb.getVMPageSize(); - return (l + pageSize -1) & (~ (pageSize - 1)); - } - - private static long getRandomBetween(long start, long end) throws Exception { - if (start > end) { - throw new IllegalArgumentException("start must be less than end"); - } - Random aRandom = Utils.getRandomInstance(); - int d = aRandom.nextInt((int)(end - start)); - if (d < 1) { - d = 1; - } - return start + d; - } - - public static long readInt(FileChannel fc, long offset, int nbytes) throws Exception { - ByteBuffer bb = ByteBuffer.allocate(nbytes); - bb.order(ByteOrder.nativeOrder()); - fc.position(offset); - fc.read(bb); - return (nbytes > 4 ? bb.getLong(0) : bb.getInt(0)); - } - - public static void writeData(FileChannel fc, long offset, ByteBuffer bb) throws Exception { - fc.position(offset); - fc.write(bb); - } - - public static FileChannel getFileChannel(File jsaFile) throws Exception { - List arry = new ArrayList(); - arry.add(READ); - arry.add(WRITE); - return FileChannel.open(jsaFile.toPath(), new HashSet(arry)); - } - - public static void modifyJsaContentRandomly(File jsaFile) throws Exception { - FileChannel fc = getFileChannel(jsaFile); - // corrupt random area in the data areas - long[] used = new long[num_regions]; // record used bytes - long start0, start, end, off; - int used_offset, path_info_size; - - int bufSize; - System.out.printf("%-24s%12s%12s%16s\n", "Space Name", "Used bytes", "Reg Start", "Random Offset"); - start0 = getFileHeaderSize(fc); - for (int i = 0; i < num_regions; i++) { - used[i] = get_region_used_size_aligned(fc, i); - start = start0; - for (int j = 0; j < i; j++) { - start += align_up_page(used[j]); - } - end = start + used[i]; - if (start == end) { - continue; // Ignore empty regions - } - off = getRandomBetween(start, end); - System.out.printf("%-24s%12d%12d%16d\n", shared_region_name[i], used[i], start, off); - if (end - off < 1024) { - bufSize = (int)(end - off + 1); - } else { - bufSize = 1024; - } - ByteBuffer bbuf = ByteBuffer.wrap(new byte[bufSize]); - writeData(fc, off, bbuf); - } - if (fc.isOpen()) { - fc.close(); - } - } - - static long get_region_used_size_aligned(FileChannel fc, int region) throws Exception { - long n = sp_offset + CDSFileMapRegion_size * region + sp_used_offset; - long used = readInt(fc, n, size_t_size); - used = (used + alignment - 1) & ~(alignment - 1); - return used; - } - - public static boolean modifyJsaContent(int region, File jsaFile) throws Exception { - FileChannel fc = getFileChannel(jsaFile); - byte[] buf = new byte[4096]; - ByteBuffer bbuf = ByteBuffer.wrap(buf); - - long total = 0L; - long[] used = new long[num_regions]; - System.out.printf("%-24s%12s\n", "Space name", "Used bytes"); - for (int i = 0; i < num_regions; i++) { - used[i] = get_region_used_size_aligned(fc, i); - System.out.printf("%-24s%12d\n", shared_region_name[i], used[i]); - total += used[i]; - } - System.out.printf("%-24s%12d\n", "Total: ", total); - long header_size = getFileHeaderSize(fc); - long region_start_offset = header_size; - for (int i=0; i end) { + throw new IllegalArgumentException("start must be less than end"); + } + Random aRandom = Utils.getRandomInstance(); + int d = aRandom.nextInt((int)(end - start)); + if (d < 1) { + d = 1; + } + return start + d; + } + + public static void modifyContentRandomly(File jsaFile) throws Exception { + // corrupt random area in the data areas + long[] used = new long[num_regions]; // record used bytes + long start0, start, end, offset; + int bufSize; + + System.out.printf("%-24s%12s%12s%16s\n", "Space Name", "Used bytes", "Reg Start", "Random Offset"); + start0 = fileHeaderSize; + for (int i = 0; i < num_regions; i++) { + used[i] = usedRegionSizeAligned(jsaFile, i); + start = start0; + for (int j = 0; j < i; j++) { + start += alignUpWithAlignment(used[j]); + } + end = start + used[i]; + if (start == end) { + continue; // Ignore empty regions + } + offset = getRandomBetween(start, end); + System.out.printf("%-24s%12d%12d%16d\n", shared_region_name[i], used[i], start, offset); + if (end - offset < 1024) { + bufSize = (int)(end - offset + 1); + } else { + bufSize = 1024; + } + writeData(jsaFile, offset, new byte[bufSize]); + } + } + + public static void modifyRegionContentRandomly(File jsaFile) throws Exception { + // corrupt random area in the data areas + long[] used = new long[num_regions]; // record used bytes + long start0, start, end, offset; + int bufSize; + + System.out.printf("%-24s%12s%12s%16s\n", "Space Name", "Used bytes", "Reg Start", "Random Offset"); + start0 = fileHeaderSize; + for (int i = 0; i < num_regions; i++) { + used[i] = usedRegionSizeAligned(jsaFile, i); + start = start0; + for (int j = 0; j < i; j++) { + start += alignUpWithAlignment(used[j]); + } + end = start + used[i]; + if (start == end) { + continue; // Ignore empty regions + } + offset = getRandomBetween(start, end); + System.out.printf("%-24s%12d%12d%16d\n", shared_region_name[i], used[i], start, offset); + if (end - offset < 1024) { + bufSize = (int)(end - offset + 1); + } else { + bufSize = 1024; + } + writeData(jsaFile, offset, new byte[bufSize]); + } + } + + public static boolean modifyRegionContent(int region, File jsaFile) throws Exception { + long total = 0L; + long[] used = new long[num_regions]; + System.out.printf("%-24s%12s\n", "Space name", "Used bytes"); + for (int i = 0; i < num_regions; i++) { + used[i] = usedRegionSizeAligned(jsaFile, i); + System.out.printf("%-24s%12d\n", shared_region_name[i], used[i]); + total += used[i]; + } + if (used[region] == 0) { + System.out.println("Region " + shared_region_name[region] + " is empty. Nothing to corrupt."); + return false; + } + byte[] buf = new byte[4096]; + System.out.printf("%-24s%12d\n", "Total: ", total); + long regionStartOffset = fileHeaderSize; + for (int i = 0; i < region; i++) { + regionStartOffset += used[i]; + } + System.out.println("Corrupt " + shared_region_name[region] + " section, start = " + regionStartOffset + + " (header_size + 0x" + Long.toHexString(regionStartOffset - fileHeaderSize) + ")"); + long bytesWritten = 0L; + while (bytesWritten < used[region]) { + bytesWritten += writeData(jsaFile, regionStartOffset + bytesWritten, buf); + } + return true; + } + + public static void modifyFileHeader(File jsaFile) throws Exception { + // screw up header info + byte[] buf = new byte[fileHeaderSize]; + writeData(jsaFile, 0, buf); + } + + public static void modifyJvmIdent(File jsaFile, String newJvmIdent) throws Exception { + byte[] buf = newJvmIdent.getBytes(); + writeData(jsaFile, (long)offsetJvmIdent, buf); + } + + public static void modifyHeaderIntField(File jsaFile, long offset, int value) throws Exception { + System.out.println(" offset " + offset); + + byte[] bytes = ByteBuffer.allocate(4).putInt(value).array(); + writeData(jsaFile, offset, bytes); + } + + // copy archive and set copied read/write permit + public static File copyArchiveFile(File orgJsaFile, String newName) throws Exception { + File newJsaFile = new File(newName); + if (newJsaFile.exists()) { + if (!newJsaFile.delete()) { + throw new IOException("Could not delete file " + newJsaFile); + } + } + Files.copy(orgJsaFile.toPath(), newJsaFile.toPath(), REPLACE_EXISTING); + + // change permission + setReadWritePermission(newJsaFile); + + return newJsaFile; + } + + private static FileChannel getFileChannel(File file) throws Exception { + List arry = new ArrayList(); + arry.add(READ); + arry.add(WRITE); + return FileChannel.open(file.toPath(), new HashSet(arry)); + } + + public static long readInt(File file, long offset, int nBytes) throws Exception { + try (FileChannel fc = getFileChannel(file)) { + ByteBuffer bb = ByteBuffer.allocate(nBytes); + bb.order(ByteOrder.nativeOrder()); + fc.position(offset); + fc.read(bb); + return (nBytes > 4 ? bb.getLong(0) : bb.getInt(0)); + } + } + + private static long writeData(FileChannel fc, long offset, ByteBuffer bb) throws Exception { + fc.position(offset); + return fc.write(bb); + } + + public static long writeData(File file, long offset, byte[] array) throws Exception { + try (FileChannel fc = getFileChannel(file)) { + ByteBuffer bbuf = ByteBuffer.wrap(array); + return writeData(fc, offset, bbuf); + } + } + + // dstFile will keep original size so will remove corresponding bytes.length bytes at end of file + public static File insertBytesRandomlyAfterHeader(File orgFile, String newFileName, byte[] bytes) throws Exception { + long offset = fileHeaderSize + getRandomBetween(0L, 4096L); + File dstFile = new File(newFileName); + try (FileChannel inputChannel = new FileInputStream(orgFile).getChannel(); + FileChannel outputChannel = new FileOutputStream(dstFile).getChannel()) { + long orgSize = inputChannel.size(); + outputChannel.transferFrom(inputChannel, 0, offset); + outputChannel.position(offset); + outputChannel.write(ByteBuffer.wrap(bytes)); + outputChannel.transferFrom(inputChannel, offset + bytes.length, orgSize - bytes.length); + } + return dstFile; + } + + // delete nBytes bytes from offset, so new file will be smaller than the original + public static File deleteBytesAtRandomPositionAfterHeader(File orgFile, String newFileName, int nBytes) throws Exception { + long offset = fileHeaderSize + getRandomBetween(0L, 4096L); + File dstFile = new File(newFileName); + try (FileChannel inputChannel = new FileInputStream(orgFile).getChannel(); + FileChannel outputChannel = new FileOutputStream(dstFile).getChannel()) { + long orgSize = inputChannel.size(); + outputChannel.transferFrom(inputChannel, 0, offset); + inputChannel.position(offset + nBytes); + outputChannel.transferFrom(inputChannel, offset, orgSize - nBytes); + } + return dstFile; + } + + // used region size + public static long usedRegionSizeAligned(File archiveFile, int region) throws Exception { + long offset = spOffset + cdsFileMapRegionSize * region + spUsedOffset; + long used = readInt(archiveFile, offset, sizetSize); + return alignUpWithAlignment(used); + } +} From 9ef3fb480ec1511caac3d409ca7eda8fedf43bb1 Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Mon, 7 Apr 2025 16:18:35 +0000 Subject: [PATCH 146/846] 8352716: (tz) Update Timezone Data to 2025b Reviewed-by: serb Backport-of: 1d205f5f0704f251eb68165f3caf1e70d542ae63 --- make/data/tzdata/VERSION | 2 +- make/data/tzdata/asia | 12 ++- make/data/tzdata/northamerica | 9 ++ make/data/tzdata/southamerica | 86 +++++++++++++++---- make/data/tzdata/zone.tab | 3 +- .../java/util/TimeZone/TimeZoneData/VERSION | 2 +- 6 files changed, 94 insertions(+), 20 deletions(-) diff --git a/make/data/tzdata/VERSION b/make/data/tzdata/VERSION index 9c056fac34575..4bd54efbcdcf3 100644 --- a/make/data/tzdata/VERSION +++ b/make/data/tzdata/VERSION @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2025a +tzdata2025b diff --git a/make/data/tzdata/asia b/make/data/tzdata/asia index b0a6fa01d2081..55b13134f9c6d 100644 --- a/make/data/tzdata/asia +++ b/make/data/tzdata/asia @@ -1523,6 +1523,16 @@ Zone Asia/Jayapura 9:22:48 - LMT 1932 Nov # (UIT No. 143 17.XI.1977) and not 23 September (UIT No. 141 13.IX.1977). # UIT is the Operational Bulletin of International Telecommunication Union. +# From Roozbeh Pournader (2025-03-18): +# ... the exact time of Iran's transition from +0400 to +0330 ... was Friday +# 1357/8/19 AP=1978-11-10. Here's a newspaper clip from the Ettela'at +# newspaper, dated 1357/8/14 AP=1978-11-05, translated from Persian +# (at https://w.wiki/DUEY): +# Following the government's decision about returning the official time +# to the previous status, the spokesperson for the Ministry of Energy +# announced today: At the hour 24 of Friday 19th of Aban (=1978-11-10), +# the country's time will be pulled back half an hour. +# # From Roozbeh Pournader (2003-03-15): # This is an English translation of what I just found (originally in Persian). # The Gregorian dates in brackets are mine: @@ -1650,7 +1660,7 @@ Rule Iran 2021 2022 - Sep 21 24:00 0 - Zone Asia/Tehran 3:25:44 - LMT 1916 3:25:44 - TMT 1935 Jun 13 # Tehran Mean Time 3:30 Iran %z 1977 Oct 20 24:00 - 4:00 Iran %z 1979 + 4:00 Iran %z 1978 Nov 10 24:00 3:30 Iran %z diff --git a/make/data/tzdata/northamerica b/make/data/tzdata/northamerica index 0a54e63becc86..21f178ee8cb05 100644 --- a/make/data/tzdata/northamerica +++ b/make/data/tzdata/northamerica @@ -1634,6 +1634,15 @@ Zone America/Moncton -4:19:08 - LMT 1883 Dec 9 # For more on Orillia, see: Daubs K. Bold attempt at daylight saving # time became a comic failure in Orillia. Toronto Star 2017-07-08. # https://www.thestar.com/news/insight/2017/07/08/bold-attempt-at-daylight-saving-time-became-a-comic-failure-in-orillia.html +# From Paul Eggert (2025-03-20): +# Also see the 1912-06-17 front page of The Evening Sunbeam, +# reproduced in: Richardson M. "Daylight saving was a confusing +# time in Orillia" in the 2025-03-15 Orillia Matters. Richardson writes, +# "The first Sunday after the switch was made, [DST proponent and +# Orillia mayor William Sword] Frost walked into church an hour late. +# This became a symbol of the downfall of daylight saving in Orillia." +# The mayor became known as "Daylight Bill". +# https://www.orilliamatters.com/local-news/column-daylight-saving-was-a-confusing-time-in-orillia-10377529 # From Mark Brader (2010-03-06): # diff --git a/make/data/tzdata/southamerica b/make/data/tzdata/southamerica index 0a5859600e8ff..ca3c338591fd8 100644 --- a/make/data/tzdata/southamerica +++ b/make/data/tzdata/southamerica @@ -1269,35 +1269,45 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914 # dates to 2014. # DST End: last Saturday of April 2014 (Sun 27 Apr 2014 03:00 UTC) # DST Start: first Saturday of September 2014 (Sun 07 Sep 2014 04:00 UTC) -# http://www.diariooficial.interior.gob.cl//media/2014/02/19/do-20140219.pdf +# From Tim Parenti (2025-03-22): +# Decreto 307 of 2014 of the Ministry of the Interior and Public Security, +# promulgated 2014-01-30 and published 2014-02-19: +# https://www.diariooficial.interior.gob.cl/media/2014/02/19/do-20140219.pdf#page=1 +# https://www.bcn.cl/leychile/navegar?idNorma=1059557 # From Eduardo Romero Urra (2015-03-03): # Today has been published officially that Chile will use the DST time # permanently until March 25 of 2017 -# http://www.diariooficial.interior.gob.cl/media/2015/03/03/1-large.jpg -# -# From Paul Eggert (2015-03-03): -# For now, assume that the extension will persist indefinitely. +# From Tim Parenti (2025-03-22): +# Decreto 106 of 2015 of the Ministry of the Interior and Public Security, +# promulgated 2015-01-27 and published 2015-03-03: +# https://www.diariooficial.interior.gob.cl/media/2015/03/03/do-20150303.pdf#page=1 +# https://www.bcn.cl/leychile/navegar?idNorma=1075157 # From Juan Correa (2016-03-18): -# The decree regarding DST has been published in today's Official Gazette: -# http://www.diariooficial.interior.gob.cl/versiones-anteriores/do/20160318/ -# http://www.leychile.cl/Navegar?idNorma=1088502 +# The decree regarding DST has been published in today's Official Gazette... # It does consider the second Saturday of May and August as the dates # for the transition; and it lists DST dates until 2019, but I think # this scheme will stick. -# # From Paul Eggert (2016-03-18): -# For now, assume the pattern holds for the indefinite future. # The decree says transitions occur at 24:00; in practice this appears # to mean 24:00 mainland time, not 24:00 local time, so that Easter # Island is always two hours behind the mainland. +# From Tim Parenti (2025-03-22): +# Decreto 253 of 2016 of the Ministry of the Interior and Public Security, +# promulgated 2016-03-16 and published 2016-03-18. +# https://www.diariooficial.interior.gob.cl/media/2016/03/18/do-20160318.pdf#page=1 +# https://www.bcn.cl/leychile/navegar?idNorma=1088502 # From Juan Correa (2016-12-04): # Magallanes region ... will keep DST (UTC -3) all year round.... # http://www.soychile.cl/Santiago/Sociedad/2016/12/04/433428/Bachelet-firmo-el-decreto-para-establecer-un-horario-unico-para-la-Region-de-Magallanes.aspx -# From Deborah Goldsmith (2017-01-19): -# http://www.diariooficial.interior.gob.cl/publicaciones/2017/01/17/41660/01/1169626.pdf +# From Tim Parenti (2025-03-22), via Deborah Goldsmith (2017-01-19): +# Decreto 1820 of 2016 of the Ministry of the Interior and Public Security, +# promulgated 2016-12-02 and published 2017-01-17: +# https://www.diariooficial.interior.gob.cl/publicaciones/2017/01/17/41660/01/1169626.pdf +# https://www.bcn.cl/leychile/Navegar?idNorma=1099217 +# Model this as a change to standard offset effective 2016-12-04. # From Juan Correa (2018-08-13): # As of moments ago, the Ministry of Energy in Chile has announced the new @@ -1316,13 +1326,20 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914 # https://twitter.com/MinEnergia/status/1029009354001973248 # "We will keep the new time policy unchanged for at least the next 4 years." # So we extend the new rules on Saturdays at 24:00 mainland time indefinitely. -# From Juan Correa (2019-02-04): -# http://www.diariooficial.interior.gob.cl/publicaciones/2018/11/23/42212/01/1498738.pdf +# From Tim Parenti (2025-03-22), via Juan Correa (2019-02-04): +# Decreto 1286 of 2018 of the Ministry of the Interior and Public Security, +# promulgated 2018-09-21 and published 2018-11-23: +# https://www.diariooficial.interior.gob.cl/publicaciones/2018/11/23/42212/01/1498738.pdf +# https://www.bcn.cl/leychile/Navegar?idNorma=1125760 # From Juan Correa (2022-04-02): # I found there was a decree published last Thursday that will keep -# Magallanes region to UTC -3 "indefinitely". The decree is available at +# Magallanes region to UTC -3 "indefinitely". +# From Tim Parenti (2025-03-22): +# Decreto 143 of 2022 of the Ministry of the Interior and Public Security, +# promulgated 2022-03-29 and published 2022-03-31: # https://www.diariooficial.interior.gob.cl/publicaciones/2022/03/31/43217-B/01/2108910.pdf +# https://www.bcn.cl/leychile/Navegar?idNorma=1174342 # From Juan Correa (2022-08-09): # the Internal Affairs Ministry (Ministerio del Interior) informed DST @@ -1331,13 +1348,36 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914 # will keep UTC -3 "indefinitely"... This is because on September 4th # we will have a voting whether to approve a new Constitution. # -# From Eduardo Romero Urra (2022-08-17): +# From Tim Parenti (2025-03-22), via Eduardo Romero Urra (2022-08-17): +# Decreto 224 of 2022 of the Ministry of the Interior and Public Security, +# promulgated 2022-07-14 and published 2022-08-13: # https://www.diariooficial.interior.gob.cl/publicaciones/2022/08/13/43327/01/2172567.pdf +# https://www.bcn.cl/leychile/navegar?idNorma=1179983 # # From Paul Eggert (2022-08-17): # Although the presidential decree stops at fall 2026, assume that # similar DST rules will continue thereafter. +# From Paul Eggert (2025-01-15): +# Diario Regional Aysén's Sebastián Martel reports that 94% of Aysén +# citizens polled in November favored changing the rules from +# -04/-03-with-DST to -03 all year... +# https://www.diarioregionalaysen.cl/noticia/actualidad/2024/12/presentan-decision-que-gano-la-votacion-sobre-el-cambio-del-huso-horario-en-aysen +# +# From Yonathan Dossow (2025-03-20): +# [T]oday we have more confirmation of the change. [Aysén] region will keep +# UTC-3 all year... +# https://www.cnnchile.com/pais/region-de-aysen-mantendra-horario-de-verano-todo-el-ano_20250320/ +# https://www.latercera.com/nacional/noticia/tras-consulta-ciudadana-region-de-aysen-mantendra-el-horario-de-verano-durante-todo-el-ano/ +# https://x.com/min_interior/status/1902692504270672098 +# +# From Tim Parenti (2025-03-22), via Eduardo Romero Urra (2025-03-20): +# Decreto 93 of 2025 of the Ministry of the Interior and Public Security, +# promulgated 2025-03-11 and published 2025-03-20: +# https://www.diariooficial.interior.gob.cl/publicaciones/2025/03/20/44104/01/2624263.pdf +# https://www.bcn.cl/leychile/Navegar?idNorma=1211955 +# Model this as a change to standard offset effective 2025-03-20. + # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Chile 1927 1931 - Sep 1 0:00 1:00 - Rule Chile 1928 1932 - Apr 1 0:00 0 - @@ -1394,6 +1434,20 @@ Zone America/Santiago -4:42:45 - LMT 1890 -5:00 1:00 %z 1947 Mar 31 24:00 -5:00 - %z 1947 May 21 23:00 -4:00 Chile %z +Zone America/Coyhaique -4:48:16 - LMT 1890 + -4:42:45 - SMT 1910 Jan 10 + -5:00 - %z 1916 Jul 1 + -4:42:45 - SMT 1918 Sep 10 + -4:00 - %z 1919 Jul 1 + -4:42:45 - SMT 1927 Sep 1 + -5:00 Chile %z 1932 Sep 1 + -4:00 - %z 1942 Jun 1 + -5:00 - %z 1942 Aug 1 + -4:00 - %z 1946 Aug 28 24:00 + -5:00 1:00 %z 1947 Mar 31 24:00 + -5:00 - %z 1947 May 21 23:00 + -4:00 Chile %z 2025 Mar 20 + -3:00 - %z Zone America/Punta_Arenas -4:43:40 - LMT 1890 -4:42:45 - SMT 1910 Jan 10 -5:00 - %z 1916 Jul 1 diff --git a/make/data/tzdata/zone.tab b/make/data/tzdata/zone.tab index e7a4868c39d0e..c8fc601041bca 100644 --- a/make/data/tzdata/zone.tab +++ b/make/data/tzdata/zone.tab @@ -162,7 +162,8 @@ CH +4723+00832 Europe/Zurich CI +0519-00402 Africa/Abidjan CK -2114-15946 Pacific/Rarotonga CL -3327-07040 America/Santiago most of Chile -CL -5309-07055 America/Punta_Arenas Region of Magallanes +CL -4534-07204 America/Coyhaique Aysen Region +CL -5309-07055 America/Punta_Arenas Magallanes Region CL -2709-10926 Pacific/Easter Easter Island CM +0403+00942 Africa/Douala CN +3114+12128 Asia/Shanghai Beijing Time diff --git a/test/jdk/java/util/TimeZone/TimeZoneData/VERSION b/test/jdk/java/util/TimeZone/TimeZoneData/VERSION index 5159b3786e385..750d9fae2b135 100644 --- a/test/jdk/java/util/TimeZone/TimeZoneData/VERSION +++ b/test/jdk/java/util/TimeZone/TimeZoneData/VERSION @@ -1 +1 @@ -tzdata2025a +tzdata2025b From ac00cd26889308164704d8bc902102c2f7486c9a Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Mon, 7 Apr 2025 16:18:48 +0000 Subject: [PATCH 147/846] 8329261: G1: interpreter post-barrier x86 code asserts index size of wrong buffer Backport-of: 1131bb77ec94dd131a10df4ba0f3fab32c65c0f2 --- src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp index 8316df3644bb5..2b06c3f365cab 100644 --- a/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp @@ -265,8 +265,6 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, Register thread, Register tmp, Register tmp2) { - // Generated code assumes that buffer index is pointer sized. - STATIC_ASSERT(in_bytes(SATBMarkQueue::byte_width_of_index()) == sizeof(intptr_t)); #ifdef _LP64 assert(thread == r15_thread, "must be"); #endif // _LP64 @@ -317,6 +315,9 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, __ movb(Address(card_addr, 0), (int)G1CardTable::dirty_card_val()); + // The code below assumes that buffer index is pointer sized. + STATIC_ASSERT(in_bytes(G1DirtyCardQueue::byte_width_of_index()) == sizeof(intptr_t)); + __ movptr(tmp2, queue_index); __ testptr(tmp2, tmp2); __ jcc(Assembler::zero, runtime); From 8ea7310b57403f20ac8b0c6e13ecd67e0360c9c1 Mon Sep 17 00:00:00 2001 From: Andrew John Hughes Date: Tue, 8 Apr 2025 14:11:41 +0000 Subject: [PATCH 148/846] 8331735: UpcallLinker::on_exit races with GC when copying frame anchor 8286875: ProgrammableUpcallHandler::on_entry/on_exit access thread fields from native Reviewed-by: mbalao Backport-of: 91457e694353386737e325e6fa0253bcefb8d579 --- src/hotspot/share/prims/universalUpcallHandler.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/prims/universalUpcallHandler.cpp b/src/hotspot/share/prims/universalUpcallHandler.cpp index 44b64504d1c75..b34704ea7b52a 100644 --- a/src/hotspot/share/prims/universalUpcallHandler.cpp +++ b/src/hotspot/share/prims/universalUpcallHandler.cpp @@ -131,21 +131,17 @@ void ProgrammableUpcallHandler::on_exit(OptimizedEntryBlob::FrameData* context) // restore previous handle block thread->set_active_handles(context->old_handles); - thread->frame_anchor()->zap(); - debug_only(thread->dec_java_call_counter()); + thread->frame_anchor()->copy(&context->jfa); + // Old thread-local info. has been restored. We are now back in native code. ThreadStateTransition::transition_from_java(thread, _thread_in_native); - thread->frame_anchor()->copy(&context->jfa); - // Release handles after we are marked as being in native code again, since this // operation might block JNIHandleBlock::release_block(context->new_handles, thread); - assert(!thread->has_pending_exception(), "Upcall can not throw an exception"); - if (context->should_detach) { detach_current_thread(); } From 0beb2718e7fd8e9cc5d8cca1c09d997b104355e8 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Apr 2025 13:32:35 +0000 Subject: [PATCH 149/846] 8196465: javax/swing/JComboBox/8182031/ComboPopupTest.java fails on Linux Backport-of: 83466434fda3bd048fa8e2d274a797a7d9506c16 --- test/jdk/ProblemList.txt | 1 - .../JComboBox/8182031/ComboPopupTest.java | 33 +++++++------------ 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index ed7411e12329c..e89b9bf260f1b 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -694,7 +694,6 @@ javax/swing/JTabbedPane/8007563/Test8007563.java 8051591 generic-all javax/swing/JTabbedPane/4624207/bug4624207.java 8064922 macosx-all javax/swing/SwingUtilities/TestBadBreak/TestBadBreak.java 8160720 generic-all javax/swing/JFileChooser/6798062/bug6798062.java 8146446 windows-all -javax/swing/JComboBox/8182031/ComboPopupTest.java 8196465 linux-all,macosx-all javax/swing/JFileChooser/6738668/bug6738668.java 8194946 generic-all javax/swing/JInternalFrame/Test6325652.java 8224977 macosx-all javax/swing/JPopupMenu/4870644/bug4870644.java 8194130 macosx-all,linux-all diff --git a/test/jdk/javax/swing/JComboBox/8182031/ComboPopupTest.java b/test/jdk/javax/swing/JComboBox/8182031/ComboPopupTest.java index 9321bd154be34..5bbf613268967 100644 --- a/test/jdk/javax/swing/JComboBox/8182031/ComboPopupTest.java +++ b/test/jdk/javax/swing/JComboBox/8182031/ComboPopupTest.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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,22 +46,6 @@ public class ComboPopupTest { private volatile Point p = null; private volatile Dimension d = null; - void blockTillDisplayed(JComponent comp) throws Exception { - while (p == null) { - try { - SwingUtilities.invokeAndWait(() -> { - p = comp.getLocationOnScreen(); - d = comboBox.getSize(); - }); - } catch (IllegalStateException e) { - try { - Thread.sleep(1000); - } catch (InterruptedException ie) { - } - } - } - } - public static void main(String[] args) throws Exception { new ComboPopupTest(); } @@ -69,13 +53,18 @@ public static void main(String[] args) throws Exception { public ComboPopupTest() throws Exception { try { Robot robot = new Robot(); - robot.setAutoDelay(200); + robot.setAutoDelay(100); SwingUtilities.invokeAndWait(() -> start()); - blockTillDisplayed(comboBox); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + p = comboBox.getLocationOnScreen(); + d = comboBox.getSize(); + }); + robot.waitForIdle(); + robot.mouseMove(p.x + d.width - 1, p.y + d.height/2); robot.waitForIdle(); - robot.mouseMove(p.x + d.width-1, p.y + d.height/2); - robot.mousePress(InputEvent.BUTTON1_MASK); - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); robot.waitForIdle(); System.out.println("popmenu visible " + comboBox.isPopupVisible()); From c2e4aa423ebbac60c1288c0cdfdf07fe9667c8cb Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Apr 2025 13:33:59 +0000 Subject: [PATCH 150/846] 8316324: Opensource five miscellaneous Swing tests Backport-of: 7560dbb9258f651a221bc8350816845735929fd9 --- .../javax/swing/InputVerifier/bug4774166.java | 255 ++++++++++++++++++ .../swing/JButton/DefaultButtonLeak.java | 69 +++++ test/jdk/javax/swing/JButton/bug4385611.java | 97 +++++++ .../javax/swing/JComponent/bug4706883.java | 109 ++++++++ .../javax/swing/plaf/motif/bug4150591.java | 42 +++ 5 files changed, 572 insertions(+) create mode 100644 test/jdk/javax/swing/InputVerifier/bug4774166.java create mode 100644 test/jdk/javax/swing/JButton/DefaultButtonLeak.java create mode 100644 test/jdk/javax/swing/JButton/bug4385611.java create mode 100644 test/jdk/javax/swing/JComponent/bug4706883.java create mode 100644 test/jdk/javax/swing/plaf/motif/bug4150591.java diff --git a/test/jdk/javax/swing/InputVerifier/bug4774166.java b/test/jdk/javax/swing/InputVerifier/bug4774166.java new file mode 100644 index 0000000000000..644845611b928 --- /dev/null +++ b/test/jdk/javax/swing/InputVerifier/bug4774166.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.FlowLayout; +import java.awt.event.KeyEvent; +import java.lang.reflect.InvocationTargetException; +import javax.swing.InputVerifier; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.JWindow; +import javax.swing.SwingUtilities; + +import static java.awt.event.InputEvent.BUTTON1_DOWN_MASK; + +/* + * @test + * @bug 4774166 + * @key headful + * @summary InputVerifier should be called after a window loses and then regains focus + * @library /javax/swing/regtesthelpers + * @build JRobot + * @run main bug4774166 + */ + +class TestPanel extends JPanel { + JTextField tf1 = null; + JTextField tf2 = null; + volatile boolean verifierCalled; + + public void init() { + tf1 = new JTextField(10); + tf2 = new JTextField(10); + + InputVerifier verifier = new InputVerifier() { + public boolean verify(JComponent input) { + verifierCalled = true; + return false; + } + }; + + setLayout(new FlowLayout()); + tf1.setInputVerifier(verifier); + add(tf1); + add(tf2); + validate(); + } +} + +public class bug4774166 { + private static JRobot robot = JRobot.getRobot(); + + JFrame testframe; + JFrame testwindowframe; + JFrame customframe; + JWindow testwindow; + JDialog testdialog; + JTextField frametf1, frametf2, windowtf1, windowtf2, dialogtf1, dialogtf2; + TestPanel testpanel; + + volatile boolean isFocused; + volatile boolean verifierCalled; + + public void setupGUI() { + testframe = new JFrame("Test 4774166"); + testframe.setLayout(new FlowLayout()); + testframe.setBounds(100, 100, 200, 100); + + testwindowframe = new JFrame("Owner of JWindow"); + testwindowframe.setBounds(0, 0, 0, 0); + + testwindow = new JWindow(testwindowframe); + testwindow.setBounds(175, 325, 200, 100); + testwindow.setLayout(new FlowLayout()); + + testdialog = new JDialog((JFrame)null, "Test dialog"); + testdialog.setBounds(420, 100, 200, 100); + testdialog.setLayout(new FlowLayout()); + + InputVerifier verifier = new InputVerifier() { + public boolean verify(JComponent input) { + verifierCalled = true; + return false; + } + }; + + frametf1 = new JTextField(10); + frametf2 = new JTextField(10); + frametf1.setInputVerifier(verifier); + testframe.add(frametf1); + testframe.add(frametf2); + testframe.setVisible(true); + + windowtf1 = new JTextField(10); + windowtf2 = new JTextField(10); + windowtf1.setInputVerifier(verifier); + testwindow.add(windowtf1); + testwindow.add(windowtf2); + testwindowframe.setVisible(true); + testwindow.setVisible(true); + + dialogtf1 = new JTextField(10); + dialogtf2 = new JTextField(10); + dialogtf1.setInputVerifier(verifier); + testdialog.add(dialogtf1); + testdialog.add(dialogtf2); + testdialog.setVisible(true); + + customframe = new JFrame("Frame with custom panel"); + customframe.setLayout(new FlowLayout()); + testpanel = new TestPanel(); + testpanel.init(); + + customframe.add(testpanel); + customframe.setBounds(420, 250, 200, 100); + customframe.pack(); + customframe.setVisible(true); + } + + public void performTest() throws InterruptedException, InvocationTargetException { + robot.setAutoDelay(100); + robot.delay(2000); + + robot.clickMouseOn(frametf1, BUTTON1_DOWN_MASK); + robot.hitKey(KeyEvent.VK_A); + robot.hitKey(KeyEvent.VK_B); + robot.hitKey(KeyEvent.VK_C); + robot.hitKey(KeyEvent.VK_D); + robot.hitKey(KeyEvent.VK_E); + + robot.clickMouseOn(windowtf1, BUTTON1_DOWN_MASK); + robot.hitKey(KeyEvent.VK_F); + robot.hitKey(KeyEvent.VK_G); + robot.hitKey(KeyEvent.VK_H); + robot.hitKey(KeyEvent.VK_I); + robot.hitKey(KeyEvent.VK_J); + + robot.clickMouseOn(dialogtf1, BUTTON1_DOWN_MASK); + robot.hitKey(KeyEvent.VK_K); + robot.hitKey(KeyEvent.VK_L); + robot.hitKey(KeyEvent.VK_M); + robot.hitKey(KeyEvent.VK_N); + robot.hitKey(KeyEvent.VK_O); + + robot.clickMouseOn(testpanel.tf1, BUTTON1_DOWN_MASK); + robot.hitKey(KeyEvent.VK_P); + robot.hitKey(KeyEvent.VK_Q); + robot.hitKey(KeyEvent.VK_R); + robot.hitKey(KeyEvent.VK_S); + robot.hitKey(KeyEvent.VK_T); + + verifierCalled = false; + robot.clickMouseOn(frametf2, BUTTON1_DOWN_MASK); + robot.delay(2000); + SwingUtilities.invokeAndWait(() -> { + isFocused = frametf1.isFocusOwner(); + }); + if (!isFocused) { + throw new RuntimeException("Focus error. Test failed!"); + } + if (!verifierCalled) { + throw new RuntimeException("Verifier was not called upon regaining focus"); + } + + verifierCalled = false; + robot.clickMouseOn(windowtf2, BUTTON1_DOWN_MASK); + robot.delay(2000); + SwingUtilities.invokeAndWait(() -> { + isFocused = windowtf1.isFocusOwner(); + }); + if (!isFocused) { + throw new RuntimeException("Focus error. Test failed!"); + } + if (!verifierCalled) { + throw new RuntimeException("Verifier was not called upon regaining focus"); + } + + testpanel.verifierCalled = false; + robot.clickMouseOn(testpanel.tf2, BUTTON1_DOWN_MASK); + robot.delay(2000); + SwingUtilities.invokeAndWait(() -> { + isFocused = testpanel.tf1.isFocusOwner(); + }); + if (!isFocused) { + throw new RuntimeException("Focus error. Test failed!"); + } + if (!testpanel.verifierCalled) { + throw new RuntimeException("Verifier was not called upon regaining focus"); + } + + verifierCalled = false; + robot.clickMouseOn(dialogtf2, BUTTON1_DOWN_MASK); + robot.delay(2000); + SwingUtilities.invokeAndWait(() -> { + isFocused = dialogtf1.isFocusOwner(); + }); + if (!isFocused) { + throw new RuntimeException("Focus error. Test failed!"); + } + if (!verifierCalled) { + throw new RuntimeException("Verifier was not called upon regaining focus"); + } + } + + public void cleanupGUI() { + if (testframe != null) { + testframe.dispose(); + } + if (testwindowframe != null) { + testwindowframe.dispose(); + } + if (testwindow != null) { + testwindow.dispose(); + } + if (customframe != null) { + customframe.dispose(); + } + if (testdialog != null) { + testdialog.dispose(); + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + bug4774166 b = new bug4774166(); + SwingUtilities.invokeAndWait(b::setupGUI); + try { + b.performTest(); + } finally { + SwingUtilities.invokeAndWait(b::cleanupGUI); + } + } +} diff --git a/test/jdk/javax/swing/JButton/DefaultButtonLeak.java b/test/jdk/javax/swing/JButton/DefaultButtonLeak.java new file mode 100644 index 0000000000000..5e03902e64bea --- /dev/null +++ b/test/jdk/javax/swing/JButton/DefaultButtonLeak.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.lang.reflect.InvocationTargetException; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +/* + * @test + * @bug 4134035 + * @key headful + * @summary Ensure default button reference is removed from the RootPane + * when a hierarchy containing the RootPane's default button is removed + * from the RootPane. (a memory leak) + * @run main DefaultButtonLeak + */ + +public class DefaultButtonLeak { + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + SwingUtilities.invokeAndWait(() -> { + JFrame frame = new JFrame("DefaultButtonLeak"); + try { + JPanel bigPanel = new JPanel(); + bigPanel.setLayout(new GridLayout(10, 10)); + for (int i = 0; i < 100; i++) { + JButton button = new JButton("Button" + i); + bigPanel.add(button); + if (i == 0) { + frame.getRootPane().setDefaultButton(button); + } + } + frame.add(bigPanel, BorderLayout.CENTER); + frame.pack(); + frame.setVisible(true); + frame.remove(bigPanel); + if (frame.getRootPane().getDefaultButton() != null) { + throw new RuntimeException("RootPane default button reference not removed."); + } + } finally { + frame.setVisible(false); + frame.dispose(); + } + }); + } +} diff --git a/test/jdk/javax/swing/JButton/bug4385611.java b/test/jdk/javax/swing/JButton/bug4385611.java new file mode 100644 index 0000000000000..b7360f273601b --- /dev/null +++ b/test/jdk/javax/swing/JButton/bug4385611.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.image.BufferedImage; +import java.lang.reflect.InvocationTargetException; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +/* + * @test + * @bug 4385611 8078655 + * @requires (os.family == "windows") + * @summary The button's preferred width/height calculation. + * @run main bug4385611 + */ + +public class bug4385611 { + static JButton bt1, bt2; + static final ImageIcon icon32x32 = generateImageIcon(); + static final Dimension DIM_32X32 = new Dimension(32, 32); + static final Dimension DIM_33X33 = new Dimension(33, 33); + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + SwingUtilities.invokeAndWait(() -> { + try { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + bt1 = new JButton(icon32x32); + bt1.setMargin(new Insets(0, 0, 0, 0)); + bt1.setBorder(null); + bt1.setFocusPainted(true); + + bt2 = new JButton(icon32x32); + bt2.setMargin(new Insets(0, 0, 0, 0)); + bt2.setBorder(null); + bt2.setFocusPainted(false); + + if (!bt1.getPreferredSize().equals(DIM_32X32) || + !bt2.getPreferredSize().equals(DIM_32X32)) { + throw new RuntimeException("The button's preferred size should be 32x32"); + } + } catch (Exception e) { + throw new RuntimeException("Can not initialize Metal LnF", e); + } + + try { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + bt1.updateUI(); + bt1.setBorder(null); + bt2.updateUI(); + bt2.setBorder(null); + if (!bt1.getPreferredSize().equals(DIM_33X33) || + !bt2.getPreferredSize().equals(DIM_32X32)) { + throw new RuntimeException("The button's preferred size should be " + + "33x33 and 32x32 correspondingly."); + } + } catch (Exception e) { + throw new RuntimeException("Can not initialize Windows LnF", e); + } + }); + } + + private static ImageIcon generateImageIcon() { + BufferedImage image = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB); + Graphics g = image.createGraphics(); + g.setColor(Color.YELLOW); + g.fillRect(0, 0, 32, 32); + g.dispose(); + return new ImageIcon(image); + } +} diff --git a/test/jdk/javax/swing/JComponent/bug4706883.java b/test/jdk/javax/swing/JComponent/bug4706883.java new file mode 100644 index 0000000000000..7375342c7a45d --- /dev/null +++ b/test/jdk/javax/swing/JComponent/bug4706883.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.Date; +import javax.swing.AbstractAction; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; + +/* + * @test + * @bug 4706883 + * @summary REGRESSION: ActionMap misses VK_PRINTSCREEN + * @key headful + * @run main bug4706883 + */ + +public class bug4706883 { + + MyPanel panel; + JFrame fr; + boolean passed = false; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + bug4706883 test = new bug4706883(); + SwingUtilities.invokeAndWait(test::init); + SwingUtilities.invokeAndWait(test::test); + } + public void init() { + fr = new JFrame("Test"); + + panel = new MyPanel(); + fr.add(panel); + + panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put + (KeyStroke.getKeyStroke(KeyEvent.VK_PRINTSCREEN, 0, true), + "RELEASED"); + + panel.getActionMap().put("RELEASED", new AbstractAction() { + public void actionPerformed(ActionEvent ev) { + setPassed(true); + } + }); + + fr.setSize(200, 200); + fr.setVisible(true); + } + + public void test() { + panel.doTest(); + try { + Thread.sleep(1000); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (fr != null) { + fr.setVisible(false); + fr.dispose(); + } + } + if (!isPassed()) { + throw new RuntimeException("The key binding for VK_PRINTSCREEN wasn't processed"); + } + } + + class MyPanel extends JPanel { + public void doTest() { + KeyEvent e = new KeyEvent(this, KeyEvent.KEY_RELEASED, + (new Date()).getTime(), + 0, KeyEvent.VK_PRINTSCREEN, + KeyEvent.CHAR_UNDEFINED); + processKeyEvent(e); + } + } + + synchronized void setPassed(boolean passed) { + this.passed = passed; + } + + synchronized boolean isPassed() { + return passed; + } +} diff --git a/test/jdk/javax/swing/plaf/motif/bug4150591.java b/test/jdk/javax/swing/plaf/motif/bug4150591.java new file mode 100644 index 0000000000000..66c668a441c38 --- /dev/null +++ b/test/jdk/javax/swing/plaf/motif/bug4150591.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.java.swing.plaf.motif.MotifInternalFrameTitlePane; +import javax.swing.JInternalFrame; + +/* + * @test + * @bug 4150591 + * @summary MotifInternalFrameTitlePane is public now and can be + * instantiated by other classes within the desktop module without using Reflection. + * This does not mean that this class will ever become part + * of the official public Java API. + * @modules java.desktop/com.sun.java.swing.plaf.motif + * @run main bug4150591 + */ + +public class bug4150591 { + public static void main(String[] args) { + MotifInternalFrameTitlePane mtp = new MotifInternalFrameTitlePane(new JInternalFrame()); + } +} From df1ec5b834b14303a8d0e2f55c1488e90dc28bbc Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Apr 2025 14:47:33 +0000 Subject: [PATCH 151/846] 8343170: java/awt/Cursor/JPanelCursorTest/JPanelCursorTest.java does not show the default cursor Backport-of: c6317191e323e27cde61b5ed3c23d1a230053969 --- .../JPanelCursorTest/JPanelCursorTest.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/test/jdk/java/awt/Cursor/JPanelCursorTest/JPanelCursorTest.java b/test/jdk/java/awt/Cursor/JPanelCursorTest/JPanelCursorTest.java index 8acd622e59212..33437a6545edc 100644 --- a/test/jdk/java/awt/Cursor/JPanelCursorTest/JPanelCursorTest.java +++ b/test/jdk/java/awt/Cursor/JPanelCursorTest/JPanelCursorTest.java @@ -44,16 +44,18 @@ public class JPanelCursorTest { public static void main(String[] args) throws Exception { - String INSTRUCTIONS = """ + final String INSTRUCTIONS = """ This test checks for setCursor in a JPanel when added to a JFrame's contentPane. 1. Verify that the cursor in the left side of the test window - is a default cursor. + is a text cursor. 2. Verify that the cursor changes to the crosshair cursor when pointing over the button. 3. Verify that the cursor changes to the hand cursor when in the right side of the splitpane (and not on the button). + 4. Verify that the cursor changes to the wait cursor when in + the empty bottom section of the test window. If true, then pass the test. Otherwise, fail this test. """; @@ -61,14 +63,14 @@ the right side of the splitpane (and not on the button). PassFailJFrame.builder() .title("Test Instructions") .instructions(INSTRUCTIONS) - .columns(35) + .columns(37) .testUI(JPanelCursorTest::createUI) .build() .awaitAndCheck(); } public static JFrame createUI() { - JFrame frame = new JFrame(); + JFrame frame = new JFrame("Cursor Test Frame"); JSplitPane j = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); ExtJComponent pane = new ExtJComponent(); @@ -78,11 +80,12 @@ public static JFrame createUI() { j.setLeftComponent(pane); j.setRightComponent(panel); j.setContinuousLayout(true); + j.setSize(200, 200); - frame.getContentPane().add("Center", j); - pane.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); + frame.getContentPane().add("North", j); + pane.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - frame.pack(); + frame.setSize(300, 200); return frame; } } @@ -96,7 +99,7 @@ public ExtJComponent() { setBorder(new BevelBorder(BevelBorder.RAISED)); } public void paintComponent(Graphics g) { - g.drawString("Default", 20, 30); + g.drawString("Text", 20, 30); } public Dimension getPreferredSize() { return new Dimension(100, 100); @@ -104,7 +107,7 @@ public Dimension getPreferredSize() { } class CursorBugPanel extends JPanel { - public CursorBugPanel () { + public CursorBugPanel() { // BUG: fails to set cursor for panel setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); From 374e67c5b3d311dd8fde790ee349762021b00f74 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Apr 2025 14:49:57 +0000 Subject: [PATCH 152/846] 8340084: Open source AWT Frame related tests Backport-of: bc7c0dc45dcd66d24ece8ebbd5c1b25e131eae67 --- .../java/awt/Frame/DefaultLocationTest.java | 66 +++++++++++++ test/jdk/java/awt/Frame/EmptyFrameTest.java | 99 +++++++++++++++++++ test/jdk/java/awt/Frame/FrameLayoutTest.java | 70 +++++++++++++ .../awt/Frame/FrameSetMinimumSizeTest.java | 91 +++++++++++++++++ test/jdk/java/awt/Frame/PackTwiceTest.java | 67 +++++++++++++ 5 files changed, 393 insertions(+) create mode 100644 test/jdk/java/awt/Frame/DefaultLocationTest.java create mode 100644 test/jdk/java/awt/Frame/EmptyFrameTest.java create mode 100644 test/jdk/java/awt/Frame/FrameLayoutTest.java create mode 100644 test/jdk/java/awt/Frame/FrameSetMinimumSizeTest.java create mode 100644 test/jdk/java/awt/Frame/PackTwiceTest.java diff --git a/test/jdk/java/awt/Frame/DefaultLocationTest.java b/test/jdk/java/awt/Frame/DefaultLocationTest.java new file mode 100644 index 0000000000000..dfeb5e93e3c89 --- /dev/null +++ b/test/jdk/java/awt/Frame/DefaultLocationTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Label; + +/* + * @test + * @bug 4085599 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Test default location for frame + * @run main/manual DefaultLocationTest + */ + +public class DefaultLocationTest { + private static Frame f; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + A small frame containing the label 'Hello World' should + appear in the upper left hand corner of the screen. The + exact location is dependent upon the window manager. + + On Linux and Mac machines, the default location for frame + is below the taskbar or close to top-left corner. + + Upon test completion, click Pass or Fail appropriately."""; + + PassFailJFrame passFailJFrame = new PassFailJFrame("DefaultLocationTest " + + " Instructions", INSTRUCTIONS, 5, 10, 40); + EventQueue.invokeAndWait(DefaultLocationTest::createAndShowUI); + passFailJFrame.awaitAndCheck(); + } + + private static void createAndShowUI() { + f = new Frame("DefaultLocation"); + f.add("Center", new Label("Hello World")); + f.pack(); + PassFailJFrame.addTestWindow(f); + PassFailJFrame.positionTestWindow( + null, PassFailJFrame.Position.HORIZONTAL); + f.setVisible(true); + } +} diff --git a/test/jdk/java/awt/Frame/EmptyFrameTest.java b/test/jdk/java/awt/Frame/EmptyFrameTest.java new file mode 100644 index 0000000000000..7a324a3cbc994 --- /dev/null +++ b/test/jdk/java/awt/Frame/EmptyFrameTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +/* + * @test + * @bug 4237529 + * @key headful + * @summary Test repainting of an empty frame + * @run main EmptyFrameTest + */ + +public class EmptyFrameTest { + private static Frame f; + private static Robot robot; + private static volatile Point p; + private static volatile Dimension d; + private static final int TOLERANCE = 5; + public static void main(String[] args) throws Exception { + robot = new Robot(); + robot.setAutoDelay(100); + try { + EventQueue.invokeAndWait(() -> { + createAndShowUI(); + }); + robot.delay(1000); + f.setSize(50, 50); + robot.delay(500); + EventQueue.invokeAndWait(() -> { + p = f.getLocation(); + d = f.getSize(); + }); + Rectangle rect = new Rectangle(p, d); + BufferedImage img = robot.createScreenCapture(rect); + if (chkImgBackgroundColor(img)) { + try { + ImageIO.write(img, "png", new File("Frame.png")); + } catch (IOException ignored) {} + throw new RuntimeException("Frame doesn't repaint itself on resize"); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + f = new Frame("EmptyFrameTest"); + f.setUndecorated(true); + f.setBackground(Color.RED); + f.setVisible(true); + } + + private static boolean chkImgBackgroundColor(BufferedImage img) { + for (int x = 1; x < img.getWidth() - 1; ++x) { + for (int y = 1; y < img.getHeight() - 1; ++y) { + Color c = new Color(img.getRGB(x, y)); + if ((c.getRed() - Color.RED.getRed()) > TOLERANCE) { + return true; + } + } + } + return false; + } +} diff --git a/test/jdk/java/awt/Frame/FrameLayoutTest.java b/test/jdk/java/awt/Frame/FrameLayoutTest.java new file mode 100644 index 0000000000000..d6e994beaace0 --- /dev/null +++ b/test/jdk/java/awt/Frame/FrameLayoutTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Frame; + +/* + * @test + * @bug 4173503 + * @library /java/awt/regtesthelpers + * @requires (os.family == "windows") + * @build PassFailJFrame + * @summary Tests that frame layout is performed when frame is maximized from taskbar + * @run main/manual FrameLayoutTest + */ + +public class FrameLayoutTest { + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Right-click on the taskbar button for this test. In the menu appeared, + choose Maximize. The frame will be maximized. Check if buttons inside + the frame are laid out properly, i.e. they occupy the frame entirely. + + If so, test passes. If buttons occupy small rectangle in the top left + corner, test fails."""; + + PassFailJFrame.builder() + .title("Frame's Layout Test Instruction") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(40) + .testUI(FrameLayoutTest::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + Frame f = new Frame("Maximize Test"); + f.add(new Button("North"), BorderLayout.NORTH); + f.add(new Button("South"), BorderLayout.SOUTH); + f.add(new Button("East"), BorderLayout.EAST); + f.add(new Button("West"), BorderLayout.WEST); + f.add(new Button("Cent"), BorderLayout.CENTER); + f.pack(); + f.setState(Frame.ICONIFIED); + return f; + } +} diff --git a/test/jdk/java/awt/Frame/FrameSetMinimumSizeTest.java b/test/jdk/java/awt/Frame/FrameSetMinimumSizeTest.java new file mode 100644 index 0000000000000..929a36e773e40 --- /dev/null +++ b/test/jdk/java/awt/Frame/FrameSetMinimumSizeTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; + +/* + * @test + * @bug 4320050 + * @key headful + * @summary Minimum size for java.awt.Frame is not being enforced. + * @run main FrameSetMinimumSizeTest + */ + +public class FrameSetMinimumSizeTest { + private static Frame f; + private static volatile boolean passed; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + try { + createAndShowUI(); + + f.setSize(200, 200); + passed = verifyFrameSize(new Dimension(300, 300)); + isFrameSizeOk(passed); + + f.setSize(200, 400); + passed = verifyFrameSize(new Dimension(300, 400)); + isFrameSizeOk(passed); + + f.setSize(400, 200); + passed = verifyFrameSize(new Dimension(400, 300)); + isFrameSizeOk(passed); + + f.setMinimumSize(null); + + f.setSize(200, 200); + passed = verifyFrameSize(new Dimension(200, 200)); + isFrameSizeOk(passed); + } finally { + if (f != null) { + f.dispose(); + } + } + }); + } + + private static void createAndShowUI() { + f = new Frame("Minimum Size Test"); + f.setSize(300, 300); + f.setMinimumSize(new Dimension(300, 300)); + f.setVisible(true); + } + + private static boolean verifyFrameSize(Dimension expected) { + + if (f.getSize().width != expected.width || f.getSize().height != expected.height) { + return false; + } + return true; + } + + private static void isFrameSizeOk(boolean passed) { + if (!passed) { + throw new RuntimeException("Frame's setMinimumSize not honoured for the" + + " frame size: " + f.getSize()); + } + } +} diff --git a/test/jdk/java/awt/Frame/PackTwiceTest.java b/test/jdk/java/awt/Frame/PackTwiceTest.java new file mode 100644 index 0000000000000..63cd20612f0d3 --- /dev/null +++ b/test/jdk/java/awt/Frame/PackTwiceTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Frame; +import java.awt.TextField; + +/* + * @test + * @bug 4097744 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary packing a frame twice stops it resizing + * @run main/manual PackTwiceTest + */ + +public class PackTwiceTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. You would see a Frame titled 'TestFrame' + 2. The Frame displays a text as below: + 'I am a lengthy sentence...can you see me?' + 3. If you can see the full text without resizing the frame + using mouse, press 'Pass' else press 'Fail'."""; + + PassFailJFrame.builder() + .title("PackTwiceTest Instruction") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(40) + .testUI(PackTwiceTest::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + Frame f = new Frame("PackTwiceTest TestFrame"); + TextField tf = new TextField(); + f.add(tf, "Center"); + tf.setText("I am a short sentence"); + f.pack(); + f.pack(); + tf.setText("I am a lengthy sentence...can you see me?"); + f.pack(); + f.requestFocus(); + return f; + } +} From de96db927f856bdbdc6c8505719214f6d7014a72 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Apr 2025 14:53:32 +0000 Subject: [PATCH 153/846] 8339995: Open source several AWT focus tests - series 6 Backport-of: 3411f9dff79c2e7cb7ce8ebf036f8b3fd9bb647d --- test/jdk/ProblemList.txt | 1 + .../java/awt/Focus/ConsumedKeyEventTest.java | 197 ++++++++++++++++++ .../java/awt/Focus/EmptyWindowKeyTest.java | 87 ++++++++ .../jdk/java/awt/Focus/InactiveFocusRace.java | 188 +++++++++++++++++ .../awt/Focus/InitialPrintDlgFocusTest.java | 107 ++++++++++ 5 files changed, 580 insertions(+) create mode 100644 test/jdk/java/awt/Focus/ConsumedKeyEventTest.java create mode 100644 test/jdk/java/awt/Focus/EmptyWindowKeyTest.java create mode 100644 test/jdk/java/awt/Focus/InactiveFocusRace.java create mode 100644 test/jdk/java/awt/Focus/InitialPrintDlgFocusTest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index e89b9bf260f1b..955d6bcd79f30 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -835,6 +835,7 @@ java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java 8258103 linux-all java/awt/Focus/FrameMinimizeTest/FrameMinimizeTest.java 8016266 linux-x64 java/awt/Frame/SizeMinimizedTest.java 8305915 linux-x64 java/awt/PopupMenu/PopupHangTest.java 8340022 windows-all +java/awt/Focus/InactiveFocusRace.java 8023263 linux-all java/awt/dnd/WinMoveFileToShellTest.java 8341665 windows-all diff --git a/test/jdk/java/awt/Focus/ConsumedKeyEventTest.java b/test/jdk/java/awt/Focus/ConsumedKeyEventTest.java new file mode 100644 index 0000000000000..dda82adeec587 --- /dev/null +++ b/test/jdk/java/awt/Focus/ConsumedKeyEventTest.java @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4700276 + * @summary Peers process KeyEvents before KeyEventPostProcessors + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ConsumedKeyEventTest +*/ + +import java.awt.Canvas; +import java.awt.Component; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.KeyboardFocusManager; +import java.awt.KeyEventPostProcessor; +import java.awt.event.KeyEvent; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class ConsumedKeyEventTest implements KeyEventPostProcessor { + + private static final String INSTRUCTIONS = """ + This is a Windows-only test. + When the test starts, you will see a Frame with two components in it, + components look like colored rectangles, one of them is lightweight, one is heavyweight. + Do the following: + 1. Click the mouse on the left component. + If it isn't yellow after the click (that means it doesn't have focus), the test fails. + 2. Press and release ALT key. + In the output window, the text should appear stating that those key events were consumed. + If no output appears, the test fails. + 3. Press space bar. If system menu drops down, the test fails. + 4. Click the right rectangle. + It should become red after the click. If it doesn't, it means that it didn't get the focus, and the test fails. + 5. Repeat steps 2. and 3. + 6. If the test didn't fail on any of the previous steps, the test passes."""; + + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("ConsumedKeyEventTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 5) + .columns(35) + .testUI(ConsumedKeyEventTest::createTestUI) + .logArea() + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + addKeyEventPostProcessor((e) -> { + System.out.println("postProcessor(" + e + ")"); + // consumes all ALT-events + if (e.getKeyCode() == KeyEvent.VK_ALT) { + println("consumed " + e); + e.consume(); + return true; + } + return false; + }); + FocusRequestor requestor = new FocusRequestor(); + Frame frame = new Frame("Main Frame"); + frame.setLayout(new FlowLayout()); + + Canvas canvas = new CustomCanvas(); + canvas.addMouseListener(requestor); + frame.add(canvas); + canvas.requestFocus(); + + Component lwComp = new LWComponent(); + lwComp.addMouseListener(requestor); + frame.add(lwComp); + + frame.pack(); + + return frame; + } + + public boolean postProcessKeyEvent(KeyEvent e) { + System.out.println("postProcessor(" + e + ")"); + // consumes all ALT-events + if (e.getKeyCode() == KeyEvent.VK_ALT) { + println("consumed " + e); + e.consume(); + return true; + } + return false; + } + + static void println(String messageIn) { + PassFailJFrame.log(messageIn); + } +}// class ConsumedKeyEventTest + +class CustomCanvas extends Canvas { + CustomCanvas() { + super(); + setName("HWComponent"); + setSize(100, 100); + addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent fe) { + repaint(); + } + + public void focusLost(FocusEvent fe) { + repaint(); + } + }); + } + + public void paint(Graphics g) { + if (isFocusOwner()) { + g.setColor(Color.YELLOW); + } else { + g.setColor(Color.GREEN); + } + g.fillRect(0, 0, 100, 100); + } + +} + +class LWComponent extends Component { + LWComponent() { + super(); + setName("LWComponent"); + addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent fe) { + repaint(); + } + + public void focusLost(FocusEvent fe) { + repaint(); + } + }); + } + + public Dimension getPreferredSize() { + return new Dimension(100, 100); + } + + public void paint(Graphics g) { + if (isFocusOwner()) { + g.setColor(Color.RED); + } else { + g.setColor(Color.BLACK); + } + g.fillRect(0, 0, 100, 100); + } + +} + +class FocusRequestor extends MouseAdapter { + static int counter = 0; + public void mouseClicked(MouseEvent me) { + System.out.println("mouseClicked on " + me.getComponent().getName()); + } + public void mousePressed(MouseEvent me) { + System.out.println("mousePressed on " + me.getComponent().getName()); + me.getComponent().requestFocus(); + } + public void mouseReleased(MouseEvent me) { + System.out.println("mouseReleased on " + me.getComponent().getName()); + } +} + diff --git a/test/jdk/java/awt/Focus/EmptyWindowKeyTest.java b/test/jdk/java/awt/Focus/EmptyWindowKeyTest.java new file mode 100644 index 0000000000000..bbdf8ce4f383b --- /dev/null +++ b/test/jdk/java/awt/Focus/EmptyWindowKeyTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4464723 + * @summary Tests simple KeyAdapter / KeyListener on an empty, focusable window + * @key headful + * @run main EmptyWindowKeyTest +*/ + +import java.awt.AWTEvent; +import java.awt.Frame; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.Robot; + +public class EmptyWindowKeyTest { + + static volatile boolean passed1, passed2; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + MainFrame mainFrame = new MainFrame(); + mainFrame.setSize(50,50); + mainFrame.addKeyListener(new KeyboardTracker()); + robot.waitForIdle(); + robot.delay(1000); + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.waitForIdle(); + robot.delay(1000); + if (!passed1 || !passed2) { + throw new RuntimeException("KeyPress/keyRelease not seen," + + "passed1 " + passed1 + " passed2 " + passed2); + } + } + + static public class KeyboardTracker extends KeyAdapter { + public KeyboardTracker() { } + public void keyTyped(KeyEvent e) {} + + public void keyPressed(KeyEvent e) { + if (e.getKeyText(e.getKeyCode()).equals("A")) { + passed1 = true; + } + } + public void keyReleased(KeyEvent e) { + if (e.getKeyText(e.getKeyCode()).equals("A")) { + passed2 = true; + } + } + } + + static public class MainFrame extends Frame { + + public MainFrame() { + super(); + enableEvents(AWTEvent.KEY_EVENT_MASK); + setVisible(true); + } + + } + +} + diff --git a/test/jdk/java/awt/Focus/InactiveFocusRace.java b/test/jdk/java/awt/Focus/InactiveFocusRace.java new file mode 100644 index 0000000000000..efca2dbf53a13 --- /dev/null +++ b/test/jdk/java/awt/Focus/InactiveFocusRace.java @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4697451 + * @summary Test that there is no race between focus component in inactive window and window activation + * @key headful + * @run main InactiveFocusRace +*/ + +import java.awt.Button; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.KeyboardFocusManager; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.InputEvent; + +public class InactiveFocusRace { + + static Frame activeFrame, inactiveFrame; + Button activeButton, inactiveButton1, inactiveButton2; + Semaphore sema; + final static int TIMEOUT = 10000; + + public static void main(String[] args) throws Exception { + try { + InactiveFocusRace test = new InactiveFocusRace(); + test.init(); + test.start(); + } finally { + if (activeFrame != null) { + activeFrame.dispose(); + } + if (inactiveFrame != null) { + inactiveFrame.dispose(); + } + } + } + + public void init() { + activeButton = new Button("active button"); + inactiveButton1 = new Button("inactive button1"); + inactiveButton2 = new Button("inactive button2"); + activeFrame = new Frame("Active frame"); + inactiveFrame = new Frame("Inactive frame"); + inactiveFrame.setLayout(new FlowLayout()); + activeFrame.add(activeButton); + inactiveFrame.add(inactiveButton1); + inactiveFrame.add(inactiveButton2); + activeFrame.pack(); + activeFrame.setLocation(300, 10); + inactiveFrame.pack(); + inactiveFrame.setLocation(300, 300); + sema = new Semaphore(); + + inactiveButton1.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + System.err.println("Button 1 got focus"); + } + }); + inactiveButton2.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + System.err.println("Button2 got focus"); + sema.raise(); + } + }); + activeFrame.addWindowListener(new WindowAdapter() { + public void windowActivated(WindowEvent e) { + System.err.println("Window activated"); + sema.raise(); + } + }); + } + + public void start() { + Robot robot = null; + try { + robot = new Robot(); + } catch (Exception e) { + throw new RuntimeException("Unable to create robot"); + } + + inactiveFrame.setVisible(true); + activeFrame.setVisible(true); + + // Wait for active frame to become active + try { + sema.doWait(TIMEOUT); + } catch (InterruptedException ie) { + throw new RuntimeException("Wait was interrupted"); + } + if (!sema.getState()) { + throw new RuntimeException("Frame doesn't become active on show"); + } + sema.setState(false); + + // press on second button in inactive frame + Point loc = inactiveButton2.getLocationOnScreen(); + robot.mouseMove(loc.x+5, loc.y+5); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + // after all second button should be focus owner. + try { + sema.doWait(TIMEOUT); + } catch (InterruptedException ie) { + throw new RuntimeException("Wait was interrupted"); + } + if (!sema.getState()) { + throw new RuntimeException("Button2 didn't become focus owner"); + } + Toolkit.getDefaultToolkit().sync(); + robot.waitForIdle(); + if (!(KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == inactiveButton2)) { + throw new RuntimeException("Button2 should be the focus owner after all"); + } + + } + +} + +class Semaphore { + boolean state = false; + int waiting = 0; + public Semaphore() { + } + public void doWait() throws InterruptedException { + synchronized(this) { + if (state) return; + waiting++; + wait(); + waiting--; + } + } + public void doWait(int timeout) throws InterruptedException { + synchronized(this) { + if (state) return; + waiting++; + wait(timeout); + waiting--; + } + } + public void raise() { + synchronized(this) { + state = true; + if (waiting > 0) { + notifyAll(); + } + } + } + public boolean getState() { + synchronized(this) { + return state; + } + } + public void setState(boolean newState) { + synchronized(this) { + state = newState; + } + } +} diff --git a/test/jdk/java/awt/Focus/InitialPrintDlgFocusTest.java b/test/jdk/java/awt/Focus/InitialPrintDlgFocusTest.java new file mode 100644 index 0000000000000..cc9d0c0371182 --- /dev/null +++ b/test/jdk/java/awt/Focus/InitialPrintDlgFocusTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4688591 + * @summary Tab key hangs in Native Print Dialog on win32 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual InitialPrintDlgFocusTest + */ + +import java.awt.BorderLayout; +import java.awt.Dialog; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.JobAttributes; +import java.awt.PageAttributes; +import java.awt.PrintJob; +import java.awt.Toolkit; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JFrame; + +public class InitialPrintDlgFocusTest { + + private static final String INSTRUCTIONS = """ + After the tests starts you will see a frame titled "PrintTest". + Press the "Print" button and the print dialog should appear. + If you are able to transfer focus between components of the Print dialog + using the TAB key, then the test passes else the test fails. + + Note: close the Print dialog before clicking on "Pass" or "Fail" buttons."""; + + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("InitialPrintDlgFocusTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(InitialPrintDlgFocusTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createTestUI() { + return new PrintTest(); + + } +} + +class PrintTest extends JFrame implements ActionListener { + + JButton b; + JobAttributes jbattrib; + Toolkit tk ; + PageAttributes pgattrib; + + public PrintTest() { + setTitle("PrintTest"); + setSize(500, 400); + + b = new JButton("Print"); + jbattrib = new JobAttributes(); + tk = Toolkit.getDefaultToolkit(); + pgattrib = new PageAttributes(); + getContentPane().setLayout(new FlowLayout()); + getContentPane().add(b); + + b.addActionListener(this); + + } + + public void actionPerformed(ActionEvent ae) { + if(ae.getSource()==b) + jbattrib.setDialog(JobAttributes.DialogType.NATIVE); + + PrintJob pjob = tk.getPrintJob(this, "Printing Test", + jbattrib, pgattrib); + + } +} + From 771adf82fc9717952d1acf9bd32c556061f60857 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Apr 2025 14:57:02 +0000 Subject: [PATCH 154/846] 8340639: Open source few more AWT List tests Backport-of: dd56990962d58e4f482773f67bc43383d7748536 --- .../java/awt/List/HorizScrollWorkTest.java | 69 +++++++++ .../awt/List/HorizScrollbarEraseTest.java | 139 ++++++++++++++++++ .../java/awt/List/ScrollbarPresenceTest.java | 71 +++++++++ test/jdk/java/awt/List/SetForegroundTest.java | 109 ++++++++++++++ 4 files changed, 388 insertions(+) create mode 100644 test/jdk/java/awt/List/HorizScrollWorkTest.java create mode 100644 test/jdk/java/awt/List/HorizScrollbarEraseTest.java create mode 100644 test/jdk/java/awt/List/ScrollbarPresenceTest.java create mode 100644 test/jdk/java/awt/List/SetForegroundTest.java diff --git a/test/jdk/java/awt/List/HorizScrollWorkTest.java b/test/jdk/java/awt/List/HorizScrollWorkTest.java new file mode 100644 index 0000000000000..6de1de1a4f264 --- /dev/null +++ b/test/jdk/java/awt/List/HorizScrollWorkTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6355467 + * @summary Horizontal scroll bar thumb of a List does not stay at the end + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @requires (os.family == "linux") + * @run main/manual HorizScrollWorkTest +*/ + +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.List; + +public class HorizScrollWorkTest { + + private static final String INSTRUCTIONS = """ + This is a linux only test. + Drag and drop the horizontal scroll bar thumb at the right end. + If the thumb does not stay at the right end, then the test failed. Otherwise passed."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("HorizScrollWorkTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int)INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(HorizScrollWorkTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Frame frame = new Frame("HorizScrollWorkTest Frame"); + List list = new List(4); + + frame.setLayout (new FlowLayout()); + + list.add("veryyyyyyyyyyyyyyyyyyyyyyyyyy longgggggggggggggggggggggg stringggggggggggggggggggggg"); + + frame.add(list); + frame.pack(); + + return frame; + } +} diff --git a/test/jdk/java/awt/List/HorizScrollbarEraseTest.java b/test/jdk/java/awt/List/HorizScrollbarEraseTest.java new file mode 100644 index 0000000000000..2601a7ed0b2e6 --- /dev/null +++ b/test/jdk/java/awt/List/HorizScrollbarEraseTest.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4895367 + * @summary List scrolling w/ down arrow keys obscures horizontal scrollbar + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @requires (os.family == "linux") + * @run main/manual HorizScrollbarEraseTest + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.List; +import java.awt.Panel; +import java.awt.TextArea; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class HorizScrollbarEraseTest { + + private static final String INSTRUCTIONS = """ + This is a Unix-only test. + Do the four mini-tests below. + If the horizontal scrollbar is ever erased by a rectangle + of the background color, the test FAILS. + If the horizontal scrollbars remain painted, test passes."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("HorizScrollbarEraseTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(HorizScrollbarEraseTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Frame frame = new Frame("HorizScrollbarEraseTest"); + Panel borderPanel = new Panel(); + borderPanel.setLayout(new BorderLayout()); + Button focusedButton = new Button("Focus starts here"); + borderPanel.add(focusedButton, BorderLayout.NORTH); + + Panel gridPanel = new Panel(); + gridPanel.setLayout(new GridLayout(0, 4)); + borderPanel.add(gridPanel, BorderLayout.CENTER); + + InstructionList il1 = new InstructionList("Tab to Item 2, then \n" + + "press the down" + + "arrow key to scroll down"); + il1.list.select(2); + il1.list.makeVisible(0); + gridPanel.add(il1); + + InstructionList il2 = new InstructionList("Tab to the next List,\n" + + "then press the down\n" + + "arrow key to select\n" + + "the last item."); + il2.list.select(3); + il2.list.makeVisible(0); + gridPanel.add(il2); + + InstructionList il3 = new InstructionList("Click the button to\n" + + "programmatically\n" + + "select item 3 (not showing)"); + Button selectBtn = new Button("Click Me"); + final List selectList = il3.list; + selectBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + selectList.select(3); + } + }); + il3.add(selectBtn, BorderLayout.CENTER); + gridPanel.add(il3); + + InstructionList il4 = new InstructionList("Click the button to\nprogrammatically\ndeselect item 3\n(not showing)"); + Button deselectBtn = new Button("Click Me"); + final List deselectList = il4.list; + deselectBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + deselectList.deselect(3); + } + }); + il4.add(deselectBtn, BorderLayout.CENTER); + il4.list.select(3); + il4.list.makeVisible(0); + gridPanel.add(il4); + + frame.add(borderPanel); + frame.pack(); + return frame; + + } +} + +class InstructionList extends Panel { + TextArea ta; + public List list; + + public InstructionList(String instructions) { + super(); + setLayout(new BorderLayout()); + ta = new TextArea(instructions, 6, 25, TextArea.SCROLLBARS_NONE); + ta.setFocusable(false); + list = new List(); + for (int i = 0; i < 5; i++) { + list.add("Item " + i + ", a long, long, long, long item"); + } + add(ta, BorderLayout.NORTH); + add(list, BorderLayout.SOUTH); + } +} diff --git a/test/jdk/java/awt/List/ScrollbarPresenceTest.java b/test/jdk/java/awt/List/ScrollbarPresenceTest.java new file mode 100644 index 0000000000000..d82cbb80060ca --- /dev/null +++ b/test/jdk/java/awt/List/ScrollbarPresenceTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6336384 + * @summary ScrollBar does not show up correctly + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ScrollbarPresenceTest +*/ + +import java.awt.Font; +import java.awt.Frame; +import java.awt.List; + +public class ScrollbarPresenceTest { + + private static final String INSTRUCTIONS = """ + You will see a list, + If a vertical scrollbar appears on the list and the list is big enough + to show all items then the test failed else the test passed."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("ScrollbarPresenceTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(ScrollbarPresenceTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Frame frame = new Frame("ScrollbarPresenceTest Frame"); + List list = new List(); + + for (int i = 0; i < 6; i++) { + list.addItem("Row " + i); + } + + list.setFont(new Font("MonoSpaced", Font.PLAIN, 12)); + list.setBounds(30, 30, 128, 104); + frame.add(list); + + frame.pack(); + return frame; + } + +} diff --git a/test/jdk/java/awt/List/SetForegroundTest.java b/test/jdk/java/awt/List/SetForegroundTest.java new file mode 100644 index 0000000000000..7b22e5385088b --- /dev/null +++ b/test/jdk/java/awt/List/SetForegroundTest.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6246467 + * @summary Tests that list works correctly if user specified foreground colors on XToolkit/Motif + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual SetForegroundTest + */ + +import java.awt.Button; +import java.awt.Component; +import java.awt.Checkbox; +import java.awt.Choice; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.List; +import java.awt.Panel; +import java.awt.TextArea; +import java.awt.TextField; +import java.awt.ScrollPane; + +public class SetForegroundTest { + + private static final String INSTRUCTIONS = """ + To make sure, that for each component + (Button, Checkbox, Label, List, TextArea, TextField, Choice) + in the frame, + the title exist and the color of the title is red. + If not, the test failed."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("SetForegroundTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(SetForegroundTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Frame frame = new Frame(); + ScrollPane sp = new ScrollPane() { + public Dimension getPreferredSize() { + return new Dimension(180, 180); + } + }; + Panel p = new Panel(); + Component childs[] = new Component[] {new Button("button"), + new Checkbox("checkbox"), + new Label("label"), + new List(3, false), + new TextArea("text area"), + new TextField("text field"), + new Choice()}; + + p.setLayout (new FlowLayout ()); + + sp.add(p); + + sp.validate(); + + frame.add(sp); + for (int i = 0; i < childs.length; i++){ + childs[i].setForeground(Color.red); + } + + for (int i = 0; i < childs.length; i++) { + p.add(childs[i]); + if (childs[i] instanceof List) { + ((List)childs[i]).add("list1"); + ((List)childs[i]).add("list2"); + } else if (childs[i] instanceof Choice) { + ((Choice)childs[i]).add("choice1"); + ((Choice)childs[i]).add("choice2"); + } + } + frame.pack(); + return frame; + } +} From 7cf57c8cc227179b6b0fbfa76223ffe0ed3a4dc0 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Apr 2025 14:58:50 +0000 Subject: [PATCH 155/846] 8340458: Open source additional Component tests (part 2) Backport-of: 021bf630351fd5369fac732b1099bc2bfe8b5e19 --- .../InitialBackgroundSettingTest.java | 132 ++++++++++++++++ .../FlickeringOnScroll.java | 139 ++++++++++++++++ .../FocusRepaintTest/FocusRepaintTest.java | 83 ++++++++++ .../ListDoubleIndentTest.java | 148 ++++++++++++++++++ 4 files changed, 502 insertions(+) create mode 100644 test/jdk/java/awt/Component/BackgroundColorTest/InitialBackgroundSettingTest.java create mode 100644 test/jdk/java/awt/Component/FlickeringOnScroll/FlickeringOnScroll.java create mode 100644 test/jdk/java/awt/Component/FocusRepaintTest/FocusRepaintTest.java create mode 100644 test/jdk/java/awt/Component/ListDoubleIndentTest/ListDoubleIndentTest.java diff --git a/test/jdk/java/awt/Component/BackgroundColorTest/InitialBackgroundSettingTest.java b/test/jdk/java/awt/Component/BackgroundColorTest/InitialBackgroundSettingTest.java new file mode 100644 index 0000000000000..3bed6f106c59a --- /dev/null +++ b/test/jdk/java/awt/Component/BackgroundColorTest/InitialBackgroundSettingTest.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4148334 + * @summary tests that background color is initially set correctly. + * @requires os.family == "windows" + * @key headful + * @run main InitialBackgroundSettingTest + */ +import java.awt.Button; +import java.awt.Choice; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.List; +import java.awt.TextArea; +import java.awt.TextField; +import java.awt.Scrollbar; +import java.lang.reflect.InvocationTargetException; + +public class InitialBackgroundSettingTest { + Frame frame; + TextField tf; + TextArea ta; + Choice choice; + List list; + Scrollbar bar; + Button button; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + InitialBackgroundSettingTest test= new InitialBackgroundSettingTest(); + try { + EventQueue.invokeAndWait(test::setupGUI); + EventQueue.invokeAndWait(test::test); + } finally { + EventQueue.invokeAndWait(test::dispose); + } + } + + public void setupGUI () { + frame = new Frame("InitialBackgroundSettingTest frame"); + tf = new TextField("I am the TextField"); + ta = new TextArea("I am the TextArea"); + choice = new Choice(); + list = new List(); + bar = new Scrollbar(Scrollbar.HORIZONTAL); + button = new Button("I am the button"); + frame.setBackground(Color.red); + frame.setLayout(new GridLayout(7, 1)); + frame.add(button); + frame.add(bar); + frame.add(choice); + frame.add(list); + frame.add(tf); + frame.add(ta); + frame.setVisible(true); + frame.setBounds (400, 0, 300, 300); + } + + public void test() { + boolean passed = true; + System.out.println("Button background color is:" + + button.getBackground()); + if (Color.red.equals(button.getBackground())) { + System.err.println("Button background is red"); + passed = false; + } + System.out.println("Scrollbar background color is:" + + bar.getBackground()); + if (Color.red.equals(bar.getBackground())) { + System.err.println("ScrollBar background is red"); + passed = false; + } + System.out.println("Choice background color is:" + + choice.getBackground()); + if (Color.red.equals(choice.getBackground())) { + System.err.println("Choice background is red"); + passed = false; + } + System.out.println("List background color is:" + + list.getBackground()); + if (Color.red.equals(list.getBackground())) { + System.err.println("List background is red"); + passed = false; + } + System.out.println("TextField background color is:" + + tf.getBackground()); + if (Color.red.equals(tf.getBackground())) { + System.err.println("TextField background is red"); + passed = false; + } + System.out.println("TextArea background color is:" + + ta.getBackground()); + if (Color.red.equals(ta.getBackground())) { + System.err.println("TextArea background is red"); + passed = false; + } + + if (!passed) { + throw new RuntimeException("One or more component inherited" + + " background from a Frame"); + } + } + + public void dispose() { + frame.dispose(); + } +} diff --git a/test/jdk/java/awt/Component/FlickeringOnScroll/FlickeringOnScroll.java b/test/jdk/java/awt/Component/FlickeringOnScroll/FlickeringOnScroll.java new file mode 100644 index 0000000000000..2119ae7bcc01e --- /dev/null +++ b/test/jdk/java/awt/Component/FlickeringOnScroll/FlickeringOnScroll.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6347994 + * @summary REG: Scrollbar, Choice, Checkbox flickers and grays out when scrolling, XToolkit + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual FlickeringOnScroll + */ + +import java.awt.BorderLayout; +import java.awt.Checkbox; +import java.awt.Choice; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.PopupMenu; +import java.awt.Scrollbar; +import java.awt.TextArea; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.lang.reflect.InvocationTargetException; + +public class FlickeringOnScroll extends Frame { + + static final String INSTRUCTIONS = """ + There are five components in the frame: + Scrollbars(vertical and horizontal), a Choice, + a Checkbox and a TextArea + 1) Drag the thumbs of each Scrollbar. + 2) Do the same with Choice's scrollbar. + 3) Focus on Checkbox and press left mouse button or SPACE repeatedly. + 4) Right click inside TextArea and navigate through all menu items + in PopupMenu using the arrow keys. + If you notice some component or its scrollbar flickers on + key/mouse press or drag, press Fail. Otherwise press Pass. + """; + + public FlickeringOnScroll() { + Choice ch = new Choice(); + ch.add("Praveen"); + ch.add("Mohan"); + ch.add("Rakesh"); + ch.add("Menon"); + ch.add("Girish"); + ch.add("Ramachandran"); + ch.add("Elancheran"); + ch.add("Subramanian"); + ch.add("Raju"); + ch.add("Pallath"); + ch.add("Mayank"); + ch.add("Joshi"); + ch.add("Sundar"); + ch.add("Srinivas"); + ch.add("Mandalika"); + Checkbox chb = new Checkbox ("Checkbox", false); + TextArea ta = new TextArea("Text Area"); + Panel panel = new Panel(); + PopupMenu popup = new PopupMenu("Popup"); + MenuItem mi1 = new MenuItem("mi1"); + MenuItem mi2 = new MenuItem("mi2"); + MenuItem mi3 = new MenuItem("mi3"); + MenuItem mi4 = new MenuItem("mi4"); + + setTitle("Flickering Scroll Area Testing Frame"); + setLayout(new FlowLayout()); + add(ch); + add(chb); + add(ta); + + panel.setLayout(new BorderLayout()); + panel.setPreferredSize(new Dimension(200, 200)); + add(panel); + panel.add("Center",new java.awt.Label("Scrollbar flickering test..." ,java.awt.Label.CENTER)); + panel.add("South",new Scrollbar(Scrollbar.HORIZONTAL, 0, 100, 0, 255)); + panel.add("East",new Scrollbar(Scrollbar.VERTICAL, 0, 100, 0, 255)); + + ta.add(popup); + popup.add (mi1); + popup.add (mi2); + popup.add (mi3); + popup.add (mi4); + + ta.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + if (me.isPopupTrigger()) { + if (popup != null) { + popup.show(me.getComponent(), me.getX(), me.getY()); + } + } + } + public void mouseReleased(MouseEvent me) { + if (me.isPopupTrigger()) { + if (popup != null) { + popup.show(me.getComponent(), me.getX(), me.getY()); + } + } + } + }); + + pack(); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Scroll Area Flickering Repaint") + .testUI(FlickeringOnScroll::new) + .instructions(INSTRUCTIONS) + .columns(40) + .logArea() + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/java/awt/Component/FocusRepaintTest/FocusRepaintTest.java b/test/jdk/java/awt/Component/FocusRepaintTest/FocusRepaintTest.java new file mode 100644 index 0000000000000..ecffdfda6135d --- /dev/null +++ b/test/jdk/java/awt/Component/FocusRepaintTest/FocusRepaintTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4079435 + * @summary Calling repaint() in focus handlers messes up the window. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual FocusRepaintTest + */ + +import java.awt.Button; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.lang.reflect.InvocationTargetException; + +public class FocusRepaintTest extends Frame implements FocusListener { + static final String INSTRUCTIONS = """ + Hit the tab key repeatedly in the Test window. + If any of the buttons disappear press Fail, otherwise press Pass. + """; + + public FocusRepaintTest() { + setTitle("Test"); + setLayout(new FlowLayout()); + setSize(200, 100); + Button b1 = new Button("Close"); + Button b2 = new Button("Button"); + add(b1); + add(b2); + b1.setSize(50, 30); + b2.setSize(50, 30); + b1.addFocusListener(this); + b2.addFocusListener(this); + } + + public void focusGained(FocusEvent e) { + Button b = (Button) e.getSource(); + PassFailJFrame.log("Focus gained for " + b.getLabel()); + b.repaint(); + } + + public void focusLost(FocusEvent e) { + Button b = (Button) e.getSource(); + PassFailJFrame.log("Focus lost for " + b.getLabel()); + b.repaint(); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Focus Repaint") + .testUI(FocusRepaintTest::new) + .instructions(INSTRUCTIONS) + .columns(40) + .logArea() + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/java/awt/Component/ListDoubleIndentTest/ListDoubleIndentTest.java b/test/jdk/java/awt/Component/ListDoubleIndentTest/ListDoubleIndentTest.java new file mode 100644 index 0000000000000..4c6c1248950e4 --- /dev/null +++ b/test/jdk/java/awt/Component/ListDoubleIndentTest/ListDoubleIndentTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4185460 + * @summary Container list the indentation is 2x the indent param value + * @key headful + * @run main ListDoubleIndentTest + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PrintStream; +import java.io.PipedOutputStream; + +import java.lang.reflect.InvocationTargetException; +import java.util.Vector; + +public class ListDoubleIndentTest { + public static void main(final String[] args) throws InterruptedException, + InvocationTargetException { + EventQueue.invokeAndWait(new ListDoubleIndentTest()::performTest); + } + + public void performTest() { + boolean bReturn = false; + int iCompCount = 0; + int iNotEqual = 0; + int iIndentWrong = 0; + System.out.println("Test: Check indentation"); + Vector v = new Vector(); + String sLine; + String sReturn; + String sExpTrim; + Button b1, b2, b3, b4, b5; + Frame f = null; + + try { + f = new Frame("ListDoubleIndentTest"); + + f.add(b1 = new Button("North"), BorderLayout.NORTH, 0); + f.add(b2 = new Button("South"), BorderLayout.SOUTH, 1); + f.add(b3 = new Button("East"), BorderLayout.EAST, 2); + f.add(b4 = new Button("West"), BorderLayout.WEST, 3); + f.add(b5 = new Button("Center"), BorderLayout.CENTER, -1); + + String[] sExpected = {f.toString(), b1.toString(), b2.toString(), + b3.toString(), b4.toString(), b5.toString()}; + + iCompCount = f.getComponentCount(); + System.out.println("Component count: " + iCompCount); + + for (int j = 0; j <= 10; j++) { + PipedInputStream pin = new PipedInputStream(); + PrintStream output = new PrintStream(new PipedOutputStream(pin), true); + BufferedReader input = new BufferedReader(new InputStreamReader(pin)); + + f.list(output, j); + + output.flush(); + output.close(); + + while ((sLine = input.readLine()) != null) { + v.addElement(sLine); + } + + for (int i = 0; i < v.size(); i++) { + sReturn = (String)v.elementAt(i); + sExpTrim = sExpected[i].trim(); + + if (!(sExpTrim.equals(sReturn.trim()))) { + System.out.println("iNotEqual"); + ++iNotEqual; + } + + int iSpace = sReturn.lastIndexOf(' ') + 1; + + if (i == 0) { + System.out.println("Indent set at: " + j); + System.out.println("Indent return: " + iSpace); + if (iSpace != j) { + System.out.println("iIndentWrong1"); + ++iIndentWrong; + } + } else { + if (iSpace != (j + 1)) { + System.out.println(iSpace + "; " + j); + ++iIndentWrong; + } + } + System.out.println(sReturn); + } + v.removeAllElements(); + v.trimToSize(); + } + + if (iNotEqual == 0 && iIndentWrong == 0) { + bReturn = true; + } else { + bReturn = false; + } + + } catch(IOException e) { + bReturn = false; + System.out.println ("Unexpected Exception thrown: " + e.getMessage()); + e.printStackTrace(); + } finally { + if (f != null) { + f.dispose(); + } + } + + if (bReturn) { + System.out.println("Test for Container.list Passed"); + } else { + System.out.println("Test for Container.list Failed"); + throw new RuntimeException("Test FAILED"); + } + } +} From f5add27ecf84344a6b419dcaf1d74ada58d94b3a Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Apr 2025 15:02:00 +0000 Subject: [PATCH 156/846] 8340432: Open source some MenuBar tests - Set2 Backport-of: 013250e4a7bc2fa83c6e57bb8fad6002dbe3176c --- .../MenuBarAddRemoveTest.java | 72 +++++++++++++++ .../MenuBarOnDisabledFrame.java | 77 ++++++++++++++++ .../MenuBarVisuals/MenuBarVisuals.java | 88 +++++++++++++++++++ .../SetHelpMenuTest/SetHelpMenuTest.java | 88 +++++++++++++++++++ 4 files changed, 325 insertions(+) create mode 100644 test/jdk/java/awt/MenuBar/MenuBarAddRemoveTest/MenuBarAddRemoveTest.java create mode 100644 test/jdk/java/awt/MenuBar/MenuBarOnDisabledFrame/MenuBarOnDisabledFrame.java create mode 100644 test/jdk/java/awt/MenuBar/MenuBarVisuals/MenuBarVisuals.java create mode 100644 test/jdk/java/awt/MenuBar/SetHelpMenuTest/SetHelpMenuTest.java diff --git a/test/jdk/java/awt/MenuBar/MenuBarAddRemoveTest/MenuBarAddRemoveTest.java b/test/jdk/java/awt/MenuBar/MenuBarAddRemoveTest/MenuBarAddRemoveTest.java new file mode 100644 index 0000000000000..fdb9f06e98c76 --- /dev/null +++ b/test/jdk/java/awt/MenuBar/MenuBarAddRemoveTest/MenuBarAddRemoveTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4028130 4112308 + * @summary Test for location of Frame/MenuBar when MenuBar is re-added + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MenuBarAddRemoveTest + */ + +import java.awt.Button; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; + +public class MenuBarAddRemoveTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Click the left mouse button on the "Re-Add MenuBar" + button several times. + 3. The Frame/MenuBar may repaint or flash, but the location + of its upper left corner should never change. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(MenuBarAddRemoveTest::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + Frame f = new Frame("Re-Add MenuBar Test Frame"); + Button b = new Button("Re-Add MenuBar"); + b.addActionListener(e -> f.setMenuBar(createMenuBar())); + f.setMenuBar(createMenuBar()); + f.add(b); + f.pack(); + return f; + } + + private static MenuBar createMenuBar() { + MenuBar bar = new MenuBar(); + bar.add(new Menu("foo")); + return bar; + } +} diff --git a/test/jdk/java/awt/MenuBar/MenuBarOnDisabledFrame/MenuBarOnDisabledFrame.java b/test/jdk/java/awt/MenuBar/MenuBarOnDisabledFrame/MenuBarOnDisabledFrame.java new file mode 100644 index 0000000000000..06f5d96c19e32 --- /dev/null +++ b/test/jdk/java/awt/MenuBar/MenuBarOnDisabledFrame/MenuBarOnDisabledFrame.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6185057 + * @summary Disabling a frame does not disable the menus on the frame, on + * solaris/linux + * @requires os.family != "mac" + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MenuBarOnDisabledFrame + */ + +import java.awt.Button; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; + +public class MenuBarOnDisabledFrame { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Check if MenuBar is disabled on 'Disabled frame' + Press pass if menu bar is disabled, fail otherwise + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(MenuBarOnDisabledFrame::createUI) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame f = new Frame("Disabled frame"); + MenuBar mb = new MenuBar(); + Menu m1 = new Menu("Disabled Menu 1"); + Menu m2 = new Menu("Disabled Menu 2"); + MenuItem m11 = new MenuItem("MenuItem 1.1"); + MenuItem m21 = new MenuItem("MenuItem 2.1"); + Button b = new Button("Disabled button"); + + m1.add(m11); + m2.add(m21); + mb.add(m1); + mb.add(m2); + f.setMenuBar(mb); + f.add(b); + f.setEnabled(false); + f.setSize(300, 300); + return f; + } +} diff --git a/test/jdk/java/awt/MenuBar/MenuBarVisuals/MenuBarVisuals.java b/test/jdk/java/awt/MenuBar/MenuBarVisuals/MenuBarVisuals.java new file mode 100644 index 0000000000000..7663dd0d99be1 --- /dev/null +++ b/test/jdk/java/awt/MenuBar/MenuBarVisuals/MenuBarVisuals.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6180416 + * @summary Tests MenuBar and drop down menu visuals + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MenuBarVisuals + */ + +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.MenuShortcut; +import java.awt.event.KeyEvent; + +public class MenuBarVisuals { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Look at the MenuBar and traverse the menus using mouse and + keyboard. Then check if following is showing correctly: + 1. Mnemonic label Ctrl+A is NOT drawn for Menu 1/Submenu 1.1 + 2. Mnemonic label Ctrl+B is drawn for + Menu 1/Submenu 1.1/Item 1.1.1 + 3. Mnemonic label Ctrl+C is drawn for Menu1/Item 1.2 + Press PASS if Menu is drawing correctly, FAIL otherwise. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(MenuBarVisuals::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + Frame f = new Frame("MenuBar Visuals Test"); + MenuBar mb = new MenuBar(); + Menu menu1 = new Menu("Menu 1"); + Menu submenu11 = new Menu("Submenu 1.1"); + MenuItem item111 = new MenuItem("Item 1.1.1"); + MenuItem item112 = new MenuItem("Item 1.1.2"); + MenuItem item12 = new MenuItem("Item 1.2"); + Menu menu2 = new Menu("Menu 2"); + MenuItem item21 = new MenuItem("Item 2.1"); + MenuItem item22 = new MenuItem("Item 2.2"); + item111.setShortcut(new MenuShortcut(KeyEvent.VK_B, false)); + submenu11.add(item111); + submenu11.add(item112); + submenu11.setShortcut(new MenuShortcut(KeyEvent.VK_A, false)); + menu1.add(submenu11); + item12.setShortcut(new MenuShortcut(KeyEvent.VK_C, false)); + menu1.add(item12); + mb.add(menu1); + menu2.add(item21); + menu2.add(item22); + mb.add(menu2); + f.setMenuBar(mb); + f.setSize(300, 300); + return f; + } +} diff --git a/test/jdk/java/awt/MenuBar/SetHelpMenuTest/SetHelpMenuTest.java b/test/jdk/java/awt/MenuBar/SetHelpMenuTest/SetHelpMenuTest.java new file mode 100644 index 0000000000000..fcfc3e80ed34c --- /dev/null +++ b/test/jdk/java/awt/MenuBar/SetHelpMenuTest/SetHelpMenuTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4275843 + * @summary MenuBar doesn't display all of its Menus correctly on Windows + * @requires os.family == "windows" + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual SetHelpMenuTest + */ + +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; + +public class SetHelpMenuTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + An empty frame should be visible. When focused, the MenuBar + should have 5 menus ("one", "two", "three", "Help 2", + "four"). If so, then the test passed. Otherwise, the test + failed. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(SetHelpMenuTest::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + Frame f = new Frame("Help MenuBar Test"); + f.setSize(100, 100); + + MenuBar mb = new MenuBar(); + Menu h1, h2; + + f.setMenuBar(mb); + mb.add(createMenu("one", false)); + mb.add(createMenu("two", false)); + mb.add(createMenu("three", true)); + + mb.add(h1 = createMenu("Help 1", false)); // h1 is HelpMenu + mb.setHelpMenu(h1); + + mb.add(h2 = createMenu("Help 2", false)); // h2 replaced h1 + mb.setHelpMenu(h2); + + mb.add(createMenu("four", false)); + + return f; + } + + private static Menu createMenu(String name, boolean tearOff) { + Menu m = new Menu(name, tearOff); + m.add(new MenuItem(name + " item 1")); + m.add(new MenuItem(name + " item 2")); + m.add(new MenuItem(name + " item 3")); + return m; + } +} From 5d7aa66ed84470fc5021fb20bdb68593c2bf0128 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Apr 2025 15:04:28 +0000 Subject: [PATCH 157/846] 8340279: Open source several AWT Dialog tests - Batch 2 Backport-of: e0dabfb4bfd93a4407518177043d3dbc85c4bbd9 --- test/jdk/ProblemList.txt | 2 + .../DialogSystemMenu/DialogSystemMenu.java | 122 ++++++++++++++ .../awt/Dialog/DialogSystemMenu/icon24x24.gif | 0 .../awt/Dialog/DialogSystemMenu/iconone.gif | 0 .../awt/Dialog/DialogSystemMenu/icontwo.gif | 0 .../java/awt/Dialog/FileDialogFilterTest.java | 68 ++++++++ .../PrintToFileTest/PrintToFileFrame.java | 40 +++++ .../PrintToFileTest/PrintToFileGranted.java | 70 ++++++++ .../PrintToFileTest/PrintToFileRevoked.java | 69 ++++++++ .../java/awt/Dialog/PrintToFileTest/granted | 10 ++ .../java/awt/Dialog/PrintToFileTest/revoked | 9 ++ .../awt/Dialog/TopmostModalDialogTest.java | 152 ++++++++++++++++++ 12 files changed, 542 insertions(+) create mode 100644 test/jdk/java/awt/Dialog/DialogSystemMenu/DialogSystemMenu.java create mode 100644 test/jdk/java/awt/Dialog/DialogSystemMenu/icon24x24.gif create mode 100644 test/jdk/java/awt/Dialog/DialogSystemMenu/iconone.gif create mode 100644 test/jdk/java/awt/Dialog/DialogSystemMenu/icontwo.gif create mode 100644 test/jdk/java/awt/Dialog/FileDialogFilterTest.java create mode 100644 test/jdk/java/awt/Dialog/PrintToFileTest/PrintToFileFrame.java create mode 100644 test/jdk/java/awt/Dialog/PrintToFileTest/PrintToFileGranted.java create mode 100644 test/jdk/java/awt/Dialog/PrintToFileTest/PrintToFileRevoked.java create mode 100644 test/jdk/java/awt/Dialog/PrintToFileTest/granted create mode 100644 test/jdk/java/awt/Dialog/PrintToFileTest/revoked create mode 100644 test/jdk/java/awt/Dialog/TopmostModalDialogTest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 955d6bcd79f30..aa08c0da61c65 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -488,6 +488,8 @@ java/awt/KeyboardFocusmanager/ConsumeNextMnemonicKeyTypedTest/ConsumeNextMnemoni java/awt/Window/GetScreenLocation/GetScreenLocationTest.java 8225787 linux-x64 java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 8266243 macosx-aarch64 +java/awt/Dialog/PrintToFileTest/PrintToFileRevoked.java 8029249 macosx-all +java/awt/Dialog/PrintToFileTest/PrintToFileGranted.java 8029249 macosx-all java/awt/dnd/DragSourceMotionListenerTest.java 8225131 windows-all java/awt/dnd/RejectDragTest.java 7124259 macosx-all java/awt/dnd/DnDHTMLToOutlookTest/DnDHTMLToOutlookTest.java 8027424 generic-all diff --git a/test/jdk/java/awt/Dialog/DialogSystemMenu/DialogSystemMenu.java b/test/jdk/java/awt/Dialog/DialogSystemMenu/DialogSystemMenu.java new file mode 100644 index 0000000000000..3f1639e90a41e --- /dev/null +++ b/test/jdk/java/awt/Dialog/DialogSystemMenu/DialogSystemMenu.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.event.WindowListener; +import java.util.List; + +/* + * @test + * @bug 4058953 4094035 + * @summary Test to verify system menu of a dialog on win32 + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DialogSystemMenu + */ + +public class DialogSystemMenu { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Check the following on the first dialog window: + Right-clicking on the title bar + should bring up a system menu. + The system menu should not allow any + of the Maximize, Minimize and + Restore actions + + 2. The second dialog should be non-resizable + and have no application icon. + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .build() + .awaitAndCheck(); + } + + public static List initialize() { + Frame frame = new java.awt.Frame("Parent Frame"); + String txt = """ + This is a resizable dialog + Right-clicking on the title bar + should bring up a system menu + The system menu should not + allow any + of the Maximize, Minimize and + Restore actions + """; + String txt_non = """ + This is a non-resizable dialog + It should be really non-resizable + and have no application icon + """; + TestApp resizable = new TestApp(frame, "Test for 4058953", txt, true); + resizable.setLocation(0, 0); + + TestApp non_resizable = new TestApp(frame, "Test for 4094035", txt_non, false); + non_resizable.setLocation(320, 0); + return List.of(resizable, non_resizable); + } +} + + +class TestApp extends Dialog implements WindowListener { + public TestApp(java.awt.Frame parent, String title, String txt, boolean resize) { + super(parent, title, false); + + java.awt.TextArea ta = new java.awt.TextArea(txt); + ta.setEditable(false); + this.add(ta, "Center"); + this.addWindowListener(this); + this.setSize(300, 200); + this.setResizable(resize); + } + + + public void windowOpened(java.awt.event.WindowEvent myEvent) { + } + + public void windowClosed(java.awt.event.WindowEvent myEvent) { + } + + public void windowIconified(java.awt.event.WindowEvent myEvent) { + } + + public void windowDeiconified(java.awt.event.WindowEvent myEvent) { + } + + public void windowActivated(java.awt.event.WindowEvent myEvent) { + } + + public void windowDeactivated(java.awt.event.WindowEvent myEvent) { + } + + public void windowClosing(java.awt.event.WindowEvent myEvent) { + this.dispose(); + } +} diff --git a/test/jdk/java/awt/Dialog/DialogSystemMenu/icon24x24.gif b/test/jdk/java/awt/Dialog/DialogSystemMenu/icon24x24.gif new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/test/jdk/java/awt/Dialog/DialogSystemMenu/iconone.gif b/test/jdk/java/awt/Dialog/DialogSystemMenu/iconone.gif new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/test/jdk/java/awt/Dialog/DialogSystemMenu/icontwo.gif b/test/jdk/java/awt/Dialog/DialogSystemMenu/icontwo.gif new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/test/jdk/java/awt/Dialog/FileDialogFilterTest.java b/test/jdk/java/awt/Dialog/FileDialogFilterTest.java new file mode 100644 index 0000000000000..e30d8ea58a2d6 --- /dev/null +++ b/test/jdk/java/awt/Dialog/FileDialogFilterTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.FileDialog; +import java.awt.Frame; +import java.io.File; +import java.io.FilenameFilter; + +/* + * @test + * @bug 4364256 + * @summary Test to File Dialog filter + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual FileDialogFilterTest + */ + +public class FileDialogFilterTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Run the test, make sure a file dialog + comes up with no crash. If the file dialog + comes up successfully then press PASS, else FAIL. + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .build() + .awaitAndCheck(); + } + + public static FileDialog initialize() { + FileDialog fDlg = new FileDialog(new Frame()); + fDlg.addNotify(); + fDlg.setFilenameFilter(new MyFilter()); + return fDlg; + } +} + +class MyFilter implements FilenameFilter { + public boolean accept(File dir, String name) { + return true; + } +} diff --git a/test/jdk/java/awt/Dialog/PrintToFileTest/PrintToFileFrame.java b/test/jdk/java/awt/Dialog/PrintToFileTest/PrintToFileFrame.java new file mode 100644 index 0000000000000..a117622d57003 --- /dev/null +++ b/test/jdk/java/awt/Dialog/PrintToFileTest/PrintToFileFrame.java @@ -0,0 +1,40 @@ +import java.awt.Button; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.PrintJob; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +class PrintToFileFrame extends Frame implements ActionListener { + Button nativeDlg = new Button("Show print dialog"); + + public PrintToFileFrame() { + this.setLayout(new FlowLayout()); + add(nativeDlg); + nativeDlg.addActionListener(this); + + setSize(300, 300); + } + + @SuppressWarnings("removal") + public void actionPerformed(ActionEvent ae) { + if (System.getSecurityManager() == null) { + throw new RuntimeException("Security manager isn't installed."); + } + + try { + System.getSecurityManager().checkPrintJobAccess(); + System.out.println("checkPrintJobAccess - OK"); + } catch (SecurityException e) { + System.out.println("checkPrintJobAccess - ERROR " + e); + } + + PrintJob printJob = getToolkit().getPrintJob(this, null, null); + + if (printJob != null) { + System.out.println("Print Job: " + printJob); + } else { + System.out.println("Print Job is null."); + } + } +} diff --git a/test/jdk/java/awt/Dialog/PrintToFileTest/PrintToFileGranted.java b/test/jdk/java/awt/Dialog/PrintToFileTest/PrintToFileGranted.java new file mode 100644 index 0000000000000..05d73123d983a --- /dev/null +++ b/test/jdk/java/awt/Dialog/PrintToFileTest/PrintToFileGranted.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.print.PrinterJob; + +/* + * @test + * @bug 6275359 + * @summary Test to verify system menu of a dialog on win32 + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @compile PrintToFileFrame.java + * @compile PrintToFileGranted.java + * @run main/manual/policy=granted/othervm PrintToFileGranted + */ + +public class PrintToFileGranted { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS; + if (isPrintSupport()) { + INSTRUCTIONS = """ + 1. Click on 'Show file dialog' button A print dialog will come up + 2. If checkbox 'Print to file' is enabled then the test passed + else the test failed + 3. Close the print dialog before pressing PASS or FAIL buttons + """; + } else { + INSTRUCTIONS = """ + 1. The test requires printer installed in your system, + but there is no printers found + Please install one and re-run the test + """; + } + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(new PrintToFileFrame()) + .build() + .awaitAndCheck(); + } + + public static boolean isPrintSupport() { + PrinterJob pj = PrinterJob.getPrinterJob(); + return pj.getPrintService() != null; + } +} diff --git a/test/jdk/java/awt/Dialog/PrintToFileTest/PrintToFileRevoked.java b/test/jdk/java/awt/Dialog/PrintToFileTest/PrintToFileRevoked.java new file mode 100644 index 0000000000000..7c724e97bed53 --- /dev/null +++ b/test/jdk/java/awt/Dialog/PrintToFileTest/PrintToFileRevoked.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.print.PrinterJob; + +/* + * @test + * @bug 6275359 + * @summary Test to verify Printing ignores Security permissions + * using native dialog + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @compile PrintToFileRevoked.java + * @run main/manual/policy=revoked/othervm PrintToFileRevoked + */ + +public class PrintToFileRevoked { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS; + if (isPrintSupport()) { + INSTRUCTIONS = """ + 1. Click on 'Show file dialog' button A print dialog will come up + 2. If checkbox 'Print to file' is disabled then the test passed + else the test failed + 3. Close the print dialog before pressing PASS or FAIL buttons + """; + } else { + INSTRUCTIONS = """ + 1. The test requires printer installed in your system, + but there is no printers found + Please install one and re-run the test + """; + } + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(new PrintToFileFrame()) + .build() + .awaitAndCheck(); + } + + public static boolean isPrintSupport() { + PrinterJob pj = PrinterJob.getPrinterJob(); + return pj.getPrintService() != null; + } +} diff --git a/test/jdk/java/awt/Dialog/PrintToFileTest/granted b/test/jdk/java/awt/Dialog/PrintToFileTest/granted new file mode 100644 index 0000000000000..e73b0fdf3cdef --- /dev/null +++ b/test/jdk/java/awt/Dialog/PrintToFileTest/granted @@ -0,0 +1,10 @@ +/* AUTOMATICALLY GENERATED ON Thu Jan 03 15:48:39 PST 2002*/ +/* DO NOT EDIT */ + +grant { + permission java.lang.RuntimePermission "queuePrintJob"; + permission java.util.PropertyPermission "*", "read"; + permission java.io.FilePermission "<>", "read"; + permission java.io.FilePermission "<>", "write"; + permission java.lang.RuntimePermission "accessClassInPackage.sun.util.locale.provider"; +}; diff --git a/test/jdk/java/awt/Dialog/PrintToFileTest/revoked b/test/jdk/java/awt/Dialog/PrintToFileTest/revoked new file mode 100644 index 0000000000000..d2545e15e1155 --- /dev/null +++ b/test/jdk/java/awt/Dialog/PrintToFileTest/revoked @@ -0,0 +1,9 @@ +/* AUTOMATICALLY GENERATED ON Thu Jan 03 15:48:39 PST 2002*/ +/* DO NOT EDIT */ + +grant { + permission java.lang.RuntimePermission "queuePrintJob"; + permission java.util.PropertyPermission "*", "read"; + permission java.lang.RuntimePermission "accessClassInPackage.sun.util.locale.provider"; +}; + diff --git a/test/jdk/java/awt/Dialog/TopmostModalDialogTest.java b/test/jdk/java/awt/Dialog/TopmostModalDialogTest.java new file mode 100644 index 0000000000000..7b91d47e248c4 --- /dev/null +++ b/test/jdk/java/awt/Dialog/TopmostModalDialogTest.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +/* + * @test + * @bug 4940645 + * @summary Test to verify setAlwaysOnTop(true) does + * work in modal dialog in Windows + * @requires (os.family == "windows" | os.family == "linux" ) + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual TopmostModalDialogTest + */ + +public class TopmostModalDialogTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + (This test verifies that modal dialog can be made always on top + This test should only be run on the platforms which support always-on-top windows + Such platforms are: Windows, Linux with GNOME2/Metacity window manager, + Solaris with GNOME2/Metacity window manager + If you are not running on any of these platforms, please select 'Pass' to skip testing + If you are unsure on which platform you are running please select 'Pass') + + 1. After test started you see a frame with \\"Main Frame\\" title + It contains three buttons. Every button starts one of test stage + You should test all three stages + 2. After you press button to start the stage. It shows modal dialog + This modal dialog should be always-on-top window + 3. Since it's a modal the only way to test this is try to cover it + using some native window + 4. If you will able to cover it be native window - test FAILS, otherwise - PASS + + Note: in stages #2 and #3 dialog is initially shown as regular modal dialogs + You will see \\"Let's wait\\" message in the message area below + Please wait until message \\"Let's make it topmost\\" will be printed in the area + After that you can continue testing. + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .logArea(8) + .build() + .awaitAndCheck(); + } + + public static Frame initialize() { + final Tester tester = new Tester(); + Frame frame = new Frame("Main Frame"); + frame.setLayout(new GridLayout(3, 1)); + for (int i = 0; i < 3; i++) { + Button btn = new Button("Stage #" + i); + frame.add(btn); + btn.addActionListener(tester); + } + frame.pack(); + return frame; + } +} + +class Tester implements ActionListener { + public void actionPerformed(ActionEvent e) { + String command = e.getActionCommand(); + PassFailJFrame.log(command); + int cmd = Integer.parseInt(command.substring(command.length() - 1)); + PassFailJFrame.log("" + cmd); + Dialog dlg = new Dialog(new Frame(""), "Modal Dialog", true); + dlg.setBounds(100, 100, 100, 100); + dlg.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent we) { + Window self = we.getWindow(); + Window owner = self.getOwner(); + if (owner != null) { + owner.dispose(); + } else { + self.dispose(); + } + } + }); + + switch (cmd) { + case 0: + dlg.setAlwaysOnTop(true); + dlg.setVisible(true); + break; + case 1: + (new Thread(new TopmostMaker(dlg))).start(); + dlg.setVisible(true); + break; + case 2: + dlg.setFocusableWindowState(false); + (new Thread(new TopmostMaker(dlg))).start(); + dlg.setVisible(true); + break; + default: + PassFailJFrame.log("Unsupported operation :("); + } + } +} + +class TopmostMaker implements Runnable { + final Window wnd; + + public TopmostMaker(Window wnd) { + this.wnd = wnd; + } + + public void run() { + PassFailJFrame.log("Let's wait"); + try { + Thread.sleep(1000); + } catch (InterruptedException ie) { + PassFailJFrame.log("Test was interrupted. " + ie); + ie.printStackTrace(); + } + PassFailJFrame.log("Let's make it topmost"); + wnd.setAlwaysOnTop(true); + } +} From 6298607643dc00f2d7a2f2c23894fed0618cc78d Mon Sep 17 00:00:00 2001 From: Roman Marchenko Date: Thu, 13 Mar 2025 16:23:34 +0000 Subject: [PATCH 158/846] 8309841: Jarsigner should print a warning if an entry is removed Reviewed-by: yan Backport-of: bdfb41f977258831e4b0ceaef5d016d095ab6e7f --- .../sun/security/tools/jarsigner/Main.java | 16 ++++ .../security/tools/jarsigner/Resources.java | 2 + .../tools/jarsigner/RemovedFiles.java | 94 +++++++++++++++++++ .../jdk/test/lib/util/JarUtilsTest.java | 77 +++++++++++++++ test/lib/jdk/test/lib/util/JarUtils.java | 53 ++++++++++- 5 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 test/jdk/sun/security/tools/jarsigner/RemovedFiles.java create mode 100644 test/lib-test/jdk/test/lib/util/JarUtilsTest.java diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java index 6957939cae4ba..d17615309e83a 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java @@ -180,6 +180,7 @@ public static void main(String args[]) throws Exception { private boolean hasExpiringCert = false; private boolean hasExpiringTsaCert = false; private boolean noTimestamp = true; + private boolean hasNonexistentEntries = false; // Expiration date. The value could be null if signed by a trusted cert. private Date expireDate = null; @@ -706,6 +707,7 @@ void verifyJar(String jarName) Map sigMap = new HashMap<>(); Map sigNameMap = new HashMap<>(); Map unparsableSignatures = new HashMap<>(); + Map> entriesInSF = new HashMap<>(); try { jf = new JarFile(jarName, true); @@ -753,6 +755,7 @@ void verifyJar(String jarName) break; } } + entriesInSF.put(alias, sf.getEntries().keySet()); if (!found) { unparsableSignatures.putIfAbsent(alias, String.format( @@ -851,6 +854,9 @@ void verifyJar(String jarName) sb.append('\n'); } } + for (var signed : entriesInSF.values()) { + signed.remove(name); + } } else if (showcerts && !verbose.equals("all")) { // Print no info for unsigned entries when -verbose:all, // to be consistent with old behavior. @@ -1044,6 +1050,13 @@ void verifyJar(String jarName) if (verbose != null) { System.out.println(history); } + var signed = entriesInSF.get(s); + if (!signed.isEmpty()) { + if (verbose != null) { + System.out.println(rb.getString("history.nonexistent.entries") + signed); + } + hasNonexistentEntries = true; + } } else { unparsableSignatures.putIfAbsent(s, String.format( rb.getString("history.nobk"), s)); @@ -1287,6 +1300,9 @@ private void displayMessagesAndResult(boolean isSigning) { } } + if (hasNonexistentEntries) { + warnings.add(rb.getString("nonexistent.entries.found")); + } if (extraAttrsDetected) { warnings.add(rb.getString("extra.attributes.detected")); } diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java index 2b74856b7ce37..4185c786aecb8 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java @@ -165,6 +165,7 @@ public class Resources extends java.util.ListResourceBundle { {"history.with.ts", "- Signed by \"%1$s\"\n Digest algorithm: %2$s\n Signature algorithm: %3$s, %4$s\n Timestamped by \"%6$s\" on %5$tc\n Timestamp digest algorithm: %7$s\n Timestamp signature algorithm: %8$s, %9$s"}, {"history.without.ts", "- Signed by \"%1$s\"\n Digest algorithm: %2$s\n Signature algorithm: %3$s, %4$s"}, + {"history.nonexistent.entries", " Warning: nonexistent signed entries: "}, {"history.unparsable", "- Unparsable signature-related file %s"}, {"history.nosf", "- Missing signature-related file META-INF/%s.SF"}, {"history.nobk", "- Missing block file for signature-related file META-INF/%s.SF"}, @@ -175,6 +176,7 @@ public class Resources extends java.util.ListResourceBundle { {"key.bit.weak", "%d-bit key (weak)"}, {"key.bit.disabled", "%d-bit key (disabled)"}, {"unknown.size", "unknown size"}, + {"nonexistent.entries.found", "This jar contains signed entries for files that do not exist. See the -verbose output for more details."}, {"extra.attributes.detected", "POSIX file permission and/or symlink attributes detected. These attributes are ignored when signing and are not protected by the signature."}, {"jarsigner.", "jarsigner: "}, diff --git a/test/jdk/sun/security/tools/jarsigner/RemovedFiles.java b/test/jdk/sun/security/tools/jarsigner/RemovedFiles.java new file mode 100644 index 0000000000000..7a4e566efa68b --- /dev/null +++ b/test/jdk/sun/security/tools/jarsigner/RemovedFiles.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 8309841 + * @summary Jarsigner should print a warning if an entry is removed + * @library /test/lib + */ + +import jdk.test.lib.SecurityTools; +import jdk.test.lib.util.JarUtils; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +public class RemovedFiles { + + private static final String NONEXISTENT_ENTRIES_FOUND + = "This jar contains signed entries for files that do not exist. See the -verbose output for more details."; + + public static void main(String[] args) throws Exception { + JarUtils.createJarFile( + Path.of("a.jar"), + Path.of("."), + Files.writeString(Path.of("a"), "a"), + Files.writeString(Path.of("b"), "b")); + SecurityTools.keytool("-genkeypair -storepass changeit -keystore ks -alias x -dname CN=x -keyalg ed25519"); + SecurityTools.jarsigner("-storepass changeit -keystore ks a.jar x"); + + // All is fine at the beginning. + SecurityTools.jarsigner("-verify a.jar") + .shouldNotContain(NONEXISTENT_ENTRIES_FOUND); + + // Remove an entry after signing. There will be a warning. + JarUtils.deleteEntries(Path.of("a.jar"), "a"); + SecurityTools.jarsigner("-verify a.jar") + .shouldContain(NONEXISTENT_ENTRIES_FOUND); + SecurityTools.jarsigner("-verify -verbose a.jar") + .shouldContain(NONEXISTENT_ENTRIES_FOUND) + .shouldContain("Warning: nonexistent signed entries: [a]"); + + // Remove one more entry. + JarUtils.deleteEntries(Path.of("a.jar"), "b"); + SecurityTools.jarsigner("-verify a.jar") + .shouldContain(NONEXISTENT_ENTRIES_FOUND); + SecurityTools.jarsigner("-verify -verbose a.jar") + .shouldContain(NONEXISTENT_ENTRIES_FOUND) + .shouldContain("Warning: nonexistent signed entries: [a, b]"); + + // Re-sign will not clear the warning. + SecurityTools.jarsigner("-storepass changeit -keystore ks a.jar x"); + SecurityTools.jarsigner("-verify a.jar") + .shouldContain(NONEXISTENT_ENTRIES_FOUND); + + // Unfortunately, if there is a non-file entry in manifest, there will be + // a false alarm. See https://bugs.openjdk.org/browse/JDK-8334261. + var man = new Manifest(); + man.getMainAttributes().putValue("Manifest-Version", "1.0"); + man.getEntries().computeIfAbsent("Hello", key -> new Attributes()) + .putValue("Foo", "Bar"); + JarUtils.createJarFile(Path.of("b.jar"), + man, + Path.of("."), + Path.of("a")); + SecurityTools.jarsigner("-storepass changeit -keystore ks b.jar x"); + SecurityTools.jarsigner("-verbose -verify b.jar") + .shouldContain("Warning: nonexistent signed entries: [Hello]") + .shouldContain(NONEXISTENT_ENTRIES_FOUND); + + } +} diff --git a/test/lib-test/jdk/test/lib/util/JarUtilsTest.java b/test/lib-test/jdk/test/lib/util/JarUtilsTest.java new file mode 100644 index 0000000000000..eb9dced32569a --- /dev/null +++ b/test/lib-test/jdk/test/lib/util/JarUtilsTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 8309841 + * @summary Unit Test for a common Test API in jdk.test.lib.util.JarUtils + * @library /test/lib + */ + +import jdk.test.lib.Asserts; +import jdk.test.lib.util.JarUtils; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.stream.Collectors; + +public class JarUtilsTest { + public static void main(String[] args) throws Exception { + Files.createDirectory(Path.of("bx")); + JarUtils.createJarFile(Path.of("a.jar"), + Path.of("."), + Files.writeString(Path.of("a"), ""), + Files.writeString(Path.of("b1"), ""), + Files.writeString(Path.of("b2"), ""), + Files.writeString(Path.of("bx/x"), ""), + Files.writeString(Path.of("c"), ""), + Files.writeString(Path.of("e1"), ""), + Files.writeString(Path.of("e2"), "")); + checkContent("a", "b1", "b2", "bx/x", "c", "e1", "e2"); + + JarUtils.deleteEntries(Path.of("a.jar"), "a"); + checkContent("b1", "b2", "bx/x", "c", "e1", "e2"); + + // Note: b* covers everything starting with b, even bx/x + JarUtils.deleteEntries(Path.of("a.jar"), "b*"); + checkContent("c", "e1", "e2"); + + // d* does not match + JarUtils.deleteEntries(Path.of("a.jar"), "d*"); + checkContent("c", "e1", "e2"); + + // multiple patterns + JarUtils.deleteEntries(Path.of("a.jar"), "d*", "e*"); + checkContent("c"); + } + + static void checkContent(String... expected) throws IOException { + try (var jf = new JarFile("a.jar")) { + Asserts.assertEquals(Set.of(expected), + jf.stream().map(JarEntry::getName).collect(Collectors.toSet())); + } + } +} diff --git a/test/lib/jdk/test/lib/util/JarUtils.java b/test/lib/jdk/test/lib/util/JarUtils.java index e1b3ccac19fc5..3aa4ada5197ad 100644 --- a/test/lib/jdk/test/lib/util/JarUtils.java +++ b/test/lib/jdk/test/lib/util/JarUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -320,6 +320,57 @@ public static void updateManifest(String src, String dest, Manifest man) updateJar(src, dest, Map.of(JarFile.MANIFEST_NAME, bout.toByteArray())); } + /** + * Remove entries from a ZIP file. + * + * Each entry can be a name or a name ending with "*". + * + * @return number of removed entries + * @throws IOException if there is any I/O error + */ + public static int deleteEntries(Path jarfile, String... patterns) + throws IOException { + Path tmpfile = Files.createTempFile("jar", "jar"); + int count = 0; + + try (OutputStream out = Files.newOutputStream(tmpfile); + JarOutputStream jos = new JarOutputStream(out)) { + try (JarFile jf = new JarFile(jarfile.toString())) { + Enumeration jentries = jf.entries(); + top: while (jentries.hasMoreElements()) { + JarEntry jentry = jentries.nextElement(); + String name = jentry.getName(); + for (String pattern : patterns) { + if (pattern.endsWith("*")) { + if (name.startsWith(pattern.substring( + 0, pattern.length() - 1))) { + // Go directly to next entry. This + // one is not written into `jos` and + // therefore removed. + count++; + continue top; + } + } else { + if (name.equals(pattern)) { + // Same as above + count++; + continue top; + } + } + } + // No pattern matched, file retained + jos.putNextEntry(copyEntry(jentry)); + jf.getInputStream(jentry).transferTo(jos); + } + } + } + + // replace the original JAR file + Files.move(tmpfile, jarfile, StandardCopyOption.REPLACE_EXISTING); + + return count; + } + private static void updateEntry(JarOutputStream jos, String name, Object content) throws IOException { if (content instanceof Boolean) { From f4039e932020d2a088faf120e351e86197bfd568 Mon Sep 17 00:00:00 2001 From: Martin Balao Date: Mon, 24 Mar 2025 18:36:42 +0000 Subject: [PATCH 159/846] 8339810: Clean up the code in sun.tools.jar.Main to properly close resources and use ZipFile during extract Reviewed-by: mbaesken Backport-of: 8fce5275fc94ebc404a6a37f5ea0407140de63c1 --- .../share/classes/sun/tools/jar/Main.java | 275 ++++++++---------- 1 file changed, 127 insertions(+), 148 deletions(-) diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java index 7a60317a5f5b3..77cb74dfce76c 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java +++ b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -252,7 +252,7 @@ private static File createTempFileInSameDirectoryAs(File file) * Starts main program with the specified arguments. */ @SuppressWarnings({"removal"}) - public synchronized boolean run(String args[]) { + public synchronized boolean run(String[] args) { ok = true; if (!parseArgs(args)) { return false; @@ -367,11 +367,9 @@ public synchronized boolean run(String args[]) { if (fname != null) { list(fname, files); } else { - InputStream in = new FileInputStream(FileDescriptor.in); - try { - list(new BufferedInputStream(in), files); - } finally { - in.close(); + try (InputStream in = new FileInputStream(FileDescriptor.in); + BufferedInputStream bis = new BufferedInputStream(in)) { + list(bis, files); } } } else if (xflag) { @@ -387,18 +385,12 @@ public synchronized boolean run(String args[]) { // latter can handle it. String[] files = filesMapToFiles(filesMap); - if (fname != null && files != null) { + if (fname != null) { extract(fname, files); } else { - InputStream in = (fname == null) - ? new FileInputStream(FileDescriptor.in) - : new FileInputStream(fname); - try { - if (!extract(new BufferedInputStream(in), files) && fname != null) { - extract(fname, files); - } - } finally { - in.close(); + try (InputStream in = new FileInputStream(FileDescriptor.in); + BufferedInputStream bis = new BufferedInputStream(in)) { + extract(bis, files); } } } else if (iflag) { @@ -495,7 +487,7 @@ Stream filesToEntryNames(Map.Entry fileEntries) { /** * Parses command line arguments. */ - boolean parseArgs(String args[]) { + boolean parseArgs(String[] args) { /* Preprocess and expand @file arguments */ try { args = CommandLine.parse(args); @@ -929,118 +921,116 @@ boolean update(InputStream in, OutputStream out, Map moduleInfos, JarIndex jarIndex) throws IOException { - ZipInputStream zis = new ZipInputStream(in); - ZipOutputStream zos = new JarOutputStream(out); - ZipEntry e = null; - boolean foundManifest = false; boolean updateOk = true; + try (ZipInputStream zis = new ZipInputStream(in); + ZipOutputStream zos = new JarOutputStream(out)) { - // All actual entries added/updated/existing, in the jar file (excl manifest - // and module-info.class ). - Set jentries = new HashSet<>(); - - if (jarIndex != null) { - addIndex(jarIndex, zos); - } + if (jarIndex != null) { + addIndex(jarIndex, zos); + } + ZipEntry e = null; + boolean foundManifest = false; + // All actual entries added/updated/existing, in the jar file (excl manifest + // and module-info.class ). + Set jentries = new HashSet<>(); - // put the old entries first, replace if necessary - while ((e = zis.getNextEntry()) != null) { - String name = e.getName(); + // put the old entries first, replace if necessary + while ((e = zis.getNextEntry()) != null) { + String name = e.getName(); - boolean isManifestEntry = equalsIgnoreCase(name, MANIFEST_NAME); - boolean isModuleInfoEntry = isModuleInfoEntry(name); + boolean isManifestEntry = equalsIgnoreCase(name, MANIFEST_NAME); + boolean isModuleInfoEntry = isModuleInfoEntry(name); - if ((jarIndex != null && equalsIgnoreCase(name, INDEX_NAME)) - || (Mflag && isManifestEntry)) { - continue; - } else if (isManifestEntry && ((newManifest != null) || + if ((jarIndex != null && equalsIgnoreCase(name, INDEX_NAME)) + || (Mflag && isManifestEntry)) { + continue; + } else if (isManifestEntry && ((newManifest != null) || (ename != null) || isMultiRelease)) { - foundManifest = true; - if (newManifest != null) { - // Don't read from the newManifest InputStream, as we - // might need it below, and we can't re-read the same data - // twice. - try (FileInputStream fis = new FileInputStream(mname)) { - if (isAmbiguousMainClass(new Manifest(fis))) { - return false; + foundManifest = true; + if (newManifest != null) { + // Don't read from the newManifest InputStream, as we + // might need it below, and we can't re-read the same data + // twice. + try (FileInputStream fis = new FileInputStream(mname)) { + if (isAmbiguousMainClass(new Manifest(fis))) { + return false; + } } } - } - // Update the manifest. - Manifest old = new Manifest(zis); - if (newManifest != null) { - old.read(newManifest); - } - if (!updateManifest(old, zos)) { - return false; - } - } else if (moduleInfos != null && isModuleInfoEntry) { - moduleInfos.putIfAbsent(name, zis.readAllBytes()); - } else { - boolean isDir = e.isDirectory(); - if (!entryMap.containsKey(name)) { // copy the old stuff - // do our own compression - ZipEntry e2 = new ZipEntry(name); - e2.setMethod(e.getMethod()); - setZipEntryTime(e2, e.getTime()); - e2.setComment(e.getComment()); - e2.setExtra(e.getExtra()); - if (e.getMethod() == ZipEntry.STORED) { - e2.setSize(e.getSize()); - e2.setCrc(e.getCrc()); + // Update the manifest. + Manifest old = new Manifest(zis); + if (newManifest != null) { + old.read(newManifest); + } + if (!updateManifest(old, zos)) { + return false; + } + } else if (moduleInfos != null && isModuleInfoEntry) { + moduleInfos.putIfAbsent(name, zis.readAllBytes()); + } else { + boolean isDir = e.isDirectory(); + if (!entryMap.containsKey(name)) { // copy the old stuff + // do our own compression + ZipEntry e2 = new ZipEntry(name); + e2.setMethod(e.getMethod()); + setZipEntryTime(e2, e.getTime()); + e2.setComment(e.getComment()); + e2.setExtra(e.getExtra()); + if (e.getMethod() == ZipEntry.STORED) { + e2.setSize(e.getSize()); + e2.setCrc(e.getCrc()); + } + zos.putNextEntry(e2); + copy(zis, zos); + } else { // replace with the new files + Entry ent = entryMap.get(name); + addFile(zos, ent); + entryMap.remove(name); + entries.remove(ent); + isDir = ent.isDir; + } + if (!isDir) { + jentries.add(name); } - zos.putNextEntry(e2); - copy(zis, zos); - } else { // replace with the new files - Entry ent = entryMap.get(name); - addFile(zos, ent); - entryMap.remove(name); - entries.remove(ent); - isDir = ent.isDir; - } - if (!isDir) { - jentries.add(name); } } - } - // add the remaining new files - for (Entry entry : entries) { - addFile(zos, entry); - if (!entry.isDir) { - jentries.add(entry.name); + // add the remaining new files + for (Entry entry : entries) { + addFile(zos, entry); + if (!entry.isDir) { + jentries.add(entry.name); + } } - } - if (!foundManifest) { - if (newManifest != null) { - Manifest m = new Manifest(newManifest); - updateOk = !isAmbiguousMainClass(m); - if (updateOk) { - if (!updateManifest(m, zos)) { + if (!foundManifest) { + if (newManifest != null) { + Manifest m = new Manifest(newManifest); + updateOk = !isAmbiguousMainClass(m); + if (updateOk) { + if (!updateManifest(m, zos)) { + updateOk = false; + } + } + } else if (ename != null) { + if (!updateManifest(new Manifest(), zos)) { updateOk = false; } } - } else if (ename != null) { - if (!updateManifest(new Manifest(), zos)) { + } + if (updateOk) { + if (moduleInfos != null && !moduleInfos.isEmpty()) { + Set pkgs = new HashSet<>(); + jentries.forEach(je -> addPackageIfNamed(pkgs, je)); + addExtendedModuleAttributes(moduleInfos, pkgs); + updateOk = checkModuleInfo(moduleInfos.get(MODULE_INFO), jentries); + updateModuleInfo(moduleInfos, zos); + // TODO: check manifest main classes, etc + } else if (moduleVersion != null || modulesToHash != null) { + error(getMsg("error.module.options.without.info")); updateOk = false; } } } - if (updateOk) { - if (moduleInfos != null && !moduleInfos.isEmpty()) { - Set pkgs = new HashSet<>(); - jentries.forEach( je -> addPackageIfNamed(pkgs, je)); - addExtendedModuleAttributes(moduleInfos, pkgs); - updateOk = checkModuleInfo(moduleInfos.get(MODULE_INFO), jentries); - updateModuleInfo(moduleInfos, zos); - // TODO: check manifest main classes, etc - } else if (moduleVersion != null || modulesToHash != null) { - error(getMsg("error.module.options.without.info")); - updateOk = false; - } - } - zis.close(); - zos.close(); return updateOk; } @@ -1362,19 +1352,12 @@ void updateLastModifiedTime(Set zes) throws IOException { /** * Extracts specified entries from JAR file. - * - * @return whether entries were found and successfully extracted - * (indicating this was a zip file without "leading garbage") */ - boolean extract(InputStream in, String files[]) throws IOException { + void extract(InputStream in, String[] files) throws IOException { ZipInputStream zis = new ZipInputStream(in); ZipEntry e; - // Set of all directory entries specified in archive. Disallows - // null entries. Disallows all entries if using pre-6.0 behavior. - boolean entriesFound = false; Set dirs = newDirSet(); while ((e = zis.getNextEntry()) != null) { - entriesFound = true; if (files == null) { dirs.add(extractFile(zis, e)); } else { @@ -1393,32 +1376,31 @@ boolean extract(InputStream in, String files[]) throws IOException { // instead of during, because creating a file in a directory changes // that directory's timestamp. updateLastModifiedTime(dirs); - - return entriesFound; } /** * Extracts specified entries from JAR file, via ZipFile. */ - void extract(String fname, String files[]) throws IOException { - ZipFile zf = new ZipFile(fname); - Set dirs = newDirSet(); - Enumeration zes = zf.entries(); - while (zes.hasMoreElements()) { - ZipEntry e = zes.nextElement(); - if (files == null) { - dirs.add(extractFile(zf.getInputStream(e), e)); - } else { - String name = e.getName(); - for (String file : files) { - if (name.startsWith(file)) { - dirs.add(extractFile(zf.getInputStream(e), e)); - break; + void extract(String fname, String[] files) throws IOException { + final Set dirs; + try (ZipFile zf = new ZipFile(fname)) { + dirs = newDirSet(); + Enumeration zes = zf.entries(); + while (zes.hasMoreElements()) { + ZipEntry e = zes.nextElement(); + if (files == null) { + dirs.add(extractFile(zf.getInputStream(e), e)); + } else { + String name = e.getName(); + for (String file : files) { + if (name.startsWith(file)) { + dirs.add(extractFile(zf.getInputStream(e), e)); + break; + } } } } } - zf.close(); updateLastModifiedTime(dirs); } @@ -1499,7 +1481,7 @@ ZipEntry extractFile(InputStream is, ZipEntry e) throws IOException { /** * Lists contents of JAR file. */ - void list(InputStream in, String files[]) throws IOException { + void list(InputStream in, String[] files) throws IOException { ZipInputStream zis = new ZipInputStream(in); ZipEntry e; while ((e = zis.getNextEntry()) != null) { @@ -1517,13 +1499,13 @@ void list(InputStream in, String files[]) throws IOException { /** * Lists contents of JAR file, via ZipFile. */ - void list(String fname, String files[]) throws IOException { - ZipFile zf = new ZipFile(fname); - Enumeration zes = zf.entries(); - while (zes.hasMoreElements()) { - printEntry(zes.nextElement(), files); + void list(String fname, String[] files) throws IOException { + try (ZipFile zf = new ZipFile(fname)) { + Enumeration zes = zf.entries(); + while (zes.hasMoreElements()) { + printEntry(zes.nextElement(), files); + } } - zf.close(); } /** @@ -1566,10 +1548,8 @@ List getJarPath(String jar) throws IOException { // class path attribute will give us jar file name with // '/' as separators, so we need to change them to the // appropriate one before we open the jar file. - JarFile rf = new JarFile(jar.replace('/', File.separatorChar)); - - if (rf != null) { - Manifest man = rf.getManifest(); + try (JarFile jarFile = new JarFile(jar.replace('/', File.separatorChar))) { + Manifest man = jarFile.getManifest(); if (man != null) { Attributes attr = man.getMainAttributes(); if (attr != null) { @@ -1590,7 +1570,6 @@ List getJarPath(String jar) throws IOException { } } } - rf.close(); return files; } @@ -1697,7 +1676,7 @@ void warn(String s) { /** * Main routine to start program. */ - public static void main(String args[]) { + public static void main(String[] args) { Main jartool = new Main(System.out, System.err, "jar"); System.exit(jartool.run(args) ? 0 : 1); } From ccf1209addf5979809dbe1cac14704224af40024 Mon Sep 17 00:00:00 2001 From: Andrew John Hughes Date: Tue, 8 Apr 2025 14:11:41 +0000 Subject: [PATCH 160/846] 8331735: UpcallLinker::on_exit races with GC when copying frame anchor 8286875: ProgrammableUpcallHandler::on_entry/on_exit access thread fields from native Reviewed-by: mbalao Backport-of: 91457e694353386737e325e6fa0253bcefb8d579 --- src/hotspot/share/prims/universalUpcallHandler.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/prims/universalUpcallHandler.cpp b/src/hotspot/share/prims/universalUpcallHandler.cpp index 44b64504d1c75..b34704ea7b52a 100644 --- a/src/hotspot/share/prims/universalUpcallHandler.cpp +++ b/src/hotspot/share/prims/universalUpcallHandler.cpp @@ -131,21 +131,17 @@ void ProgrammableUpcallHandler::on_exit(OptimizedEntryBlob::FrameData* context) // restore previous handle block thread->set_active_handles(context->old_handles); - thread->frame_anchor()->zap(); - debug_only(thread->dec_java_call_counter()); + thread->frame_anchor()->copy(&context->jfa); + // Old thread-local info. has been restored. We are now back in native code. ThreadStateTransition::transition_from_java(thread, _thread_in_native); - thread->frame_anchor()->copy(&context->jfa); - // Release handles after we are marked as being in native code again, since this // operation might block JNIHandleBlock::release_block(context->new_handles, thread); - assert(!thread->has_pending_exception(), "Upcall can not throw an exception"); - if (context->should_detach) { detach_current_thread(); } From 0b592b7f04aae6cec666345be37c1456845e6e0d Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Mon, 7 Apr 2025 17:58:03 +0200 Subject: [PATCH 161/846] 8353905: [17u] Remove designator DEFAULT_PROMOTED_VERSION_PRE=ea for release 17.0.15 Reviewed-by: goetz --- make/conf/version-numbers.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf index 29ccfb0801b37..b5ff3d783b3f1 100644 --- a/make/conf/version-numbers.conf +++ b/make/conf/version-numbers.conf @@ -39,4 +39,4 @@ DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 DEFAULT_ACCEPTABLE_BOOT_VERSIONS="16 17" DEFAULT_JDK_SOURCE_TARGET_VERSION=17 -DEFAULT_PROMOTED_VERSION_PRE=ea +DEFAULT_PROMOTED_VERSION_PRE= From 9d6ffda9b435b84063425c974c28b842a89711ee Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 08:34:15 +0000 Subject: [PATCH 162/846] 8298709: Fix typos in src/java.desktop/ and various test classes of client component Backport-of: fa322e40b68abf0a253040d14414d41f4e01e028 --- .../share/classes/javax/swing/text/Document.java | 2 +- .../DeviceIdentificationTest/DeviceIdentificationTest.java | 2 +- .../HTMLDataFlavors/ManualHTMLDataFlavorTest.java | 2 +- test/jdk/java/awt/print/PrinterJob/PageFormatChange.java | 2 +- test/jdk/javax/imageio/stream/DeleteOnExitTest.sh | 2 +- test/jdk/javax/print/attribute/ServiceDlgPageRangeTest.java | 2 +- test/jdk/javax/sound/midi/Sequencer/SequencerState.java | 2 +- test/jdk/javax/swing/JColorChooser/Test4193384.java | 2 +- test/jdk/sanity/client/SwingSet/src/EditorPaneDemoTest.java | 2 +- test/jdk/sanity/client/SwingSet/src/TabbedPaneDemoTest.java | 2 +- .../sun/swingset3/demos/tree/resources/TreeDemo.properties | 2 +- .../lib/jemmy/src/org/netbeans/jemmy/WindowWaiter.java | 4 ++-- .../src/org/netbeans/jemmy/operators/ComponentOperator.java | 2 +- .../src/org/netbeans/jemmy/operators/JTreeOperator.java | 2 +- .../jemmy/src/org/netbeans/jemmy/operators/Operator.java | 6 +++--- test/jdk/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java | 2 +- 16 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/text/Document.java b/src/java.desktop/share/classes/javax/swing/text/Document.java index e0f4ac791d5e8..e16d11acecb6f 100644 --- a/src/java.desktop/share/classes/javax/swing/text/Document.java +++ b/src/java.desktop/share/classes/javax/swing/text/Document.java @@ -277,7 +277,7 @@ *

Removing text from a DefaultStyledDocument is similar to removing text from * a PlainDocument. The only difference is the extra level of Elements. * Consider what would happen if you deleted two characters at Offset 1 - * from Figure 10, above. Since the the second Element of Paragraph 1 is + * from Figure 10, above. Since the second Element of Paragraph 1 is * completely contained in the deleted region, it would be removed. * Assuming the attributes of Paragraph 1's first child matched those of * Paragraph2's first child, the results would be those shown in Figure 11. diff --git a/test/jdk/java/awt/Multiscreen/DeviceIdentificationTest/DeviceIdentificationTest.java b/test/jdk/java/awt/Multiscreen/DeviceIdentificationTest/DeviceIdentificationTest.java index 425588d669351..684ac9e253860 100644 --- a/test/jdk/java/awt/Multiscreen/DeviceIdentificationTest/DeviceIdentificationTest.java +++ b/test/jdk/java/awt/Multiscreen/DeviceIdentificationTest/DeviceIdentificationTest.java @@ -24,7 +24,7 @@ * @test * @bug 6614214 8198613 * @summary Verifies that we enter the fs mode on the correct screen. - * Here is how to test: start the test on on a multi-screen system. + * Here is how to test: start the test on a multi-screen system. * Verify that the display is correctly tracked by dragging the frame back * and forth between screens. Then verify that the correct device enters * the full-screen mode - when "Enter FS mode" is pressed it should enter on diff --git a/test/jdk/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.java b/test/jdk/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.java index 015d46f03b244..bd1ea752edba5 100644 --- a/test/jdk/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.java +++ b/test/jdk/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.java @@ -121,7 +121,7 @@ public void init() { "6) The output should contain data in three different formats", " provided by the system clipboard", " - Data after the \"ALL:\" marker should include the data", - " from the the \"SELECTION:\" marker", + " from the \"SELECTION:\" marker", " - Data after the \"FRAGMENT\" marker should include the data", " from the \"SELECTION:\" marker and may be some closing", " tags could be added to the mark-up", diff --git a/test/jdk/java/awt/print/PrinterJob/PageFormatChange.java b/test/jdk/java/awt/print/PrinterJob/PageFormatChange.java index 3cb4254c64fb9..10aaaea89f1ff 100644 --- a/test/jdk/java/awt/print/PrinterJob/PageFormatChange.java +++ b/test/jdk/java/awt/print/PrinterJob/PageFormatChange.java @@ -35,7 +35,7 @@ public class PageFormatChange { static String[] text = { - "This is is a manual test intended to be run on Windows, and you", + "This is a manual test intended to be run on Windows, and you", "must have at least two printers installed, and ideally the second", "printer should support large paper sizes. When the pageDialog appears", "first change printers, then choose a large paper size, then OK", diff --git a/test/jdk/javax/imageio/stream/DeleteOnExitTest.sh b/test/jdk/javax/imageio/stream/DeleteOnExitTest.sh index feafda7bf250b..0e66b03d3d394 100644 --- a/test/jdk/javax/imageio/stream/DeleteOnExitTest.sh +++ b/test/jdk/javax/imageio/stream/DeleteOnExitTest.sh @@ -22,7 +22,7 @@ # @test # @bug 6291034 # @run shell DeleteOnExitTest.sh -# @summary Verify that temporary imageio files files are deleted on VM exit. +# @summary Verify that temporary imageio files are deleted on VM exit. if [ -z "${TESTSRC}" ]; then echo "TESTSRC undefined: defaulting to ." diff --git a/test/jdk/javax/print/attribute/ServiceDlgPageRangeTest.java b/test/jdk/javax/print/attribute/ServiceDlgPageRangeTest.java index 5d38d4b1e11dc..f2982a13669bb 100644 --- a/test/jdk/javax/print/attribute/ServiceDlgPageRangeTest.java +++ b/test/jdk/javax/print/attribute/ServiceDlgPageRangeTest.java @@ -100,7 +100,7 @@ public static void main(java.lang.String[] args) throws Exception { } catch (InterruptedException e) { if (!testPassed && testGeneratedInterrupt) { throw new RuntimeException("PageRanges option is not disabled " - + "for for Non serv-formatted flvrs"); + + "for Non serv-formatted flvrs"); } } if (!testGeneratedInterrupt) { diff --git a/test/jdk/javax/sound/midi/Sequencer/SequencerState.java b/test/jdk/javax/sound/midi/Sequencer/SequencerState.java index 01b49e2e47124..01b1c6a45d8a0 100644 --- a/test/jdk/javax/sound/midi/Sequencer/SequencerState.java +++ b/test/jdk/javax/sound/midi/Sequencer/SequencerState.java @@ -55,7 +55,7 @@ private static boolean hasSequencer() { public static void main(String[] args) throws Exception { - out("4913027: several Sequencer methods should should specify behaviour on closed Sequencer"); + out("4913027: several Sequencer methods should specify behaviour on closed Sequencer"); if (hasSequencer()) { boolean passed = testAll(); if (passed) { diff --git a/test/jdk/javax/swing/JColorChooser/Test4193384.java b/test/jdk/javax/swing/JColorChooser/Test4193384.java index 826e9893696ed..b32006e905c30 100644 --- a/test/jdk/javax/swing/JColorChooser/Test4193384.java +++ b/test/jdk/javax/swing/JColorChooser/Test4193384.java @@ -51,7 +51,7 @@ private static void test(Color[] colors) { float[] hsb = new float[3]; for (int i = 0; i < colors.length; i++) { Color color = colors[i]; - // Make sure sure that there wasn't a regression + // Make sure that there wasn't a regression // in java.awt.Color and the conversion methods Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), hsb); if (!color.equals(Color.getHSBColor(hsb[0], hsb[1], hsb[2]))) { diff --git a/test/jdk/sanity/client/SwingSet/src/EditorPaneDemoTest.java b/test/jdk/sanity/client/SwingSet/src/EditorPaneDemoTest.java index b769c6d826878..4cc16e53e71a2 100644 --- a/test/jdk/sanity/client/SwingSet/src/EditorPaneDemoTest.java +++ b/test/jdk/sanity/client/SwingSet/src/EditorPaneDemoTest.java @@ -52,7 +52,7 @@ /* * @test * @key headful screenshots - * @summary Verifies SwingSet3 EditorPaneDemo by navigating and and validating + * @summary Verifies SwingSet3 EditorPaneDemo by navigating and validating * the page contents in all pages * * @library /sanity/client/lib/jemmy/src diff --git a/test/jdk/sanity/client/SwingSet/src/TabbedPaneDemoTest.java b/test/jdk/sanity/client/SwingSet/src/TabbedPaneDemoTest.java index 6b7b270173f37..0e80df72a6346 100644 --- a/test/jdk/sanity/client/SwingSet/src/TabbedPaneDemoTest.java +++ b/test/jdk/sanity/client/SwingSet/src/TabbedPaneDemoTest.java @@ -39,7 +39,7 @@ * @test * @key headful * @summary Verifies SwingSet3 TabbedPaneDemo by iterating through tab placement - * positions, opening each tab and verifying the the tab gets selected. + * positions, opening each tab and verifying the tab gets selected. * * @library /sanity/client/lib/jemmy/src * @library /sanity/client/lib/Extensions/src diff --git a/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/TreeDemo.properties b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/TreeDemo.properties index 77c6f82fc1e62..3d584efb05af2 100644 --- a/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/TreeDemo.properties +++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/resources/TreeDemo.properties @@ -1,6 +1,6 @@ ### Tree Demo ### -TreeDemo.accessible_description=This demo shows shows a sample usage of a JTree component. +TreeDemo.accessible_description=This demo shows a sample usage of a JTree component. TreeDemo.tooltip=JTree demo TreeDemo.name=Tree Demo TreeDemo.music=Music diff --git a/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/WindowWaiter.java b/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/WindowWaiter.java index c7b27be0895c9..0e2c6866fd01e 100644 --- a/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/WindowWaiter.java +++ b/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/WindowWaiter.java @@ -286,7 +286,7 @@ public Window waitWindow(Window o, ComponentChooser ch) } /** - * Wait till the count of windows which meet the the search criteria becomes + * Wait till the count of windows which meet the search criteria becomes * equal to count. * * @param ch a component chooser used to define and apply the search @@ -300,7 +300,7 @@ public static void waitWindowCount(ComponentChooser ch, int count) } /** - * Wait till the count of windows which meet the the search criteria becomes + * Wait till the count of windows which meet the search criteria becomes * equal to count. * * @param owner The owner window of all the windows to be checked diff --git a/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/ComponentOperator.java b/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/ComponentOperator.java index 99a076b7b4ddd..4575c4dbe981a 100644 --- a/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/ComponentOperator.java +++ b/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/ComponentOperator.java @@ -252,7 +252,7 @@ public ComponentOperator(ContainerOperator cont, int index) { /** * Constructor. Waits for a component in a container to show. The component - * is is the first {@code java.awt.Component} that shows and that lies + * is the first {@code java.awt.Component} that shows and that lies * below the container in the display containment hierarchy. Uses cont's * timeout and output for waiting and to init operator. * diff --git a/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/JTreeOperator.java b/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/JTreeOperator.java index e97862832e279..29d7c238b7948 100644 --- a/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/JTreeOperator.java +++ b/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/JTreeOperator.java @@ -66,7 +66,7 @@ *

Timeouts used:
* JTreeOperator.WaitNodeExpandedTimeout - time to wait node expanded
* JTreeOperator.WaitNodeCollapsedTimeout - time to wait node collapsed
- * JTreeOperator.WaitAfterNodeExpandedTimeout - time to to sleep after node + * JTreeOperator.WaitAfterNodeExpandedTimeout - time to sleep after node * expanded
* JTreeOperator.WaitNextNodeTimeout - time to wait next node displayed
* JTreeOperator.WaitNodeVisibleTimeout - time to wait node visible
diff --git a/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/Operator.java b/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/Operator.java index 840362b73bdf5..e29bf9b116b02 100644 --- a/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/Operator.java +++ b/test/jdk/sanity/client/lib/jemmy/src/org/netbeans/jemmy/operators/Operator.java @@ -366,7 +366,7 @@ public Timeouts getTimeouts() { } /** - * Returns component visualizer. Visualizer is used from from + * Returns component visualizer. Visualizer is used from * makeComponentVisible() method. * * @return a visualizer assigned to this operator. @@ -378,7 +378,7 @@ public ComponentVisualizer getVisualizer() { } /** - * Changes component visualizer. Visualizer is used from from + * Changes component visualizer. Visualizer is used from * makeComponentVisible() method. * * @param vo a visualizer to assign to this operator. @@ -1080,7 +1080,7 @@ public String map() { } /** - * Interface used to make component visible & ready to to make operations + * Interface used to make component visible & ready to make operations * with. */ public interface ComponentVisualizer { diff --git a/test/jdk/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java b/test/jdk/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java index 9e0194b498530..9c5cf3de2e37c 100644 --- a/test/jdk/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java +++ b/test/jdk/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java @@ -75,7 +75,7 @@ private static void testInvalidType(AccelSurface surface, int type) { if (ret != 0l) { System.err.printf( "FAILED: surface.getNativeResource(%d) returned" + - " 0x%s. It should have have returned 0L\n", + " 0x%s. It should have returned 0L\n", type, ret); failed = true; } From 59a6f65b7e4ef2f4e67f1a78ae0983c9a97725f9 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 08:38:18 +0000 Subject: [PATCH 163/846] 8296920: Regression Test DialogOrient.java fails on MacOS Backport-of: 8c9d21e5193cd20585eae0636337a78bc9d89f60 --- test/jdk/java/awt/print/Dialog/DialogOrient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/java/awt/print/Dialog/DialogOrient.java b/test/jdk/java/awt/print/Dialog/DialogOrient.java index 982e51548bf2a..6650ced64f46e 100644 --- a/test/jdk/java/awt/print/Dialog/DialogOrient.java +++ b/test/jdk/java/awt/print/Dialog/DialogOrient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -70,8 +70,8 @@ private static void init() throws Exception { Sysout.printInstructions( instructions ); PrinterJob job = PrinterJob.getPrinterJob(); - job.setPrintable(new DialogOrient()); PageFormat landscape = job.pageDialog(job.defaultPage()); + job.setPrintable(new DialogOrient(), landscape); if (job.printDialog()) { job.print(); From 2c5f771e25a47c5603738788b871cf767506210c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 08:39:59 +0000 Subject: [PATCH 164/846] 8314828: Mark 3 jcmd command-line options test as vm.flagless 8316228: jcmd tests are broken by 8314828 Backport-of: 315d051f6842120f233bb5b7dd488cabcd2e968d --- test/hotspot/jtreg/serviceability/dcmd/framework/HelpTest.java | 3 ++- .../serviceability/dcmd/framework/InvalidCommandTest.java | 3 ++- .../jtreg/serviceability/dcmd/framework/VMVersionTest.java | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/dcmd/framework/HelpTest.java b/test/hotspot/jtreg/serviceability/dcmd/framework/HelpTest.java index 5e159aaeb9e92..7d88faaaa30b3 100644 --- a/test/hotspot/jtreg/serviceability/dcmd/framework/HelpTest.java +++ b/test/hotspot/jtreg/serviceability/dcmd/framework/HelpTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -34,6 +34,7 @@ * @summary Test of diagnostic command help (tests all DCMD executors) * @library /test/lib * /vmTestbase + * @requires vm.flagless * @modules java.base/jdk.internal.misc * java.compiler * java.management diff --git a/test/hotspot/jtreg/serviceability/dcmd/framework/InvalidCommandTest.java b/test/hotspot/jtreg/serviceability/dcmd/framework/InvalidCommandTest.java index 178216fe89c09..1d44b16dcdd2d 100644 --- a/test/hotspot/jtreg/serviceability/dcmd/framework/InvalidCommandTest.java +++ b/test/hotspot/jtreg/serviceability/dcmd/framework/InvalidCommandTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -34,6 +34,7 @@ * @summary Test of invalid diagnostic command (tests all DCMD executors) * @library /test/lib * /vmTestbase + * @requires vm.flagless * @modules java.base/jdk.internal.misc * java.compiler * java.management diff --git a/test/hotspot/jtreg/serviceability/dcmd/framework/VMVersionTest.java b/test/hotspot/jtreg/serviceability/dcmd/framework/VMVersionTest.java index ae25a54ddf535..e3fdee95624de 100644 --- a/test/hotspot/jtreg/serviceability/dcmd/framework/VMVersionTest.java +++ b/test/hotspot/jtreg/serviceability/dcmd/framework/VMVersionTest.java @@ -27,7 +27,6 @@ import jdk.test.lib.dcmd.MainClassJcmdExecutor; import jdk.test.lib.dcmd.FileJcmdExecutor; import jdk.test.lib.dcmd.JMXExecutor; -import nsk.share.jdi.ArgumentHandler; import org.testng.annotations.Test; @@ -37,6 +36,7 @@ * @summary Test of diagnostic command VM.version (tests all DCMD executors) * @library /test/lib * /vmTestbase + * @requires vm.flagless * @modules java.base/jdk.internal.misc * java.base/jdk.internal.module * java.compiler From 76f771e172d930b1e37fa1d11714afbef3c4e8bc Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 08:41:38 +0000 Subject: [PATCH 165/846] 8316452: java/lang/instrument/modules/AppendToClassPathModuleTest.java ignores VM flags Backport-of: fec1d497835de2a37d056f1d6642deac09541118 --- .../lang/instrument/modules/AppendToClassPathModuleTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/java/lang/instrument/modules/AppendToClassPathModuleTest.java b/test/jdk/java/lang/instrument/modules/AppendToClassPathModuleTest.java index 1b0e1f50dd283..76655758b8b8a 100644 --- a/test/jdk/java/lang/instrument/modules/AppendToClassPathModuleTest.java +++ b/test/jdk/java/lang/instrument/modules/AppendToClassPathModuleTest.java @@ -24,6 +24,7 @@ /** * @test * @bug 8169909 + * @requires vm.flagless * @library src /test/lib * @build test/* * @run shell AppendToClassPathModuleTest.sh From 414dbe6d6f16164c9bfff847c52c384d0622a71d Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 08:43:12 +0000 Subject: [PATCH 166/846] 8319572: Test jdk/incubator/vector/LoadJsvmlTest.java ignores VM flags Backport-of: d9a89c59daa40fdc8da620940d5c518a9f18bc7b --- test/jdk/jdk/incubator/vector/LoadJsvmlTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/jdk/incubator/vector/LoadJsvmlTest.java b/test/jdk/jdk/incubator/vector/LoadJsvmlTest.java index e6e613bbc90b7..f654b179e616d 100644 --- a/test/jdk/jdk/incubator/vector/LoadJsvmlTest.java +++ b/test/jdk/jdk/incubator/vector/LoadJsvmlTest.java @@ -29,6 +29,7 @@ * @requires vm.compiler2.enabled * @requires os.arch == "x86_64" | os.arch == "amd64" * @requires os.family == "linux" | os.family == "windows" + * @requires vm.flagless * @library /test/lib * @run main LoadJsvmlTest */ From 865442e1c47facb5a10691c35d705ef21fe4b091 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 08:44:29 +0000 Subject: [PATCH 167/846] 8295804: javax/swing/JFileChooser/JFileChooserSetLocationTest.java failed with "setLocation() is not working properly" Backport-of: 05dad67cc23fb49627fabfb306acee247ff67aef --- .../JFileChooser/JFileChooserSetLocationTest.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/jdk/javax/swing/JFileChooser/JFileChooserSetLocationTest.java b/test/jdk/javax/swing/JFileChooser/JFileChooserSetLocationTest.java index 0e1831afb315a..c1d49127f76e4 100644 --- a/test/jdk/javax/swing/JFileChooser/JFileChooserSetLocationTest.java +++ b/test/jdk/javax/swing/JFileChooser/JFileChooserSetLocationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; +import java.awt.Toolkit; import java.awt.event.ActionListener; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; @@ -209,7 +210,11 @@ private static void hitKeys(int... keys) { } public static void createUI() { - frame = new JFrame(); + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + + int xPos = (int) screenSize.getWidth() / 2; + int yPos = (int) screenSize.getHeight() / 2; + frame = new JFrame("FileChooser set location test"); panel = new JPanel(); btn = new JButton(SHOW_DIALOG_OUTSIDE_THE_PANEL); btn1 = new JButton(SHOW_DIALOG_OVER_THE_PANEL); @@ -238,6 +243,7 @@ public static void createUI() { frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.pack(); + frame.setLocation(xPos, yPos - 200); frame.setVisible(true); } @@ -280,7 +286,6 @@ protected JDialog createDialog(Component parent) System.out.println( "createDialog and set location to (" + x + ", " + y + ")"); dialog.setLocation(x, y); - return dialog; } @@ -289,5 +294,4 @@ public Point getDialogLocation() { } } - } From 12467367b6673afd42dce4668aec034fd163a1a8 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 08:47:01 +0000 Subject: [PATCH 168/846] 8319578: Few java/lang/instrument ignore test.java.opts and accept test.vm.opts only Backport-of: 3ebe6c192a5dd5cc46ae2d263713c9ff38cd46bb --- .../lang/instrument/BootClassPath/BootClassPathTest.sh | 8 ++++---- test/jdk/java/lang/instrument/ManifestTest.sh | 4 ++-- test/jdk/java/lang/instrument/RedefineBigClass.sh | 6 +++--- .../java/lang/instrument/RedefineClassWithNativeMethod.sh | 4 ++-- test/jdk/java/lang/instrument/RedefineMethodAddInvoke.sh | 4 ++-- test/jdk/java/lang/instrument/RedefineMethodDelInvoke.sh | 4 ++-- .../jdk/java/lang/instrument/RedefineMethodInBacktrace.sh | 4 ++-- .../java/lang/instrument/RedefineMethodWithAnnotations.sh | 4 ++-- .../lang/instrument/RedefineSubclassWithTwoInterfaces.sh | 6 +++--- test/jdk/java/lang/instrument/RetransformBigClass.sh | 6 +++--- test/jdk/java/lang/instrument/StressGetObjectSizeTest.sh | 4 ++-- .../appendToClassLoaderSearch/CircularityErrorTest.sh | 4 ++-- .../appendToClassLoaderSearch/ClassUnloadTest.sh | 4 ++-- .../instrument/appendToClassLoaderSearch/run_tests.sh | 8 ++++---- 14 files changed, 35 insertions(+), 35 deletions(-) diff --git a/test/jdk/java/lang/instrument/BootClassPath/BootClassPathTest.sh b/test/jdk/java/lang/instrument/BootClassPath/BootClassPathTest.sh index 9ab260425cf17..e5cca341d64ed 100644 --- a/test/jdk/java/lang/instrument/BootClassPath/BootClassPathTest.sh +++ b/test/jdk/java/lang/instrument/BootClassPath/BootClassPathTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -74,7 +74,7 @@ case ${OS} in ;; esac -"$JAVA" ${TESTVMOPTS} -classpath "${TESTCLASSES}" Setup "${TESTCLASSES}" Agent "${CYGWIN}" +"$JAVA" ${TESTVMOPTS} ${TESTJAVAOPTS} -classpath "${TESTCLASSES}" Setup "${TESTCLASSES}" Agent "${CYGWIN}" BOOTDIR=`cat ${TESTCLASSES}/boot.dir` @@ -94,13 +94,13 @@ echo "Creating agent jar file..." echo "Running test..." -"${JAVA}" ${TESTVMOPTS} -javaagent:"${TESTCLASSES}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:"${TESTCLASSES}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain result=$? echo "Cleanup..." "$JAVAC" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d "${TESTCLASSES}" \ "${TESTSRC}"/Cleanup.java -"$JAVA" ${TESTVMOPTS} -classpath "${TESTCLASSES}" Cleanup "${BOOTDIR}" +"$JAVA" ${TESTVMOPTS} ${TESTJAVAOPTS} -classpath "${TESTCLASSES}" Cleanup "${BOOTDIR}" exit $result diff --git a/test/jdk/java/lang/instrument/ManifestTest.sh b/test/jdk/java/lang/instrument/ManifestTest.sh index daed5ad3c4c8d..9feb1de53f571 100644 --- a/test/jdk/java/lang/instrument/ManifestTest.sh +++ b/test/jdk/java/lang/instrument/ManifestTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -380,7 +380,7 @@ while read token; do echo "===== begin test case: $token =====" make_a_JAR "$token" - "${JAVA}" ${TESTVMOPTS} -javaagent:${AGENT}.jar \ + "${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:${AGENT}.jar \ -classpath "${TESTCLASSES}" ManifestTestApp > output.log 2>&1 result=$? diff --git a/test/jdk/java/lang/instrument/RedefineBigClass.sh b/test/jdk/java/lang/instrument/RedefineBigClass.sh index 1c2bfb6b0c1f4..19421301fb0b8 100644 --- a/test/jdk/java/lang/instrument/RedefineBigClass.sh +++ b/test/jdk/java/lang/instrument/RedefineBigClass.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -62,14 +62,14 @@ JAVAC="${COMPILEJAVA}"/bin/javac JAVA="${TESTJAVA}"/bin/java # Does this VM support the 'detail' level of NMT? -"${JAVA}" ${TESTVMOPTS} -XX:NativeMemoryTracking=detail -version +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -XX:NativeMemoryTracking=detail -version if [ "$?" = 0 ]; then NMT=-XX:NativeMemoryTracking=detail else NMT=-XX:NativeMemoryTracking=summary fi -"${JAVA}" ${TESTVMOPTS} \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} \ -Xlog:redefine+class+load=debug,redefine+class+load+exceptions=info ${NMT} \ -javaagent:RedefineBigClassAgent.jar=BigClass.class \ -classpath "${TESTCLASSES}" RedefineBigClassApp \ diff --git a/test/jdk/java/lang/instrument/RedefineClassWithNativeMethod.sh b/test/jdk/java/lang/instrument/RedefineClassWithNativeMethod.sh index 0a029bd1ebc7c..8c269ab1929b8 100644 --- a/test/jdk/java/lang/instrument/RedefineClassWithNativeMethod.sh +++ b/test/jdk/java/lang/instrument/RedefineClassWithNativeMethod.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ fi JAVAC="${COMPILEJAVA}"/bin/javac JAVA="${TESTJAVA}"/bin/java -"${JAVA}" ${TESTVMOPTS} \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} \ -javaagent:RedefineClassWithNativeMethodAgent.jar=java/lang/Thread.class \ -classpath "${TESTCLASSES}" RedefineClassWithNativeMethodApp \ > output.log 2>&1 diff --git a/test/jdk/java/lang/instrument/RedefineMethodAddInvoke.sh b/test/jdk/java/lang/instrument/RedefineMethodAddInvoke.sh index b5864fbc26b88..284051d05d8d0 100644 --- a/test/jdk/java/lang/instrument/RedefineMethodAddInvoke.sh +++ b/test/jdk/java/lang/instrument/RedefineMethodAddInvoke.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -70,7 +70,7 @@ cp "${TESTSRC}"/RedefineMethodAddInvokeTarget_2.java \ mv RedefineMethodAddInvokeTarget.java RedefineMethodAddInvokeTarget_2.java mv RedefineMethodAddInvokeTarget.class RedefineMethodAddInvokeTarget_2.class -"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodAddInvokeAgent.jar \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:RedefineMethodAddInvokeAgent.jar \ -XX:+AllowRedefinitionToAddDeleteMethods \ -classpath "${TESTCLASSES}" RedefineMethodAddInvokeApp > output.log 2>&1 cat output.log diff --git a/test/jdk/java/lang/instrument/RedefineMethodDelInvoke.sh b/test/jdk/java/lang/instrument/RedefineMethodDelInvoke.sh index 9924af3d2a839..0df5a10474115 100644 --- a/test/jdk/java/lang/instrument/RedefineMethodDelInvoke.sh +++ b/test/jdk/java/lang/instrument/RedefineMethodDelInvoke.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -71,7 +71,7 @@ cp "${TESTSRC}"/RedefineMethodDelInvokeTarget_2.java \ mv RedefineMethodDelInvokeTarget.java RedefineMethodDelInvokeTarget_2.java mv RedefineMethodDelInvokeTarget.class RedefineMethodDelInvokeTarget_2.class -"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodDelInvokeAgent.jar \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:RedefineMethodDelInvokeAgent.jar \ -XX:+AllowRedefinitionToAddDeleteMethods \ -classpath "${TESTCLASSES}" RedefineMethodDelInvokeApp > output.log 2>&1 diff --git a/test/jdk/java/lang/instrument/RedefineMethodInBacktrace.sh b/test/jdk/java/lang/instrument/RedefineMethodInBacktrace.sh index d7cb2aa1c03ca..85d06fd486e66 100644 --- a/test/jdk/java/lang/instrument/RedefineMethodInBacktrace.sh +++ b/test/jdk/java/lang/instrument/RedefineMethodInBacktrace.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -68,7 +68,7 @@ cp "${TESTSRC}"/RedefineMethodInBacktraceTargetB_2.java \ RedefineMethodInBacktraceTargetB.java "${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . RedefineMethodInBacktraceTargetB.java -"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodInBacktraceAgent.jar \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:RedefineMethodInBacktraceAgent.jar \ -XX:+AllowRedefinitionToAddDeleteMethods \ -classpath "${TESTCLASSES}" RedefineMethodInBacktraceApp > output.log 2>&1 RUN_RESULT=$? diff --git a/test/jdk/java/lang/instrument/RedefineMethodWithAnnotations.sh b/test/jdk/java/lang/instrument/RedefineMethodWithAnnotations.sh index ed3ef4ef4122d..beb0486462352 100644 --- a/test/jdk/java/lang/instrument/RedefineMethodWithAnnotations.sh +++ b/test/jdk/java/lang/instrument/RedefineMethodWithAnnotations.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -67,7 +67,7 @@ cp "${TESTSRC}"/RedefineMethodWithAnnotationsAnnotations.java \ RedefineMethodWithAnnotationsTarget.java \ RedefineMethodWithAnnotationsAnnotations.java -"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodWithAnnotationsAgent.jar \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:RedefineMethodWithAnnotationsAgent.jar \ -XX:+UnlockDiagnosticVMOptions -XX:+StressLdcRewrite -XX:+IgnoreUnrecognizedVMOptions \ -cp "${TESTCLASSES}" RedefineMethodWithAnnotationsApp > output.log 2>&1 cat output.log diff --git a/test/jdk/java/lang/instrument/RedefineSubclassWithTwoInterfaces.sh b/test/jdk/java/lang/instrument/RedefineSubclassWithTwoInterfaces.sh index e583c9df469f8..fea99aecbaa4e 100644 --- a/test/jdk/java/lang/instrument/RedefineSubclassWithTwoInterfaces.sh +++ b/test/jdk/java/lang/instrument/RedefineSubclassWithTwoInterfaces.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -69,7 +69,7 @@ cp "${TESTSRC}"/RedefineSubclassWithTwoInterfacesImpl_1.java \ "${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \ -cp "${TESTCLASSES}" -d . \ RedefineSubclassWithTwoInterfacesTarget.java \ - RedefineSubclassWithTwoInterfacesImpl.java + RedefineSubclassWithTwoInterfacesImpl.java status="$?" if [ "$status" != 0 ]; then echo "FAIL: compile of *_1.java files failed." @@ -87,7 +87,7 @@ mv RedefineSubclassWithTwoInterfacesImpl.class \ echo "INFO: launching RedefineSubclassWithTwoInterfacesApp" -"${JAVA}" ${TESTVMOPTS} \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} \ -Xlog:redefine+class+load=trace,redefine+class+load+exceptions=trace,redefine+class+timer=trace,redefine+class+obsolete=trace,redefine+class+obsolete+metadata=trace,redefine+class+constantpool=trace \ -javaagent:RedefineSubclassWithTwoInterfacesAgent.jar \ -classpath "${TESTCLASSES}" \ diff --git a/test/jdk/java/lang/instrument/RetransformBigClass.sh b/test/jdk/java/lang/instrument/RetransformBigClass.sh index 455f42a3247df..31c92117e9336 100644 --- a/test/jdk/java/lang/instrument/RetransformBigClass.sh +++ b/test/jdk/java/lang/instrument/RetransformBigClass.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -62,14 +62,14 @@ JAVAC="${COMPILEJAVA}"/bin/javac JAVA="${TESTJAVA}"/bin/java # Does this VM support the 'detail' level of NMT? -"${JAVA}" ${TESTVMOPTS} -XX:NativeMemoryTracking=detail -version +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -XX:NativeMemoryTracking=detail -version if [ "$?" = 0 ]; then NMT=-XX:NativeMemoryTracking=detail else NMT=-XX:NativeMemoryTracking=summary fi -"${JAVA}" ${TESTVMOPTS} \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} \ -Xlog:redefine+class+load=debug,redefine+class+load+exceptions=info ${NMT} \ -javaagent:RetransformBigClassAgent.jar=BigClass.class \ -classpath "${TESTCLASSES}" RetransformBigClassApp \ diff --git a/test/jdk/java/lang/instrument/StressGetObjectSizeTest.sh b/test/jdk/java/lang/instrument/StressGetObjectSizeTest.sh index a2ba29d238b65..3b9364f0cc371 100644 --- a/test/jdk/java/lang/instrument/StressGetObjectSizeTest.sh +++ b/test/jdk/java/lang/instrument/StressGetObjectSizeTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ fi JAVA="${TESTJAVA}"/bin/java -"${JAVA}" ${TESTVMOPTS} -javaagent:basicAgent.jar \ +"${JAVA}" ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:basicAgent.jar \ -classpath "${TESTCLASSES}" StressGetObjectSizeApp StressGetObjectSizeApp \ > output.log 2>&1 cat output.log diff --git a/test/jdk/java/lang/instrument/appendToClassLoaderSearch/CircularityErrorTest.sh b/test/jdk/java/lang/instrument/appendToClassLoaderSearch/CircularityErrorTest.sh index 0589b43ee070c..0cfe6a641579c 100644 --- a/test/jdk/java/lang/instrument/appendToClassLoaderSearch/CircularityErrorTest.sh +++ b/test/jdk/java/lang/instrument/appendToClassLoaderSearch/CircularityErrorTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -77,4 +77,4 @@ $JAR ${TESTTOOLVMOPTS} -cfm "${TESTCLASSES}"/CircularityErrorTest.jar "${MANIFES # Finally we run the test (cd "${TESTCLASSES}"; - $JAVA ${TESTVMOPTS} -javaagent:CircularityErrorTest.jar CircularityErrorTest) + $JAVA ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:CircularityErrorTest.jar CircularityErrorTest) diff --git a/test/jdk/java/lang/instrument/appendToClassLoaderSearch/ClassUnloadTest.sh b/test/jdk/java/lang/instrument/appendToClassLoaderSearch/ClassUnloadTest.sh index 71923152da4ac..d6aec21a2293e 100644 --- a/test/jdk/java/lang/instrument/appendToClassLoaderSearch/ClassUnloadTest.sh +++ b/test/jdk/java/lang/instrument/appendToClassLoaderSearch/ClassUnloadTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -80,5 +80,5 @@ $JAR ${TESTTOOLVMOPTS} -cfm "${TESTCLASSES}"/ClassUnloadTest.jar "${MANIFEST}" \ # Finally we run the test (cd "${TESTCLASSES}"; \ - $JAVA ${TESTVMOPTS} -Xlog:class+unload \ + $JAVA ${TESTVMOPTS} ${TESTJAVAOPTS} -Xlog:class+unload \ -javaagent:ClassUnloadTest.jar ClassUnloadTest "${OTHERDIR}" Bar.jar) diff --git a/test/jdk/java/lang/instrument/appendToClassLoaderSearch/run_tests.sh b/test/jdk/java/lang/instrument/appendToClassLoaderSearch/run_tests.sh index 51f89f09239a4..eb7abe71edc71 100644 --- a/test/jdk/java/lang/instrument/appendToClassLoaderSearch/run_tests.sh +++ b/test/jdk/java/lang/instrument/appendToClassLoaderSearch/run_tests.sh @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ failures=0 go() { echo '' - sh -xc "$JAVA ${TESTVMOPTS} -javaagent:Agent.jar -classpath SimpleTests.jar $1 $2 $3" 2>&1 + sh -xc "$JAVA ${TESTVMOPTS} ${TESTJAVAOPTS} -javaagent:Agent.jar -classpath SimpleTests.jar $1 $2 $3" 2>&1 if [ $? != 0 ]; then failures=`expr $failures + 1`; fi } @@ -85,11 +85,11 @@ mv Application.class InstrumentedApplication.bytes cp "${TESTSRC}"/Application.java . "${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . Application.java -sh -xc "$JAVA ${TESTVMOPTS} -classpath . -javaagent:Agent.jar DynamicTest" 2>&1 +sh -xc "$JAVA ${TESTVMOPTS} ${TESTJAVAOPTS} -classpath . -javaagent:Agent.jar DynamicTest" 2>&1 if [ $? != 0 ]; then failures=`expr $failures + 1`; fi # Repeat test with security manager -sh -xc "$JAVA ${TESTVMOPTS} -classpath . -javaagent:Agent.jar -Djava.security.manager DynamicTest" 2>&1 +sh -xc "$JAVA ${TESTVMOPTS} ${TESTJAVAOPTS} -classpath . -javaagent:Agent.jar -Djava.security.manager DynamicTest" 2>&1 if [ $? != 0 ]; then failures=`expr $failures + 1`; fi # From 448481bca260d1d7fab0c4089f85d314cdbd8952 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 08:48:34 +0000 Subject: [PATCH 169/846] 8316451: 6 java/lang/instrument/PremainClass tests ignore VM flags Backport-of: 9029bf644e238a504e1f114a73edf5760d19980b --- .../java/lang/instrument/NegativeAgentRunner.java | 4 ++-- .../instrument/PremainClass/PremainClassTest.java | 12 ++++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/test/jdk/java/lang/instrument/NegativeAgentRunner.java b/test/jdk/java/lang/instrument/NegativeAgentRunner.java index 9689c323114d1..2d585cc6e6a58 100644 --- a/test/jdk/java/lang/instrument/NegativeAgentRunner.java +++ b/test/jdk/java/lang/instrument/NegativeAgentRunner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ public static void main(String argv[]) throws Exception { } String agentClassName = argv[0]; String excepClassName = argv[1]; - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( "-javaagent:" + agentClassName + ".jar", "-Xmx128m", "-XX:-CreateCoredumpOnCrash", agentClassName); OutputAnalyzer output = new OutputAnalyzer(pb.start()); diff --git a/test/jdk/java/lang/instrument/PremainClass/PremainClassTest.java b/test/jdk/java/lang/instrument/PremainClass/PremainClassTest.java index ecd284fe6e0c1..216dbb94d8a63 100644 --- a/test/jdk/java/lang/instrument/PremainClass/PremainClassTest.java +++ b/test/jdk/java/lang/instrument/PremainClass/PremainClassTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,14 +39,10 @@ public class PremainClassTest { // a non ascii character. // Verify that the premain() function is executed correctly. public static void main(String[] a) throws Exception { - String testArgs = String.format( - "-javaagent:%s/Agent.jar -classpath %s DummyMain", - System.getProperty("test.src"), - System.getProperty("test.classes", ".")); + String testArgs = String.format("-javaagent:%s/Agent.jar", + System.getProperty("test.src")); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( - Utils.addTestJavaOpts(testArgs.split("\\s+"))); - System.out.println("testjvm.cmd:" + Utils.getCommandLine(pb)); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(testArgs, "DummyMain"); OutputAnalyzer output = ProcessTools.executeProcess(pb); System.out.println("testjvm.stdout:" + output.getStdout()); From 32fde3c498349d8f1cf3a78e6fe81daedbef6907 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 08:52:05 +0000 Subject: [PATCH 170/846] 8340621: Open source several AWT List tests Backport-of: ae4d2f15901bf02efceaac26ee4aa3ae666bf467 --- .../java/awt/List/DisabledListIsGreyTest.java | 75 ++++++++++ .../java/awt/List/ListFrameResizeTest.java | 104 ++++++++++++++ .../awt/List/MultiSelectionListCrashTest.java | 89 ++++++++++++ .../java/awt/List/ScrollbarPositionTest.java | 104 ++++++++++++++ .../awt/List/SelectedItemVisibilityTest.java | 128 ++++++++++++++++++ 5 files changed, 500 insertions(+) create mode 100644 test/jdk/java/awt/List/DisabledListIsGreyTest.java create mode 100644 test/jdk/java/awt/List/ListFrameResizeTest.java create mode 100644 test/jdk/java/awt/List/MultiSelectionListCrashTest.java create mode 100644 test/jdk/java/awt/List/ScrollbarPositionTest.java create mode 100644 test/jdk/java/awt/List/SelectedItemVisibilityTest.java diff --git a/test/jdk/java/awt/List/DisabledListIsGreyTest.java b/test/jdk/java/awt/List/DisabledListIsGreyTest.java new file mode 100644 index 0000000000000..ec1a257066606 --- /dev/null +++ b/test/jdk/java/awt/List/DisabledListIsGreyTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6354810 + * @summary Items in the list are not grayed out when disabled, XToolkit + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DisabledListIsGreyTest +*/ + +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.List; + +public class DisabledListIsGreyTest { + + private static final String INSTRUCTIONS = """ + 1) After the test started you will see two lists. + 2) One of them is enabled, and the second is disabled. + 3) Check that the items of the disabled list are grayed. + 4) If so, the test passed. Otherwise, failed."""; + + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("DisabledListIsGreyTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(DisabledListIsGreyTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Frame frame = new Frame("DisabledListIsGreyTest Frame"); + frame.setLayout(new FlowLayout()); + + List list1 = new List(3); + List list2 = new List(3); + for (int i = 0; i < 5; i++) { + list1.addItem("Item " + i); + list2.addItem("Item " + i); + } + frame.add(list1); + + list2.setEnabled(false); + frame.add(list2); + frame.pack(); + return frame; + } + +} diff --git a/test/jdk/java/awt/List/ListFrameResizeTest.java b/test/jdk/java/awt/List/ListFrameResizeTest.java new file mode 100644 index 0000000000000..4655e817da581 --- /dev/null +++ b/test/jdk/java/awt/List/ListFrameResizeTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4085379 + * @summary List component not properly "resized" with GridBagLayout + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ListFrameResizeTest + */ + +import java.awt.Color; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.List; + +public class ListFrameResizeTest { + + private static final String INSTRUCTIONS = """ + This test is for windows only. + + 1. A Frame will appear with a List + (the List occupies the whole Frame) + 2. Minimize the Frame, the Frame is now in the Task Bar (ie.,iconified) + 3. Right click (right mouse button) the icon in the task bar + and click on the 'maximize' menuitem to maximize the Frame + 4. If you notice the List has not been resized + (ie.,if it partly occupies the Frame), then press FAIL else press PASS"."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("ListFrameResizeTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(ListFrameResizeTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + wintest client = new wintest("ListFrameResizeTest Frame"); + client.resize(500, 300); + client.setBackground(Color.blue); + return client; + } + +} + +class wintest extends Frame { + private List msg; + + public wintest(String title) { + super(title); + msg = new List(); + for (int i = 0; i < 100; i++) { + msg.add("" + i); + } + + GridBagLayout gridbag = new GridBagLayout(); + GridBagConstraints constraints = new GridBagConstraints(); + + setLayout(gridbag); + + constraints.fill = GridBagConstraints.BOTH; + + constraints.anchor = GridBagConstraints.CENTER; + constraints.insets = new Insets(10, 10, 10, 10); + constraints.ipadx = 0; + constraints.ipady = 0; + constraints.weightx = 1; + constraints.weighty = 1; + constraints.gridx = 0; + constraints.gridy = 0; + constraints.gridwidth = GridBagConstraints.REMAINDER; + constraints.gridheight = GridBagConstraints.REMAINDER; + gridbag.setConstraints(msg, constraints); + add(msg); + } +} diff --git a/test/jdk/java/awt/List/MultiSelectionListCrashTest.java b/test/jdk/java/awt/List/MultiSelectionListCrashTest.java new file mode 100644 index 0000000000000..b408a12ebbac7 --- /dev/null +++ b/test/jdk/java/awt/List/MultiSelectionListCrashTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4201967 + * @summary tests that a multiselection list doesn't causes crash when FileDialog is invoked + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MultiSelectionListCrashTest + */ + +import java.awt.Button; +import java.awt.FileDialog; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.List; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class MultiSelectionListCrashTest { + + private static final String INSTRUCTIONS = """ + Press "Invoke dialog" button to invoke a FileDialog. + When it appears close it by pressing cancel button. + If all remaining frames are enabled and + page fault didn't occur the test passed. Otherwise the test failed. + + Try to invoke a FileDialog several times to verify that the bug doesn't exist."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("MultiSelectionListCrashTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(MultiSelectionListCrashTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + + Frame frame = new Frame("MultiSelectionListCrashTest frame"); + Button button = new Button("Invoke dialog"); + button.addActionListener(new FileDialogInvoker(frame)); + List list = new List(4, true); + list.add("Item1"); + list.add("Item2"); + frame.setLayout(new FlowLayout()); + frame.add(button); + frame.add(list); + frame.setSize(200, 200); + return frame; + } +} + +class FileDialogInvoker implements ActionListener { + FileDialog fileDialog; + + public FileDialogInvoker(Frame frame) { + fileDialog = new FileDialog(frame); + } + + public void actionPerformed(ActionEvent e) { + fileDialog.setVisible(true); + } + +} diff --git a/test/jdk/java/awt/List/ScrollbarPositionTest.java b/test/jdk/java/awt/List/ScrollbarPositionTest.java new file mode 100644 index 0000000000000..25167fa56278c --- /dev/null +++ b/test/jdk/java/awt/List/ScrollbarPositionTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4024943 + * @summary Test for position of List scrollbar when it is added + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ScrollbarPositionTest + */ + +import java.awt.Button; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.List; +import java.awt.Panel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class ScrollbarPositionTest { + static int item = 0; + static List list; + static Button addButton, delButton; + + private static final String INSTRUCTIONS = """ + Click on the "Add List Item" button many times + until the vertical scrollbar appears. + Verify that the displayed vertical scrollbar does not take the space + that was occupied by buttons before the scrollbar is shown."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("ScrollbarPositionTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(ScrollbarPositionTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Panel pan; + + Frame frame = new Frame("ScrollbarPositionTest Frame"); + frame.setLayout(new GridLayout(1, 2)); + list = new List(); + frame.add(list); + frame.add(pan = new Panel()); + pan.setLayout(new GridLayout(4, 1)); + + MyListener listener = new MyListener(); + addButton = new Button("Add List Item"); + addButton.addActionListener(listener); + pan.add(addButton); + + delButton = new Button("Delete List Item"); + delButton.addActionListener(listener); + pan.add(delButton); + + frame.pack(); + return frame; + } + + static class MyListener implements ActionListener { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource() == addButton) { + String s = "item"; + for (int i = 0; i <= item; i++) { + s = s +" "+Integer.toString(i); + } + item++; + list.addItem(s); + } else if (evt.getSource() == delButton) { + int i; + if ((i = list.countItems()) > 0) { + list.delItem(i - 1); + --item; + } + } + } + } +} diff --git a/test/jdk/java/awt/List/SelectedItemVisibilityTest.java b/test/jdk/java/awt/List/SelectedItemVisibilityTest.java new file mode 100644 index 0000000000000..53364e937713c --- /dev/null +++ b/test/jdk/java/awt/List/SelectedItemVisibilityTest.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4676536 + * @summary REGRESSION: makeVisible() method of List Component does not perform + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual SelectedItemVisibilityTest + */ + +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.List; + +public class SelectedItemVisibilityTest { + + static List list1, list2; + static int visibleItem = 4; + static int selectedItems[] = {6, 7, 8}; + static String selectedItemsStr = ""; + + static { + for (int i = 0 ; i < selectedItems.length ; i++) { + selectedItemsStr += ""+selectedItems[i]+" "; + } + } + + private static final String INSTRUCTIONS = + "You should see two lists.\n" + + "\n" + + "list1: \n" + + "\t1. the first visible item should be " + visibleItem + + "\n\t2. the selected item should be " + selectedItems[0] + + "\n" + + "list2:\n" + + "\t1. the first visible item should be " + visibleItem + + "\n\t2. the selected items should be " + selectedItemsStr + + "\n" + + "\nIf it is so the test passed else failed."; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("SelectedItemVisibilityTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(SelectedItemVisibilityTest::createTestUI) + .logArea() + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + + Frame frame = new Frame("SelectedItemVisibilityTest Frame"); + frame.setLayout(new FlowLayout()); + + // list1 + list1 = new List(4); + for (int i = 0; i < 20; i++) { + list1.add(""+i); + } + list1.makeVisible(visibleItem); + list1.select(selectedItems[0]); + frame.add(new Label("list1:")); + frame.add(list1); + + // list2 + list2 = new List(4); + list2.setMultipleMode(true); + for (int i = 0; i < 20; i++) { + list2.add(""+i); + } + list2.makeVisible(visibleItem); + for (int i = 0 ; i < selectedItems.length ; i++) { + list2.select(selectedItems[i]); + } + frame.add(new Label("list2:")); + frame.add(list2); + frame.setSize(200, 200); + + // common output + String s; + int sel[]; + + PassFailJFrame.log("list1: "); + PassFailJFrame.log("\tgetVisibleIndex="+list1.getVisibleIndex()); + sel = list1.getSelectedIndexes(); + s = "\tgetSelectedIndexes="; + for (int i = 0 ; i < sel.length ; i++) { + s += "" + sel[i] + " "; + } + PassFailJFrame.log(s); + + PassFailJFrame.log("list2: "); + PassFailJFrame.log("\tgetVisibleIndex="+list2.getVisibleIndex()); + sel = list2.getSelectedIndexes(); + s = "\tgetSelectedIndexes="; + for (int i = 0 ; i < sel.length ; i++) { + s += "" + sel[i] + " "; + } + PassFailJFrame.log(s); + return frame; + } +} From ed14e7afe7ab650962505ea42bd5a98165aea3d3 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 08:53:22 +0000 Subject: [PATCH 171/846] 8211400: nsk.share.gc.Memory::getArrayLength returns wrong value Backport-of: 860d49db22cf352eaf1b3b20fff43d090f0eebc8 --- .../hotspot/jtreg/vmTestbase/nsk/share/gc/Memory.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/Memory.java b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/Memory.java index f5c70671e5e10..244bcf423c5bc 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/Memory.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/Memory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -150,12 +150,9 @@ public static int getReferenceObjectSize() { * @return length of array */ public static int getArrayLength(long memory, long objectSize) { - int referenceSize = getReferenceSize(); int arrayExtraSize = getArrayExtraSize(); - return (int) Math.min( - (memory - arrayExtraSize) / (objectSize + referenceSize), - Integer.MAX_VALUE - ); + return (int) Math.min((memory - arrayExtraSize) / objectSize, + Integer.MAX_VALUE); } /** @@ -166,7 +163,7 @@ public static int getArrayLength(long memory, long objectSize) { * @return size of array */ public static long getArraySize(int length, long objectSize) { - return getObjectExtraSize() + length * (objectSize + getReferenceSize()); + return getArrayExtraSize() + length * objectSize; } /** From e3861ce3ea0b499581ea0923c674eeea0863936f Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 08:54:33 +0000 Subject: [PATCH 172/846] 8341191: Open source few more AWT FileDialog tests Backport-of: 50ec169116b486a49dc2dcb4218264bd48db79cc --- .../FileDialog/KeyboardInteractionTest.java | 87 +++++++++++++++++++ .../awt/FileDialog/PathChoiceDisposeTest.java | 76 ++++++++++++++++ .../FileDialog/PathChoiceWorkArrowsTest.java | 86 ++++++++++++++++++ .../java/awt/FileDialog/SavedDirInitTest.java | 79 +++++++++++++++++ 4 files changed, 328 insertions(+) create mode 100644 test/jdk/java/awt/FileDialog/KeyboardInteractionTest.java create mode 100644 test/jdk/java/awt/FileDialog/PathChoiceDisposeTest.java create mode 100644 test/jdk/java/awt/FileDialog/PathChoiceWorkArrowsTest.java create mode 100644 test/jdk/java/awt/FileDialog/SavedDirInitTest.java diff --git a/test/jdk/java/awt/FileDialog/KeyboardInteractionTest.java b/test/jdk/java/awt/FileDialog/KeyboardInteractionTest.java new file mode 100644 index 0000000000000..f919a8a338af8 --- /dev/null +++ b/test/jdk/java/awt/FileDialog/KeyboardInteractionTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.FileDialog; +import java.awt.Frame; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/* + * @test + * @bug 6259434 + * @summary PIT: Choice in FileDialog is not responding to keyboard interactions, XToolkit + * @requires (os.family == "linux") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual KeyboardInteractionTest + */ + +public class KeyboardInteractionTest { + public static void main(String[] args) throws Exception { + System.setProperty("sun.awt.disableGtkFileDialogs", "true"); + String INSTRUCTIONS = """ + 1) Click on 'Show File Dialog' button to bring up the FileDialog window. + A file dialog will come up. + 2) You will see a text field 'Enter full path or filename'. + Right next to it, you will see a button. + Transfer the focus on this button using 'TAB'. + Make sure that the popup choice is not shown. + 3) Press 'ESC'. If file dialog isn't disposed, then the test failed. + 4) Again, click on 'Show File Dialog' to bring up the file dialog. + A file dialog will come up. + 5) You will see a text field 'Enter full path or filename'. + Right next to it, you will see a button. + Click on this button. The popup choice will appear. + 6) Look at the popup choice. Change the current item in the popup + choice by the arrow keys. + If the text in the 'Enter full path or filename' text field isn't + changed, then the test failed. + 7) The test passed. + """; + + PassFailJFrame.builder() + .title("KeyboardInteractionTest Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(KeyboardInteractionTest::createUI) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame f = new Frame("KeyboardInteractionTest Test"); + Button b = new Button("Show File Dialog"); + FileDialog fd = new FileDialog(f); + b.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + fd.setVisible(true); + } + }); + f.add(b); + f.setSize(300, 200); + return f; + } +} diff --git a/test/jdk/java/awt/FileDialog/PathChoiceDisposeTest.java b/test/jdk/java/awt/FileDialog/PathChoiceDisposeTest.java new file mode 100644 index 0000000000000..267b2a807cff8 --- /dev/null +++ b/test/jdk/java/awt/FileDialog/PathChoiceDisposeTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.FileDialog; +import java.awt.Frame; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/* + * @test + * @bug 6240084 + * @summary Test that disposing unfurled list by the pressing ESC + * in FileDialog is working properly on XToolkit + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual PathChoiceDisposeTest + */ + +public class PathChoiceDisposeTest { + public static void main(String[] args) throws Exception { + System.setProperty("sun.awt.disableGtkFileDialogs", "true"); + String INSTRUCTIONS = """ + 1) Click on 'Show File Dialog' button to bring up the FileDialog window. + 2) Open the directory selection choice by clicking button next to + 'Enter Path or Folder Name'. A drop-down will appear. + 3) Press 'ESC'. + 4) If you see that the dialog gets disposed and the popup + still remains on the screen, the test failed, otherwise passed. + """; + + PassFailJFrame.builder() + .title("PathChoiceDisposeTest Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(PathChoiceDisposeTest::createUI) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame f = new Frame("PathChoiceDisposeTest Test"); + Button b = new Button("Show File Dialog"); + FileDialog fd = new FileDialog(f); + b.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + fd.setVisible(true); + } + }); + f.add(b); + f.setSize(300, 200); + return f; + } +} diff --git a/test/jdk/java/awt/FileDialog/PathChoiceWorkArrowsTest.java b/test/jdk/java/awt/FileDialog/PathChoiceWorkArrowsTest.java new file mode 100644 index 0000000000000..17aee8abb800a --- /dev/null +++ b/test/jdk/java/awt/FileDialog/PathChoiceWorkArrowsTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.FileDialog; +import java.awt.Frame; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/* + * @test + * @bug 6240074 + * @summary Test that file drop-down field in FileDialog is working properly on XToolkit + * @requires (os.family == "linux") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual PathChoiceWorkArrowsTest + */ + +public class PathChoiceWorkArrowsTest { + public static void main(String[] args) throws Exception { + System.setProperty("sun.awt.disableGtkFileDialogs", "true"); + String INSTRUCTIONS = """ + This is only XAWT test. + + 1) Click on 'Show File Dialog' to bring up the FileDialog window. + A file dialog would come up. + 2) Click on the button next to 'Enter folder name' field. + A drop-down will appear. After this, there are 2 scenarios. + 3) Press the down arrow one by one. You will see a '/' being + appended as soon as the current entry is removed. + Keep pressing till the last entry is reached. Now the drop-down + will stop responding to arrow keys. If yes, the test failed. + 4) Press the up arrow. The cursor will directly go to the last + entry ('/') and navigation will stop there. You will see 2 + entries being selected at the same time. + If yes, the test failed. + """; + + PassFailJFrame.builder() + .title("PathChoiceWorkArrowsTest Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(PathChoiceWorkArrowsTest::createUI) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame f = new Frame("PathChoiceWorkArrowsTest Test"); + Button b = new Button("Show File Dialog"); + FileDialog fd = new FileDialog(f); + b.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + fd.setSize(200, 200); + fd.setLocation(200, 200); + fd.setVisible(true); + } + }); + f.add(b); + f.setSize(300, 200); + return f; + } +} diff --git a/test/jdk/java/awt/FileDialog/SavedDirInitTest.java b/test/jdk/java/awt/FileDialog/SavedDirInitTest.java new file mode 100644 index 0000000000000..7a3b33f55fe16 --- /dev/null +++ b/test/jdk/java/awt/FileDialog/SavedDirInitTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.FileDialog; +import java.awt.Frame; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/* + * @test + * @bug 6260650 + * @summary FileDialog.getDirectory() does not return null when file dialog is cancelled + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual SavedDirInitTest + */ + +public class SavedDirInitTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Click on 'Show File Dialog' button to bring up the FileDialog window. + 1) A file dialog will come up. + 2) Press 'Cancel' button to cancel the file dialog. + 3) The result (passed or failed) will be shown in the message window below. + """; + + PassFailJFrame.builder() + .title("SavedDirInitTest Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(SavedDirInitTest::createUI) + .logArea(2) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame f = new Frame("SavedDirInitTest Test"); + Button b = new Button("Show File Dialog"); + FileDialog fd = new FileDialog(f); + b.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + fd.setVisible(true); + if (fd.getDirectory() == null && fd.getFile() == null) { + PassFailJFrame.log("TEST PASSED"); + } else { + PassFailJFrame.log("TEST FAILED. dir = " + fd.getDirectory() + + " , file = " + fd.getFile()); + } + } + }); + f.add(b); + f.setSize(300, 200); + return f; + } +} From d11f64d404e2ee4b695e8077879633ee10220618 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 08:56:45 +0000 Subject: [PATCH 173/846] 8341148: Open source several Choice related tests Backport-of: 19642bd3833fa96eb4bc7a8a11e902782e0b7844 --- .../Choice/ChoiceInLWTest/ChoiceInLWTest.java | 96 +++++++++++++++++++ .../MultiItemSelected_DragOut.java | 74 ++++++++++++++ .../MultiItemSelected_KeySelect.java | 75 +++++++++++++++ .../MultiItemSelected_UpDown.java | 76 +++++++++++++++ .../RepaintAfterRemoveLastItemTest.java | 77 +++++++++++++++ 5 files changed, 398 insertions(+) create mode 100644 test/jdk/java/awt/Choice/ChoiceInLWTest/ChoiceInLWTest.java create mode 100644 test/jdk/java/awt/Choice/MultiItemSelected/MultiItemSelected_DragOut.java create mode 100644 test/jdk/java/awt/Choice/MultiItemSelected/MultiItemSelected_KeySelect.java create mode 100644 test/jdk/java/awt/Choice/MultiItemSelected/MultiItemSelected_UpDown.java create mode 100644 test/jdk/java/awt/Choice/RepaintAfterRemoveLastItemTest/RepaintAfterRemoveLastItemTest.java diff --git a/test/jdk/java/awt/Choice/ChoiceInLWTest/ChoiceInLWTest.java b/test/jdk/java/awt/Choice/ChoiceInLWTest/ChoiceInLWTest.java new file mode 100644 index 0000000000000..9d1ad19549189 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceInLWTest/ChoiceInLWTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4130788 + * @summary Choice components move unexpectedly when in lightweight containers + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ChoiceInLWTest + */ + +import java.awt.BorderLayout; +import java.awt.Choice; +import java.awt.Container; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.lang.reflect.InvocationTargetException; + +public class ChoiceInLWTest extends Frame implements Runnable { + private final Choice choices; + static final String INSTRUCTIONS = """ + After test starts wait for two seconds and open a choice. + If choice's popup obscures the label above it press Fail. + Otherwise press Pass. + """; + + public ChoiceInLWTest() { + setLayout(new BorderLayout()); + Container lwCont = new Container(); + lwCont.setLayout(new FlowLayout()); + choices = new Choice(); + choices.add("This is just a token item to get a nice width."); + lwCont.add(choices); + add("Center", lwCont); + Label label = new Label("You should see an unobscured Choice below."); + label.setAlignment(Label.CENTER); + add("North", label); + addChoiceItem(); + addWindowListener(new WindowAdapter() { + @Override + public void windowOpened(WindowEvent e) { + super.windowOpened(e); + new Thread(ChoiceInLWTest.this).start(); + } + }); + pack(); + } + + private void addChoiceItem() { + choices.add("Adding an item used to move the Choice!"); + } + + public void run() { + try { + Thread.sleep(1000); + } catch (InterruptedException ignore) { + } + addChoiceItem(); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Choice in LW Container Test") + .testUI(ChoiceInLWTest::new) + .instructions(INSTRUCTIONS) + .columns(40) + .build() + .awaitAndCheck(); + + } +} diff --git a/test/jdk/java/awt/Choice/MultiItemSelected/MultiItemSelected_DragOut.java b/test/jdk/java/awt/Choice/MultiItemSelected/MultiItemSelected_DragOut.java new file mode 100644 index 0000000000000..aed1543774575 --- /dev/null +++ b/test/jdk/java/awt/Choice/MultiItemSelected/MultiItemSelected_DragOut.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6367251 + * @summary 2 items are highlighted when pressing, dragging the mouse inside the choice, XToolkit + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MultiItemSelected_DragOut + */ + +import java.awt.Choice; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.lang.reflect.InvocationTargetException; + +public class MultiItemSelected_DragOut extends Frame { + static final String INSTRUCTIONS = """ + 1) Open Choice. + 2) Start drag from first item to second or third one. + 3) Without releasing left mouse button + press and release right mouse button. + 4) Release left mouse button. + 5) Open choice again. + 6) If there is only one selection cursor + in the dropdown list press Pass otherwise press Fail. + """; + + public MultiItemSelected_DragOut() { + Choice choice = new Choice(); + + for (int i = 1; i < 10; i++) { + choice.add("item " + i); + } + add(choice); + choice.addItemListener(ie -> System.out.println(ie)); + + setLayout(new FlowLayout()); + setSize(200, 200); + validate(); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("MultiItemSelected Drag Out Test") + .testUI(MultiItemSelected_DragOut::new) + .instructions(INSTRUCTIONS) + .columns(40) + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/java/awt/Choice/MultiItemSelected/MultiItemSelected_KeySelect.java b/test/jdk/java/awt/Choice/MultiItemSelected/MultiItemSelected_KeySelect.java new file mode 100644 index 0000000000000..9e930f9923b81 --- /dev/null +++ b/test/jdk/java/awt/Choice/MultiItemSelected/MultiItemSelected_KeySelect.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6367251 + * @summary 2 items are highlighted when dragging inside and press ESC or ENTER + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MultiItemSelected_KeySelect + */ + +import java.awt.Choice; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.lang.reflect.InvocationTargetException; + +public class MultiItemSelected_KeySelect extends Frame { + static final String INSTRUCTIONS = """ + 1) Open Choice. + 2) Start drag from first item to another one. + 3) Without releasing the mouse button press ESC key. + 4) Open choice again. + 5) Verify that there is only one + selection cursor in the dropdown list. + 6) Repeat steps 2-5 once again but this time + press ENTER key instead of ESC. + 7) If in both scenarios there is only one selection cursor + press Pass otherwise press Fail. + """; + + public MultiItemSelected_KeySelect() { + Choice choice = new Choice(); + + for (int i = 1; i < 10; i++) { + choice.add("item " + i); + } + add(choice); + choice.addItemListener(ie -> System.out.println(ie)); + setLayout(new FlowLayout()); + setSize(200, 200); + validate(); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("MultiItemSelected Key Select Test") + .testUI(MultiItemSelected_KeySelect::new) + .instructions(INSTRUCTIONS) + .columns(40) + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/java/awt/Choice/MultiItemSelected/MultiItemSelected_UpDown.java b/test/jdk/java/awt/Choice/MultiItemSelected/MultiItemSelected_UpDown.java new file mode 100644 index 0000000000000..5904d98a9081f --- /dev/null +++ b/test/jdk/java/awt/Choice/MultiItemSelected/MultiItemSelected_UpDown.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6367251 + * @summary 2 items are highlighted when dragging outside and press UP or DOWN + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MultiItemSelected_UpDown + */ + +import java.awt.Choice; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.lang.reflect.InvocationTargetException; + +public class MultiItemSelected_UpDown extends Frame { + static final String INSTRUCTIONS = """ + 1) Open Choice. + 2) Start drag from first item to another one. + 3) Without interrupting drag + move mouse cursor outside the choice popup. + 4) Press UP, DOWN key several times to position + selection cursor to a different item. + 5) Release mouse button. + 6) If popup is closed upon mouse button release open Choice again. + 7) Verify that there is only one + selection cursor in the dropdown list. + 8) If true then press Pass, otherwise press Fail. + """; + + public MultiItemSelected_UpDown() { + Choice choice = new Choice(); + + for (int i = 1; i < 20; i++) { + choice.add(" item " + i); + } + add(choice); + choice.addItemListener(ie -> System.out.println(ie)); + setLayout(new FlowLayout()); + setSize(200, 200); + validate(); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("MultiItemSelected Up/Down Test") + .testUI(MultiItemSelected_UpDown::new) + .instructions(INSTRUCTIONS) + .columns(40) + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/java/awt/Choice/RepaintAfterRemoveLastItemTest/RepaintAfterRemoveLastItemTest.java b/test/jdk/java/awt/Choice/RepaintAfterRemoveLastItemTest/RepaintAfterRemoveLastItemTest.java new file mode 100644 index 0000000000000..20acc66b6bda1 --- /dev/null +++ b/test/jdk/java/awt/Choice/RepaintAfterRemoveLastItemTest/RepaintAfterRemoveLastItemTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6292186 + * @summary Choice is not refreshed properly when the last item gets removed + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual RepaintAfterRemoveLastItemTest + */ + +import java.awt.Button; +import java.awt.Choice; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.lang.reflect.InvocationTargetException; + +public class RepaintAfterRemoveLastItemTest extends Frame implements ActionListener { + Choice ch = new Choice(); + + static final String INSTRUCTIONS = """ + Press on the 'remove' button after that if the choice does not display + 'only item' press Pass. If 'only item' is still displayed press Fail. + """; + + public RepaintAfterRemoveLastItemTest() { + ch.add("only item"); + add(ch); + + Button b = new Button("remove"); + add(b); + b.addActionListener(this); + setLayout(new FlowLayout()); + setSize(200, 200); + validate(); + } + + public void actionPerformed(ActionEvent ae) { + if (ch.getItemCount() != 0) { + ch.remove(0); + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Repaint After Remove Test") + .testUI(RepaintAfterRemoveLastItemTest::new) + .instructions(INSTRUCTIONS) + .columns(40) + .build() + .awaitAndCheck(); + } +} From 62ce4e0cb9bd2d64112622500f657bef017e8cf2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 08:58:12 +0000 Subject: [PATCH 174/846] 8340077: Open source few Checkbox tests - Set2 Backport-of: 6f459aff453679ee89fd80bb325737d76288e4d2 --- test/jdk/ProblemList.txt | 3 + .../awt/Checkbox/CheckboxBoxSizeTest.java | 71 ++++++++ .../Checkbox/CheckboxIndicatorSizeTest.java | 168 ++++++++++++++++++ .../awt/Checkbox/CheckboxNullLabelTest.java | 95 ++++++++++ .../Checkbox/CheckboxPreferredSizeTest.java | 67 +++++++ 5 files changed, 404 insertions(+) create mode 100644 test/jdk/java/awt/Checkbox/CheckboxBoxSizeTest.java create mode 100644 test/jdk/java/awt/Checkbox/CheckboxIndicatorSizeTest.java create mode 100644 test/jdk/java/awt/Checkbox/CheckboxNullLabelTest.java create mode 100644 test/jdk/java/awt/Checkbox/CheckboxPreferredSizeTest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index aa08c0da61c65..2ec12f15ce8d2 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -838,6 +838,9 @@ java/awt/Focus/FrameMinimizeTest/FrameMinimizeTest.java 8016266 linux-x64 java/awt/Frame/SizeMinimizedTest.java 8305915 linux-x64 java/awt/PopupMenu/PopupHangTest.java 8340022 windows-all java/awt/Focus/InactiveFocusRace.java 8023263 linux-all +java/awt/Checkbox/CheckboxBoxSizeTest.java 8340870 windows-all +java/awt/Checkbox/CheckboxIndicatorSizeTest.java 8340870 windows-all +java/awt/Checkbox/CheckboxNullLabelTest.java 8340870 windows-all java/awt/dnd/WinMoveFileToShellTest.java 8341665 windows-all diff --git a/test/jdk/java/awt/Checkbox/CheckboxBoxSizeTest.java b/test/jdk/java/awt/Checkbox/CheckboxBoxSizeTest.java new file mode 100644 index 0000000000000..0d500e5daa16d --- /dev/null +++ b/test/jdk/java/awt/Checkbox/CheckboxBoxSizeTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Checkbox; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Panel; + +/* + * @test + * @bug 4410522 + * @requires (os.family == "windows") + * @summary The box size of the Checkbox control should be the same as + * in Windows native applications. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual CheckboxBoxSizeTest + */ + +public class CheckboxBoxSizeTest { + private static final String INSTRUCTIONS = """ + This test must be run at UI Scale of 100% AND + 150% or greater. + Compare the size of box to any of native apps on Windows + (Eg. Font Dialog Settings on Word). + They should be the same. + + If the sizes are same Press PASS, else Press FAIL. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("CheckboxBoxSizeTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(CheckboxBoxSizeTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Frame frame = new Frame("CheckboxBoxSizeTest"); + Panel panel = new Panel(new FlowLayout()); + Checkbox checkbox = new Checkbox("Compare the box size"); + panel.add(checkbox); + frame.add(panel); + frame.pack(); + return frame; + } +} diff --git a/test/jdk/java/awt/Checkbox/CheckboxIndicatorSizeTest.java b/test/jdk/java/awt/Checkbox/CheckboxIndicatorSizeTest.java new file mode 100644 index 0000000000000..3456e7e040d17 --- /dev/null +++ b/test/jdk/java/awt/Checkbox/CheckboxIndicatorSizeTest.java @@ -0,0 +1,168 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Checkbox; +import java.awt.CheckboxGroup; +import java.awt.Color; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Label; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/* + * @test + * @bug 4090493 + * @summary Test for Checkbox indicator size + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual CheckboxIndicatorSizeTest + */ + +public class CheckboxIndicatorSizeTest implements ActionListener { + private static final String INSTRUCTIONS = """ + Indicator size of Checkbox depends + on the platform font used to render the label. + + In the frame you can see a group of checkboxes + and radio buttons. + Verify that all checkboxes and radio buttons have + indicators of the same size and proportional to + the uiScale and/or font-size. + + Use menu to change the font size and the indicators + should scale proportionally. + + If there is a bug, the checkbox/radiobutton with + dingbats label will have a smaller indicator. + + Press PASS if the above conditions are true else Press FAIL. + """; + private static Frame frame; + private static Panel testPanel; + + public static void main(String[] args) throws Exception { + + CheckboxIndicatorSizeTest obj = new CheckboxIndicatorSizeTest(); + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 3) + .columns(60) + .testUI(obj::createAndShowUI) + .build() + .awaitAndCheck(); + } + + private Frame createAndShowUI() { + frame = new Frame("CheckboxIndicatorSizeTest"); + + testPanel = new Panel(new GridLayout(0, 1)); + testPanel.setFont(new Font("Dialog", Font.PLAIN, 12)); + frame.add(testPanel); + + MenuBar menuBar = new MenuBar(); + Menu fontSizeMenu = new Menu("FontSize"); + + MenuItem size10 = new MenuItem("10"); + size10.addActionListener(this); + fontSizeMenu.add(size10); + + MenuItem size12 = new MenuItem("12"); + size12.addActionListener(this); + fontSizeMenu.add(size12); + + MenuItem size14 = new MenuItem("14"); + size14.addActionListener(this); + fontSizeMenu.add(size14); + + MenuItem size18 = new MenuItem("18"); + size18.addActionListener(this); + fontSizeMenu.add(size18); + + MenuItem size24 = new MenuItem("24"); + size24.addActionListener(this); + fontSizeMenu.add(size24); + + MenuItem size36 = new MenuItem("36"); + size36.addActionListener(this); + fontSizeMenu.add(size36); + + menuBar.add(fontSizeMenu); + frame.setMenuBar(menuBar); + + Checkbox cbEnglishOnly + = new Checkbox("Toggle", true); + Checkbox cbDingbatsOnly + = new Checkbox("\u274a\u274b\u274c\u274d", true); + Checkbox cbEnglishDingbats + = new Checkbox("Toggle \u274a\u274d", true); + Checkbox cbDingbatsEnglish + = new Checkbox("\u274a\u274d toggle", true); + + CheckboxGroup radioGroup = new CheckboxGroup(); + Checkbox rbEnglishOnly + = new Checkbox("Radio", true, radioGroup); + Checkbox rbDingbatsOnly + = new Checkbox("\u274a\u274b\u274c\u274d", false, radioGroup); + Checkbox rbEnglishDingbats + = new Checkbox("Radio \u274a\u274d", false, radioGroup); + Checkbox rbDingbatsEnglish + = new Checkbox("\u274a\u274d radio", false, radioGroup); + + Label cbLabel = new Label("Checkboxes"); + cbLabel.setBackground(Color.YELLOW); + testPanel.add(cbLabel); + testPanel.add(cbEnglishOnly); + testPanel.add(cbDingbatsOnly); + testPanel.add(cbEnglishDingbats); + testPanel.add(cbDingbatsEnglish); + + Label rbLabel = new Label("Radio buttons"); + rbLabel.setBackground(Color.YELLOW); + testPanel.add(rbLabel); + testPanel.add(rbEnglishOnly); + testPanel.add(rbDingbatsOnly); + testPanel.add(rbEnglishDingbats); + testPanel.add(rbDingbatsEnglish); + + frame.pack(); + return frame; + } + + @Override + public void actionPerformed(ActionEvent e) { + String sizeStr = e.getActionCommand(); + int size = Integer.parseInt(sizeStr); + Font oldFont = testPanel.getFont(); + Font newFont = new Font(oldFont.getName(), oldFont.getStyle(), size); + testPanel.setFont(newFont); + frame.pack(); + frame.setVisible(true); + } +} diff --git a/test/jdk/java/awt/Checkbox/CheckboxNullLabelTest.java b/test/jdk/java/awt/Checkbox/CheckboxNullLabelTest.java new file mode 100644 index 0000000000000..c5cb7c278297a --- /dev/null +++ b/test/jdk/java/awt/Checkbox/CheckboxNullLabelTest.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Checkbox; +import java.awt.CheckboxGroup; +import java.awt.Color; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Panel; + +/* + * @test + * @bug 4383735 + * @summary Checkbox buttons are too small with java 1.3 and 1.4 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual CheckboxNullLabelTest + */ + +public class CheckboxNullLabelTest { + private static final String INSTRUCTIONS = """ + Please look at the frame titled 'CheckboxNullLabelTest'. + Check if all the check boxes in each group + (of 3 check boxes) have the same size. + + If the size of labeled check box is NOT the same as + the size of non-labeled Press FAIL otherwise Press PASS. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 1) + .columns(35) + .testUI(CheckboxNullLabelTest::createAndShowUI) + .build() + .awaitAndCheck(); + } + + private static Frame createAndShowUI() { + Frame f = new Frame("CheckboxNullLabelTest"); + f.setLayout(new BorderLayout()); + f.add(new CheckboxTest(Color.gray, new Font(null, 0, 12)), "North"); + f.add(new CheckboxTest(Color.green, new Font(null, 0, 18)), "South"); + f.add(new CheckboxTest(Color.red, new Font(null, 0, 24)), "East"); + f.add(new CheckboxTest(Color.white, new Font(null, 0, 30)), "West"); + f.add(new CheckboxTest(f.getBackground(), new Font(null, 0, 36)), "Center"); + f.setSize(600, 450); + return f; + } + + private static class CheckboxTest extends Panel { + Checkbox cb1, cb2, cb3; + + CheckboxTest(Color background, Font font) { + setBackground(background); + CheckboxGroup cbg = new CheckboxGroup(); + + cb1 = new Checkbox(null, cbg, true); + cb1.setFont(font); + + cb2 = new Checkbox("", cbg, true); + cb2.setFont(font); + + cb3 = new Checkbox("Label", cbg, false); + cb3.setFont(font); + + add(cb1); + add(cb2); + add(cb3); + } + } +} diff --git a/test/jdk/java/awt/Checkbox/CheckboxPreferredSizeTest.java b/test/jdk/java/awt/Checkbox/CheckboxPreferredSizeTest.java new file mode 100644 index 0000000000000..dd61b52aaedbe --- /dev/null +++ b/test/jdk/java/awt/Checkbox/CheckboxPreferredSizeTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Checkbox; +import java.awt.Color; +import java.awt.Font; +import java.awt.Frame; + +/* + * @test + * @bug 4304049 + * @summary tests that Checkbox fits into its preferred size entirely + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual CheckboxPreferredSizeTest + */ + +public class CheckboxPreferredSizeTest { + private static final String INSTRUCTIONS = """ + As the test starts, ensure that the + whole checkbox with all its text is visible. + If the checkbox is entirely visible, press PASS else, + press FAIL. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 1) + .columns(35) + .testUI(CheckboxPreferredSizeTest::createAndShowUI) + .build() + .awaitAndCheck(); + } + + private static Frame createAndShowUI() { + Frame frame = new Frame("Checkbox Preferred Size Test"); + frame.setBackground(Color.BLUE); + Checkbox box = new Checkbox("Checkbox_With_Some_Size"); + box.setFont(new Font("Helvetica", Font.PLAIN, 36)); + box.setBackground(Color.RED); + frame.add(box); + frame.pack(); + return frame; + } +} From 6a23c47b4cf764998aa6222c588ea301956695e1 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 08:59:38 +0000 Subject: [PATCH 175/846] 8341128: open source some 2d graphics tests Backport-of: e89fd1d2ceff82952a4859c0febe902412fcf064 --- .../awt/Graphics2D/BasicStrokeValidate.java | 87 +++++++++ .../DrawImageIAETest/DrawImageIAETest.java | 169 ++++++++++++++++++ .../awt/Graphics2D/DrawImageIAETest/duke.gif | Bin 0 -> 1929 bytes .../ImageRendering/ImageRendering.java | 66 +++++++ .../awt/Graphics2D/ImageRendering/snooze.gif | Bin 0 -> 2859 bytes .../awt/Graphics2D/ScaledThinLineTest.java | 82 +++++++++ test/jdk/java/awt/Graphics2D/TextPerf.java | 159 ++++++++++++++++ 7 files changed, 563 insertions(+) create mode 100644 test/jdk/java/awt/Graphics2D/BasicStrokeValidate.java create mode 100644 test/jdk/java/awt/Graphics2D/DrawImageIAETest/DrawImageIAETest.java create mode 100644 test/jdk/java/awt/Graphics2D/DrawImageIAETest/duke.gif create mode 100644 test/jdk/java/awt/Graphics2D/ImageRendering/ImageRendering.java create mode 100644 test/jdk/java/awt/Graphics2D/ImageRendering/snooze.gif create mode 100644 test/jdk/java/awt/Graphics2D/ScaledThinLineTest.java create mode 100644 test/jdk/java/awt/Graphics2D/TextPerf.java diff --git a/test/jdk/java/awt/Graphics2D/BasicStrokeValidate.java b/test/jdk/java/awt/Graphics2D/BasicStrokeValidate.java new file mode 100644 index 0000000000000..251f14e5081bd --- /dev/null +++ b/test/jdk/java/awt/Graphics2D/BasicStrokeValidate.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4363534 + * @summary This test verifies that setting a non-thin-line BasicStroke + * on a Graphics2D obtained from a BufferedImage will correctly validate + * the pipelines for the line-widening pipeline even if that is the only + * non-default attribute on the graphics. + * + */ + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +public class BasicStrokeValidate { + + public static final int TESTW = 100; + public static final int TESTH = 100; + + public static void main(String[] args) { + BufferedImage bi1 = createImage(false); + BufferedImage bi2 = createImage(true); + compare(bi1, bi2); // images should differ + } + + static BufferedImage createImage(boolean dashed) { + BufferedImage bi = new BufferedImage(TESTW, TESTH, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = bi.createGraphics(); + g2d.setColor(Color.white); + g2d.fillRect(0, 0, TESTW, TESTH); + g2d.setColor(Color.black); + if (dashed) { + g2d.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, + BasicStroke.JOIN_MITER, 10.0f, + new float[] {2.5f, 3.5f}, + 0.0f)); + } + g2d.drawRect(10, 10, TESTW-20, TESTH-20); + g2d.setStroke(new BasicStroke(10f)); + g2d.drawRect(20, 20, TESTW-40, TESTH-40); + return bi; + } + + static void compare(BufferedImage i1, BufferedImage i2) { + boolean same = true; + int w = i1.getWidth(), h = i1.getHeight(); + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + int p1 = i1.getRGB(x, y); + int p2 = i2.getRGB(x, y); + if (p1 != p2) { + same = false; + } + } + if (!same) { + break; + } + } + if (same) { + throw new RuntimeException("No difference"); + } + } +} diff --git a/test/jdk/java/awt/Graphics2D/DrawImageIAETest/DrawImageIAETest.java b/test/jdk/java/awt/Graphics2D/DrawImageIAETest/DrawImageIAETest.java new file mode 100644 index 0000000000000..af7ebae72a6c8 --- /dev/null +++ b/test/jdk/java/awt/Graphics2D/DrawImageIAETest/DrawImageIAETest.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4191004 + * @summary Tests that no IllegalArgumentException is thrown when calling + * drawImage with certain conditions + * @key headful + */ + +import java.awt.AlphaComposite; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.MediaTracker; +import java.awt.Toolkit; +import java.awt.geom.GeneralPath; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.swing.JFrame; +import javax.swing.JPanel; + +public class DrawImageIAETest extends Frame { + + static String filename = "/duke.gif"; + private volatile Image dimg; + private volatile BufferedImage bimg; + static volatile DrawImageIAETest app; + static volatile JFrame jframe; + static volatile boolean passed = true; + static volatile Exception exception = null; + static volatile CountDownLatch imageLatch = new CountDownLatch(1); + + DrawImageIAETest(String title) { + super(title); + } + + public static void main(final String[] args) throws Exception { + EventQueue.invokeAndWait(DrawImageIAETest:: createUI); + imageLatch.await(3, TimeUnit.MILLISECONDS); + try { + if (!passed) { + throw new RuntimeException("Test FAILED: exception caught:" + exception); + } + } finally { + if (jframe != null) { + EventQueue.invokeAndWait(jframe::dispose); + } + if (app != null) { + EventQueue.invokeAndWait(app::dispose); + } + } + } + + static void createUI() { + app = new DrawImageIAETest("DrawImageIAETest"); + app.setLayout (new BorderLayout()); + app.setSize(200,200); + app.setLocationRelativeTo(null); + app.setVisible(true); + + String file; + try { + String dir = System.getProperty("test.src", + System.getProperty("user.dir")); + file = dir + filename; + } catch (Exception e) { + file = "." + filename; + } + + Image textureAlphaSource = null; + MediaTracker tracker = new MediaTracker(app); + app.dimg = Toolkit.getDefaultToolkit().getImage(file); + tracker.addImage(app.dimg, 1); + try { + tracker.waitForAll(); + imageLatch.countDown(); + } catch (Exception e) { + System.err.println("Can't load images"); + } + + if (app.dimg == null) { + passed = false; + return; + } + + jframe = new JFrame("Test DrawImageIAETest"); + jframe.setSize(300, 300); + JPanel jpanel; + jframe.getContentPane().add("Center", jpanel = new JPanel() { + public void paint(Graphics _g) { + Graphics2D g = (Graphics2D)_g; + Dimension d = getSize(); + Graphics2D g2 = app.createGraphics2D(d.width, d.height); + app.drawDemo(d.width, d.height, g2); + g2.dispose(); + g.drawImage(app.bimg, 0, 0, app); + } + }); + jpanel.setSize(140, 140); + jframe.setVisible(true); + } + + public void drawDemo(int w, int h, Graphics2D g2) { + GeneralPath p1 = new GeneralPath(); + GeneralPath p2 = new GeneralPath(); + + int dukeX = 73; + int dukeY = 26; + + double x = 118; + double y = 17; + double ew = 50; + double eh = 48; + + p1.append(new Ellipse2D.Double(x, y, ew, eh), false); + p2.append(new Rectangle2D.Double(x+5, y+5, ew-10, eh-10),false); + + g2.setClip(p1); + g2.clip(p2); + try { + g2.drawImage(dimg, dukeX, dukeY, null); + } catch (IllegalArgumentException e) { + passed = false; + exception = e; + } + } + + public Graphics2D createGraphics2D(int w, int h) { + Graphics2D g2 = null; + if (bimg == null || bimg.getWidth() != w || bimg.getHeight() != h) { + bimg = (BufferedImage) createImage(w, h); + } + g2 = bimg.createGraphics(); + g2.setBackground(getBackground()); + g2.clearRect(0, 0, w, h); + g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); + return g2; + } +} diff --git a/test/jdk/java/awt/Graphics2D/DrawImageIAETest/duke.gif b/test/jdk/java/awt/Graphics2D/DrawImageIAETest/duke.gif new file mode 100644 index 0000000000000000000000000000000000000000..ed32e0ff79b05c07b82863ce6fb07fa9898adaa2 GIT binary patch literal 1929 zcmWlYe^AtB8pi`HvM4_?{J2I$8$dLc1#@!R2zwgXMWdj^k;9xr+bDW&4{JlE8WpDj z7F-cwwK{H<)?L&#SJz$!;hJ{%BY2FYf)Wp^xl?aq!5Xcdi$c#hV~>m9_n-Hl=Xsy+ z=li^?*Q~;pZ+R1N1J40KRkeWM7ew3~jLM24A{CM-A}~TzqzYpq&od0GC=z71!w_=b z-==B0rt2t*nA}((5YSLs6a*Z@X__WqiSjTW6oLo{5km&|K1mGAimYjhs#wwZtvV8SV~7LCFpgub+-TTAk%UQb0dE_cj+pc?!+0o?qG$?% zVFD)%!w7Z;g)ndE8Uk6Aky=+kLaUQ{UW`XS?Nn*s@SQ{VmFgGdkV{&&98EcEQ5hjc@H$`e)fX zj@&GdchxpMUo|-A^M4iBP3(#Ib53Ap?5{nGT7SBA_V!o!TTzL5R~FUWe)4X?@iTd8 z1;TcF^rQLj?4p0uy?@ikb2eUSXdHVa_jIn=@W%a<6~57D>am6&Z!{lzc=@ZbuGB8` zpU38H8d~@82Da!+qdYG5ls&Cx?~|oPMnbqTHMw%I*KlV~?fc{rSwe29?Om}fsknG# z@n5IwY=4Mx>>0WJLG>=yJX^WbHA30iQ$H!X)3<4K zBe1|sf3NKKTS;)mg{$k(2eDJG^u5=&x{@M!V>EWgzRA((>}?o{WQBehp1mIHU!BGG zYz5_6B(+KIVdCVoum2ItM&gXZd+SB^vQTN=a zeYbbah=i-xCho2{4Pazv_i%2mH`EkM{r8XYDLbdY@(a7Ud}$%!$QrTN_DqwNXA9~g zTGKxKyfto7NDp;5A3O5zgb(hyxjN@OAG!(zy^*Ug4!yjF=Y*8aHA@ovB1({&a4;sR zTf1CVC{>Pgy`m$lG;P1$pC_6F7u%iP+qz0q4{lXT`i9g-ThiYgO^GXC`f?JNo*|@p zr{b%U-tSKw99q0|YJa9{Va?`H{IaNICo>p5lGEY*+IDR4bfIUwq~CTRuC_mGWA%~W zea{@eKJ(Iq^7MvdsPsR%&vt$@4i&s?bPptz#y#!FcRZEaMS0WFTyXMCUEfsNxnJ_9 zPwpt`Er4O>``2G{7=4r1GCSTO8#0xw+{<^L4X(K8y1wKj72KLrYD}Y7SJuY7y==wf z;UkI5?(v?h+4r;vR{P*U`ul~=D@U7K5$eV8c!%rX-38vE>azU80UrhFXCv#d`(ylZS4+i2a^vI91MTIxCx%9gd2&N&D9RC&xcpx8#f=GZv%9;F z#?CEVT%UV$nk;L%RJA+d=f8ZB@U*Xz-TZbG?HKKT(VJZMBH!)$#qRuwbFc%Aljqha zoNBs8od~V$_^vux0ZSk!iP!hI($t35SxY8`FV{pxCjpU}Ova2VIg1&>V)CvvMb_ 2000) { + throw new RuntimeException("Paint time is " + paintTime + "ms"); + } + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + } + + static void createUI() { + frame = new Frame("TextPerf"); + frame.setLayout(new BorderLayout()); + TextPerf tp = new TextPerf(); + frame.add(tp, BorderLayout.CENTER); + frame.pack(); + frame.setVisible(true); + } + + public Dimension getPreferredSize() { + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + return new Dimension(d.width - 50, d.height - 50); + } + + static Font[] fonts = { + new Font(Font.SERIF, Font.PLAIN, 10), + new Font(Font.SANS_SERIF, Font.PLAIN, 10), + new Font(Font.MONOSPACED, Font.ITALIC, 10), + new Font(Font.SERIF, Font.PLAIN, 14), + new Font(Font.SERIF, Font.BOLD, 12), + }; + + public void paint(Graphics g1) { + + Graphics2D g = (Graphics2D)g1; + String text = "Hello,_Wgjpqy!"; + Toolkit.getDefaultToolkit().sync(); + long startTime = System.currentTimeMillis(); + FontMetrics[] cachedMetrics = new FontMetrics[fonts.length]; + Dimension size = getSize(); + int prim = 0; + int spaceWidth = 5; + Color cols[] = { Color.red, Color.blue, Color.yellow, + Color.green, Color.pink, Color.orange} ; + + for (int y = 20; y < size.height; y += 20) { + int i = 0; + for (int x = 0; x < size.width; i++) { + Font font = fonts[i % fonts.length]; + FontMetrics metrics = cachedMetrics[i % fonts.length]; + if (metrics == null) { + metrics = g.getFontMetrics(font); + cachedMetrics[i % fonts.length] = metrics; + } + + g.setFont(font); + g.setColor(cols[i % cols.length]); + switch (prim++) { + case 0: g.drawString(text, x, y); + break; + case 1: g.drawBytes(text.getBytes(), 0, text.length(), x, y); + break; + case 2: char[] chs= new char[text.length()]; + text.getChars(0,text.length(), chs, 0); + g.drawChars(chs, 0, text.length(), x, y); + break; + case 3: GlyphVector gv = font.createGlyphVector( + g.getFontRenderContext(), text); + g.drawGlyphVector(gv, (float)x, (float)y); + default: prim = 0; + } + + x += metrics.stringWidth(text) + spaceWidth; + } + } + + // Draw some transformed text to verify correct bounds calculated + AffineTransform at = AffineTransform.getTranslateInstance(50, 50); + at.scale(7.0,7.0); + at.rotate(1.0); + g.transform(at); + g.setColor(Color.black); + Font font = new Font(Font.SERIF, Font.PLAIN, 20); + RenderingHints hints = new RenderingHints(null); + hints.put(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g.setRenderingHints(hints); + g.setFont(font); + FontMetrics metrics = g.getFontMetrics(font); + g.drawString("Java", 5,5); + + Toolkit.getDefaultToolkit().sync(); + long endTime = System.currentTimeMillis(); + paintTime = endTime - startTime; + String msg = "repainted in " + paintTime + " milliseconds"; + System.out.println(msg); + System.out.flush(); + + paintLatch.countDown(); + } +} From 169e8935be40fa93f6ee3de97a422721203d6de1 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 09:00:46 +0000 Subject: [PATCH 176/846] 8341162: Open source some of the AWT window test Backport-of: c8e70df37ebc90faaffae469244cefa10e8274c1 --- .../TestLocationByPlatform.java | 105 ++++++++++++++++++ .../OwnedWindowShowTest.java | 54 +++++++++ .../awt/Window/ResizeTest/ResizeTest.java | 80 +++++++++++++ .../Window/ShowWindowTest/ShowWindowTest.java | 88 +++++++++++++++ 4 files changed, 327 insertions(+) create mode 100644 test/jdk/java/awt/Window/LocationByPlatform/TestLocationByPlatform.java create mode 100644 test/jdk/java/awt/Window/OwnedWindowShowTest/OwnedWindowShowTest.java create mode 100644 test/jdk/java/awt/Window/ResizeTest/ResizeTest.java create mode 100644 test/jdk/java/awt/Window/ShowWindowTest/ShowWindowTest.java diff --git a/test/jdk/java/awt/Window/LocationByPlatform/TestLocationByPlatform.java b/test/jdk/java/awt/Window/LocationByPlatform/TestLocationByPlatform.java new file mode 100644 index 0000000000000..33b9d048ef2a9 --- /dev/null +++ b/test/jdk/java/awt/Window/LocationByPlatform/TestLocationByPlatform.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6318630 + * @summary Test that location by platform works + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual TestLocationByPlatform + */ + +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; + +public class TestLocationByPlatform { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + You should see two frames. One has locationByPlatform set, it + should be displayed somewhere on the screen most probably without + intersecting other Frames or stacked over normal frame with some + offset. Another has its location explicitly set to (0, 450). + Please verify that the frames are located correctly on the screen. + + Also verify that the picture inside of frames looks the same + and consists of red descending triangle occupying exactly the bottom + half of the frame. Make sure that there is a blue rectangle exactly + surrounding the client area of frame with no pixels between it and + the frame's decorations. Press Pass if this all is true, + otherwise press Fail. + """; + + PassFailJFrame passFailJFrame = PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows(13) + .columns(40) + .build(); + EventQueue.invokeAndWait(TestLocationByPlatform::createUI); + passFailJFrame.awaitAndCheck(); + } + private static void createUI() { + Frame frame = new Frame("Normal"); + frame.setLocation(0, 450); + Canvas c = new MyCanvas(); + frame.add(c, BorderLayout.CENTER); + frame.pack(); + PassFailJFrame.addTestWindow(frame); + frame.setVisible(true); + + frame = new Frame("Location by platform"); + frame.setLocationByPlatform(true); + c = new MyCanvas(); + frame.add(c, BorderLayout.CENTER); + frame.pack(); + PassFailJFrame.addTestWindow(frame); + frame.setVisible(true); + } + + static class MyCanvas extends Canvas { + @Override + public Dimension getPreferredSize() { + return new Dimension(400, 400); + } + + @Override + public void paint(Graphics g) { + g.setColor(Color.red); + for (int i = 399; i >= 0; i--) { + g.drawLine(400 - i - 1, 400 - i - 1, + 400 - i - 1, 399); + } + g.setColor(Color.blue); + g.drawLine(0, 0, 399, 0); + g.drawLine(0, 0, 0, 399); + g.drawLine(0, 399, 399, 399); + g.drawLine(399, 0, 399, 399); + } + } +} diff --git a/test/jdk/java/awt/Window/OwnedWindowShowTest/OwnedWindowShowTest.java b/test/jdk/java/awt/Window/OwnedWindowShowTest/OwnedWindowShowTest.java new file mode 100644 index 0000000000000..c8b5ad4a619d0 --- /dev/null +++ b/test/jdk/java/awt/Window/OwnedWindowShowTest/OwnedWindowShowTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4177156 + * @key headful + * @summary Tests that multiple level of window ownership doesn't cause + * NullPointerException when showing a Window + * @run main OwnedWindowShowTest + */ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Window; + +public class OwnedWindowShowTest { + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(OwnedWindowShowTest::runTest); + } + + static void runTest() { + Frame parent = new Frame("OwnedWindowShowTest"); + try { + Window owner = new Window(parent); + Window window = new Window(owner); + // Showing a window with multiple levels of ownership + // should not throw NullPointerException + window.setVisible(true); + } finally { + parent.dispose(); + } + } +} diff --git a/test/jdk/java/awt/Window/ResizeTest/ResizeTest.java b/test/jdk/java/awt/Window/ResizeTest/ResizeTest.java new file mode 100644 index 0000000000000..a9191f8bd0536 --- /dev/null +++ b/test/jdk/java/awt/Window/ResizeTest/ResizeTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4225955 + * @summary Tests that focus lost is delivered to a lightweight component + * in a disposed window + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ResizeTest + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.Frame; + +public class ResizeTest +{ + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1) Push button A to create modal dialog 2. + 2) Resize dialog 2, then click button B to hide it. + 3) Push button A again. Dialog B should be packed to its original + size. + 4) Push button B again to hide, and A to reshow. + Dialog B should still be the same size, then test is passed, + otherwise failed. + 5) Push button B to hide the modal dialog and then select pass/fail. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(ResizeTest::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + Frame f = new Frame("1"); + Dialog d = new Dialog(f, "2", true); + d.setLocationRelativeTo(null); + Button b2 = new Button("B"); + b2.addActionListener(e -> d.setVisible(false)); + d.setLayout(new BorderLayout()); + d.add(b2, BorderLayout.CENTER); + + Button b = new Button("A"); + f.add(b, BorderLayout.CENTER); + b.addActionListener(e -> { + d.pack(); + d.setVisible(true); + }); + f.pack(); + return f; + } +} diff --git a/test/jdk/java/awt/Window/ShowWindowTest/ShowWindowTest.java b/test/jdk/java/awt/Window/ShowWindowTest/ShowWindowTest.java new file mode 100644 index 0000000000000..4857929c94ebc --- /dev/null +++ b/test/jdk/java/awt/Window/ShowWindowTest/ShowWindowTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4084997 + * @summary See if Window can be created without its size explicitly set + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ShowWindowTest + */ + +import java.awt.Button; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class ShowWindowTest implements ActionListener +{ + private static Window window; + private static Button showButton; + private static Button hideButton; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. You should see a Frame with a "Show" and a "Hide" button in it. + 2. Click on the "Show" button. A window with a "Hello World" Label + should appear + 3. If the window does not appear, the test failed, otherwise passed. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(ShowWindowTest::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + Frame frame = new Frame("ShowWindowTest"); + frame.setLayout(new FlowLayout()); + frame.setSize(100,100); + frame.add(showButton = new Button("Show")); + frame.add(hideButton = new Button("Hide")); + + ActionListener handler = new ShowWindowTest(); + showButton.addActionListener(handler); + hideButton.addActionListener(handler); + + window = new Window(frame); + window.add("Center", new Label("Hello World")); + window.setLocationRelativeTo(null); + return frame; + } + + public void actionPerformed(ActionEvent e) { + if (e.getSource() == showButton) { + window.pack(); + window.setVisible(true); + } else if (e.getSource() == hideButton) + window.setVisible(false); + } +} From a6dd9670ad70c0ed85993b849b5732075cf1191e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 09:02:14 +0000 Subject: [PATCH 177/846] 8341258: Open source few various AWT tests - Set1 Backport-of: 86e3d52c70a611975da3abdebd2e1f14c7a1d019 --- .../RemoveComponentTest.java | 166 ++++++++++++++++++ .../java/awt/GradientPaint/JerkyGradient.java | 125 +++++++++++++ .../jdk/java/awt/GradientPaint/ShearTest.java | 137 +++++++++++++++ 3 files changed, 428 insertions(+) create mode 100644 test/jdk/java/awt/CardLayout/RemoveComponentTest/RemoveComponentTest.java create mode 100644 test/jdk/java/awt/GradientPaint/JerkyGradient.java create mode 100644 test/jdk/java/awt/GradientPaint/ShearTest.java diff --git a/test/jdk/java/awt/CardLayout/RemoveComponentTest/RemoveComponentTest.java b/test/jdk/java/awt/CardLayout/RemoveComponentTest/RemoveComponentTest.java new file mode 100644 index 0000000000000..0a23a98953302 --- /dev/null +++ b/test/jdk/java/awt/CardLayout/RemoveComponentTest/RemoveComponentTest.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4546123 + * @summary CardLayout becomes unusable after deleting an element + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual RemoveComponentTest + */ + +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Frame; +import java.awt.Insets; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JLabel; +import javax.swing.JPanel; + +public class RemoveComponentTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + You should see a frame titled "Test Frame For + RemoveComponentTest". Try to select a few different panels from + the second menu. Make sure your last choice is the red panel. + Then click close (in first menu). After that you should be able + to select any panels except red one. + If that is the case, the test passes. Otherwise, the test failed. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(RemoveComponentTest::createUI) + .logArea(5) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + TestFrame frame = new TestFrame(); + frame.setSize(200, 200); + return frame; + } +} + +class TestFrame extends Frame implements ActionListener { + public Panel aPanel; + public TestPanel pageRed; + public TestPanel pageGreen; + public TestPanel pageBlue; + public String currentSelection = ""; + + public MenuItem mi; + public CardLayout theCardLayout; + + + public TestFrame() { + super("Test Frame For RemoveComponentTest"); + + setBackground(Color.black); + setLayout(new BorderLayout(5, 5)); + + MenuBar mb = new MenuBar(); + + Menu fileMenu = new Menu("File"); + Menu pageMenu = new Menu("Pages"); + + mi = new MenuItem("Close"); + mi.addActionListener(this); + fileMenu.add(mi); + + mi = new MenuItem("Red"); + mi.addActionListener(this); + pageMenu.add(mi); + + mi = new MenuItem("Green"); + mi.addActionListener(this); + pageMenu.add(mi); + + mi = new MenuItem("Blue"); + mi.addActionListener(this); + pageMenu.add(mi); + + mb.add(fileMenu); + mb.add(pageMenu); + + setMenuBar(mb); + + aPanel = new Panel(); + theCardLayout = new CardLayout(); + + aPanel.setLayout(theCardLayout); + + pageRed = new TestPanel("PageRed", Color.red); + pageGreen = new TestPanel("PageGreen", Color.green); + pageBlue = new TestPanel("PageBlue", Color.blue); + + aPanel.add("PageRed", pageRed); + aPanel.add("PageGreen", pageGreen); + aPanel.add("PageBlue", pageBlue); + + add("Center", aPanel); + setSize(getPreferredSize()); + } + + public Insets getInsets() { + return new Insets(47, 9, 9, 9); + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("Red")) { + theCardLayout.show(aPanel, "PageRed"); + currentSelection = "PageRed"; + } else if (e.getActionCommand().equals("Green")) { + theCardLayout.show(aPanel, "PageGreen"); + } else if (e.getActionCommand().equals("Blue")) { + theCardLayout.show(aPanel, "PageBlue"); + } else if (e.getActionCommand().equals("Close")) { + PassFailJFrame.log("Closing"); + + if (currentSelection.equals("PageRed")) { + PassFailJFrame.log("Remove page red"); + theCardLayout.removeLayoutComponent(pageRed); + } + } + } +} + +class TestPanel extends JPanel { + private String pageName; + + TestPanel(String pageName, Color color) { + setBackground(color); + add(new JLabel(pageName)); + } +} diff --git a/test/jdk/java/awt/GradientPaint/JerkyGradient.java b/test/jdk/java/awt/GradientPaint/JerkyGradient.java new file mode 100644 index 0000000000000..dc33b9c185af8 --- /dev/null +++ b/test/jdk/java/awt/GradientPaint/JerkyGradient.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4221201 + * @summary Test where the gradient drawn should remain in sync with the + * rotating rectangle. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual JerkyGradient + */ + +import java.awt.Color; +import java.awt.Frame; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Paint; +import java.awt.Panel; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; + +public class JerkyGradient extends Panel implements Runnable { + protected static Shape mShape; + protected static Paint mPaint; + protected static double mTheta; + static Thread animatorThread; + static BufferedImage mImg; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Watch at least one full rotation of the rectangle. Check that + the gradient drawn remains in sync with the rotating + rectangle. If so, pass this test. Otherwise, fail this test. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(JerkyGradient::createUI) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame f = new Frame("Rotating Gradient Test"); + JerkyGradient jg = new JerkyGradient(); + f.add(jg); + f.setSize(200, 200); + return f; + } + + public JerkyGradient() { + mShape = new Rectangle2D.Double(60, 50, 80, 100); + mPaint = new GradientPaint(0, 0, Color.red, + 25, 25, Color.yellow, + true); + mImg = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB); + + animatorThread = new Thread(this); + animatorThread.setPriority(Thread.MIN_PRIORITY); + animatorThread.start(); + } + + public synchronized void run() { + Thread me = Thread.currentThread(); + double increment = Math.PI / 36; + double twoPI = Math.PI * 2; + + while (animatorThread == me) { + mTheta = (mTheta + increment) % twoPI; + repaint(); + try { + wait(50); + } catch (InterruptedException ie) { + break; + } + } + } + + public void update(Graphics g) { + Graphics2D g2 = mImg.createGraphics(); + g2.setColor(getBackground()); + g2.fillRect(0, 0, 200, 200); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g2.rotate(mTheta, 100, 100); + g2.setPaint(Color.black); + g2.drawLine(100, 30, 100, 55); + g2.setPaint(mPaint); + g2.fill(mShape); + g2.setPaint(Color.black); + g2.draw(mShape); + paint(g); + g2.dispose(); + } + + public void paint(Graphics g) { + g.drawImage(mImg, 0, 0, null); + } +} diff --git a/test/jdk/java/awt/GradientPaint/ShearTest.java b/test/jdk/java/awt/GradientPaint/ShearTest.java new file mode 100644 index 0000000000000..95a4e4a6dcd3e --- /dev/null +++ b/test/jdk/java/awt/GradientPaint/ShearTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4171820 + * @summary Checks that GradientPaint responds to shearing transforms correctly + * The gradients drawn should be parallel to the sides of the + * indicated anchor rectangle. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ShearTest + */ + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; + +public class ShearTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + This test displays 2 rows each containing 4 gradient fills. Each + gradient fill is labeled depending on whether the line or lines + of the gradient should be truly vertical, truly horizontal, or + some slanted diagonal direction. The test passes if the direction + of each gradient matches its label. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(ShearTest::createUI) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame f = new Frame("Shear Gradient Test"); + f.setLayout(new GridLayout(0, 1)); + f.add(getPanelSet(false), "North"); + f.add(getPanelSet(true), "Center"); + f.setSize(500, 300); + return f; + } + + public static Panel getPanelSet(boolean horizontal) { + String direven = horizontal ? "Slanted" : "Vertical"; + String dirodd = horizontal ? "Horizontal" : "Slanted"; + + Panel p = new Panel(); + p.setLayout(new GridLayout(0, 4)); + p.add(new ShearCanvas(direven, false, horizontal, false, true)); + p.add(new ShearCanvas(dirodd, false, horizontal, true, false)); + p.add(new ShearCanvas(direven, true, horizontal, false, true)); + p.add(new ShearCanvas(dirodd, true, horizontal, true, false)); + + return p; + } + + public static class ShearCanvas extends Canvas { + public static final int GRADW = 30; + + public static final Rectangle anchor = + new Rectangle(-GRADW / 2, -GRADW / 2, GRADW, GRADW); + + public static final Color faintblue = new Color(0f, 0f, 1.0f, 0.35f); + + private AffineTransform txform; + private GradientPaint grad; + private String label; + + public ShearCanvas(String label, + boolean cyclic, boolean horizontal, + boolean shearx, boolean sheary) { + txform = new AffineTransform(); + if (shearx) { + txform.shear(-.5, 0); + } + if (sheary) { + txform.shear(0, -.5); + } + int relx = horizontal ? 0 : GRADW / 2; + int rely = horizontal ? GRADW / 2 : 0; + grad = new GradientPaint(-relx, -rely, Color.green, + relx, rely, Color.yellow, cyclic); + this.label = label; + } + + public void paint(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + + AffineTransform at = g2d.getTransform(); + g2d.translate(75, 75); + g2d.transform(txform); + g2d.setPaint(grad); + g2d.fill(g.getClip()); + g2d.setColor(faintblue); + g2d.fill(anchor); + g2d.setTransform(at); + + Dimension d = getSize(); + g2d.setColor(Color.black); + g2d.drawRect(0, 0, d.width - 1, d.height - 1); + g2d.drawString(label, 5, d.height - 5); + g2d.dispose(); + } + } +} From 7b77ba17e2f50cba6b2d0a3410853b5b8567ee65 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 09:04:05 +0000 Subject: [PATCH 178/846] 8340417: Open source some MenuBar tests - Set1 Backport-of: 559289487d97230760cff6f3349be4dc55c3a2ef --- test/jdk/java/awt/MenuBar/CellsResize.java | 159 ++++++++++++++++++ .../MenuBarRemoveMenuTest.java | 93 ++++++++++ .../jdk/java/awt/MenuBar/MenuNPE/MenuNPE.java | 63 +++++++ .../SetMBarWhenHidden/SetMBarWhenHidden.java | 92 ++++++++++ 4 files changed, 407 insertions(+) create mode 100644 test/jdk/java/awt/MenuBar/CellsResize.java create mode 100644 test/jdk/java/awt/MenuBar/MenuBarRemoveMenu/MenuBarRemoveMenuTest.java create mode 100644 test/jdk/java/awt/MenuBar/MenuNPE/MenuNPE.java create mode 100644 test/jdk/java/awt/MenuBar/SetMBarWhenHidden/SetMBarWhenHidden.java diff --git a/test/jdk/java/awt/MenuBar/CellsResize.java b/test/jdk/java/awt/MenuBar/CellsResize.java new file mode 100644 index 0000000000000..64777095fa8d5 --- /dev/null +++ b/test/jdk/java/awt/MenuBar/CellsResize.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6502052 + * @summary Menu cells must resize if font changes (XToolkit) + * @requires os.family == "linux" + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual CellsResize + */ + +import java.awt.Button; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuComponent; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.PopupMenu; +import java.awt.Toolkit; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class CellsResize { + private static Frame frame; + private static MenuBar menuBar; + private static PopupMenu popupMenu; + private static Menu barSubMenu; + private static Menu popupSubMenu; + private static boolean fontMultiplied = false; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Open all nested menus in menu bar. + 2. Click on "popup-menu" button to show popup-menus. + 3. Open all nested menus in popup-menu. + 4. Click on "big-font" button (to make all menus have a + bigger font). + 5. Open all nested menus again (as described in 1, 2, 3). + 6. If all menu items use a bigger font now and their labels fit + into menu-item size, press "pass", otherwise press "fail". + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(CellsResize::createUI) + .logArea(5) + .build() + .awaitAndCheck(); + } + + public static Frame createUI () { + if (!checkToolkit()) { + new RuntimeException("Toolkit check failed."); + } + frame = new Frame("MenuBar Cell Resize Test"); + + popupMenu = new PopupMenu(); + popupMenu.add(createMenu(false)); + + frame.add(popupMenu); + + menuBar = new MenuBar(); + menuBar.add(createMenu(true)); + + frame.setMenuBar(menuBar); + + Button bp = new Button("popup-menu"); + bp.addMouseListener(new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + popupMenu.show(e.getComponent(), e.getX(), e.getY()); + } + }); + + Button bf = new Button("big-font"); + bf.addMouseListener(new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + bigFont(); + } + }); + + Panel panel = new Panel(); + panel.setLayout(new GridLayout(2, 1)); + panel.add(bp); + panel.add(bf); + + frame.add(panel); + frame.setSize(300, 300); + return frame; + } + + static boolean checkToolkit() { + String toolkitName = Toolkit.getDefaultToolkit().getClass().getName(); + return toolkitName.equals("sun.awt.X11.XToolkit"); + } + + static Menu createMenu(boolean bar) { + Menu menu1 = new Menu("Menu-1"); + Menu menu11 = new Menu("Menu-11"); + menu1.add(menu11); + if (bar) { + barSubMenu = menu11; + } else { + popupSubMenu = menu11; + } + menu11.add(new MenuItem("MenuItem")); + return menu1; + } + + static void bigFont() { + if (fontMultiplied) { + return; + } else { + fontMultiplied = true; + } + + multiplyFont(barSubMenu, 7); + multiplyFont(popupSubMenu, 7); + + // NOTE: if previous two are moved below following + // two, they get their font multiplied twice. + + multiplyFont(menuBar, 5); + multiplyFont(popupMenu, 5); + } + + static void multiplyFont(MenuComponent comp, int times) { + Font font = comp.getFont(); + float size = font.getSize() * times; + comp.setFont(font.deriveFont(size)); + } +} diff --git a/test/jdk/java/awt/MenuBar/MenuBarRemoveMenu/MenuBarRemoveMenuTest.java b/test/jdk/java/awt/MenuBar/MenuBarRemoveMenu/MenuBarRemoveMenuTest.java new file mode 100644 index 0000000000000..098065d1361f6 --- /dev/null +++ b/test/jdk/java/awt/MenuBar/MenuBarRemoveMenu/MenuBarRemoveMenuTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4275848 + * @summary Tests that MenuBar is painted correctly after its submenu is removed + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MenuBarRemoveMenuTest + */ + +import java.awt.Button; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class MenuBarRemoveMenuTest implements ActionListener { + private static MenuBar menubar; + private static Button removeButton; + private static Button addButton; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Press "Remove menu" button. If you see that both menus + disappeared, the test failed. Otherwise try to add and remove + menu several times to verify that the test passed. Every time + you press "Remove menu" button only one menu should go away. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(MenuBarRemoveMenuTest::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + Frame frame = new Frame(); + menubar = new MenuBar(); + removeButton = new Button("Remove menu"); + addButton = new Button("Add menu"); + removeButton.addActionListener(new MenuBarRemoveMenuTest()); + addButton.addActionListener(new MenuBarRemoveMenuTest()); + addButton.setEnabled(false); + menubar.add(new Menu("menu")); + menubar.add(new Menu("menu")); + frame.setMenuBar(menubar); + frame.setLayout(new GridLayout(1, 2)); + frame.add(removeButton); + frame.add(addButton); + frame.pack(); + return frame; + } + + public void actionPerformed(ActionEvent e) { + if (e.getSource() == removeButton) { + menubar.remove(0); + removeButton.setEnabled(false); + addButton.setEnabled(true); + } else { + menubar.add(new Menu("menu")); + removeButton.setEnabled(true); + addButton.setEnabled(false); + } + } +} diff --git a/test/jdk/java/awt/MenuBar/MenuNPE/MenuNPE.java b/test/jdk/java/awt/MenuBar/MenuNPE/MenuNPE.java new file mode 100644 index 0000000000000..a7a3a3480118e --- /dev/null +++ b/test/jdk/java/awt/MenuBar/MenuNPE/MenuNPE.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 5005194 + * @summary Frame.remove(getMenuBar()) throws NPE if the frame doesn't + * have a menu bar + * @key headful + * @run main MenuNPE + */ + +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; + +public class MenuNPE { + private static Frame frame; + public static void main(String[] args) throws Exception { + try { + frame = new Frame("Menu NPE"); + MenuBar menuBar = new MenuBar(); + Menu menu1 = new Menu("Menu 01"); + MenuItem menuLabel = new MenuItem("Item 01"); + menu1.add(menuLabel); + menuBar.add(menu1); + frame.setMenuBar(menuBar); + frame.setSize(200, 200); + frame.setVisible(true); + frame.validate(); + frame.remove(frame.getMenuBar()); + frame.remove(frame.getMenuBar()); + System.out.println("Test passed."); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (frame != null) { + frame.dispose(); + } + } + } +} diff --git a/test/jdk/java/awt/MenuBar/SetMBarWhenHidden/SetMBarWhenHidden.java b/test/jdk/java/awt/MenuBar/SetMBarWhenHidden/SetMBarWhenHidden.java new file mode 100644 index 0000000000000..67eefe4894248 --- /dev/null +++ b/test/jdk/java/awt/MenuBar/SetMBarWhenHidden/SetMBarWhenHidden.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4105881 + * @summary Sets the menu bar while frame window is hidden, then shows + frame again + * @key headful + * @run main SetMBarWhenHidden + */ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.Rectangle; + +// test case for 4105881: FRAME.SETSIZE() DOESN'T WORK FOR SOME SOLARIS WITH +// JDK115+CASES ON +public class SetMBarWhenHidden { + private static Frame f; + private static Rectangle startBounds; + private static Rectangle endBounds; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> { + f = new Frame("Set MenuBar When Hidden Test"); + Menu file; + Menu edit; + MenuBar menubar = new MenuBar(); + file = new Menu("File"); + menubar.add(file); + edit = new Menu("Edit"); + menubar.add(edit); + edit.setEnabled(false); + f.setMenuBar(menubar); + f.setSize(200, 200); + startBounds = f.getBounds(); + System.out.println("About to call setVisible(false)"); + f.setVisible(false); + System.out.println("About to call setSize(500, 500)"); + f.setSize(500, 500); + // create a new menubar and add + MenuBar menubar1 = new MenuBar(); + menubar1.add(file); + menubar1.add(edit); + System.out.println("About to call setMenuBar"); + f.setMenuBar(menubar1); + System.out.println("About to call setVisible(true)"); + f.setVisible(true); + endBounds = f.getBounds(); + }); + if (startBounds.getHeight() > endBounds.getHeight() && + startBounds.getWidth() > endBounds.getWidth()) { + throw new RuntimeException("Test failed. Frame size didn't " + + "change.\nStart: " + startBounds + "\n" + + "End: " + endBounds); + } else { + System.out.println("Test passed.\nStart: " + startBounds + + "\nEnd: " + endBounds); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } +} From 7a35a33e56317639db213cb3d0946fda987c47af Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 09:05:08 +0000 Subject: [PATCH 179/846] 8339836: Open source several AWT Mouse tests - Batch 1 Backport-of: 57c859e4adfedc963b1f4b3bf066453ace41ee36 --- .../java/awt/Mouse/MouseEnterExitTest.java | 174 ++++++++++++++++++ .../java/awt/Mouse/MouseEnterExitTest2.java | 140 ++++++++++++++ .../java/awt/Mouse/MouseEnterExitTest3.java | 84 +++++++++ .../java/awt/Mouse/MouseEnterExitTest4.java | 96 ++++++++++ test/jdk/java/awt/Mouse/MousePressedTest.java | 87 +++++++++ 5 files changed, 581 insertions(+) create mode 100644 test/jdk/java/awt/Mouse/MouseEnterExitTest.java create mode 100644 test/jdk/java/awt/Mouse/MouseEnterExitTest2.java create mode 100644 test/jdk/java/awt/Mouse/MouseEnterExitTest3.java create mode 100644 test/jdk/java/awt/Mouse/MouseEnterExitTest4.java create mode 100644 test/jdk/java/awt/Mouse/MousePressedTest.java diff --git a/test/jdk/java/awt/Mouse/MouseEnterExitTest.java b/test/jdk/java/awt/Mouse/MouseEnterExitTest.java new file mode 100644 index 0000000000000..059ad5c054829 --- /dev/null +++ b/test/jdk/java/awt/Mouse/MouseEnterExitTest.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Robot; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +/* + * @test + * @bug 4050138 + * @key headful + * @summary Test to verify Lightweight components don't get + * enter/exit during drags + * @run main MouseEnterExitTest + */ + +class LWSquare extends Container { + int width; + int height; + + public LWSquare(Color color, int w, int h) { + setBackground(color); + setLayout(new FlowLayout()); + width = w; + height = h; + addMouseListener(new EnterExitAdapter(this)); + setName("LWSquare-" + color.toString()); + } + + public void paint(Graphics g) { + g.setColor(getBackground()); + g.fillRect(0, 0, getSize().width, getSize().height); + super.paint(g); + } + + public Dimension getPreferredSize() { + return new Dimension(width, height); + } + + public Cursor getCursor() { + return new Cursor(Cursor.CROSSHAIR_CURSOR); + } +} + +class MouseFrame extends Frame { + public LWSquare lw; + + public MouseFrame() { + super("MouseEnterExitTest"); + setLayout(new FlowLayout()); + + lw = new LWSquare(Color.red, 75, 75); + add(lw); + setBounds(50, 50, 300, 200); + setVisible(true); + System.out.println(getInsets()); + + addMouseListener(new EnterExitAdapter(this)); + addWindowListener( + new WindowAdapter() { + public void windowClosing(WindowEvent ev) { + dispose(); + } + } + ); + addKeyListener( + new KeyAdapter() { + public void keyPressed(KeyEvent ev) { + MouseEnterExitTest.getFrame().setTitle("MouseEnterExitTest"); + } + } + ); + } +} + + +public class MouseEnterExitTest { + static MouseFrame testFrame; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + + robot.setAutoDelay(100); + try { + EventQueue.invokeAndWait(() -> testFrame = new MouseFrame()); + if (testFrame.lw.getBackground() != Color.red) { + throw new RuntimeException("Initial Background color not matching"); + } + robot.waitForIdle(); + robot.delay(100); + EventQueue.invokeAndWait(() -> robot.mouseMove( + testFrame.getLocationOnScreen().x + testFrame.getSize().width / 2, + testFrame.getLocationOnScreen().y + testFrame.getSize().height / 2)); + robot.waitForIdle(); + robot.delay(100); + + if (testFrame.lw.getBackground() != Color.green) { + throw new RuntimeException("Initial Background color not matching"); + } + EventQueue.invokeAndWait(() -> robot.mouseMove( + testFrame.getLocationOnScreen().x + testFrame.getSize().width * 2, + testFrame.getLocationOnScreen().y + testFrame.getSize().height / 2)); + robot.waitForIdle(); + robot.delay(100); + + if (testFrame.lw.getBackground() != Color.red) { + throw new RuntimeException("Initial Background color not matching"); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (testFrame != null) { + testFrame.dispose(); + } + }); + } + } + + public static Frame getFrame() { + return testFrame; + } +} + +class EnterExitAdapter extends MouseAdapter { + Component compToColor; + Color colorNormal; + + EnterExitAdapter(Component comp) { + compToColor = comp; + colorNormal = comp.getBackground(); + } + + public void mouseEntered(MouseEvent ev) { + compToColor.setBackground(Color.green); + compToColor.repaint(); + } + + public void mouseExited(MouseEvent ev) { + compToColor.setBackground(colorNormal); + compToColor.repaint(); + } +} diff --git a/test/jdk/java/awt/Mouse/MouseEnterExitTest2.java b/test/jdk/java/awt/Mouse/MouseEnterExitTest2.java new file mode 100644 index 0000000000000..e09ac333447f6 --- /dev/null +++ b/test/jdk/java/awt/Mouse/MouseEnterExitTest2.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GridLayout; +import java.awt.Rectangle; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +/* + * @test + * @bug 4150851 + * @summary Tests enter and exit events when a lightweight component is on a border + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MouseEnterExitTest2 + */ + +public class MouseEnterExitTest2 { + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Verify that white component turns black whenever mouse enters the frame, + except when it enters the red rectangle. + 2. When the mouse enters the red part of the frame the component should stay white. + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(EntryExitTest.initialize()) + .build() + .awaitAndCheck(); + } +} + +class EntryExitTest extends Component { + boolean inWin; + + public Dimension getPreferredSize() { + return new Dimension(200, 150); + } + + public void paint(Graphics g) { + Color c1, c2; + String s; + if (inWin) { + c1 = Color.black; + c2 = Color.white; + s = "IN"; + } else { + c2 = Color.black; + c1 = Color.white; + s = "OUT"; + } + g.setColor(c1); + Rectangle r = getBounds(); + g.fillRect(0, 0, r.width, r.height); + g.setColor(c2); + g.drawString(s, r.width / 2, r.height / 2); + } + + public static Frame initialize() { + EntryExitTest test = new EntryExitTest(); + MouseListener frameEnterExitListener = new MouseAdapter() { + public void mouseEntered(MouseEvent e) { + test.inWin = true; + test.repaint(); + } + + public void mouseExited(MouseEvent e) { + test.inWin = false; + test.repaint(); + } + }; + + Frame f = new Frame("Mouse Modifier Test"); + + f.add(test); + Component jc = new Component() { + public Dimension getPreferredSize() { + return new Dimension(100, 50); + } + + public void paint(Graphics g) { + Dimension d = getSize(); + g.setColor(Color.red); + g.fillRect(0, 0, d.width, d.height); + } + }; + final Container cont = new Container() { + public Dimension getPreferredSize() { + return new Dimension(100, 100); + } + }; + cont.setLayout(new GridLayout(2, 1)); + cont.add(jc); + jc.addMouseListener(new MouseAdapter() { + public void mouseEntered(MouseEvent e) { + //System.out.println("Component entered"); + } + public void mouseExited(MouseEvent e) { + //System.out.println("Component exited"); + } + }); + + f.add(cont, BorderLayout.NORTH); + f.addMouseListener(frameEnterExitListener); + f.pack(); + return f; + } +} diff --git a/test/jdk/java/awt/Mouse/MouseEnterExitTest3.java b/test/jdk/java/awt/Mouse/MouseEnterExitTest3.java new file mode 100644 index 0000000000000..d5096d7acf022 --- /dev/null +++ b/test/jdk/java/awt/Mouse/MouseEnterExitTest3.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import javax.swing.JButton; + +/* + * @test + * @bug 4431868 + * @summary Tests that hw container doesn't receive mouse enter/exit events when mouse + * is moved between its lw and hw children + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MouseEnterExitTest3 + */ + +public class MouseEnterExitTest3 { + static final Button button = new Button("Button"); + static final JButton jbutton = new JButton("JButton"); + static final Frame frame = new Frame("Mouse Enter/Exit Test"); + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Move the mouse between Button and JButton + 2. Verify that the frame doesn't receive enter/exit events + (Enter/exit events are dumped to the area below) + 4. If you see enter/exit events dumped the test fails + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .logArea(4) + .build() + .awaitAndCheck(); + } + + final static MouseListener listener = new MouseAdapter() { + public void mouseEntered(MouseEvent e) { + PassFailJFrame.log(e.toString()); + } + + public void mouseExited(MouseEvent e) { + PassFailJFrame.log(e.toString()); + } + }; + + public static Frame initialize() { + frame.setLayout(new GridLayout(2, 1)); + frame.add(button); + frame.add(jbutton); + frame.addMouseListener(listener); + frame.pack(); + return frame; + } +} diff --git a/test/jdk/java/awt/Mouse/MouseEnterExitTest4.java b/test/jdk/java/awt/Mouse/MouseEnterExitTest4.java new file mode 100644 index 0000000000000..2ee3993ae4ede --- /dev/null +++ b/test/jdk/java/awt/Mouse/MouseEnterExitTest4.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.Window; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +/* + * @test + * @bug 4431868 + * @key headful + * @summary Tests that window totally obscured by its child doesn't receive + * enter/exit events when located over another frame + * @run main MouseEnterExitTest4 + */ + +public class MouseEnterExitTest4 { + static Button button = new Button("Button"); + static Frame frame = new Frame("Mouse Enter/Exit test"); + static Window window = new Window(frame); + static MouseListener listener = new MouseAdapter() { + public void mouseEntered(MouseEvent e) { + throw new RuntimeException("Test failed due to Mouse Enter event"); + } + + public void mouseExited(MouseEvent e) { + throw new RuntimeException("Test failed due to Mouse Exit event"); + } + }; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + + robot.setAutoDelay(100); + try { + EventQueue.invokeAndWait(() -> { + button.setBackground(Color.red); + window.add(button); + frame.setBounds(100, 100, 300, 300); + window.setBounds(200, 200, 100, 100); + window.addMouseListener(listener); + window.setVisible(true); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(200); + EventQueue.invokeAndWait(() -> robot.mouseMove( + frame.getLocationOnScreen().x + frame.getSize().width / 2, + frame.getLocationOnScreen().y + frame.getSize().height / 2)); + robot.waitForIdle(); + robot.delay(200); + EventQueue.invokeAndWait(() -> robot.mouseMove( + window.getLocationOnScreen().x + window.getSize().width * 2, + window.getLocationOnScreen().y + window.getSize().height / 2)); + robot.waitForIdle(); + robot.delay(500); + System.out.println("Test Passed"); + + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + if (window != null) { + window.dispose(); + } + }); + } + } +} diff --git a/test/jdk/java/awt/Mouse/MousePressedTest.java b/test/jdk/java/awt/Mouse/MousePressedTest.java new file mode 100644 index 0000000000000..721d69bd5ddf0 --- /dev/null +++ b/test/jdk/java/awt/Mouse/MousePressedTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Container; +import java.awt.GridLayout; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JScrollPane; +import javax.swing.JToggleButton; + +/* + * @test + * @bug 4268759 + * @summary Tests whether clicking on the edge of a lightweight button + * causes sticking behavior + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MousePressedTest + */ + +public class MousePressedTest { + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Click and hold on the very bottom border (2-pixel-wide border) of the + JButton. Then drag the mouse straight down out of the JButton and + into the JRadioButton, and release the mouse button + 2. If the component remains highlighted as if the mouse button is still + down, the test fails + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .build() + .awaitAndCheck(); + } + + public static JFrame initialize() { + JFrame f = new JFrame("JButton Test"); + JPanel p = new JPanel(); + p.setLayout(new GridLayout(2, 2)); + JButton b = new JButton("JButton"); + p.add(b); + JCheckBox cb = new JCheckBox("JCheckBox"); + p.add(cb); + JRadioButton rb = new JRadioButton("JRadioButton"); + p.add(rb); + p.add(new JToggleButton("JToggleButton")); + + JScrollPane j = new JScrollPane(p, + JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, + JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); + + Container c = f.getContentPane(); + c.setLayout(new GridLayout(1, 1)); + c.add(j); + f.pack(); + return f; + } +} From 62a65ac7adf1d6e0dd7e30544c5655d1eae90d03 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 09:06:54 +0000 Subject: [PATCH 180/846] 8341257: Open source few DND tests - Set1 Backport-of: cd4981c29245b4ddd37b49aef1a051e29a1001f9 --- test/jdk/ProblemList.txt | 2 + .../awt/dnd/DnDClipboardDeadlockTest.java | 441 ++++++++++++++++++ test/jdk/java/awt/dnd/DnDCursorCrashTest.java | 231 +++++++++ .../awt/dnd/DnDRemoveFocusOwnerCrashTest.java | 234 ++++++++++ test/jdk/java/awt/dnd/DnDToWordpadTest.java | 237 ++++++++++ test/jdk/java/awt/dnd/NonAsciiFilenames.java | 158 +++++++ 6 files changed, 1303 insertions(+) create mode 100644 test/jdk/java/awt/dnd/DnDClipboardDeadlockTest.java create mode 100644 test/jdk/java/awt/dnd/DnDCursorCrashTest.java create mode 100644 test/jdk/java/awt/dnd/DnDRemoveFocusOwnerCrashTest.java create mode 100644 test/jdk/java/awt/dnd/DnDToWordpadTest.java create mode 100644 test/jdk/java/awt/dnd/NonAsciiFilenames.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 2ec12f15ce8d2..1fb1c54c6ec0b 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -203,6 +203,8 @@ java/awt/event/KeyEvent/ExtendedModifiersTest/ExtendedModifiersTest.java 8129778 java/awt/event/KeyEvent/KeyMaskTest/KeyMaskTest.java 8129778 generic-all java/awt/event/MouseEvent/MouseButtonsAndKeyMasksTest/MouseButtonsAndKeyMasksTest.java 8129778 generic-all +java/awt/dnd/DnDCursorCrashTest.java 8242805 macosx-all +java/awt/dnd/DnDClipboardDeadlockTest.java 8079553 linux-all java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListToFileListBetweenJVMsTest.java 8194947 generic-all java/awt/Frame/FramesGC/FramesGC.java 8079069 macosx-all java/awt/GridLayout/LayoutExtraGaps/LayoutExtraGaps.java 8000171 windows-all diff --git a/test/jdk/java/awt/dnd/DnDClipboardDeadlockTest.java b/test/jdk/java/awt/dnd/DnDClipboardDeadlockTest.java new file mode 100644 index 0000000000000..ab2bff8ecc5a5 --- /dev/null +++ b/test/jdk/java/awt/dnd/DnDClipboardDeadlockTest.java @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4388802 + * @summary tests that clipboard operations during drag-and-drop don't deadlock + * @key headful + * @run main DnDClipboardDeadlockTest + */ + +import java.awt.AWTEvent; +import java.awt.AWTException; +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GridLayout; +import java.awt.List; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetContext; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.AWTEventListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; + +public class DnDClipboardDeadlockTest { + + public static final int CODE_NOT_RETURNED = -1; + public static final int CODE_OK = 0; + public static final int CODE_FAILURE = 1; + + private int returnCode = CODE_NOT_RETURNED; + + final Frame frame = new Frame(); + Robot robot = null; + Panel panel = null; + + public static void main(String[] args) throws Exception { + DnDClipboardDeadlockTest test = new DnDClipboardDeadlockTest(); + if (args.length == 4) { + test.run(args); + } else { + test.start(); + } + } + + public void run(String[] args) throws InterruptedException, AWTException { + try { + if (args.length != 4) { + throw new RuntimeException("Incorrect command line arguments."); + } + + int x = Integer.parseInt(args[0]); + int y = Integer.parseInt(args[1]); + int w = Integer.parseInt(args[2]); + int h = Integer.parseInt(args[3]); + + Transferable t = new StringSelection("TEXT"); + panel = new DragSourcePanel(t); + + frame.setTitle("DragSource frame"); + frame.setLocation(300, 200); + frame.add(panel); + frame.pack(); + frame.setVisible(true); + + Util.waitForInit(); + + Point sourcePoint = panel.getLocationOnScreen(); + Dimension d = panel.getSize(); + sourcePoint.translate(d.width / 2, d.height / 2); + + Point targetPoint = new Point(x + w / 2, y + h / 2); + + robot = new Robot(); + + if (!Util.pointInComponent(robot, sourcePoint, panel)) { + throw new RuntimeException("WARNING: Cannot locate source panel"); + } + + robot.mouseMove(sourcePoint.x, sourcePoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (; !sourcePoint.equals(targetPoint); + sourcePoint.translate(sign(targetPoint.x - sourcePoint.x), + sign(targetPoint.y - sourcePoint.y))) { + robot.mouseMove(sourcePoint.x, sourcePoint.y); + Thread.sleep(10); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + if (frame != null) { + frame.dispose(); + } + + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } // run() + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } + + public void start() { + panel = new DropTargetPanel(); + + frame.setTitle("DropTarget frame"); + frame.setLocation(10, 200); + frame.add(panel); + + frame.pack(); + frame.setVisible(true); + + try { + Util.waitForInit(); + + Point p = panel.getLocationOnScreen(); + Dimension d = panel.getSize(); + + try { + Robot robot = new Robot(); + Point center = new Point(p); + center.translate(d.width / 2, d.height / 2); + if (!Util.pointInComponent(robot, center, panel)) { + System.err.println("WARNING: Cannot locate target panel"); + return; + } + } catch (AWTException awte) { + awte.printStackTrace(); + return; + } + + String javaPath = System.getProperty("java.home", ""); + String command = javaPath + File.separator + "bin" + + File.separator + "java -cp " + + System.getProperty("java.class.path", ".") + + " DnDClipboardDeadlockTest " + + p.x + " " + p.y + " " + d.width + " " + d.height; + + Process process = Runtime.getRuntime().exec(command); + returnCode = process.waitFor(); + + InputStream errorStream = process.getErrorStream(); + int count = errorStream.available(); + if (count > 0) { + byte[] b = new byte[count]; + errorStream.read(b); + System.err.println("========= Child VM System.err ========"); + System.err.print(new String(b)); + System.err.println("======================================"); + } + + } catch (Throwable e) { + e.printStackTrace(); + } + switch (returnCode) { + case CODE_NOT_RETURNED: + System.err.println("Child VM: failed to start"); + break; + case CODE_OK: + System.err.println("Child VM: normal termination"); + break; + case CODE_FAILURE: + System.err.println("Child VM: abnormal termination"); + break; + } + if (returnCode != CODE_OK) { + throw new RuntimeException("The test failed."); + } + if (frame != null) { + frame.dispose(); + } + } // start() +} // class DnDClipboardDeadlockTest + +class Util implements AWTEventListener { + private static final Toolkit tk = Toolkit.getDefaultToolkit(); + private static final Object SYNC_LOCK = new Object(); + private Component clickedComponent = null; + private static final int PAINT_TIMEOUT = 10000; + private static final int MOUSE_RELEASE_TIMEOUT = 10000; + private static final Util util = new Util(); + + static { + tk.addAWTEventListener(util, 0xFFFFFFFF); + } + + private void reset() { + clickedComponent = null; + } + + public void eventDispatched(AWTEvent e) { + if (e.getID() == MouseEvent.MOUSE_RELEASED) { + clickedComponent = (Component) e.getSource(); + synchronized (SYNC_LOCK) { + SYNC_LOCK.notifyAll(); + } + } + } + + public static boolean pointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + return util.isPointInComponent(robot, p, comp); + } + + private boolean isPointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + tk.sync(); + robot.waitForIdle(); + reset(); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + synchronized (SYNC_LOCK) { + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + SYNC_LOCK.wait(MOUSE_RELEASE_TIMEOUT); + } + + Component c = clickedComponent; + + while (c != null && c != comp) { + c = c.getParent(); + } + + return c == comp; + } + + public static void waitForInit() throws InterruptedException { + final Frame f = new Frame() { + public void paint(Graphics g) { + dispose(); + synchronized (SYNC_LOCK) { + SYNC_LOCK.notifyAll(); + } + } + }; + f.setBounds(600, 400, 200, 200); + synchronized (SYNC_LOCK) { + f.setVisible(true); + SYNC_LOCK.wait(PAINT_TIMEOUT); + } + tk.sync(); + } +} + +class DragSourceButton extends Button implements Serializable, + DragGestureListener, + DragSourceListener { + static final Clipboard systemClipboard = + Toolkit.getDefaultToolkit().getSystemClipboard(); + final Transferable transferable; + + public DragSourceButton(Transferable t) { + super("DragSourceButton"); + + this.transferable = t; + DragSource ds = DragSource.getDefaultDragSource(); + ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, + this); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, transferable, this); + } + + public void dragEnter(DragSourceDragEvent dsde) { + } + + public void dragExit(DragSourceEvent dse) { + } + + public void dragOver(DragSourceDragEvent dsde) { + try { + Transferable t = systemClipboard.getContents(null); + if (t.isDataFlavorSupported(DataFlavor.stringFlavor)) { + String str = (String) t.getTransferData(DataFlavor.stringFlavor); + } + systemClipboard.setContents(new StringSelection("SOURCE"), null); + } catch (IOException ioe) { + ioe.printStackTrace(); + if (!ioe.getMessage().equals("Owner failed to convert data")) { + throw new RuntimeException("Owner failed to convert data"); + } + } catch (IllegalStateException e) { + // IllegalStateExceptions do not indicate a bug in this case. + // They result from concurrent modification of system clipboard + // contents by the parent and child processes. + // These exceptions are numerous, so we avoid dumping their + // backtraces to prevent blocking child process io, which + // causes test failure on timeout. + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void dragDropEnd(DragSourceDropEvent dsde) { + System.exit(DnDClipboardDeadlockTest.CODE_OK); + } + + public void dropActionChanged(DragSourceDragEvent dsde) { + } +} + +class DragSourcePanel extends Panel { + + final Dimension preferredDimension = new Dimension(200, 200); + + public DragSourcePanel(Transferable t) { + setLayout(new GridLayout(1, 1)); + add(new DragSourceButton(t)); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } +} + +class DropTargetPanel extends Panel implements DropTargetListener { + + static final Clipboard systemClipboard = + Toolkit.getDefaultToolkit().getSystemClipboard(); + final Dimension preferredDimension = new Dimension(200, 200); + + public DropTargetPanel() { + setBackground(Color.green); + setDropTarget(new DropTarget(this, this)); + setLayout(new GridLayout(1, 1)); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragEnter(DropTargetDragEvent dtde) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + + public void dragExit(DropTargetEvent dte) { + } + + public void dragOver(DropTargetDragEvent dtde) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + try { + Transferable t = systemClipboard.getContents(null); + if (t.isDataFlavorSupported(DataFlavor.stringFlavor)) { + String str = (String) t.getTransferData(DataFlavor.stringFlavor); + } + systemClipboard.setContents(new StringSelection("TARGET"), null); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void drop(DropTargetDropEvent dtde) { + DropTargetContext dtc = dtde.getDropTargetContext(); + + if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY) != 0) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + } else { + dtde.rejectDrop(); + return; + } + + removeAll(); + final List list = new List(); + add(list); + + Transferable t = dtde.getTransferable(); + DataFlavor[] dfs = t.getTransferDataFlavors(); + + for (int i = 0; i < dfs.length; i++) { + + DataFlavor flavor = dfs[i]; + String str = null; + + if (DataFlavor.stringFlavor.equals(flavor)) { + try { + str = (String) t.getTransferData(flavor); + } catch (Exception e) { + e.printStackTrace(); + } + } + + list.add(str + ":" + flavor.getMimeType()); + } + + dtc.dropComplete(true); + validate(); + } + + public void dropActionChanged(DropTargetDragEvent dtde) { + } +} diff --git a/test/jdk/java/awt/dnd/DnDCursorCrashTest.java b/test/jdk/java/awt/dnd/DnDCursorCrashTest.java new file mode 100644 index 0000000000000..7b1f4483ef991 --- /dev/null +++ b/test/jdk/java/awt/dnd/DnDCursorCrashTest.java @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4343300 + * @summary tests that drag attempt doesn't cause crash when + * custom cursor is used + * @key headful + * @run main DnDCursorCrashTest + */ + +import java.awt.Button; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetContext; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +public class DnDCursorCrashTest { + static final Frame frame = new Frame(); + static final DragSourcePanel dragSourcePanel = new DragSourcePanel(); + static final DropTargetPanel dropTargetPanel = new DropTargetPanel(); + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame.setTitle("DnD Cursor Test Frame"); + frame.setLocation(200, 200); + frame.setLayout(new GridLayout(2, 1)); + frame.add(dragSourcePanel); + frame.add(dropTargetPanel); + frame.pack(); + frame.setVisible(true); + }); + + Robot robot = new Robot(); + robot.delay(1000); + robot.mouseMove(250, 250); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (int y = 250; y < 350; y += 5) { + robot.mouseMove(250, y); + robot.delay(100); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } +} + +class DragSourceButton extends Button implements Serializable, + Transferable, + DragGestureListener, + DragSourceListener { + private final DataFlavor dataflavor = + new DataFlavor(Button.class, "DragSourceButton"); + + public DragSourceButton() { + this("DragSourceButton"); + } + + public DragSourceButton(String str) { + super(str); + + DragSource ds = DragSource.getDefaultDragSource(); + ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, + this); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(new Cursor(Cursor.HAND_CURSOR), this, this); + } + + public void dragEnter(DragSourceDragEvent dsde) {} + + public void dragExit(DragSourceEvent dse) {} + + public void dragOver(DragSourceDragEvent dsde) {} + + public void dragDropEnd(DragSourceDropEvent dsde) {} + + public void dropActionChanged(DragSourceDragEvent dsde) {} + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, IOException { + + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } + + Object retObj; + + ByteArrayOutputStream baoStream = new ByteArrayOutputStream(); + ObjectOutputStream ooStream = new ObjectOutputStream(baoStream); + ooStream.writeObject(this); + + ByteArrayInputStream baiStream = new ByteArrayInputStream(baoStream.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(baiStream); + try { + retObj = ois.readObject(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + throw new RuntimeException(e.toString()); + } + + return retObj; + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { dataflavor }; + } + + public boolean isDataFlavorSupported(DataFlavor dflavor) { + return dataflavor.equals(dflavor); + } +} + +class DragSourcePanel extends Panel { + + final Dimension preferredDimension = new Dimension(200, 100); + + public DragSourcePanel() { + setLayout(new GridLayout(1, 1)); + add(new DragSourceButton()); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } +} + +class DropTargetPanel extends Panel implements DropTargetListener { + + final Dimension preferredDimension = new Dimension(200, 100); + + public DropTargetPanel() { + setDropTarget(new DropTarget(this, this)); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragEnter(DropTargetDragEvent dtde) {} + + public void dragExit(DropTargetEvent dte) {} + + public void dragOver(DropTargetDragEvent dtde) {} + + public void dropActionChanged(DropTargetDragEvent dtde) {} + + public void drop(DropTargetDropEvent dtde) { + DropTargetContext dtc = dtde.getDropTargetContext(); + + if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY) != 0) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + } else { + dtde.rejectDrop(); + } + + DataFlavor[] dfs = dtde.getCurrentDataFlavors(); + Component comp = null; + + if (dfs != null && dfs.length >= 1) { + Transferable transfer = dtde.getTransferable(); + + try { + comp = (Component)transfer.getTransferData(dfs[0]); + } catch (Throwable e) { + e.printStackTrace(); + dtc.dropComplete(false); + } + } + dtc.dropComplete(true); + + add(comp); + } +} diff --git a/test/jdk/java/awt/dnd/DnDRemoveFocusOwnerCrashTest.java b/test/jdk/java/awt/dnd/DnDRemoveFocusOwnerCrashTest.java new file mode 100644 index 0000000000000..27cf54e184558 --- /dev/null +++ b/test/jdk/java/awt/dnd/DnDRemoveFocusOwnerCrashTest.java @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4357905 + * @summary Tests that removal of the focus owner component during + * drop processing doesn't cause crash + * @key headful + * @run main DnDRemoveFocusOwnerCrashTest + */ + +import java.awt.Button; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetContext; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.io.Serializable; + +public class DnDRemoveFocusOwnerCrashTest { + public static final int FRAME_ACTIVATION_TIMEOUT = 1000; + public static Frame frame; + public static Robot robot; + public static DragSourceButton dragSourceButton; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + EventQueue.invokeAndWait(() -> { + frame = new Frame(); + dragSourceButton = new DragSourceButton(); + DropTargetPanel dropTargetPanel = + new DropTargetPanel(dragSourceButton); + frame.add(new Button("Test")); + frame.setTitle("Remove Focus Owner Test Frame"); + frame.setLocation(200, 200); + frame.add(dropTargetPanel); + frame.pack(); + frame.setVisible(true); + + try { + robot.delay(FRAME_ACTIVATION_TIMEOUT); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("The test failed."); + } + + Point p = dragSourceButton.getLocationOnScreen(); + p.translate(10, 10); + + try { + Robot robot = new Robot(); + robot.mouseMove(p.x, p.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (int dy = 0; dy < 50; dy++) { + robot.mouseMove(p.x, p.y + dy); + robot.delay(10); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("The test failed."); + } + }); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static class DragSourceButton extends Button implements Serializable, + Transferable, + DragGestureListener, + DragSourceListener { + + private static DataFlavor dataflavor; + + static { + try { + dataflavor = + new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType); + dataflavor.setHumanPresentableName("Local Object Flavor"); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + throw new ExceptionInInitializerError(); + } + } + + public DragSourceButton() { + this("DragSourceButton"); + } + + public DragSourceButton(String str) { + super(str); + + DragSource ds = DragSource.getDefaultDragSource(); + ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, + this); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, this, this); + } + + public void dragEnter(DragSourceDragEvent dsde) { + } + + public void dragExit(DragSourceEvent dse) { + } + + public void dragOver(DragSourceDragEvent dsde) { + } + + public void dragDropEnd(DragSourceDropEvent dsde) { + } + + public void dropActionChanged(DragSourceDragEvent dsde) { + } + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException { + + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } + + return this; + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[]{dataflavor}; + } + + public boolean isDataFlavorSupported(DataFlavor dflavor) { + return dataflavor.equals(dflavor); + } + } + + static class DropTargetPanel extends Panel implements DropTargetListener { + + public DropTargetPanel(DragSourceButton button) { + setLayout(new FlowLayout(FlowLayout.CENTER, 50, 50)); + add(button); + setDropTarget(new DropTarget(this, this)); + } + + public void dragEnter(DropTargetDragEvent dtde) { + } + + public void dragExit(DropTargetEvent dte) { + } + + public void dragOver(DropTargetDragEvent dtde) { + } + + public void dropActionChanged(DropTargetDragEvent dtde) { + } + + public void drop(DropTargetDropEvent dtde) { + removeAll(); + + DropTargetContext dtc = dtde.getDropTargetContext(); + + if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY) != 0) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + } else { + dtde.rejectDrop(); + } + + DataFlavor[] dfs = dtde.getCurrentDataFlavors(); + Component comp = null; + + if (dfs != null && dfs.length >= 1) { + Transferable transfer = dtde.getTransferable(); + + try { + comp = (Component) transfer.getTransferData(dfs[0]); + } catch (Throwable e) { + e.printStackTrace(); + dtc.dropComplete(false); + } + } + dtc.dropComplete(true); + + add(comp); + validate(); + } + } +} diff --git a/test/jdk/java/awt/dnd/DnDToWordpadTest.java b/test/jdk/java/awt/dnd/DnDToWordpadTest.java new file mode 100644 index 0000000000000..181a6ee873a85 --- /dev/null +++ b/test/jdk/java/awt/dnd/DnDToWordpadTest.java @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6362095 + * @summary Tests basic DnD functionality to a wordpad + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DnDToWordpadTest + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Panel; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.InvalidDnDOperationException; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; + +import javax.imageio.ImageIO; + +import static java.awt.image.BufferedImage.TYPE_INT_ARGB; + +public class DnDToWordpadTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + The test window contains a yellow button. Click on the button + to copy image into the clipboard or drag the image. + Paste or drop the image over Wordpad (when the mouse + enters the Wordpad during the drag, the application + should change the cursor to indicate that a copy operation is + about to happen; release the mouse button). + An image of a red rectangle should appear inside the document. + You should be able to repeat this operation multiple times. + Please, click "Pass" if above conditions are true, + otherwise click "Fail". + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(DnDToWordpadTest::createUI) + .build() + .awaitAndCheck(); + } + + public static Frame createUI() { + Frame f = new Frame("DnD To WordPad Test"); + Panel mainPanel; + Component dragSource; + + mainPanel = new Panel(); + mainPanel.setLayout(null); + + mainPanel.setBackground(Color.black); + try { + dragSource = new DnDSource("Drag ME!"); + mainPanel.add(dragSource); + f.add(mainPanel); + } catch (IOException e) { + e.printStackTrace(); + } + + f.setSize(200, 200); + return f; + } +} + +class DnDSource extends Button implements Transferable, + DragGestureListener, + DragSourceListener { + private DataFlavor m_df; + private transient int m_dropAction; + private Image m_img; + + DnDSource(String label) throws IOException { + super(label); + + setBackground(Color.yellow); + setForeground(Color.blue); + setSize(200, 120); + + m_df = DataFlavor.imageFlavor; + + DragSource dragSource = new DragSource(); + dragSource.createDefaultDragGestureRecognizer( + this, + DnDConstants.ACTION_COPY_OR_MOVE, + this + ); + dragSource.addDragSourceListener(this); + + // Create test gif image to drag + Path p = Path.of(System.getProperty("test.classes", ".")); + BufferedImage bImg = new BufferedImage(79, 109, TYPE_INT_ARGB); + Graphics2D cg = bImg.createGraphics(); + cg.setColor(Color.RED); + cg.fillRect(0, 0, 79, 109); + ImageIO.write(bImg, "png", new File(p + java.io.File.separator + + "DnDSource_Red.gif")); + + m_img = Toolkit.getDefaultToolkit() + .getImage(System.getProperty("test.classes", ".") + + java.io.File.separator + "DnDSource_Red.gif"); + + addActionListener( + ae -> Toolkit.getDefaultToolkit().getSystemClipboard().setContents( + (Transferable) DnDSource.this, + null + ) + ); + } + + public void paint(Graphics g) { + g.drawImage(m_img, 10, 10, null); + } + + /** + * a Drag gesture has been recognized + */ + + public void dragGestureRecognized(DragGestureEvent dge) { + System.err.println("starting Drag"); + try { + dge.startDrag(null, this, this); + } catch (InvalidDnDOperationException e) { + e.printStackTrace(); + } + } + + /** + * as the hotspot enters a platform dependent drop site + */ + + public void dragEnter(DragSourceDragEvent dsde) { + System.err.println("[Source] dragEnter"); + } + + /** + * as the hotspot moves over a platform dependent drop site + */ + + public void dragOver(DragSourceDragEvent dsde) { + System.err.println("[Source] dragOver"); + m_dropAction = dsde.getDropAction(); + System.out.println("m_dropAction = " + m_dropAction); + } + + /** + * as the operation changes + */ + + public void dragGestureChanged(DragSourceDragEvent dsde) { + System.err.println("[Source] dragGestureChanged"); + m_dropAction = dsde.getDropAction(); + System.out.println("m_dropAction = " + m_dropAction); + } + + /** + * as the hotspot exits a platform dependent drop site + */ + + public void dragExit(DragSourceEvent dsde) { + System.err.println("[Source] dragExit"); + } + + /** + * as the operation completes + */ + + public void dragDropEnd(DragSourceDropEvent dsde) { + System.err.println("[Source] dragDropEnd"); + } + + public void dropActionChanged(DragSourceDragEvent dsde) { + System.err.println("[Source] dropActionChanged"); + m_dropAction = dsde.getDropAction(); + System.out.println("m_dropAction = " + m_dropAction); + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[]{m_df}; + } + + public boolean isDataFlavorSupported(DataFlavor sdf) { + System.err.println("[Source] isDataFlavorSupported" + m_df.equals(sdf)); + return m_df.equals(sdf); + } + + public Object getTransferData(DataFlavor tdf) throws UnsupportedFlavorException { + if (!m_df.equals(tdf)) { + throw new UnsupportedFlavorException(tdf); + } + System.err.println("[Source] Ok"); + return m_img; + } +} diff --git a/test/jdk/java/awt/dnd/NonAsciiFilenames.java b/test/jdk/java/awt/dnd/NonAsciiFilenames.java new file mode 100644 index 0000000000000..b508350c05ef3 --- /dev/null +++ b/test/jdk/java/awt/dnd/NonAsciiFilenames.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4187490 + * @summary Verify that Non-ASCII file names can be dragged and dropped + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual NonAsciiFilenames + */ + +import java.awt.Color; +import java.awt.datatransfer.DataFlavor; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.io.File; +import java.util.AbstractList; + +import javax.swing.JFrame; +import javax.swing.JLabel; + +public class NonAsciiFilenames { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + This test must be run on an OS which does not use ISO 8859-1 + as its default encoding. + + Open a native file browsing application, such as Windows + Explorer. Try to find a file whose name uses non-ISO 8859-1 + characters. Create a file and name it such that it contains + non-ISO 8859-1 characters (For ex. é, à, ö, €, ¥). Drag + the file from the native application and drop it on the test + Frame. If the file name appears normally, then the test passes. + If boxes or question marks appear for characters, or if you see + the word "Error", then the test fails. + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(NonAsciiFilenames::createUI) + .build() + .awaitAndCheck(); + } + + public static JFrame createUI() { + JFrame frame = new JFrame(); + frame.setTitle("DropLabel test"); + frame.getContentPane().add(new DropLabel("Drop here")); + frame.setSize(300, 100); + return frame; + } +} + +class DropLabel extends JLabel implements DropTargetListener { + public DropLabel(String s) { + setText(s); + new DropTarget(this, DnDConstants.ACTION_COPY, this, true); + showDrop(false); + } + + private void showDrop(boolean b) { + setForeground(b ? Color.white : Color.black); + } + + /** + * Configure to desired flavor of dropped data. + */ + private DataFlavor getDesiredFlavor() { + return DataFlavor.javaFileListFlavor; + } + + /** + * Check to make sure that the contains the expected object types. + */ + private void checkDroppedData(Object data) { + System.out.println("Got data: " + data.getClass().getName()); + if (data instanceof AbstractList) { + AbstractList files = (AbstractList) data; + if (((File) files.get(0)).isFile()) + setText(((File) files.get(0)).toString()); + else + setText("Error: not valid file: " + + ((File) files.get(0)).toString()); + } else { + System.out.println("Error: wrong type of data dropped"); + } + } + + private boolean isDragOk(DropTargetDragEvent e) { + boolean canDrop = false; + try { + canDrop = e.isDataFlavorSupported(getDesiredFlavor()); + } catch (Exception ex) { + } + + if (canDrop) + e.acceptDrag(DnDConstants.ACTION_COPY); + else + e.rejectDrag(); + showDrop(canDrop); + return canDrop; + } + + public void dragEnter(DropTargetDragEvent e) { + isDragOk(e); + } + + + public void dragOver(DropTargetDragEvent e) { + isDragOk(e); + } + + public void dropActionChanged(DropTargetDragEvent e) { + isDragOk(e); + } + + public void dragExit(DropTargetEvent e) { + showDrop(false); + } + + public void drop(DropTargetDropEvent e) { + try { + e.acceptDrop(DnDConstants.ACTION_COPY); + checkDroppedData(e.getTransferable(). + getTransferData(getDesiredFlavor())); + } catch (Exception err) { + } + e.dropComplete(true); + showDrop(false); + } +} From f30379b277746223618e58c55099b66051064dfe Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 09:08:12 +0000 Subject: [PATCH 181/846] 8341072: Open source several AWT Canvas and Rectangle related tests Backport-of: f6fe5eaf1a24ba083e7ecf28b02290020ccab142 --- test/jdk/java/awt/Canvas/MultiDitherTest.java | 422 ++++++++++++++++++ .../java/awt/Canvas/MultiGraphicsTest.java | 139 ++++++ .../jdk/java/awt/Canvas/NoEventsLeakTest.java | 96 ++++ test/jdk/java/awt/Canvas/duke_404.gif | Bin 0 -> 5529 bytes .../java/awt/Rectangle/IntersectionTest.java | 88 ++++ 5 files changed, 745 insertions(+) create mode 100644 test/jdk/java/awt/Canvas/MultiDitherTest.java create mode 100644 test/jdk/java/awt/Canvas/MultiGraphicsTest.java create mode 100644 test/jdk/java/awt/Canvas/NoEventsLeakTest.java create mode 100644 test/jdk/java/awt/Canvas/duke_404.gif create mode 100644 test/jdk/java/awt/Rectangle/IntersectionTest.java diff --git a/test/jdk/java/awt/Canvas/MultiDitherTest.java b/test/jdk/java/awt/Canvas/MultiDitherTest.java new file mode 100644 index 0000000000000..ab592280c80b4 --- /dev/null +++ b/test/jdk/java/awt/Canvas/MultiDitherTest.java @@ -0,0 +1,422 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6616089 + * @summary Displays a dithered Canvas on all available GraphicsConfigurations + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MultiDitherTest + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Canvas; +import java.awt.Choice; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Label; +import java.awt.LayoutManager; +import java.awt.Panel; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.ColorModel; +import java.awt.image.MemoryImageSource; +import java.util.List; + +public class MultiDitherTest extends Panel implements Runnable { + final static int NOOP = 0; + final static int RED = 1; + final static int GREEN = 2; + final static int BLUE = 3; + final static int ALPHA = 4; + final static int SATURATION = 5; + final static String calcString = "Calculating..."; + static LayoutManager dcLayout = new FlowLayout(FlowLayout.CENTER, 10, 5); + Thread runner; + DitherControls XControls; + DitherControls YControls; + DitherCanvas canvas; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Depending on the GraphicsConfiguration, the dithering may be in + color or in grayscale and/or display at a lower bitdepth. + The number of GraphicsConfigurations will be printed in the + TextArea below as the test is starting up. + Ensure that there are as many Frames created as there are + available GraphicsConfigurations. + Examine each Frame to ensure it displays the dither pattern. + If all Canvases display correctly, the test PASSES. + Otherwise, the test FAILS. + The GC button runs the garbage collector. + This button can be ignored for now. + + """; + PassFailJFrame passFailJFrame = PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .build(); + + EventQueue.invokeAndWait(() -> { + for (Frame frame : MultiDitherTest.initialize()) { + PassFailJFrame.addTestWindow(frame); + frame.setVisible(true); + } + }); + passFailJFrame.awaitAndCheck(); + } + + public MultiDitherTest(GraphicsConfiguration gc) { + String xSpec, ySpec; + int[] xValues = new int[2]; + int[] yValues = new int[2]; + + xSpec = "red"; + ySpec = "blue"; + int xMethod = colorMethod(xSpec, xValues); + int yMethod = colorMethod(ySpec, yValues); + + setLayout(new BorderLayout()); + XControls = new DitherControls(this, xValues[0], xValues[1], + xMethod, false); + YControls = new DitherControls(this, yValues[0], yValues[1], + yMethod, true); + YControls.addRenderButton(); + YControls.addGCButton(); + add("North", XControls); + add("South", YControls); + add("Center", canvas = new DitherCanvas(gc)); + } + + private static List initialize() { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] gds = ge.getScreenDevices(); + Frame[] frames = new Frame[0]; + System.out.println(gds.length + " screens detected"); + + for (int j = 0; j < gds.length; j++) { + + GraphicsDevice gd = gds[j]; + GraphicsConfiguration[] gcs = gd.getConfigurations(); + frames = new Frame[gcs.length]; + System.out.println(gcs.length + " GraphicsConfigurations available on screen " + j); + for (int i = 0; i < gcs.length; i++) { + Frame f = new Frame("MultiDitherTest " + (i + 1), gcs[i]); + f.setLayout(new BorderLayout()); + f.setLocation(gcs[i].getBounds().x + 100 + (i * 10), + gcs[i].getBounds().y + 100 + (i * 10)); + MultiDitherTest ditherTest = new MultiDitherTest(gcs[i]); + f.add("Center", ditherTest); + f.pack(); + f.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent ev) { + ev.getWindow().dispose(); + } + }); + f.setVisible(true); + ditherTest.start(); + frames[i] = f; + } + + } + return List.of(frames); + } + + int colorMethod(String s, int[] values) { + int method = NOOP; + + if (s == null) { + s = ""; + } + + String lower = s.toLowerCase(); + if (lower.startsWith("red")) { + method = RED; + lower = lower.substring(3); + } else if (lower.startsWith("green")) { + method = GREEN; + lower = lower.substring(5); + } else if (lower.startsWith("blue")) { + method = BLUE; + lower = lower.substring(4); + } else if (lower.startsWith("alpha")) { + method = ALPHA; + lower = lower.substring(4); + } else if (lower.startsWith("saturation")) { + method = SATURATION; + lower = lower.substring(10); + } + + if (method == NOOP) { + values[0] = 0; + values[1] = 0; + return method; + } + + int begval = 0; + int endval = 255; + + try { + int dash = lower.indexOf('-'); + if (dash < 0) { + begval = endval = Integer.parseInt(lower); + } else { + begval = Integer.parseInt(lower.substring(0, dash)); + endval = Integer.parseInt(lower.substring(dash + 1)); + } + } catch (Exception e) { + } + + if (begval < 0) { + begval = 0; + } + if (endval < 0) { + endval = 0; + } + if (begval > 255) { + begval = 255; + } + if (endval > 255) { + endval = 255; + } + + values[0] = begval; + values[1] = endval; + + return method; + } + + public void start() { + runner = new Thread(this); + runner.start(); + } + + public void stop() { + runner = null; + } + + public void destroy() { + remove(XControls); + remove(YControls); + remove(canvas); + } + + void applyMethod(int[] c, int method, int step, int total, int[] values) { + if (method == NOOP) { + return; + } + int val = ((total < 2) + ? values[0] + : values[0] + ((values[1] - values[0]) * step / (total - 1))); + switch (method) { + case RED: + c[0] = val; + break; + case GREEN: + c[1] = val; + break; + case BLUE: + c[2] = val; + break; + case ALPHA: + c[3] = val; + break; + case SATURATION: + int max = Math.max(Math.max(c[0], c[1]), c[2]); + int min = max * (255 - val) / 255; + if (c[0] == 0) c[0] = min; + if (c[1] == 0) c[1] = min; + if (c[2] == 0) c[2] = min; + break; + } + } + + public void run() { + canvas.setImage(null); + Image img = calculateImage(); + synchronized (this) { + if (img != null && runner == Thread.currentThread()) { + canvas.setImage(img); + } + } + } + + /** + * Calculates and returns the image. Halts the calculation and returns + * null if the Application is stopped during the calculation. + */ + Image calculateImage() { + Thread me = Thread.currentThread(); + + int width = canvas.getSize().width; + int height = canvas.getSize().height; + int[] xValues = new int[2]; + int[] yValues = new int[2]; + int xMethod = XControls.getParams(xValues); + int yMethod = YControls.getParams(yValues); + int[] pixels = new int[width * height]; + int[] c = new int[4]; + int index = 0; + + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + c[0] = c[1] = c[2] = 0; + c[3] = 255; + if (xMethod < yMethod) { + applyMethod(c, xMethod, i, width, xValues); + applyMethod(c, yMethod, j, height, yValues); + } else { + applyMethod(c, yMethod, j, height, yValues); + applyMethod(c, xMethod, i, width, xValues); + } + pixels[index++] = ((c[3] << 24) | + (c[0] << 16) | + (c[1] << 8) | + (c[2] << 0)); + } + // Poll once per row to see if we've been told to stop. + if (runner != me) { + return null; + } + } + + return createImage(new MemoryImageSource(width, height, + ColorModel.getRGBdefault(), pixels, 0, width)); + } + + static class DitherCanvas extends Canvas { + Image img; + GraphicsConfiguration mGC; + + public DitherCanvas(GraphicsConfiguration gc) { + super(gc); + mGC = gc; + } + + public GraphicsConfiguration getGraphicsConfig() { + return mGC; + } + + public void paint(Graphics g) { + int w = getSize().width; + int h = getSize().height; + if (img == null) { + super.paint(g); + g.setColor(Color.black); + FontMetrics fm = g.getFontMetrics(); + int x = (w - fm.stringWidth(calcString)) / 2; + int y = h / 2; + g.drawString(calcString, x, y); + } else { + g.drawImage(img, 0, 0, w, h, this); + } + } + + public void update(Graphics g) { + paint(g); + } + + public Dimension getMinimumSize() { + return new Dimension(20, 20); + } + + public Dimension getPreferredSize() { + return new Dimension(200, 200); + } + + public Image getImage() { + return img; + } + + public void setImage(Image img) { + this.img = img; + paint(getGraphics()); + } + } + + static class DitherControls extends Panel implements ActionListener { + TextField start; + TextField end; + Button button; + Choice choice; + MultiDitherTest panel; + Button gc; + + public DitherControls(MultiDitherTest app, int s, int e, int type, + boolean vertical) { + panel = app; + setLayout(dcLayout); + add(new Label(vertical ? "Vertical" : "Horizontal")); + add(choice = new Choice()); + choice.addItem("Noop"); + choice.addItem("Red"); + choice.addItem("Green"); + choice.addItem("Blue"); + choice.addItem("Alpha"); + choice.addItem("Saturation"); + choice.select(type); + add(start = new TextField(Integer.toString(s), 4)); + add(end = new TextField(Integer.toString(e), 4)); + } + + public void addRenderButton() { + add(button = new Button("New Image")); + button.addActionListener(this); + } + + public void addGCButton() { + add(gc = new Button("GC")); + gc.addActionListener(this); + } + + public int getParams(int[] values) { + values[0] = Integer.parseInt(start.getText()); + values[1] = Integer.parseInt(end.getText()); + return choice.getSelectedIndex(); + } + + public void actionPerformed(ActionEvent e) { + if (e.getSource() == button) { + panel.start(); + } else if (e.getSource() == gc) { + System.gc(); + } + } + } +} \ No newline at end of file diff --git a/test/jdk/java/awt/Canvas/MultiGraphicsTest.java b/test/jdk/java/awt/Canvas/MultiGraphicsTest.java new file mode 100644 index 0000000000000..c38d6041c2b77 --- /dev/null +++ b/test/jdk/java/awt/Canvas/MultiGraphicsTest.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6616089 + * @summary Display an image in all available GraphicsConfigurations + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MultiGraphicsTest + */ + +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.MediaTracker; +import java.awt.Toolkit; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.net.URL; +import java.util.List; + +public class MultiGraphicsTest extends Canvas { + final static String IMAGEFILE = "duke_404.gif"; + static Image jim; + MediaTracker tracker; + int w, h; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + This test displays several Windows containing an image, + one Window for each available GraphicsConfiguration. + Depending on the GraphicsConfiguration, images may be + displayed in color or in grayscale and/or displayed at a + lower bitdepth. + The number of GraphicsConfigurations will be printed below + as the test is starting up. + Ensure that there are as many Windows created as there are + available GraphicsConfigurations. + Examine each Window to ensure it displays Duke_404. + If all Canvases display correctly, the test PASSES. + Otherwise, the test FAILS." + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .build() + .awaitAndCheck(); + } + + public MultiGraphicsTest(GraphicsConfiguration gc) { + super(gc); + tracker = new MediaTracker(this); + tracker.addImage(jim, 0); + try { + tracker.waitForAll(); + } catch (java.lang.InterruptedException e) { + System.err.println(e); + } + w = jim.getWidth(this); + h = jim.getHeight(this); + } + + private static List initialize() { + URL imgURL; + imgURL = MultiGraphicsTest.class.getResource(IMAGEFILE); + if (imgURL == null) { + System.err.println("Unable to locate " + IMAGEFILE); + return null; + } + jim = Toolkit.getDefaultToolkit().getImage(imgURL); + + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + GraphicsConfiguration[] gc = gd.getConfigurations(); + Frame[] frames = new Frame[gc.length]; + System.out.println(gc.length + " available GraphicsConfigurations"); + for (int i = 0; i < gc.length; i++) { + Frame f = new Frame("GraphicsTest " + (i + 1)); + f.setLayout(new BorderLayout()); + f.setLocation(100 + (i * 10), 100 + (i * 10)); + MultiGraphicsTest gcTest = new MultiGraphicsTest(gc[i]); + f.add("Center", gcTest); + f.pack(); + f.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent ev) { + ev.getWindow().setVisible(false); + } + }); + frames[i] = f; + } + return List.of(frames); + } + + public void paint(Graphics g) { + g.drawImage(jim, 0, 0, w, h, this); + } + + public void update(Graphics g) { + paint(g); + } + + public Dimension getMinimumSize() { + return new Dimension(w, h); + } + + public Dimension getPreferredSize() { + return new Dimension(w, h); + } +} diff --git a/test/jdk/java/awt/Canvas/NoEventsLeakTest.java b/test/jdk/java/awt/Canvas/NoEventsLeakTest.java new file mode 100644 index 0000000000000..4768775224a58 --- /dev/null +++ b/test/jdk/java/awt/Canvas/NoEventsLeakTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4250354 + * @key headful + * @summary tests that JNI global refs are cleaned up correctly + * @run main/timeout=600 NoEventsLeakTest + */ + +import java.awt.Canvas; +import java.awt.EventQueue; +import java.awt.Frame; + +public class NoEventsLeakTest extends Frame { + static final int nLoopCount = 1000; + + private static void initialize() { + NoEventsLeakTest app = new NoEventsLeakTest(); + boolean result = app.run(); + if (result) { + throw new RuntimeException("Memory leak in Component"); + } + System.out.println("Test Passed"); + } + + public boolean run() { + setSize(10, 10); + addNotify(); + for (int i = 0; i < nLoopCount; i++) { + Canvas panel = new TestCanvas(); + add(panel, 0); + remove(0); + panel = null; + System.gc(); + } + try { + Thread.currentThread().sleep(1000); + } catch (InterruptedException e) { + } + System.gc(); + System.out.println("Checking"); + return ((TestCanvas.created - TestCanvas.finalized) > 800); + } + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(NoEventsLeakTest::initialize); + } +} + +class TestCanvas extends Canvas { + static int finalized = 0; + static int created = 0; + static final int nLoopPrint = 100; + + public TestCanvas() { + if (created % nLoopPrint == 0) { + System.out.println("Created " + getClass() + " " + created); + } + created++; + } + + @SuppressWarnings("removal") + protected void finalize() { + try { + super.finalize(); + if (finalized % nLoopPrint == 0) { + System.out.println("Finalized " + getClass() + " " + finalized); + } + finalized++; + } catch (Throwable t) { + System.out.println("Exception in " + getClass() + ": " + t); + } + } +} diff --git a/test/jdk/java/awt/Canvas/duke_404.gif b/test/jdk/java/awt/Canvas/duke_404.gif new file mode 100644 index 0000000000000000000000000000000000000000..4958e0d0dfa8c059b704e11fe173f23091cfe8fd GIT binary patch literal 5529 zcmWmB`6JVh5C@(K>XYx)-NeKppymWcs``g#**;)0yd+MuK)!p5{PMlCzR{ly){}mMUpS3jw zj<7@$L$!=D39JB&)-MX>2O6DdA6vi5yNF;eC0d-(GkrBNH(GV!H(q%I(VDRezO1Pk zvMr(RxcvFV-E*6A#x+U3+PY#2L9JHzrk`qI?@H6r?z(ub%-DR7IeYQdRC-#lj7*te z+XndA^hnN~bK#a3*`(}XrELkm-GBYBd7m$DSjh>5+R%u_?rwh@tJX%dZ*O!D9Jo=@D5?H5F6e(Ab2* z)t)>hZ$9190>Jd(a6OPL#vSXyXuv9IJ!nGf;O|$jozZR}ftTvhU_?vtJg3Ln1+T%YV{8ZFxSjM z?*qtir%~zny4-q(MzEb>DV}C;n>yS6@m5*j16|__c^^2XTE^i$%SXIR$Lf7T>S(Ze zj+acIOz#jFd2@6bREXCmTDSrRBgNrjxLeq` zodjEYZ`l7RQejg|kP|RYQa{T&%N+L9kPIa%b56Gk8e)!uEZfXY+j}|S5aQ~=4>-B8 zrLZr7vJ8@hULpw~S#NhrA$KXlQrOBEBj-nDr}g5$(LRh+7OXe7;v5I$q6CcCqzm^V zuaJxkdYtg&VeSp}quu|F9s~ER_@0WB+9U=5bB=HXH&I>=QwH&b zt3$YRezbVIW*RHIXUI=4v~?&@H{Ix|AN5j-%#T`rNvnh$o8K#<65LdYh`q13{0S0@ z=x@yF9yL04ZHl+_YijKF4!KQY-fnJmz zT3@Q@f3OKw9~BiiUINY}JsZ{8{ci5vn$Qc6Zs}&$t{YvG=_U;Tb#IzM2tECj2OTHr z{Is~e{tTFG5RmTyz9cci&bPkbSa!ob7x(=7j$d-+$PYh@-r*DA&NMXw{z_0%fyb=e z);r`RNF0f*OZ)q7rA5gQk`zs?t}-39$TEuRdz5K`PL%SQdi+cw%JreeCq9|aU{x{b z-uG;siSM%O;`)xk&Q_4hA}2QQOwY8}8TM{@%sbP%%OIr}=HpujYwhxXVhC0MOhUB1 z1E5HGc}Kr4Tep`erpw%-w|Fq6aDTkkC^bEycF%Ph4{DYWSPi%14*d$o zQ*}eyj}(LYYi6i4UByq0b0ks?NK+jLm3R3?&`}q*%9B&MNUj~f6KatsZjrRufQ%Ekp|%O+hX`vAp-j4)gAI~s_#g= zlN}E>kCel7ifjj5xNv{EnlPtwC{M`v}?z26y3(J8h8M3UlWR^#@L5kT9`}_aPBv*a68=oS_cn5zAE}T^X#uk7(>T&;cs@`X7BvTNUojZ$Udf470lMx>$qj6TpfS&rQVDYW5ZQ}f%1 zZufHn)cgIXFXQdJbG}l%$a@utH8)l3Y%m|UUgx7M8Ht2s?3#D>SX@m-x|*^Epd&bi^x;RlVcd-(DhP+oPiz2k@gYI>5BinIDCD!Kbxb6>FnT6}QwgvVZR76z@!c`5p&|2d+YC zA+v(s^4W9VS>@Z#*irW_1;b){VWRLmPRuqIa^Ul25nMIu6aBtVXGU7gMx@<4&~e%N zc5&lzFF2s5fPmhMWw_-A@3iBiAXp3oejG}cW*`ojXrx}IjN#RAh= zP%!JbjtW_P?8A3wXN=mib8}N`eWAaNHm^U*DwCRP!Gc@!{Ie&_eq;tNg&)KUfHWZJ zxe+=W3VJF7(-gXYGSRR4cJ=ZR>5$bD8GLG^w(ztKTuI1(rm}_sj-5=5%~CkZNyKdk zy>Egcs5l?(_I@B+H`Vg=Wz$BSCM^c+HV=!1t$l2b5lnZYwP#6gBirz1CX~&^{1W3bPp{^; zZg#==y<-MLr#I@JK?X=sVSrgW8@+Z5+K>x;6of2FB0lxy)Whj{7fR1MMY|`^L|@A< zL{wbLuNX)sy47aik^}qeE3Bu&XZRY5h^<@+!F2(<5>jdV&!)G^4TK(B%fgK#8Sx)p zRosiP1yp$%EkHH~a6WqANrc)ECJo4HHLuKojr0(AT;}+nUH8(|&V-6bjbeyx*e#T5 zdwAfCltm?JM%m{clN$V>IlQ#ZXnK?L3}~YSaj*$KH)7 z5oKvMEx?k?>OigNSZw7%N}Wf4?wPau#SM|i&S?HrYW~N7-?&&8^Q7+bOs(Jw7R`eN z6vR&*)ijBZGFGY^s-8qu{R2A~8GFmAy1@prRKl%R;A~QYK{&#i)MU*_|Mf}MQPc2k zN0fPnQ^iQsb$fnGPQ@O71FR5n+6Uv(gUIK&v=+E<9imusnw^a??hIG`wy3L=#)IGM z2WDh{L4dXhL(z&K*GBx4gWV7w*QtG6l7-+8#ds?bzkhC0P@=y;6*ayF-<>eFBo}Q~ zY62XV)9CPBNH!mjo3&rVl_J+EqpC+-o#T;TMSy!oxzA;yxzyQKY0e|Ltb9IcFN8CK z;~J-6vnfu`jFHcbUHw%}_Q5Chd3dKg0vuqXt1@V0`1eXgbW&=eOCN?& zb=-@Z6L0++dv_VDKZkGXAVnFy3XGEW7ki^6VjzW$$^salw5?DK&H+5o{@WEPQK+dv>i5(j$!X!XzjY@rAAjU_2$Gtn7k`SiYk_YkwD>x zIyyz}JM33q162LG301FHbT5zGSZb zo$HiqK>oxX1M;LO#!A&!hFCY=d!l+sk-@T&gn+X!9WL%$p^ASia7%Cp*XJ^jg#Q znn@|biYctfwta9#<3M6cWTl}lAnR2C)H~FmzFXxgAO%7PNx{TQH%mBOtaJP9GXi=q zz9g~$-cKX}CVGkhceuIeYi{7MZE_$6zXF`p0|XYv9G)=}>YY^rqfK1hBo16k;00-5MRWjpf;fG+r>?NAwv^M;Gx9GhoNzpdJuV^T?+t~HsQ-8Y_&cvZi{~`D)gT0UtDouh{5ndipo&jtkf%#H&0S|1=qmF#FUgIPw6XbD(_op*PP1o1H z%V)p;@kgH!X1^b!b`znw560%ud*{$32y%!~G)*TJYxB(N znZV4EJC*t7EuZeldF%7uVwC%b-mwK~*%O7*iHpO9Aq^yLlABtDdNmq|0R!V~@&?ihAZvdJdw1YQKATa(nsUQc`9{b$--d_HAzOBCkG`p1T8bsS%6+71j_ATNU1(tg$`_jZOSY{9xYXl zTSLj#aT?e{sGw97Rh!M^6w3xUGkG}&u7O}!6)7o zr^}IkRwixv#2@4r_n;Y&W|A4=U+-gs4Ye7SJ=|W;Dqig$e^TW!fN2*~b@$ldT+A}MGZGsZmfQ_|D~8#(H~=> zf$llYH2-$NDleu?$9TCY7X9@sQkT8>H2Hz2Q|USP!w-ih|8*+uh~6HnLPyt<8 literal 0 HcmV?d00001 diff --git a/test/jdk/java/awt/Rectangle/IntersectionTest.java b/test/jdk/java/awt/Rectangle/IntersectionTest.java new file mode 100644 index 0000000000000..41680b2e7b6b1 --- /dev/null +++ b/test/jdk/java/awt/Rectangle/IntersectionTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4147957 + * @key headful + * @summary Test to verify setClip with invalid rect changes rect to valid + * @run main IntersectionTest + */ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.Rectangle; +import java.awt.Robot; + +public class IntersectionTest { + public static Frame frame; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + try { + robot.setAutoDelay(100); + EventQueue.invokeAndWait(() -> { + TestFrame panel = new TestFrame(); + frame = new Frame("Rectangle Intersection Test"); + frame.add(panel); + + frame.pack(); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(200); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} + +class TestFrame extends Panel { + @Override + public void paint(Graphics g) { + Rectangle r1 = new Rectangle(0, 0, 100, 100); + Rectangle r2 = new Rectangle(200, 200, 20, 20); + Rectangle r3 = r1.intersection(r2); + System.out.println("intersect:(" + (int) r3.getX() + "," + + (int) r3.getY() + "," + (int) r3.getWidth() + "," + + (int) r3.getHeight() + ")"); + g.setClip(r3); + Rectangle r4 = g.getClipBounds(); + System.out.println("getClipBounds:(" + (int) r4.getX() + "," + + (int) r4.getY() + "," + (int) r4.getWidth() + "," + + (int) r4.getHeight() + ")"); + + if ((r4.getWidth() <= 0) || (r4.getHeight() <= 0)) { + System.out.println("Test Passed"); + } else { + throw new RuntimeException("IntersectionTest failed. " + + "Non-empty clip bounds."); + } + } +} From 1f039fe2044edbd09d62914bc99e01facfc453c4 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 11 Apr 2025 13:21:52 +0000 Subject: [PATCH 182/846] 8344361: Restore null return for invalid services from legacy providers Backport-of: e20bd018c4046870d0cf632bb8e5440cb9f5c3c2 --- .../share/classes/java/security/Provider.java | 1 + .../security/Provider/InvalidServiceTest.java | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 test/jdk/java/security/Provider/InvalidServiceTest.java diff --git a/src/java.base/share/classes/java/security/Provider.java b/src/java.base/share/classes/java/security/Provider.java index 72ddb41257896..65781da8c50e7 100644 --- a/src/java.base/share/classes/java/security/Provider.java +++ b/src/java.base/share/classes/java/security/Provider.java @@ -1288,6 +1288,7 @@ public Service getService(String type, String algorithm) { s = legacyMap.get(key); if (s != null && !s.isValid()) { legacyMap.remove(key, s); + return null; } } diff --git a/test/jdk/java/security/Provider/InvalidServiceTest.java b/test/jdk/java/security/Provider/InvalidServiceTest.java new file mode 100644 index 0000000000000..fd56e6b3286da --- /dev/null +++ b/test/jdk/java/security/Provider/InvalidServiceTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025, 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 8344361 + * @summary Restore null return for invalid services + */ + +import java.security.Provider; + +public class InvalidServiceTest { + + public static void main(String[] args) throws Exception { + Provider p1 = new LProvider("LegacyFormat"); + // this returns a service with null class name. Helps exercise the code path + Provider.Service s1 = p1.getService("MessageDigest", "SHA-1"); + if (s1 != null) + throw new RuntimeException("expecting null service"); + } + + private static class LProvider extends Provider { + LProvider(String name) { + super(name, "1.0", null); + put("Signature.MD5withRSA", "com.foo.Sig"); + put("MessageDigest.SHA-1 ImplementedIn", "Software"); + } + } +} From 07b580bf22f6e557dbced9e40346ff8dbb96c1dd Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Tue, 15 Apr 2025 09:04:54 +0000 Subject: [PATCH 183/846] 8353709: Debug symbols bundle should contain full debug files when building --with-external-symbols-in-bundles=public Backport-of: bc441e39dbcbc9114dfb8cf7da06b65ff5b7a5bb --- make/Bundles.gmk | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/make/Bundles.gmk b/make/Bundles.gmk index 9dc5f9602d5fe..904b371c706ce 100644 --- a/make/Bundles.gmk +++ b/make/Bundles.gmk @@ -242,7 +242,10 @@ ifneq ($(filter product-bundles% legacy-bundles, $(MAKECMDGOALS)), ) ) JDK_SYMBOLS_BUNDLE_FILES := \ - $(call FindFiles, $(SYMBOLS_IMAGE_DIR)) + $(filter-out \ + %.stripped.pdb, \ + $(call FindFiles, $(SYMBOLS_IMAGE_DIR)) \ + ) TEST_DEMOS_BUNDLE_FILES := $(filter $(JDK_DEMOS_IMAGE_HOMEDIR)/demo/%, \ $(ALL_JDK_DEMOS_FILES)) From 3dbeb83ce2b380cab9a6f66d1962ab4f01efb554 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 15 Apr 2025 09:14:28 +0000 Subject: [PATCH 184/846] 8314320: Mark runtime/CommandLine/ tests as flagless Backport-of: f481477144d25bf2b5ee44f202705588bd99d4f4 --- .../CommandLine/BooleanFlagWithInvalidValue.java | 3 ++- .../CommandLine/CompilerConfigFileWarning.java | 1 + .../jtreg/runtime/CommandLine/ConfigFileParsing.java | 3 ++- .../jtreg/runtime/CommandLine/ConfigFileWarning.java | 3 ++- .../CommandLine/DoubleFlagWithIntegerValue.java | 3 ++- .../runtime/CommandLine/FlagWithInvalidValue.java | 3 ++- .../CommandLine/IgnoreUnrecognizedVMOptions.java | 4 ++-- .../NonBooleanFlagWithInvalidBooleanPrefix.java | 3 ++- .../CommandLine/ObsoleteFlagErrorMessage.java | 3 ++- .../OptionsValidation/TestJcmdOutput.java | 3 ++- .../OptionsValidation/TestOptionsWithRanges.java | 12 +++++++++++- .../TestOptionsWithRangesDynamic.java | 3 ++- .../TestOptionsWithRanges_generate.sh | 5 +++-- .../jtreg/runtime/CommandLine/TestHexArguments.java | 3 ++- .../CommandLine/TestLongUnrecognizedVMOption.java | 3 ++- .../runtime/CommandLine/TestNullTerminatedFlags.java | 4 ++-- .../jtreg/runtime/CommandLine/TestVMOptions.java | 3 ++- .../runtime/CommandLine/TraceExceptionsTest.java | 3 ++- .../runtime/CommandLine/UnrecognizedVMOption.java | 3 ++- .../jtreg/runtime/CommandLine/VMAliasOptions.java | 3 ++- .../runtime/CommandLine/VMDeprecatedOptions.java | 3 ++- .../jtreg/runtime/CommandLine/VMOptionWarning.java | 3 ++- .../CommandLine/VMOptionsFile/TestVMOptionsFile.java | 3 ++- 23 files changed, 55 insertions(+), 25 deletions(-) diff --git a/test/hotspot/jtreg/runtime/CommandLine/BooleanFlagWithInvalidValue.java b/test/hotspot/jtreg/runtime/CommandLine/BooleanFlagWithInvalidValue.java index f57ca7299800b..1ca819497fa6e 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/BooleanFlagWithInvalidValue.java +++ b/test/hotspot/jtreg/runtime/CommandLine/BooleanFlagWithInvalidValue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,6 +25,7 @@ * @test * @bug 8006298 * @summary Setting an invalid value for a bool argument should result in a useful error message + * @requires vm.flagless * @library /test/lib * @modules java.base/jdk.internal.misc * java.management diff --git a/test/hotspot/jtreg/runtime/CommandLine/CompilerConfigFileWarning.java b/test/hotspot/jtreg/runtime/CommandLine/CompilerConfigFileWarning.java index 0917832aef0f5..6b40dc0a35775 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/CompilerConfigFileWarning.java +++ b/test/hotspot/jtreg/runtime/CommandLine/CompilerConfigFileWarning.java @@ -25,6 +25,7 @@ * @test * @bug 7167142 * @summary Warn if unused .hotspot_compiler file is present + * @requires vm.flagless * @library /test/lib * @modules java.base/jdk.internal.misc * java.management diff --git a/test/hotspot/jtreg/runtime/CommandLine/ConfigFileParsing.java b/test/hotspot/jtreg/runtime/CommandLine/ConfigFileParsing.java index 218fd2ce1feff..4f31b210da1ec 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/ConfigFileParsing.java +++ b/test/hotspot/jtreg/runtime/CommandLine/ConfigFileParsing.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,6 +25,7 @@ * @test ConfigFileParsing * @bug 7158804 * @summary Improve config file parsing + * @requires vm.flagless * @library /test/lib * @modules java.base/jdk.internal.misc * java.management diff --git a/test/hotspot/jtreg/runtime/CommandLine/ConfigFileWarning.java b/test/hotspot/jtreg/runtime/CommandLine/ConfigFileWarning.java index df643b13d64e5..d9e72fa300adf 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/ConfigFileWarning.java +++ b/test/hotspot/jtreg/runtime/CommandLine/ConfigFileWarning.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,6 +25,7 @@ * @test * @bug 7167142 * @summary Warn if unused .hotspot_rc file is present + * @requires vm.flagless * @library /test/lib * @modules java.base/jdk.internal.misc * java.management diff --git a/test/hotspot/jtreg/runtime/CommandLine/DoubleFlagWithIntegerValue.java b/test/hotspot/jtreg/runtime/CommandLine/DoubleFlagWithIntegerValue.java index 69dd553e8b97e..6ed785fe0fc44 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/DoubleFlagWithIntegerValue.java +++ b/test/hotspot/jtreg/runtime/CommandLine/DoubleFlagWithIntegerValue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -25,6 +25,7 @@ * @test DoubleFlagWithIntegerValue * @bug 8178364 * @summary Command-line flags of type double should accept integer values + * @requires vm.flagless * @library /test/lib * @modules java.base/jdk.internal.misc * java.management diff --git a/test/hotspot/jtreg/runtime/CommandLine/FlagWithInvalidValue.java b/test/hotspot/jtreg/runtime/CommandLine/FlagWithInvalidValue.java index 175cefcad6a98..c16a05a79a845 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/FlagWithInvalidValue.java +++ b/test/hotspot/jtreg/runtime/CommandLine/FlagWithInvalidValue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,6 +25,7 @@ * @test * @bug 8006298 * @summary Setting a flag to an invalid value should print a useful error message + * @requires vm.flagless * @library /test/lib * @modules java.base/jdk.internal.misc * java.management diff --git a/test/hotspot/jtreg/runtime/CommandLine/IgnoreUnrecognizedVMOptions.java b/test/hotspot/jtreg/runtime/CommandLine/IgnoreUnrecognizedVMOptions.java index 727fb1bd0a19a..4a5a4f7127b2c 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/IgnoreUnrecognizedVMOptions.java +++ b/test/hotspot/jtreg/runtime/CommandLine/IgnoreUnrecognizedVMOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -29,7 +29,7 @@ * @test * @bug 8129855 * @summary -XX:+IgnoreUnrecognizedVMOptions should work according to the spec from JDK-8129855 - * + * @requires vm.flagless * @library /test/lib * @modules java.base/jdk.internal.misc * java.management diff --git a/test/hotspot/jtreg/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java b/test/hotspot/jtreg/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java index a6aca1ebf0eae..5ea305431b0b9 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java +++ b/test/hotspot/jtreg/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,6 +25,7 @@ * @test * @bug 8006298 * @summary Using a bool (+/-) prefix on non-bool flag should result in a useful error message + * @requires vm.flagless * @library /test/lib * @modules java.base/jdk.internal.misc * java.management diff --git a/test/hotspot/jtreg/runtime/CommandLine/ObsoleteFlagErrorMessage.java b/test/hotspot/jtreg/runtime/CommandLine/ObsoleteFlagErrorMessage.java index 5f697bdeb44b9..1dc1cd9976b1d 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/ObsoleteFlagErrorMessage.java +++ b/test/hotspot/jtreg/runtime/CommandLine/ObsoleteFlagErrorMessage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -28,6 +28,7 @@ * @modules java.base/jdk.internal.misc * @library /test/lib * @requires vm.debug == true + * @requires vm.flagless * @run driver ObsoleteFlagErrorMessage */ diff --git a/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestJcmdOutput.java b/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestJcmdOutput.java index e7f59481478af..b5b15f6d75f04 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestJcmdOutput.java +++ b/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestJcmdOutput.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -26,6 +26,7 @@ * @summary Verify jcmd error message for out-of-range value and for * value which is not allowed by constraint. Also check that * jcmd does not print an error message to the target process output. + * @requires vm.flagless * @library /test/lib * @modules java.base/jdk.internal.misc * java.management diff --git a/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java b/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java index c8557609b19bd..a342951621394 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java +++ b/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -27,6 +27,7 @@ * @test * @bug 8205633 * @summary Test VM Options with ranges (1 of 10) + * @requires vm.flagless * @library /test/lib /runtime/CommandLine/OptionsValidation/common * @modules java.base/jdk.internal.misc * java.management @@ -38,6 +39,7 @@ * @test * @bug 8205633 * @summary Test VM Options with ranges (2 of 10) + * @requires vm.flagless * @library /test/lib /runtime/CommandLine/OptionsValidation/common * @modules java.base/jdk.internal.misc * java.management @@ -49,6 +51,7 @@ * @test * @bug 8205633 * @summary Test VM Options with ranges (3 of 10) + * @requires vm.flagless * @library /test/lib /runtime/CommandLine/OptionsValidation/common * @modules java.base/jdk.internal.misc * java.management @@ -60,6 +63,7 @@ * @test * @bug 8205633 * @summary Test VM Options with ranges (4 of 10) + * @requires vm.flagless * @library /test/lib /runtime/CommandLine/OptionsValidation/common * @modules java.base/jdk.internal.misc * java.management @@ -71,6 +75,7 @@ * @test * @bug 8205633 * @summary Test VM Options with ranges (5 of 10) + * @requires vm.flagless * @library /test/lib /runtime/CommandLine/OptionsValidation/common * @modules java.base/jdk.internal.misc * java.management @@ -82,6 +87,7 @@ * @test * @bug 8205633 * @summary Test VM Options with ranges (6 of 10) + * @requires vm.flagless * @library /test/lib /runtime/CommandLine/OptionsValidation/common * @modules java.base/jdk.internal.misc * java.management @@ -93,6 +99,7 @@ * @test * @bug 8205633 * @summary Test VM Options with ranges (7 of 10) + * @requires vm.flagless * @library /test/lib /runtime/CommandLine/OptionsValidation/common * @modules java.base/jdk.internal.misc * java.management @@ -104,6 +111,7 @@ * @test * @bug 8205633 * @summary Test VM Options with ranges (8 of 10) + * @requires vm.flagless * @library /test/lib /runtime/CommandLine/OptionsValidation/common * @modules java.base/jdk.internal.misc * java.management @@ -115,6 +123,7 @@ * @test * @bug 8205633 * @summary Test VM Options with ranges (9 of 10) + * @requires vm.flagless * @library /test/lib /runtime/CommandLine/OptionsValidation/common * @modules java.base/jdk.internal.misc * java.management @@ -126,6 +135,7 @@ * @test * @bug 8205633 * @summary Test VM Options with ranges (10 of 10) + * @requires vm.flagless * @library /test/lib /runtime/CommandLine/OptionsValidation/common * @modules java.base/jdk.internal.misc * java.management diff --git a/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRangesDynamic.java b/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRangesDynamic.java index 04bc2f76965bd..480e8929ff8fc 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRangesDynamic.java +++ b/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRangesDynamic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -24,6 +24,7 @@ /* * @test * @summary Test writeable VM Options with ranges. + * @requires vm.flagless * @library /test/lib /runtime/CommandLine/OptionsValidation/common * @modules java.base/jdk.internal.misc * jdk.attach/sun.tools.attach diff --git a/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges_generate.sh b/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges_generate.sh index 1fe8015c54d2d..73d8f2b31aff1 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges_generate.sh +++ b/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges_generate.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 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 @@ -24,12 +24,13 @@ echo "// --- start auto-generated" echo "// the following portion is auto-generated by $0. Do not edit manually." -for i in {1..10}; do +for i in {1..10}; do cat < Date: Tue, 15 Apr 2025 09:16:27 +0000 Subject: [PATCH 185/846] 8318962: Update ProcessTools javadoc with suggestions in 8315097 Backport-of: 7e4cb2f09d1219c6ba7bfa77be831a7c7c9b055a --- .../jdk/test/lib/process/ProcessTools.java | 94 +++++++++++++------ 1 file changed, 66 insertions(+), 28 deletions(-) diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java index 439539e7009af..e99139ce5c07b 100644 --- a/test/lib/jdk/test/lib/process/ProcessTools.java +++ b/test/lib/jdk/test/lib/process/ProcessTools.java @@ -401,12 +401,21 @@ private static void printStack(Thread t, StackTraceElement[] stack) { } /** - * Create ProcessBuilder using the java launcher from the jdk to be tested. - * The default jvm options from jtreg, test.vm.opts and test.java.opts, are added. - *

- * The command line will be like: - * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds - * Create ProcessBuilder using the java launcher from the jdk to be tested. + * Create ProcessBuilder using the java launcher from the jdk to + * be tested. The default jvm options from jtreg, test.vm.opts and + * test.java.opts, are added. + * + *

Unless the "test.noclasspath" property is "true" the + * classpath property "java.class.path" is appended to the command + * line and the environment of the ProcessBuilder is modified to + * remove "CLASSPATH". If the property "test.thread.factory" is + * provided the command args are updated and appended to invoke + * ProcessTools main() and provide the name of the thread factory. + * + *

The "-Dtest.thread.factory" is appended to the arguments + * with the thread factory value. The remaining command args are + * scanned for unsupported options and are appended to the + * ProcessBuilder. * * @param command Arguments to pass to the java command. * @return The ProcessBuilder instance representing the java command. @@ -416,12 +425,21 @@ public static ProcessBuilder createTestJavaProcessBuilder(List command) } /** - * Create ProcessBuilder using the java launcher from the jdk to be tested. - * The default jvm options from jtreg, test.vm.opts and test.java.opts, are added. - *

- * The command line will be like: - * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds - * Create ProcessBuilder using the java launcher from the jdk to be tested. + * Create ProcessBuilder using the java launcher from the jdk to + * be tested. The default jvm options from jtreg, test.vm.opts and + * test.java.opts, are added. + * + *

Unless the "test.noclasspath" property is "true" the + * classpath property "java.class.path" is appended to the command + * line and the environment of the ProcessBuilder is modified to + * remove "CLASSPATH". If the property "test.thread.factory" is + * provided the command args are updated and appended to invoke + * ProcessTools main() and provide the name of the thread factory. + * + *

The "-Dtest.thread.factory" is appended to the arguments + * with the thread factory value. The remaining command args are + * scanned for unsupported options and are appended to the + * ProcessBuilder. * * @param command Arguments to pass to the java command. * @return The ProcessBuilder instance representing the java command. @@ -445,6 +463,18 @@ public static ProcessBuilder createTestJavaProcessBuilder(String... command) { * it in combination with @requires vm.flagless JTREG * anotation as to not waste energy and test resources. * + *

Unless the "test.noclasspath" property is "true" the + * classpath property "java.class.path" is appended to the command + * line and the environment of the ProcessBuilder is modified to + * remove "CLASSPATH". If the property "test.thread.factory" is + * provided the command args are updated and appended to invoke + * ProcessTools main() and provide the name of the thread factory. + * + *

The "-Dtest.thread.factory" is appended to the arguments + * with the thread factory value. The remaining command args are + * scanned for unsupported options and are appended to the + * ProcessBuilder. + * * @param command Arguments to pass to the java command. * @return The ProcessBuilder instance representing the java command. */ @@ -467,6 +497,18 @@ public static ProcessBuilder createLimitedTestJavaProcessBuilder(List co * it in combination with @requires vm.flagless JTREG * anotation as to not waste energy and test resources. * + *

Unless the "test.noclasspath" property is "true" the + * classpath property "java.class.path" is appended to the command + * line and the environment of the ProcessBuilder is modified to + * remove "CLASSPATH". If the property "test.thread.factory" is + * provided the command args are updated and appended to invoke + * ProcessTools main() and provide the name of the thread factory. + * + *

The "-Dtest.thread.factory" is appended to the arguments + * with the thread factory value. The remaining command args are + * scanned for unsupported options and are appended to the + * ProcessBuilder. + * * @param command Arguments to pass to the java command. * @return The ProcessBuilder instance representing the java command. */ @@ -475,14 +517,12 @@ public static ProcessBuilder createLimitedTestJavaProcessBuilder(String... comma } /** - * Executes a test jvm process, waits for it to finish and returns the process output. - * The default jvm options from jtreg, test.vm.opts and test.java.opts, are added. - * The java from the test.jdk is used to execute the command. - *

- * The command line will be like: - * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds - *

- * The jvm process will have exited before this method returns. + * Executes a test jvm process, waits for it to finish and returns + * the process output. + * + *

The process is created using runtime flags set up by: + * {@link #createTestJavaProcessBuilder(String...)}. The + * jvm process will have exited before this method returns. * * @param cmds User specified arguments. * @return The output from the process. @@ -492,14 +532,12 @@ public static OutputAnalyzer executeTestJvm(List cmds) throws Exception } /** - * Executes a test jvm process, waits for it to finish and returns the process output. - * The default jvm options from jtreg, test.vm.opts and test.java.opts, are added. - * The java from the test.jdk is used to execute the command. - *

- * The command line will be like: - * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds - *

- * The jvm process will have exited before this method returns. + * Executes a test jvm process, waits for it to finish and returns + * the process output. + * + *

The process is created using runtime flags set up by: + * {@link #createTestJavaProcessBuilder(String...)}. The + * jvm process will have exited before this method returns. * * @param cmds User specified arguments. * @return The output from the process. From d50fbcd06c9611b0e807a16f704ab6070a543b15 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 15 Apr 2025 09:18:14 +0000 Subject: [PATCH 186/846] 8321718: ProcessTools.executeProcess calls waitFor before logging Backport-of: 9ab29f8dcd1c0092e4251f996bd53c704e87a74a --- .../jdk/test/lib/process/OutputAnalyzer.java | 8 +++ .../jdk/test/lib/process/OutputBuffer.java | 51 ++++++++++++++----- .../jdk/test/lib/process/ProcessTools.java | 5 +- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/test/lib/jdk/test/lib/process/OutputAnalyzer.java b/test/lib/jdk/test/lib/process/OutputAnalyzer.java index e0d27e2374bbc..8f9ebde24262d 100644 --- a/test/lib/jdk/test/lib/process/OutputAnalyzer.java +++ b/test/lib/jdk/test/lib/process/OutputAnalyzer.java @@ -106,6 +106,14 @@ public OutputAnalyzer(String stdout, String stderr, int exitValue) buffer = OutputBuffer.of(stdout, stderr, exitValue); } + /** + * Delegate waitFor to the OutputBuffer. This ensures that + * the progress and timestamps are logged correctly. + */ + public void waitFor() { + buffer.waitFor(); + } + /** * Verify that the stdout contents of output buffer is empty * diff --git a/test/lib/jdk/test/lib/process/OutputBuffer.java b/test/lib/jdk/test/lib/process/OutputBuffer.java index fba2a5f6dcf3f..f032591f3584c 100644 --- a/test/lib/jdk/test/lib/process/OutputBuffer.java +++ b/test/lib/jdk/test/lib/process/OutputBuffer.java @@ -44,6 +44,12 @@ public OutputBufferException(Throwable cause) { } } + /** + * Waits for a process to finish, if there is one assocated with + * this OutputBuffer. + */ + public void waitFor(); + /** * Returns the stdout result * @@ -67,6 +73,13 @@ default public List getStdoutAsList() { * @return stderr result */ public String getStderr(); + + + /** + * Returns the exit value + * + * @return exit value + */ public int getExitValue(); /** @@ -136,20 +149,12 @@ private LazyOutputBuffer(Process p, Charset cs) { } @Override - public String getStdout() { - return outTask.get(); - } - - @Override - public String getStderr() { - return errTask.get(); - } - - @Override - public int getExitValue() { + public void waitFor() { if (exitValue != null) { - return exitValue; + // Already waited for this process + return; } + try { logProgress("Waiting for completion"); boolean aborted = true; @@ -157,7 +162,6 @@ public int getExitValue() { exitValue = p.waitFor(); logProgress("Waiting for completion finished"); aborted = false; - return exitValue; } finally { if (aborted) { logProgress("Waiting for completion FAILED"); @@ -169,6 +173,22 @@ public int getExitValue() { } } + @Override + public String getStdout() { + return outTask.get(); + } + + @Override + public String getStderr() { + return errTask.get(); + } + + @Override + public int getExitValue() { + waitFor(); + return exitValue; + } + @Override public long pid() { return p.pid(); @@ -186,6 +206,11 @@ private EagerOutputBuffer(String stdout, String stderr, int exitValue) { this.exitValue = exitValue; } + @Override + public void waitFor() { + // Nothing to do since this buffer is not associated with a Process. + } + @Override public String getStdout() { return stdout; diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java index e99139ce5c07b..cad9d9ecd57a6 100644 --- a/test/lib/jdk/test/lib/process/ProcessTools.java +++ b/test/lib/jdk/test/lib/process/ProcessTools.java @@ -606,7 +606,10 @@ public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input, } output = new OutputAnalyzer(p, cs); - p.waitFor(); + + // Wait for the process to finish. Call through the output + // analyzer to get correct logging and timestamps. + output.waitFor(); { // Dumping the process output to a separate file var fileName = String.format("pid-%d-output.log", p.pid()); From bec2e07144923a70746dd55a5482cb8f7ea6add2 Mon Sep 17 00:00:00 2001 From: Boris Ulasevich Date: Tue, 15 Apr 2025 17:41:15 +0000 Subject: [PATCH 187/846] 8320682: [AArch64] C1 compilation fails with "Field too big for insn" Reviewed-by: phh --- src/hotspot/share/c1/c1_globals.hpp | 6 +- .../compiler/arguments/TestC1Globals.java | 67 +++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/arguments/TestC1Globals.java diff --git a/src/hotspot/share/c1/c1_globals.hpp b/src/hotspot/share/c1/c1_globals.hpp index 7564b2b8aae0d..41d4607f8e32e 100644 --- a/src/hotspot/share/c1/c1_globals.hpp +++ b/src/hotspot/share/c1/c1_globals.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -287,9 +287,11 @@ develop(bool, InstallMethods, true, \ "Install methods at the end of successful compilations") \ \ + /* The compiler assumes, in many places, that methods are at most 1MB. */ \ + /* Therefore, we restrict this flag to at most 1MB. */ \ develop(intx, NMethodSizeLimit, (64*K)*wordSize, \ "Maximum size of a compiled method.") \ - range(0, max_jint) \ + range(0, 1*M) \ \ develop(bool, TraceFPUStack, false, \ "Trace emulation of the FPU stack (intel only)") \ diff --git a/test/hotspot/jtreg/compiler/arguments/TestC1Globals.java b/test/hotspot/jtreg/compiler/arguments/TestC1Globals.java new file mode 100644 index 0000000000000..ff639a69bd937 --- /dev/null +++ b/test/hotspot/jtreg/compiler/arguments/TestC1Globals.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 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. + */ + +/** + * @test + * @bug 8316653 + * @requires vm.debug + * @summary Test flag with max value. + * + * @run main/othervm -XX:NMethodSizeLimit=1M + * compiler.arguments.TestC1Globals + */ + +/** + * @test + * @bug 8318817 + * @requires vm.debug + * @requires os.family == "linux" + * @summary Test flag with max value combined with transparent huge pages on + * Linux. + * + * @run main/othervm -XX:NMethodSizeLimit=1M + * -XX:+UseTransparentHugePages + * compiler.arguments.TestC1Globals + */ + +/** + * @test + * @bug 8320682 + * @requires vm.debug + * @summary Test flag with max value and specific compilation. + * + * @run main/othervm -XX:NMethodSizeLimit=1M + * -XX:CompileOnly=java.util.HashMap::putMapEntries + * -Xcomp + * compiler.arguments.TestC1Globals + * + */ + +package compiler.arguments; + +public class TestC1Globals { + + public static void main(String args[]) { + System.out.println("Passed"); + } +} From e0ee6db134ff674a8d6d2a40898a70a59b6e5390 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 16 Apr 2025 12:59:02 +0000 Subject: [PATCH 188/846] 8316460: 4 javax/management tests ignore VM flags Reviewed-by: rschmelter Backport-of: d39b7bab27af5ba24ff0925037b8e5fb99680dc0 --- .../ImplVersionTest.java | 92 +++++++------------ .../connection/DefaultAgentFilterTest.java | 10 +- .../mandatory/version/ImplVersionTest.java | 79 ++++++---------- .../security/HashedPasswordFileTest.java | 8 +- 4 files changed, 70 insertions(+), 119 deletions(-) diff --git a/test/jdk/javax/management/ImplementationVersion/ImplVersionTest.java b/test/jdk/javax/management/ImplementationVersion/ImplVersionTest.java index cc77fced68331..16f0c8f262f7d 100644 --- a/test/jdk/javax/management/ImplementationVersion/ImplVersionTest.java +++ b/test/jdk/javax/management/ImplementationVersion/ImplVersionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,70 +30,48 @@ * system property. * @author Luis-Miguel Alventosa * - * @run clean ImplVersionTest ImplVersionCommand + * @library /test/lib * @run build ImplVersionTest ImplVersionCommand ImplVersionReader * @run main ImplVersionTest */ +import jdk.test.lib.process.ProcessTools; + import java.io.File; public class ImplVersionTest { - public static void main(String[] args) { - try { - // Get OS name - // - String osName = System.getProperty("os.name"); - System.out.println("osName = " + osName); - if ("Windows 98".equals(osName)) { - // Disable this test on Win98 due to parsing - // errors (bad handling of white spaces) when - // J2SE is installed under "Program Files". - // - System.out.println("This test is disabled on Windows 98."); - System.out.println("Bye! Bye!"); - return; - } - // Get Java Home - // - String javaHome = System.getProperty("java.home"); - System.out.println("javaHome = " + javaHome); - // Get test src - // - String testSrc = System.getProperty("test.src"); - System.out.println("testSrc = " + testSrc); - // Get test classes - // - String testClasses = System.getProperty("test.classes"); - System.out.println("testClasses = " + testClasses); - // Get boot class path - // - String command = - javaHome + File.separator + "bin" + File.separator + "java " + - " -classpath " + testClasses + - " -Djava.security.manager -Djava.security.policy==" + testSrc + - File.separator + "policy -Dtest.classes=" + testClasses + - " ImplVersionCommand " + - System.getProperty("java.runtime.version"); - System.out.println("ImplVersionCommand Exec Command = " +command); - Process proc = Runtime.getRuntime().exec(command); - new ImplVersionReader(proc, proc.getInputStream()).start(); - new ImplVersionReader(proc, proc.getErrorStream()).start(); - int exitValue = proc.waitFor(); - System.out.println("ImplVersionCommand Exit Value = " + - exitValue); - if (exitValue != 0) { - System.out.println("TEST FAILED: Incorrect exit value " + - "from ImplVersionCommand"); - System.exit(exitValue); - } - // Test OK! - // - System.out.println("Bye! Bye!"); - } catch (Exception e) { - System.out.println("Unexpected exception caught = " + e); - e.printStackTrace(); - System.exit(1); + public static void main(String[] args) throws Exception { + // Get test src + // + String testSrc = System.getProperty("test.src"); + System.out.println("testSrc = " + testSrc); + // Get test classes + // + String testClasses = System.getProperty("test.classes"); + System.out.println("testClasses = " + testClasses); + // Get boot class path + // + String[] command = new String[] { + "-Djava.security.manager", + "-Djava.security.policy==" + testSrc + File.separator + "policy", + "-Dtest.classes=" + testClasses, + "ImplVersionCommand", + System.getProperty("java.runtime.version") + }; + + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(command); + Process proc = pb.start(); + new ImplVersionReader(proc, proc.getInputStream()).start(); + new ImplVersionReader(proc, proc.getErrorStream()).start(); + int exitValue = proc.waitFor(); + System.out.println("ImplVersionCommand Exit Value = " + exitValue); + if (exitValue != 0) { + throw new RuntimeException("TEST FAILED: Incorrect exit value " + + "from ImplVersionCommand " + exitValue); } + // Test OK! + // + System.out.println("Bye! Bye!"); } } diff --git a/test/jdk/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java b/test/jdk/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java index 1b036ce2f563e..6b4aa5e67dfa4 100644 --- a/test/jdk/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java +++ b/test/jdk/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java @@ -189,11 +189,9 @@ private static void testDefaultAgent(String propertyFile) throws Exception { private static void testDefaultAgent(String propertyFile, int port) throws Exception { String propFile = System.getProperty("test.src") + File.separator + propertyFile; - List pbArgs = new ArrayList<>(Arrays.asList( - "-cp", - System.getProperty("test.class.path"), - "-XX:+UsePerfData" - )); + List pbArgs = new ArrayList<>(); + pbArgs.add("-XX:+UsePerfData"); + String[] args = new String[]{ "-Dcom.sun.management.jmxremote.port=" + port, "-Dcom.sun.management.jmxremote.authenticate=false", @@ -203,7 +201,7 @@ private static void testDefaultAgent(String propertyFile, int port) throws Excep pbArgs.addAll(Arrays.asList(args)); pbArgs.add(TEST_APP_NAME); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( pbArgs.toArray(new String[pbArgs.size()]) ); diff --git a/test/jdk/javax/management/remote/mandatory/version/ImplVersionTest.java b/test/jdk/javax/management/remote/mandatory/version/ImplVersionTest.java index 8ee4e769cd85c..0a1793584666c 100644 --- a/test/jdk/javax/management/remote/mandatory/version/ImplVersionTest.java +++ b/test/jdk/javax/management/remote/mandatory/version/ImplVersionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,69 +30,48 @@ * system property. * @author Luis-Miguel Alventosa, Joel Feraud * - * @run clean ImplVersionTest ImplVersionCommand + * @library /test/lib * @run build ImplVersionTest ImplVersionCommand ImplVersionReader * @run main ImplVersionTest */ +import jdk.test.lib.process.ProcessTools; + import java.io.File; public class ImplVersionTest { - public static void main(String[] args) { - try { - // Get OS name - // - String osName = System.getProperty("os.name"); - System.out.println("osName = " + osName); - if ("Windows 98".equals(osName)) { - // Disable this test on Win98 due to parsing - // errors (bad handling of white spaces) when - // J2SE is installed under "Program Files". - // - System.out.println("This test is disabled on Windows 98."); - System.out.println("Bye! Bye!"); - return; - } + public static void main(String[] args) throws Exception { - // Get Java Home - String javaHome = System.getProperty("java.home"); + // Get test src + // + String testSrc = System.getProperty("test.src"); - // Get test src - // - String testSrc = System.getProperty("test.src"); + // Get test classes + String testClasses = System.getProperty("test.classes"); - // Get test classes - String testClasses = System.getProperty("test.classes"); + // Build command string - // Build command string - String command = - javaHome + File.separator + "bin" + File.separator + "java " + - " -classpath " + testClasses + - " -Djava.security.manager -Djava.security.policy==" + testSrc + - File.separator + "policy -Dtest.classes=" + testClasses + - " ImplVersionCommand " + System.getProperty("java.runtime.version"); - System.out.println("ImplVersionCommand Exec Command = " + command); + String[] command = new String[] { + "-Djava.security.manager", + "-Djava.security.policy==" + testSrc + File.separator + "policy", + "-Dtest.classes=" + testClasses, + "ImplVersionCommand", + System.getProperty("java.runtime.version") + }; - // Exec command - Process proc = Runtime.getRuntime().exec(command); - new ImplVersionReader(proc, proc.getInputStream()).start(); - new ImplVersionReader(proc, proc.getErrorStream()).start(); - int exitValue = proc.waitFor(); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(command); + Process proc = pb.start(); + new ImplVersionReader(proc, proc.getInputStream()).start(); + new ImplVersionReader(proc, proc.getErrorStream()).start(); + int exitValue = proc.waitFor(); - System.out.println("ImplVersionCommand Exit Value = " + - exitValue); - if (exitValue != 0) { - System.out.println("TEST FAILED: Incorrect exit value " + - "from ImplVersionCommand"); - System.exit(exitValue); - } - // Test OK! - System.out.println("Bye! Bye!"); - } catch (Exception e) { - System.out.println("Unexpected exception caught = " + e); - e.printStackTrace(); - System.exit(1); + System.out.println("ImplVersionCommand Exit Value = " + exitValue); + if (exitValue != 0) { + throw new RuntimeException("TEST FAILED: Incorrect exit value " + + "from ImplVersionCommand " + exitValue); } + // Test OK! + System.out.println("Bye! Bye!"); } } diff --git a/test/jdk/javax/management/security/HashedPasswordFileTest.java b/test/jdk/javax/management/security/HashedPasswordFileTest.java index 7a3f02bc7c845..195a9cd344993 100644 --- a/test/jdk/javax/management/security/HashedPasswordFileTest.java +++ b/test/jdk/javax/management/security/HashedPasswordFileTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -468,10 +468,6 @@ public void testDefaultAgentNoHash() throws Exception { perms.add(PosixFilePermission.OWNER_READ); perms.add(PosixFilePermission.OWNER_WRITE); Files.setPosixFilePermissions(file.toPath(), perms); - - pbArgs.add("-cp"); - pbArgs.add(System.getProperty("test.class.path")); - pbArgs.add("-Dcom.sun.management.jmxremote.port=0"); pbArgs.add("-Dcom.sun.management.jmxremote.authenticate=true"); pbArgs.add("-Dcom.sun.management.jmxremote.password.file=" + file.getAbsolutePath()); @@ -481,7 +477,7 @@ public void testDefaultAgentNoHash() throws Exception { pbArgs.add("jdk.management.agent/jdk.internal.agent=ALL-UNNAMED"); pbArgs.add(TestApp.class.getSimpleName()); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( pbArgs.toArray(new String[0])); Process process = ProcessTools.startProcess( TestApp.class.getSimpleName(), From 8aba95c7dbe3108a604ca5534b9209042742ea96 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 16 Apr 2025 13:00:28 +0000 Subject: [PATCH 189/846] 8328301: Convert Applet test ManualHTMLDataFlavorTest.java to main program Backport-of: f7f291c5d4d2d01dab3ccda7518ebc13f6bd58f6 --- .../ManualHTMLDataFlavorTest.html | 43 --- .../ManualHTMLDataFlavorTest.java | 273 +++++------------- 2 files changed, 71 insertions(+), 245 deletions(-) delete mode 100644 test/jdk/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.html diff --git a/test/jdk/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.html b/test/jdk/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.html deleted file mode 100644 index 0a444d5b8ea45..0000000000000 --- a/test/jdk/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - -ManualHTMLDataFlavorTest - - - -

ManualHTMLDataFlavorTest
Bug ID: 7075105

- -

See the dialog box (usually in upper left corner) for instructions

- - - - diff --git a/test/jdk/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.java b/test/jdk/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.java index bd1ea752edba5..4e875461ba274 100644 --- a/test/jdk/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.java +++ b/test/jdk/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,24 +22,32 @@ */ /* - test + @test @bug 7075105 @summary WIN: Provide a way to format HTML on drop - @author Denis Fokin: area=datatransfer - @run applet/manual=yesno ManualHTMLDataFlavorTest + @library /java/awt/regtesthelpers + @run main/manual ManualHTMLDataFlavorTest */ -import java.applet.Applet; -import java.awt.*; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Panel; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; -import java.awt.dnd.*; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; import java.io.IOException; -public class ManualHTMLDataFlavorTest extends Applet { +public class ManualHTMLDataFlavorTest { - class DropPane extends Panel implements DropTargetListener { + static class DropPane extends Panel implements DropTargetListener { DropPane() { requestFocus(); @@ -49,7 +57,7 @@ class DropPane extends Panel implements DropTargetListener { @Override public Dimension getPreferredSize() { - return new Dimension(200,200); + return new Dimension(400, 400); } @Override @@ -73,15 +81,15 @@ public void dragExit(DropTargetEvent dte) {} @Override public void drop(DropTargetDropEvent dtde) { if (!dtde.isDataFlavorSupported(DataFlavor.allHtmlFlavor)) { - Sysout.println("DataFlavor.allHtmlFlavor is not present in the system clipboard"); + ManualHTMLDataFlavorTest.log("DataFlavor.allHtmlFlavor is not present in the system clipboard"); dtde.rejectDrop(); return; } else if (!dtde.isDataFlavorSupported(DataFlavor.fragmentHtmlFlavor)) { - Sysout.println("DataFlavor.fragmentHtmlFlavor is not present in the system clipboard"); + ManualHTMLDataFlavorTest.log("DataFlavor.fragmentHtmlFlavor is not present in the system clipboard"); dtde.rejectDrop(); return; } else if (!dtde.isDataFlavorSupported(DataFlavor.selectionHtmlFlavor)) { - Sysout.println("DataFlavor.selectionHtmlFlavor is not present in the system clipboard"); + ManualHTMLDataFlavorTest.log("DataFlavor.selectionHtmlFlavor is not present in the system clipboard"); dtde.rejectDrop(); return; } @@ -90,12 +98,13 @@ public void drop(DropTargetDropEvent dtde) { Transferable t = dtde.getTransferable(); try { - Sysout.println("ALL:"); - Sysout.println(t.getTransferData(DataFlavor.allHtmlFlavor).toString()); - Sysout.println("FRAGMENT:"); - Sysout.println(t.getTransferData(DataFlavor.fragmentHtmlFlavor).toString()); - Sysout.println("SELECTION:"); - Sysout.println(t.getTransferData(DataFlavor.selectionHtmlFlavor).toString()); + ManualHTMLDataFlavorTest.log("ALL:"); + ManualHTMLDataFlavorTest.log(t.getTransferData(DataFlavor.allHtmlFlavor).toString()); + t.getTransferData(DataFlavor.allHtmlFlavor).toString(); + ManualHTMLDataFlavorTest.log("FRAGMENT:"); + ManualHTMLDataFlavorTest.log(t.getTransferData(DataFlavor.fragmentHtmlFlavor).toString()); + ManualHTMLDataFlavorTest.log("SELECTION:"); + ManualHTMLDataFlavorTest.log(t.getTransferData(DataFlavor.selectionHtmlFlavor).toString()); } catch (UnsupportedFlavorException | IOException e) { e.printStackTrace(); } @@ -103,189 +112,49 @@ public void drop(DropTargetDropEvent dtde) { } } - public void init() { - - String[] instructions = - { - "1) The test contains a drop-aware panel with a red background", - "2) Open some page in a browser, select some text", - " Drag and drop it on the red panel", - " IMPORTANT NOTE: the page should be stored locally.", - " otherwise for instance iexplore can prohibit drag and drop from", - " the browser to other applications because of", - " the protected mode restrictions.", - " On Mac OS X do NOT use Safari, it does not provide the needed DataFlavor", - "3) Check the data in the output area of this dialog", - "5) The output should not contain information that any of", - " flavors is not present in the system clipboard", - "6) The output should contain data in three different formats", - " provided by the system clipboard", - " - Data after the \"ALL:\" marker should include the data", - " from the \"SELECTION:\" marker", - " - Data after the \"FRAGMENT\" marker should include the data", - " from the \"SELECTION:\" marker and may be some closing", - " tags could be added to the mark-up", - " - Data after the \"SELECTION:\" marker should correspond", - " to the data selected in the browser", - "7) If the above requirements are met, the test is passed" - }; - - add(new DropPane()); - Sysout.createDialogWithInstructions( instructions ); - - new ManualHTMLDataFlavorTest(); + static final String INSTRUCTIONS = """ + 1) The test contains a drop-aware panel with a red background. + 2) Open some page in a browser, select some text. + Drag and drop it on the red panel. + IMPORTANT NOTE: the page should be stored locally. + Otherwise for instance Internet Explorer may prohibit drag and drop from + the browser to other applications because of protected mode restrictions. + On MacOS do NOT use Safari, it does not provide the needed DataFlavor. + 3) Check the data in the output area of this window. + 5) The output should not contain information that any of + flavors is not present in the system clipboard. + 6) The output should contain data in three different formats + provided by the system clipboard. + - Data after the "ALL:" marker should include the data + from the "SELECTION:" marker". + - Data after the "FRAGMENT" marker should include the data + from the "SELECTION:" marker and may be some closing + tags could be added to the mark-up. + - Data after the "SELECTION:" marker should correspond + to the data selected in the browser. + 7) If the above requirements are met, the test is passed. + """; + + static Frame createDropWindow() { + Frame frame = new Frame("Manual HTML DataFlavor Test"); + frame.add(new DropPane()); + frame.setAlwaysOnTop(true); + frame.pack(); + return frame; } - public void start () - { - setSize (200,200); - setVisible(true); - validate(); - - }// start() - + static void log(String msg) { + PassFailJFrame.log(msg); + } + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .rows(25) + .columns(50) + .testUI(ManualHTMLDataFlavorTest::createDropWindow) + .logArea() + .build() + .awaitAndCheck(); + } } - - -/* Place other classes related to the test after this line */ - - - - - -/**************************************************** - Standard Test Machinery - DO NOT modify anything below -- it's a standard - chunk of code whose purpose is to make user - interaction uniform, and thereby make it simpler - to read and understand someone else's test. - ****************************************************/ - -/** - This is part of the standard test machinery. - It creates a dialog (with the instructions), and is the interface - for sending text messages to the user. - To print the instructions, send an array of strings to Sysout.createDialog - WithInstructions method. Put one line of instructions per array entry. - To display a message for the tester to see, simply call Sysout.println - with the string to be displayed. - This mimics System.out.println but works within the test harness as well - as standalone. - */ - -class Sysout -{ - private static TestDialog dialog; - - public static void createDialogWithInstructions( String[] instructions ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - dialog.printInstructions( instructions ); - dialog.setVisible(true); - println( "Any messages for the tester will display here." ); - } - - public static void createDialog( ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - String[] defInstr = { "Instructions will appear here. ", "" } ; - dialog.printInstructions( defInstr ); - dialog.setVisible(true); - println( "Any messages for the tester will display here." ); - } - - - public static void printInstructions( String[] instructions ) - { - dialog.printInstructions( instructions ); - } - - - public static void println( String messageIn ) - { - dialog.displayMessage( messageIn ); - } - -}// Sysout class - -/** - This is part of the standard test machinery. It provides a place for the - test instructions to be displayed, and a place for interactive messages - to the user to be displayed. - To have the test instructions displayed, see Sysout. - To have a message to the user be displayed, see Sysout. - Do not call anything in this dialog directly. - */ -class TestDialog extends Dialog -{ - - TextArea instructionsText; - TextArea messageText; - int maxStringLength = 80; - - //DO NOT call this directly, go through Sysout - public TestDialog( Frame frame, String name ) - { - super( frame, name ); - int scrollBoth = TextArea.SCROLLBARS_BOTH; - instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); - add( "North", instructionsText ); - - messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); - add("Center", messageText); - - pack(); - - setVisible(true); - }// TestDialog() - - //DO NOT call this directly, go through Sysout - public void printInstructions( String[] instructions ) - { - //Clear out any current instructions - instructionsText.setText( "" ); - - //Go down array of instruction strings - - String printStr, remainingStr; - for( int i=0; i < instructions.length; i++ ) - { - //chop up each into pieces maxSringLength long - remainingStr = instructions[ i ]; - while( remainingStr.length() > 0 ) - { - //if longer than max then chop off first max chars to print - if( remainingStr.length() >= maxStringLength ) - { - //Try to chop on a word boundary - int posOfSpace = remainingStr. - lastIndexOf( ' ', maxStringLength - 1 ); - - if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; - - printStr = remainingStr.substring( 0, posOfSpace + 1 ); - remainingStr = remainingStr.substring( posOfSpace + 1 ); - } - //else just print - else - { - printStr = remainingStr; - remainingStr = ""; - } - - instructionsText.append( printStr + "\n" ); - - }// while - - }// for - - }//printInstructions() - - //DO NOT call this directly, go through Sysout - public void displayMessage( String messageIn ) - { - messageText.append( messageIn + "\n" ); - System.out.println(messageIn); - } - -}// TestDialog class From 95b0091c89aecb76a1fbe6186d6823c95000c2bf Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 16 Apr 2025 13:02:00 +0000 Subject: [PATCH 190/846] 8341278: Open source few TrayIcon tests - Set7 Backport-of: 4d50cbb5a73ad1f84ecd6a895045ecfdb0835adc --- test/jdk/ProblemList.txt | 2 + .../java/awt/TrayIcon/ClearPrevImageTest.java | 126 ++++++++++++++++ .../awt/TrayIcon/FocusLostAfterTrayTest.java | 136 ++++++++++++++++++ test/jdk/java/awt/TrayIcon/MouseMoveTest.java | 107 ++++++++++++++ .../awt/TrayIcon/TrayIconKeySelectTest.java | 122 ++++++++++++++++ 5 files changed, 493 insertions(+) create mode 100644 test/jdk/java/awt/TrayIcon/ClearPrevImageTest.java create mode 100644 test/jdk/java/awt/TrayIcon/FocusLostAfterTrayTest.java create mode 100644 test/jdk/java/awt/TrayIcon/MouseMoveTest.java create mode 100644 test/jdk/java/awt/TrayIcon/TrayIconKeySelectTest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 1fb1c54c6ec0b..07b3d9f37d8c2 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -223,6 +223,8 @@ java/awt/TrayIcon/TrayIconMouseTest/TrayIconMouseTest.java 8150540 windows-all java/awt/TrayIcon/TrayIconPopup/TrayIconPopupClickTest.java 8150540 windows-all,macosx-all java/awt/TrayIcon/TrayIconPopup/TrayIconPopupTest.java 8150540 windows-all java/awt/TrayIcon/PopupMenuLeakTest/PopupMenuLeakTest.java 8196440 linux-all +java/awt/TrayIcon/MouseMoveTest.java 8203053 linux-all +java/awt/TrayIcon/TrayIconKeySelectTest.java 8341557 windows-all java/awt/TrayIcon/TrayIconTest.java 8341559 generic-all java/awt/Window/ShapedAndTranslucentWindows/SetShapeAndClick.java 8197936 macosx-all diff --git a/test/jdk/java/awt/TrayIcon/ClearPrevImageTest.java b/test/jdk/java/awt/TrayIcon/ClearPrevImageTest.java new file mode 100644 index 0000000000000..e97f645bec594 --- /dev/null +++ b/test/jdk/java/awt/TrayIcon/ClearPrevImageTest.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTException; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.SystemTray; +import java.awt.TrayIcon; +import java.awt.image.BufferedImage; + +import jtreg.SkippedException; + +/* + * @test + * @bug 6267936 + * @library /java/awt/regtesthelpers /test/lib + * @build PassFailJFrame jtreg.SkippedException + * @summary Tests that the previous image in TrayIcon is cleared + * when a new image is set + * @run main/manual ClearPrevImageTest + */ + +public class ClearPrevImageTest { + private static SystemTray tray; + private static TrayIcon icon; + private static final String INSTRUCTIONS = """ + This test checks that the previous image in TrayIcon is cleared + when a new image is set. + + When the test starts, a RED square TrayIcon is added + to the SystemTray (also, called Taskbar Status Area in MS Windows, + Notification Area in, GNOME and System Tray in KDE). + + You should see it change into YELLOW after 5 seconds. + If you still see RED TrayIcon after 5 seconds, + press FAIL, otherwise press PASS + """; + + + public static void main(String[] args) throws Exception { + if (!SystemTray.isSupported()) { + throw new SkippedException("Test not applicable as" + + " System Tray not supported"); + } + + PassFailJFrame passFailJFrame + = PassFailJFrame.builder() + .title("TrayIcon Change Test Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .build(); + + EventQueue.invokeAndWait(ClearPrevImageTest::createAndShowTrayIcon); + try { + changeTrayIcon(); + passFailJFrame.awaitAndCheck(); + } catch (Exception e) { + throw new RuntimeException("Test failed: ", e); + } finally { + EventQueue.invokeAndWait(() -> { + if (tray != null) { + tray.remove(icon); + } + }); + } + } + + private static void createAndShowTrayIcon() { + Image img1 = createIcon(Color.RED); + tray = SystemTray.getSystemTray(); + icon = new TrayIcon(img1); + icon.setImageAutoSize(true); + + try { + tray.add(icon); + } catch (AWTException e) { + throw new RuntimeException("Error while adding" + + " icon to system tray", e); + } + } + + private static void changeTrayIcon() { + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + Image img2 = createIcon(Color.YELLOW); + icon.setImage(img2); + } + + private static Image createIcon(Color color) { + BufferedImage image = new BufferedImage(16, 16, + BufferedImage.TYPE_INT_ARGB); + Graphics2D g = image.createGraphics(); + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + g.setColor(color); + g.fillRect(0, 0, 16, 16); + g.dispose(); + return image; + } +} diff --git a/test/jdk/java/awt/TrayIcon/FocusLostAfterTrayTest.java b/test/jdk/java/awt/TrayIcon/FocusLostAfterTrayTest.java new file mode 100644 index 0000000000000..bd831ce94e4c0 --- /dev/null +++ b/test/jdk/java/awt/TrayIcon/FocusLostAfterTrayTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.SystemTray; +import java.awt.TextArea; +import java.awt.TrayIcon; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.image.BufferedImage; + +import jtreg.SkippedException; + +/* + * @test + * @bug 6269309 + * @library /java/awt/regtesthelpers /test/lib + * @build PassFailJFrame jtreg.SkippedException + * @summary Tests that focus is transferred properly back + * to toplevel after clicking on a tray icon. + * @run main/manual FocusLostAfterTrayTest + */ + +public class FocusLostAfterTrayTest { + private static SystemTray tray; + private static TrayIcon icon; + + private static final String INSTRUCTIONS = """ + This test checks that focus is transferred properly back + to top-level after clicking on a tray icon. + + When the test starts, a Frame with a text area & a RED tray icon + are shown. If you don't see a tray icon please make sure that + the tray area (also called Taskbar Status Area on MS Windows + Notification Area on Gnome or System Tray on KDE) is visible. + + Click with a mouse inside a text area and make sure that it has + received input focus. Then click on the tray icon and then back + on the text area and verify that it has input focus again. Repeat + the last step several times. Ensure that the text area always + has the input focus and there are no "FOCUS LOST" event + for text area in the log section. + + If above is true, Press PASS, else FAIL. + """; + + public static void main(String[] args) throws Exception { + if (!SystemTray.isSupported()) { + throw new SkippedException("Test not applicable as" + + " System Tray not supported"); + } + + try { + PassFailJFrame.builder() + .title("FocusLostAfterTrayTest Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(FocusLostAfterTrayTest::createAndShowTrayIcon) + .logArea() + .build() + .awaitAndCheck(); + } finally { + EventQueue.invokeAndWait(() -> { + if (tray != null) { + tray.remove(icon); + } + }); + } + } + + private static Frame createAndShowTrayIcon() { + Frame frame = new Frame("FocusLostAfterTrayTest"); + frame.setBounds(100, 300, 200, 200); + frame.setLayout(new BorderLayout()); + TextArea ta = new TextArea(); + ta.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + PassFailJFrame.log("FOCUS GAINED: " + + e.getComponent().getClass().toString()); + } + @Override + public void focusLost(FocusEvent e) { + PassFailJFrame.log("FOCUS LOST !! " + + e.getComponent().getClass().toString()); + } + }); + frame.add(ta); + + BufferedImage image = new BufferedImage(16, 16, + BufferedImage.TYPE_INT_ARGB); + Graphics2D g = image.createGraphics(); + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + g.setColor(Color.RED); + g.fillRect(0, 0, 16, 16); + g.dispose(); + tray = SystemTray.getSystemTray(); + icon = new TrayIcon(image); + icon.setImageAutoSize(true); + + try { + tray.add(icon); + } catch (AWTException e) { + throw new RuntimeException("Error while adding" + + " icon to system tray", e); + } + return frame; + } +} diff --git a/test/jdk/java/awt/TrayIcon/MouseMoveTest.java b/test/jdk/java/awt/TrayIcon/MouseMoveTest.java new file mode 100644 index 0000000000000..51d80ff127b1b --- /dev/null +++ b/test/jdk/java/awt/TrayIcon/MouseMoveTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTException; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Graphics; +import java.awt.SystemTray; +import java.awt.TrayIcon; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.image.BufferedImage; + +import jtreg.SkippedException; + +/* + * @test + * @bug 6267980 + * @summary PIT:Spurious MouseMoved events are triggered by Tray Icon + * @library /java/awt/regtesthelpers /test/lib + * @build PassFailJFrame jtreg.SkippedException + * @run main/manual MouseMoveTest + */ + +public class MouseMoveTest { + private static SystemTray tray; + private static TrayIcon icon; + private static final String INSTRUCTIONS = """ + 1) You will see a tray icon (white square) in notification area, + 2) Move mouse pointer to the icon and leave it somewhere inside the icon, + 3) Verify that MOUSE_MOVE events are NOT triggered after you have STOPPED + moving mouse. + 4) If events are still triggered Press FAIL else PASS. + """; + + public static void main(String[] args) throws Exception { + if (!SystemTray.isSupported()) { + throw new SkippedException("Test not applicable as" + + " System Tray not supported"); + } + + PassFailJFrame passFailJFrame + = PassFailJFrame.builder() + .title("TrayIcon Change Test Instructions") + .instructions(INSTRUCTIONS) + .columns(45) + .logArea() + .build(); + + try { + EventQueue.invokeAndWait(MouseMoveTest::createAndShowTrayIcon); + passFailJFrame.awaitAndCheck(); + } finally { + EventQueue.invokeAndWait(() -> { + if (tray != null) { + tray.remove(icon); + } + }); + } + } + + private static void createAndShowTrayIcon() { + BufferedImage img = new BufferedImage(32, 32, + BufferedImage.TYPE_INT_ARGB); + Graphics g = img.createGraphics(); + g.setColor(Color.WHITE); + g.fillRect(0, 0, 32, 32); + g.dispose(); + + tray = SystemTray.getSystemTray(); + icon = new TrayIcon(img); + icon.setImageAutoSize(true); + + icon.addMouseMotionListener(new MouseMotionAdapter() { + public void mouseMoved(MouseEvent me){ + PassFailJFrame.log(me.toString()); + } + }); + + try { + tray.add(icon); + } catch (AWTException e) { + throw new RuntimeException("Error while adding" + + " icon to system tray", e); + } + } +} diff --git a/test/jdk/java/awt/TrayIcon/TrayIconKeySelectTest.java b/test/jdk/java/awt/TrayIcon/TrayIconKeySelectTest.java new file mode 100644 index 0000000000000..5e41f54638236 --- /dev/null +++ b/test/jdk/java/awt/TrayIcon/TrayIconKeySelectTest.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTException; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Graphics; +import java.awt.SystemTray; +import java.awt.TrayIcon; +import java.awt.image.BufferedImage; + +import jtreg.SkippedException; + +/* + * @test + * @bug 6267943 + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers /test/lib + * @build PassFailJFrame jtreg.SkippedException + * @summary Tests the possibility of selecting a tray icon with the keyboard. + * @run main/manual TrayIconKeySelectTest + */ + +public class TrayIconKeySelectTest { + private static SystemTray tray; + private static TrayIcon icon; + private static final String INSTRUCTIONS = """ + Tests that TrayIcon is selectable with the keyboard + When the test is started you will see three-color icon + in the system tray. + + 1. Bring the focus to the icon with TAB. Press ENTER key. + - One or more ActionEvent should be generated + (see the output area of the test) + + 2. Bring the focus again to the icon. Press SPACE key twice. + - One or more ActionEvent should be generated. + + 3. Bring the focus again to the icon. Click on the icon with + the LEFT mouse button twice. + - One or more ActionEvent should be generated. + + 4. Again bring the focus to the icon. Click on the icon with + the LEFT mouse button just once. + - NO ActionEvent should be generated. + + 5. Repeat the 4th step with other mouse buttons. + + If all the above are true press PASS, else FAIL + """; + + public static void main(String[] args) throws Exception { + if (!SystemTray.isSupported()) { + throw new SkippedException("Test not applicable as" + + " System Tray not supported"); + } + PassFailJFrame passFailJFrame; + try { + passFailJFrame + = PassFailJFrame.builder() + .title("TrayIconKeySelectTest Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .logArea() + .build(); + + EventQueue.invokeAndWait(TrayIconKeySelectTest::createAndShowTrayIcon); + passFailJFrame.awaitAndCheck(); + } finally { + EventQueue.invokeAndWait(() -> { + if (tray != null) { + tray.remove(icon); + } + }); + } + } + + private static void createAndShowTrayIcon() { + BufferedImage im = new BufferedImage(16, 16, + BufferedImage.TYPE_INT_ARGB); + Graphics gr = im.createGraphics(); + gr.setColor(Color.white); + gr.fillRect(0, 0, 16, 5); + gr.setColor(Color.blue); + gr.fillRect(0, 5, 16, 10); + gr.setColor(Color.red); + gr.fillRect(0, 10, 16, 16); + gr.dispose(); + + tray = SystemTray.getSystemTray(); + icon = new TrayIcon(im); + icon.setImageAutoSize(true); + icon.addActionListener(e -> PassFailJFrame.log(e.toString())); + + try { + tray.add(icon); + } catch (AWTException e) { + throw new RuntimeException("Error while adding" + + " icon to system tray", e); + } + } +} From 38b523f29315f8ea58b1feabcefe6217cc4c9793 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 16 Apr 2025 13:03:24 +0000 Subject: [PATCH 191/846] 8339982: Open source several AWT Mouse tests - Batch 2 Backport-of: b6a4047387dbe4e07df0032dfdd7ee5ad8f571a4 --- test/jdk/ProblemList.txt | 1 + .../DefaultScreenDeviceTest.java | 116 ++++++++++ test/jdk/java/awt/Mouse/DoubleClickTest.java | 88 +++++++ test/jdk/java/awt/Mouse/MouseClickCount.java | 69 ++++++ .../awt/Mouse/MouseDragEnterExitTest.java | 117 ++++++++++ test/jdk/java/awt/Mouse/MouseDragTest.java | 215 ++++++++++++++++++ 6 files changed, 606 insertions(+) create mode 100644 test/jdk/java/awt/GraphicsEnvironment/DefaultScreenDeviceTest.java create mode 100644 test/jdk/java/awt/Mouse/DoubleClickTest.java create mode 100644 test/jdk/java/awt/Mouse/MouseClickCount.java create mode 100644 test/jdk/java/awt/Mouse/MouseDragEnterExitTest.java create mode 100644 test/jdk/java/awt/Mouse/MouseDragTest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 07b3d9f37d8c2..9a1634da99628 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -455,6 +455,7 @@ java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.j java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java 7107528 linux-all,macosx-all java/awt/Mouse/MouseDragEvent/MouseDraggedTest.java 8080676 linux-all java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersInKeyEvent.java 8157147 linux-all,windows-all,macosx-all +java/awt/Mouse/MouseClickCount.java 8017182 macosx-all java/awt/Mouse/TitleBarDoubleClick/TitleBarDoubleClick.java 8148041 linux-all java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java 6847163 linux-all java/awt/xembed/server/RunTestXEmbed.java 7034201 linux-all diff --git a/test/jdk/java/awt/GraphicsEnvironment/DefaultScreenDeviceTest.java b/test/jdk/java/awt/GraphicsEnvironment/DefaultScreenDeviceTest.java new file mode 100644 index 0000000000000..b59460322daf6 --- /dev/null +++ b/test/jdk/java/awt/GraphicsEnvironment/DefaultScreenDeviceTest.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.Frame; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Label; +import java.awt.Rectangle; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.List; + +/* + * @test + * @bug 4473671 + * @summary Test to verify GraphicsEnvironment.getDefaultScreenDevice always + * returning first screen + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DefaultScreenDeviceTest + */ + +public class DefaultScreenDeviceTest { + private static Frame testFrame; + + public static void main(String[] args) throws Exception { + GraphicsEnvironment ge = GraphicsEnvironment. + getLocalGraphicsEnvironment(); + GraphicsDevice[] gds = ge.getScreenDevices(); + if (gds.length < 2) { + System.out.println("Test requires at least 2 displays"); + return; + } + + String INSTRUCTIONS = """ + 1. The test is for systems which allows primary display + selection in multiscreen systems. + Set the system primary screen to be the rightmost + (i.e. the right screen in two screen configuration) + This can be done by going to OS Display Settings + selecting the screen and checking the 'Use this device + as primary monitor' checkbox. + 2. When done, click on 'Frame on Primary Screen' button and + see where the frame will pop up + 3. If Primary Frame pops up on the primary display, + the test passed, otherwise it failed + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .build() + .awaitAndCheck(); + } + + private static List initialize() { + Frame frame = new Frame("Default screen device test"); + GraphicsConfiguration gc = + GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getDefaultConfiguration(); + + testFrame = new Frame("Primary screen frame", gc); + frame.setLayout(new BorderLayout()); + frame.setSize(200, 200); + + Button b = new Button("Frame on Primary Screen"); + b.addActionListener(e -> { + if (testFrame != null) { + testFrame.setVisible(false); + testFrame.dispose(); + } + + testFrame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e1) { + testFrame.setVisible(false); + testFrame.dispose(); + } + }); + testFrame.add(new Label("This frame should be on the primary screen")); + testFrame.setBackground(Color.red); + testFrame.pack(); + Rectangle rect = gc.getBounds(); + testFrame.setLocation(rect.x + 100, rect.y + 100); + testFrame.setVisible(true); + }); + frame.add(b); + return List.of(testFrame, frame); + } +} diff --git a/test/jdk/java/awt/Mouse/DoubleClickTest.java b/test/jdk/java/awt/Mouse/DoubleClickTest.java new file mode 100644 index 0000000000000..037332a40981e --- /dev/null +++ b/test/jdk/java/awt/Mouse/DoubleClickTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.TextArea; + +/* + * @test + * @bug 4092370 + * @summary Test to verify double click + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DoubleClickTest + */ + +public class DoubleClickTest { + static TextArea ta = new TextArea("", 10, 40); + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Double click on the red area. + 2. Verify that the event reports click_count > 1 on + Double-Click. If click_count shows only 1 for every + Double-Clicks then test FAILS, else test PASS. + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .build() + .awaitAndCheck(); + } + + public static Frame initialize() { + Frame frame = new Frame("Double-click Test"); + frame.setLayout(new BorderLayout()); + frame.add("East", new MyPanel(ta)); + frame.add("West", ta); + frame.setSize(200, 200); + return frame; + } +} + +class MyPanel extends Panel { + TextArea ta; + + MyPanel(TextArea ta) { + this.ta = ta; + setBackground(Color.red); + } + + public Dimension getPreferredSize() { + return new Dimension(50, 50); + } + + + public boolean mouseDown(Event event, int x, int y) { + ta.append("event click count= " + event.clickCount + "\n"); + return false; + } +} diff --git a/test/jdk/java/awt/Mouse/MouseClickCount.java b/test/jdk/java/awt/Mouse/MouseClickCount.java new file mode 100644 index 0000000000000..a63d24fcb9ffb --- /dev/null +++ b/test/jdk/java/awt/Mouse/MouseClickCount.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Frame; +import java.awt.TextArea; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 4199397 + * @summary Test to mouse click count + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MouseClickCount + */ + +public class MouseClickCount { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Clicking on Frame panel quickly will produce clickCount larger than 1 + in the TextArea the count is printed for each mouse click + 2. Verify that a left-button click followed by a right button click quickly + will not generate 1, 2, i.e. it's not considered a double clicking. + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .build() + .awaitAndCheck(); + } + + private static Frame initialize() { + Frame f = new Frame("Mouse Click Count Test"); + final TextArea ta = new TextArea(); + f.add("South", ta); + f.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + if (e.getClickCount() == 1) ta.append("\n1"); + else ta.append(", " + e.getClickCount()); + } + }); + f.setSize(300, 500); + return f; + } +} diff --git a/test/jdk/java/awt/Mouse/MouseDragEnterExitTest.java b/test/jdk/java/awt/Mouse/MouseDragEnterExitTest.java new file mode 100644 index 0000000000000..b2d8e446ffc36 --- /dev/null +++ b/test/jdk/java/awt/Mouse/MouseDragEnterExitTest.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; + +/* + * @test + * @bug 4141361 + * @summary Test to Ensures that mouse enter / exit is delivered to a new + * frame or component during a drag + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MouseDragEnterExitTest + */ + +public class MouseDragEnterExitTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Click on the blue frame, drag to the white frame, and back + You should get enter/exit messages for the frames when dragging + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(MouseEvents.initialize()) + .logArea(8) + .build() + .awaitAndCheck(); + } +} + +class MouseEvents extends Frame { + static int WITH_WIDGET = 0; + + public MouseEvents(int mode) { + super("Mouse Drag Enter/Exit Test"); + setSize(300, 300); + + addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + PassFailJFrame.log("Frame MOUSE_ENTERED" + ": " + " " + + e.getX() + " " + e.getY()); + } + + @Override + public void mouseExited(MouseEvent e) { + PassFailJFrame.log("Frame MOUSE_EXITED" + ": " + " " + + e.getX() + " " + e.getY()); + } + }); + + if (mode == WITH_WIDGET) { + setLayout(new BorderLayout()); + add("Center", new SimplePanel()); + } + } + + public static List initialize() { + MouseEvents m = new MouseEvents(MouseEvents.WITH_WIDGET); + m.setLocation(500, 300); + MouseEvents t = new MouseEvents(MouseEvents.WITH_WIDGET + 1); + t.setLocation(200, 200); + return List.of(m, t); + } +} + +class SimplePanel extends Panel { + public SimplePanel() { + super(); + setName("Test Panel"); + addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + PassFailJFrame.log("Panel MOUSE_ENTERED" + ": " + " " + + e.getX() + " " + e.getY()); + } + + @Override + public void mouseExited(MouseEvent e) { + PassFailJFrame.log("Panel MOUSE_EXITED" + ": " + " " + + e.getX() + " " + e.getY()); + } + }); + setSize(100, 100); + setBackground(Color.blue); + } +} + diff --git a/test/jdk/java/awt/Mouse/MouseDragTest.java b/test/jdk/java/awt/Mouse/MouseDragTest.java new file mode 100644 index 0000000000000..cb8be7b0de25b --- /dev/null +++ b/test/jdk/java/awt/Mouse/MouseDragTest.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.MouseMotionListener; + +/* + * @test + * @bug 4035189 + * @summary Test to verify that Drag events go to wrong component + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MouseDragTest + */ + +class HeavySquare extends Canvas { + private final Color colorNormal; + private boolean gotADragEvent; + + public HeavySquare(Color color) { + colorNormal = color; + setBackground(colorNormal); + new MouseChecker(this); + addMouseMotionListener(new DragAdapter()); + addMouseListener(new PressReleaseAdapter()); + } + + class DragAdapter extends MouseMotionAdapter { + public void mouseDragged(MouseEvent ev) { + if (gotADragEvent) + return; + + Point mousePt = ev.getPoint(); + Dimension csize = getSize(); + boolean inBounds = + (mousePt.x >= 0 && mousePt.x <= csize.width && + mousePt.y >= 0 && mousePt.y <= csize.height); + if (!inBounds) { + setBackground(Color.green); + } + gotADragEvent = true; + } + } + + class PressReleaseAdapter extends MouseAdapter { + public void mousePressed(MouseEvent ev) { + gotADragEvent = false; + } + + public void mouseReleased(MouseEvent ev) { + setBackground(colorNormal); + } + } + + public Dimension preferredSize() { + return new Dimension(50, 50); + } +} + +class MouseFrame extends Frame { + public MouseFrame() { + super("MouseDragTest"); + new MouseChecker(this); + setLayout(new FlowLayout()); + add(new HeavySquare(Color.red)); + add(new HeavySquare(Color.blue)); + setBounds(new Rectangle(20, 20, 400, 300)); + } +} + +public class MouseDragTest { + static Frame TestFrame; + + public MouseDragTest() { + TestFrame = new MouseFrame(); + } + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. A frame with two boxes will appear. Click and drag _very_ quickly + off one of the components. You will know you were quick enough + when the component you dragged off of turns green + 2. Repeat this several times on both boxes, ensuring you get them + to turn green. The components should revert to their original + color when you release the mouse + 3. The test FAILS if the component doesn't revert to original + color, else PASS. + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(new MouseFrame()) + .build() + .awaitAndCheck(); + } +} + +class MouseChecker implements MouseListener, MouseMotionListener { + private boolean isPressed = false; + private MouseEvent evPrev = null; + private MouseEvent evPrevPrev = null; + + public MouseChecker(Component comp) { + comp.addMouseListener(this); + comp.addMouseMotionListener(this); + } + + private void recordEv(MouseEvent ev) { + evPrevPrev = evPrev; + evPrev = ev; + } + + private synchronized void failure(String str) { + PassFailJFrame.forceFail("Test Failed : "+str); + } + + public void mouseClicked(MouseEvent ev) { + if (!(evPrev.getID() == MouseEvent.MOUSE_RELEASED && + evPrevPrev.getID() == MouseEvent.MOUSE_PRESSED)) { + failure("Got mouse click without press/release preceding."); + } + recordEv(ev); + } + + public void mousePressed(MouseEvent ev) { + recordEv(ev); + if (isPressed) { + failure("Got two mouse presses without a release."); + } + isPressed = true; + } + + public void mouseReleased(MouseEvent ev) { + recordEv(ev); + if (!isPressed) { + failure("Got mouse release without being pressed."); + } + isPressed = false; + } + + public void mouseEntered(MouseEvent ev) { + recordEv(ev); + Point mousePt = ev.getPoint(); + Component comp = (Component) ev.getSource(); + Dimension size = comp.getSize(); + boolean inBounds = + (mousePt.x >= 0 && mousePt.x <= size.width && + mousePt.y >= 0 && mousePt.y <= size.height); + + if (!inBounds) { + failure("Got mouse entered, but mouse not inside component."); + } + } + + public void mouseExited(MouseEvent ev) { + recordEv(ev); + Point mousePt = ev.getPoint(); + Component comp = (Component) ev.getSource(); + if (comp instanceof Frame) { + return; + } + Dimension size = comp.getSize(); + boolean isOnChild = (comp != comp.getComponentAt(mousePt)); + boolean inBounds = + (mousePt.x >= 0 && mousePt.x <= size.width && + mousePt.y >= 0 && mousePt.y <= size.height); + if (!isOnChild && inBounds) { + failure("Got mouse exit, but mouse still inside component."); + } + } + + public void mouseDragged(MouseEvent ev) { + recordEv(ev); + if (!isPressed) { + failure("Got drag without a press first."); + } + } + + public void mouseMoved(MouseEvent ev) { + recordEv(ev); + } +} From c395a9919003aa045a2c7c7297741fd4e4a28571 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 16 Apr 2025 13:05:11 +0000 Subject: [PATCH 192/846] 8341447: Open source closed frame tests # 5 Reviewed-by: rschmelter Backport-of: 966eb7232ff867d9a68269d5a2007da20259565f --- test/jdk/ProblemList.txt | 3 +- test/jdk/java/awt/Frame/FocusTest.java | 151 ++++++++++++++++++ .../java/awt/Frame/InitialIconifiedTest.java | 54 ++++++- 3 files changed, 200 insertions(+), 8 deletions(-) create mode 100644 test/jdk/java/awt/Frame/FocusTest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 9a1634da99628..7a81a208e1f53 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -121,7 +121,8 @@ java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusToFrontTest.java 6848406 gen java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusSetVisibleTest.java 6848407 generic-all java/awt/Frame/MaximizedUndecorated/MaximizedUndecorated.java 8022302 generic-all java/awt/Frame/FrameLocation/FrameLocation.java 8233703 linux-all -java/awt/Frame/InitialIconifiedTest.java 8203920 macosx-all,linux-all +java/awt/Frame/InitialIconifiedTest.java 7144049,8203920 macosx-all,linux-all +java/awt/Frame/FocusTest.java 8341480 macosx-all java/awt/FileDialog/FileDialogIconTest/FileDialogIconTest.java 8160558 windows-all java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java 8060176 windows-all,macosx-all java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java 8060176 windows-all,macosx-all diff --git a/test/jdk/java/awt/Frame/FocusTest.java b/test/jdk/java/awt/Frame/FocusTest.java new file mode 100644 index 0000000000000..14d194789fe94 --- /dev/null +++ b/test/jdk/java/awt/Frame/FocusTest.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.Window; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +/* + * @test + * @bug 4140293 + * @summary Tests that focus is returned to the correct Component when a Frame + * is reactivated. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual FocusTest + */ + +public class FocusTest { + private static final String INSTRUCTIONS = """ + Click on the bottom rectangle. Move the mouse slightly. + A focus rectangle should appear around the bottom rectangle. + + Now, deactivate the window and then reactivate it. + (You would click on the caption bar of another window, + and then on the caption bar of the FocusTest Frame.) + + If the focus rectangle appears again, the test passes. + If it does not appear, or appears around the top rectangle, + the test fails. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("FocusTest Instructions") + .instructions(INSTRUCTIONS) + .columns(45) + .logArea(6) + .testUI(FocusTest::createAndShowUI) + .build() + .awaitAndCheck(); + } + + private static Window createAndShowUI() { + Frame frame = new Frame("FocusTest"); + + frame.add(new FocusTestPanel()); + frame.setSize(400, 400); + + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + frame.dispose(); + } + }); + + frame.validate(); + return frame; + } + + private static class FocusTestPanel extends Panel { + PassiveClient pc1 = new PassiveClient("pc1"); + PassiveClient pc2 = new PassiveClient("pc2"); + + public FocusTestPanel() { + super(); + setLayout(new GridLayout(2, 1, 10, 10)); + add(pc1); + add(pc2); + } + } + + private static class PassiveClient extends Canvas implements FocusListener { + boolean haveFocus = false; + final String name; + + PassiveClient(String name) { + super(); + this.name = name; + setSize(400, 100); + setBackground(Color.cyan); + setVisible(true); + setEnabled(true); + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + requestFocus(); + } + }); + addFocusListener(this); + } + + public void paint(Graphics g) { + g.setColor(getBackground()); + Dimension size = getSize(); + g.fillRect(0, 0, size.width, size.height); + if (haveFocus) { + g.setColor(Color.black); + g.drawRect(0, 0, size.width - 1, size.height - 1); + g.drawRect(1, 1, size.width - 3, size.height - 3); + } + g.setColor(getForeground()); + } + + public void focusGained(FocusEvent event) { + haveFocus = true; + paint(getGraphics()); + PassFailJFrame.log("<<<< %s Got focus!! %s>>>>".formatted(this, event)); + } + + public void focusLost(FocusEvent event) { + haveFocus = false; + paint(getGraphics()); + PassFailJFrame.log("<<<< %s Lost focus!! %s>>>>".formatted(this, event)); + } + + @Override + public String toString() { + return "PassiveClient " + name; + } + } +} diff --git a/test/jdk/java/awt/Frame/InitialIconifiedTest.java b/test/jdk/java/awt/Frame/InitialIconifiedTest.java index f3f43929e7b16..4a8d959566575 100644 --- a/test/jdk/java/awt/Frame/InitialIconifiedTest.java +++ b/test/jdk/java/awt/Frame/InitialIconifiedTest.java @@ -50,36 +50,75 @@ public class InitialIconifiedTest { private static Robot robot; + private static final StringBuilder FAILURES = new StringBuilder(); + public static void main(String[] args) throws Exception { robot = new Robot(); - try { - EventQueue.invokeAndWait(InitialIconifiedTest::initAndShowGui); + EventQueue.invokeAndWait(InitialIconifiedTest::initAndShowBackground); robot.waitForIdle(); robot.delay(500); - test(); + + test(false); + test(true); } finally { EventQueue.invokeAndWait(() -> { backgroundFrame.dispose(); testedFrame.dispose(); }); } + + if (!FAILURES.isEmpty()) { + throw new RuntimeException(FAILURES.toString()); + } + } + + private static void test(boolean isUndecorated) throws Exception { + String prefix = isUndecorated ? "undecorated" : "decorated"; + + EventQueue.invokeAndWait(() -> initAndShowTestedFrame(isUndecorated)); + // On macos, we can observe the animation of the window from the initial + // NORMAL state to the ICONIFIED state, + // even if the window was created in the ICONIFIED state. + // The following delay is commented out to capture this animation + // robot.waitForIdle(); + // robot.delay(500); + if (!testIfIconified(prefix + "_no_extra_delay")) { + FAILURES.append("Case %s frame with no extra delay failed\n" + .formatted(isUndecorated ? "undecorated" : "decorated")); + } + + EventQueue.invokeAndWait(() -> initAndShowTestedFrame(isUndecorated)); + robot.waitForIdle(); + robot.delay(500); + if (!testIfIconified(prefix + "_with_extra_delay")) { + FAILURES.append("Case %s frame with extra delay failed\n" + .formatted(isUndecorated ? "undecorated" : "decorated")); + } } - private static void initAndShowGui() { + private static void initAndShowBackground() { backgroundFrame = new Frame("DisposeTest background"); backgroundFrame.setUndecorated(true); backgroundFrame.setBackground(Color.RED); backgroundFrame.setBounds(backgroundFrameBounds); backgroundFrame.setVisible(true); + } + private static void initAndShowTestedFrame(boolean isUndecorated) { + if (testedFrame != null) { + testedFrame.dispose(); + } testedFrame = new Frame("Should have started ICONIC"); + if (isUndecorated) { + testedFrame.setUndecorated(true); + } testedFrame.setExtendedState(Frame.ICONIFIED); testedFrame.setBounds(testedFrameBounds); testedFrame.setVisible(true); } - private static void test() { + private static boolean testIfIconified(String prefix) { BufferedImage bi = robot.createScreenCapture(backgroundFrameBounds); int redPix = Color.RED.getRGB(); @@ -88,11 +127,12 @@ private static void test() { if (bi.getRGB(x, y) != redPix) { try { ImageIO.write(bi, "png", - new File("failure.png")); + new File(prefix + "_failure.png")); } catch (IOException ignored) {} - throw new RuntimeException("Test failed"); + return false; } } } + return true; } } From d5e87b4924d441068b4abaa9e4cb6d5bec503a19 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 16 Apr 2025 13:07:47 +0000 Subject: [PATCH 193/846] 8340193: Open source several AWT Dialog tests - Batch 1 Backport-of: 2d8fcc4271802b211c4718c6abae3ce9c99eafbd --- .../Dialog/DialogIconTest/DialogIconTest.java | 91 ++++++ .../awt/Dialog/DialogIconTest/swing.small.gif | Bin 0 -> 1136 bytes .../jdk/java/awt/Dialog/DialogResizeTest.java | 118 ++++++++ .../FileDialogIconTest.java | 258 ++++++++++++++++++ .../java/awt/Dialog/FileDialogIconTest/T1.gif | Bin 0 -> 2553 bytes .../java/awt/Dialog/FileDialogIconTest/T2.gif | Bin 0 -> 2704 bytes .../java/awt/Dialog/FileDialogIconTest/T3.gif | Bin 0 -> 2523 bytes .../java/awt/Dialog/FileDialogIconTest/T4.gif | Bin 0 -> 2721 bytes .../Dialog/FileDialogIconTest/loading-msg.gif | Bin 0 -> 1518 bytes .../awt/Dialog/FileDialogWrongNameCrash.java | 72 +++++ .../java/awt/Dialog/GetLocationTest_1.java | 129 +++++++++ 11 files changed, 668 insertions(+) create mode 100644 test/jdk/java/awt/Dialog/DialogIconTest/DialogIconTest.java create mode 100644 test/jdk/java/awt/Dialog/DialogIconTest/swing.small.gif create mode 100644 test/jdk/java/awt/Dialog/DialogResizeTest.java create mode 100644 test/jdk/java/awt/Dialog/FileDialogIconTest/FileDialogIconTest.java create mode 100644 test/jdk/java/awt/Dialog/FileDialogIconTest/T1.gif create mode 100644 test/jdk/java/awt/Dialog/FileDialogIconTest/T2.gif create mode 100644 test/jdk/java/awt/Dialog/FileDialogIconTest/T3.gif create mode 100644 test/jdk/java/awt/Dialog/FileDialogIconTest/T4.gif create mode 100644 test/jdk/java/awt/Dialog/FileDialogIconTest/loading-msg.gif create mode 100644 test/jdk/java/awt/Dialog/FileDialogWrongNameCrash.java create mode 100644 test/jdk/java/awt/Dialog/GetLocationTest_1.java diff --git a/test/jdk/java/awt/Dialog/DialogIconTest/DialogIconTest.java b/test/jdk/java/awt/Dialog/DialogIconTest/DialogIconTest.java new file mode 100644 index 0000000000000..06debe28fc551 --- /dev/null +++ b/test/jdk/java/awt/Dialog/DialogIconTest/DialogIconTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Image; +import java.awt.Label; +import java.awt.MediaTracker; +import java.awt.Toolkit; +import java.awt.Window; +import java.util.List; + +/* + * @test + * @bug 4779641 + * @summary Test to verify that Non-resizable dialogs should not show icons + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DialogIconTest + */ + +public class DialogIconTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. This is a Windows-only test of Dialog icons + 2. You can see a frame with a swing icon and two dialogs that it + owns. The resizable dialog should have the same icon as the + frame. The non-resizable dialog should have no icon at all + 3. Press PASS if this is true, press FAIL otherwise + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .build() + .awaitAndCheck(); + } + + public static List initialize() { + Frame f = new Frame("Parent frame"); + f.setBounds(50, 50, 200, 200); + + Dialog dr = new Dialog(f, "Resizable Dialog"); + dr.setLocation(100, 100); + dr.add(new Label("Should inherit icon from parent")); + dr.pack(); + + Dialog dn = new Dialog(f, "NON Resizable Dialog"); + dn.setLocation(150, 150); + dn.add(new Label("Should have no icon")); + dn.pack(); + dn.setResizable(false); + + String fileName = System.getProperty("test.src") + + System.getProperty("file.separator") + "swing.small.gif"; + + Image icon = Toolkit.getDefaultToolkit().createImage(fileName); + MediaTracker tracker = new MediaTracker(f); + tracker.addImage(icon, 0); + try { + tracker.waitForAll(); + } catch (InterruptedException ie) { + throw new RuntimeException("MediaTracker addImage Interrupted!"); + } + f.setIconImage(icon); + return List.of(f, dn, dr); + } +} diff --git a/test/jdk/java/awt/Dialog/DialogIconTest/swing.small.gif b/test/jdk/java/awt/Dialog/DialogIconTest/swing.small.gif new file mode 100644 index 0000000000000000000000000000000000000000..14a489ff4e7df0b4a268582701a1e7ef655047fa GIT binary patch literal 1136 zcmV-$1dsbiNk%w1VL$*t0QCR>_xJa}z`*bC@8{>|*4EagrKOCFjD&=QeSLjeT3Tac zW0aJXwY9ZrX=zeYQZX?xDJdx!7#Ii$2mk;85D*X{AtA=b#@^oEb8~Y_N=iaPLanW> zoSdAhs;ZWjmSb94)6>&TOiV%u7-I+_F&GGx5HWKYDV!lftvOoo@bFR?5PKL1jD&=* zudk()gq(X?j9M{!N-29vA%ts6b5c2DLLr=lbG@aU|Ns9|LNQt~5K=J^LLmrBDF{+2 z5IG?TA^8LW00031EC2ui06+jh000L5z<_W_EE5BEk63?u2XB#Ki+2bU6B-(+VV7|Ys1pivl9>%6B$wrjDnqEyr{Dp!$}Mc z5q+OT$x<1{$I(T95vY$GhC{0riB}G>s0vLRtEdn~23A8DvlIaa4GtL%!A%USvl8w~ z2qch8P-K)KW8_eUW0I!9g9!wcFqoEb;ie)R5+;1`Pv3(G8?13CmawCiA__Dnl=oy` zL?i|TYGgU&3y}laRFZ?jL4p1+m^x_{DK%uAN}0N#EWq&72!^1&3O<^qVUYm?9MEuB zB>~C-bVnLcpddkni4h`@HYjpS2!{#glyzj1NkP6%5dt(AQKD~&6EYW`^j1sFEezcP z9FV{O2L!);Q+Pm?j{zGY4Io&f(w4&k&k{HQ!0`ie2^1(qOxVWAK!wdyo(b7Ep#hHD z8CI+?o%Ye?1r+Xv;Z_8~g8{d3bReM{@`MTn11zW@oK!vx5(p&60RRE>z9vW{m4g6T zAXfo6gx;RKfQAYxG;GMQZU}=1l?)SkpkXxo+W`27Lk5M-lYvF1z_Azz|1~(^I^2*^ zoqlIjfPjDwCKtj4bN-}(-X4FXVL$}hWyoF#_3@!e05$~x0S6}jmqSw*X)?)l7sSZk zjP@ZIM>_#zfB|wkCYM79LrkK{8w|WwLkzIM!~WoH0h(A==?pdK;DgH_f84{v zJVYF@nJd~?K)E!u{IbVA$jrmc5r2>~6D_z images; + static String fileBase; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Select the Image for a Dialog and Frame using either + Load/Save/Just Dialog. + 2. Set the Icon Image/s to Frame and Dialog. Verify that the + Icon is set for the respective Frame and Dialog. + If selected Icon is set to Frame and Dialog press PASS + else FAIL. + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .logArea(8) + .build() + .awaitAndCheck(); + } + + public static void setImagesToFD(java.util.List listIcon) { + FileDialogIconTest.images = listIcon; + } + + public static void setImagesToFrame(java.util.List listIcon) { + frame.setIconImages(listIcon); + } + + public static void setImageToFD(Image img) { + FileDialogIconTest.image = img; + } + + public static void setImageToFrame(Image img) { + frame.setIconImage(img); + } + + public static Frame initialize() { + frame = new Frame("FileDialogIconTest"); + Button setImageButton1 = new Button("setIconImageToFrame"); + Button setImageButton2 = new Button("setIconImageToDialog"); + Button setImageButton3 = new Button("setIconImagesToFrame"); + Button setImageButton4 = new Button("setIconImagesToDialog"); + Button setImageButton5 = new Button("setIconBufferedImagesToDialog"); + Button setImageButton6 = new Button("setIconBufferedImagesToFrame"); + + if (System.getProperty("test.src") == null) { + fileBase = ""; + } else { + fileBase = System.getProperty("test.src") + System.getProperty("file.separator"); + } + + final String fileName = fileBase + "loading-msg.gif"; + + setImageButton1.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent event) { + try { + Image image = Toolkit.getDefaultToolkit().getImage(fileName); + setImageToFrame(image); + PassFailJFrame.log("Loaded image . setting to frame"); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + + setImageButton2.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent event) { + try { + Image image = Toolkit.getDefaultToolkit().getImage(fileName); + setImageToFD(image); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + + setImageButton3.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent event) { + try { + Image image; + java.util.List list = new java.util.ArrayList(); + for (int i = 1; i <= 4; i++) { + String fileName = fileBase + "T" + i + ".gif"; + image = Toolkit.getDefaultToolkit().getImage(fileName); + PassFailJFrame.log("Loaded image " + fileName + ". setting to the list for frame"); + list.add(image); + } + setImagesToFrame(list); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + + + setImageButton4.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent event) { + try { + Image image; + List list = new ArrayList<>(); + for (int i = 1; i <= 4; i++) { + String fileName = fileBase + "T" + i + ".gif"; + image = Toolkit.getDefaultToolkit().getImage(fileName); + PassFailJFrame.log("Loaded image " + fileName + ". setting to the list for dialog"); + list.add(image); + } + setImagesToFD(list); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + + + setImageButton5.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent event) { + List list = new ArrayList<>(); + try { + Robot robot = new Robot(); + Rectangle rectangle; + for (int i = 1; i <= 4; i++) { + rectangle = new Rectangle(i * 10, i * 10, i * 10 + 40, i * 10 + 40); + java.awt.image.BufferedImage image = robot.createScreenCapture(rectangle); + robot.delay(100); + list.add(image); + } + } catch (Throwable t) { + t.printStackTrace(); + } + PassFailJFrame.log("Captured images and set to the list for dialog"); + } + }); + + setImageButton6.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent event) { + List list = new ArrayList<>(); + try { + Robot robot = new Robot(); + Rectangle rectangle; + for (int i = 1; i <= 4; i++) { + rectangle = new Rectangle(i * 10, i * 10, i * 10 + 40, i * 10 + 40); + java.awt.image.BufferedImage image = robot.createScreenCapture(rectangle); + robot.delay(100); + list.add(image); + } + } catch (Throwable t) { + t.printStackTrace(); + } + PassFailJFrame.log("Captured images and set to the list for frame"); + } + }); + + Button buttonLoad = new Button("Load Dialog"); + Button buttonSave = new Button("Save Dialog"); + Button buttonSimple = new Button("Just Dialog"); + buttonLoad.addActionListener(new MyActionListener(FileDialog.LOAD, "LOAD")); + buttonSave.addActionListener(new MyActionListener(FileDialog.SAVE, "SAVE")); + buttonSimple.addActionListener(new MyActionListener(-1, "")); + + frame.setSize(400, 400); + frame.setLayout(new FlowLayout()); + frame.add(buttonLoad); + frame.add(buttonSave); + frame.add(buttonSimple); + frame.add(setImageButton1); + frame.add(setImageButton2); + frame.add(setImageButton3); + frame.add(setImageButton4); + frame.pack(); + return frame; + } +} + +class MyActionListener implements ActionListener { + int id; + String name; + + public MyActionListener(int id, String name) { + this.id = id; + this.name = name; + } + + public void actionPerformed(ActionEvent ae) { + try { + FileDialog filedialog; + if (id == -1 && Objects.equals(name, "")) { + filedialog = new FileDialog(FileDialogIconTest.frame); + } else { + filedialog = new FileDialog(FileDialogIconTest.frame, name, id); + } + if (FileDialogIconTest.image != null) { + filedialog.setIconImage(FileDialogIconTest.image); + } + + if (FileDialogIconTest.images != null) { + filedialog.setIconImages(FileDialogIconTest.images); + } + filedialog.setVisible(true); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/test/jdk/java/awt/Dialog/FileDialogIconTest/T1.gif b/test/jdk/java/awt/Dialog/FileDialogIconTest/T1.gif new file mode 100644 index 0000000000000000000000000000000000000000..24a7dea299fd1c877792ce09a5b64d1f57c1b323 GIT binary patch literal 2553 zcmVUj1S&E~Ljg3aD)&M9tGcT}~(d!To zlU7%}Yinx^3Su-gH3WCA1!a_IXvTzu&NP_DCyBIcy4y`oPqntT1%$p&YjviUU=Ge8LEq* zb)s9PMTG?}I-MCfA~Ole$_X>g%@sGbxw?`uzCx!AoW;w@&fm}96$a9YyOWh#hqw+I zBHhmw@&@$uE%*2>755Xj7CL?cS#y&G2OV7Qmd%)V!@z_I6evJ^NKuBpd@cI@i_{Cu zsbRSYC>(bqB83ttA*fVY;=uz95oJuUSdX5G40j}vqLL+tF#kpj-g$!tG3AD%NRw_@ z=@Nqg8Bk@kusFd4ADvaQ1Ow^7#WJENAs_`nmh1)qAI>IK`Je;_3>Krxw8{W0A%k3T zD4TJksMxb*(SG>Afy3azC)Pq}`c$qA3axliio)jSBE89=MHEZ+0DvAJB7hhTB7$hs z3pgwojFj!$#!(^vVIxJ3w#!2eoCHiZGzbY2NSj8zVEBU6BhtEd+W0AjKck??aluF= zvkDM7fBx`0cxmFteHN03RJ;JOUpGAV5Qa z0s`oRcnFSQ!%~brr5*+**tG-~hb*!JG7H(q*#Q}JSO3}q2LdP{4J6XgL5T$Z_uqjd zFqoct0=z}Qdjn0l&LZz*NP%|x1=rt!0(KzekVF!RVu~Z6$6SmUJg~-OSjYjANHd6_ z8;`)D24Im~c6lO+1k#{jQ_Q{fz$+bLaYzpiSa8ff6p#Q|k3W)Fqyj=Jfajih771p6 z11|PfnN5xYr4bZP`AkG}`Uql>TwFehFR;73fO?F znGl$8=r3|?VnGEuLO>P=sfH=ual@5sZgJ!R3IAxVdY%BmYcW2ck_e!Rn!!T4m2m25 z2evAnY2J+%oCM~c8y=w0;%UQ@Z>dCpnzsQv&afP4=`X;*k--BG9(aI44Fe2NgU2ZF zV8#ypJv!^8LPFqRlk$>q?GV0NaKkwEor_-s_;l3!)!h{0S65)$my& zNI(5LE7X(o2P1%}Dwj1F+0b;*f#Zct1BobI$ZFsK8VF5*pGzClNZ>pSa0Ul3$RN#v z!3ui#Wdr>K(6cJlffppg0xQr{3Kr;q(BUZr3oKrn7y&v7HlPC~sNe-NXuls&F9X(t z$O9@TqGzS8eI4+@09}YD2ZoFV#RDDtQs=(nQBZz6)F2$T0z~=U#|9(lml4x;A|LcE zWK6^p0$@0R5a=n5%X^~&C};o~$p4Eh1>oTZ8L)y3Kt+fp03(6=q&gD*X91dXBNCBS zfT0ENh=zM(14u9v8CZ}kI0%3ifABau__2-@kQW5PI3OZj>X17i8q+XWoCxq>XewaZ z4Gp)v2E2d-Q<(q;j>kXtIY~@Z=w#HpCIMie*DOq$`QGf)4yA0^T8C4Qfcjghg?V zb(Dd=0C0d9z(A8jxPVU>;Kx5UNsuElrH~G}0P+!TK*jlu0f%-rT9WXMFL(h3>NtTR za#IAq4CizhP|0{bzy|3gBjrPybQ;0PQU4tpoJno15h1I89K&CP5&f)l4agR?1SMg}|kI zk|pRy;K3bnGXt6gC(Wi~g7p~G26qZ-rBqPVq8-(qN_|1yY`1{}93Ybcy^p!q)opm zRU%Nx6@xuzAunZE#VVGJl59W^CQv*3aPt5zh^k+)A-7<_Yfuj`k^AmxSUI9Cu4r4D z>g4*^j8Nb#X8l25O+khNm|##$!hj75yS#hGv5={2ZX9bnMVaDEUuK2sa2OsxtN-Z%Ji1-(lEDOIg3$vCOGf9CSDm#D-2r;58xovWyOkv_8Crte z#nIQWDCLuaIeS;oU2Pu_0j>jt+ukU}fB=hmk%5aB-k`qpqBfK(5Fz{9)26nss}-;b zGRz#Pkl+MJ%`Jl$d|SDGfLjyuuUUKW(F#w93-@WzQ|8NIi%PJzN1W@`W^g?@?U=m* z7K7ZF;*_XNzy`LAtC4G4OY?%R2a;PzNw8~HwEEZy7a+h=1XX1hpJ0kL#BFH3tY3FD zgC21zt65KcW+L>~IEn?u6VnJ4c$ z#aGZE0RnRrRF{C;6R1f&8Uhh#%gNEYK6fdkm%$5UpaRjqm P7x~0Bcm#DS1OWg$YOidd literal 0 HcmV?d00001 diff --git a/test/jdk/java/awt/Dialog/FileDialogIconTest/T2.gif b/test/jdk/java/awt/Dialog/FileDialogIconTest/T2.gif new file mode 100644 index 0000000000000000000000000000000000000000..1f3fd66328ba678811608133a189ae76837cb7db GIT binary patch literal 2704 zcmV;B3UBpCNk%w1VN3u`0M-8hu_Q{*Ol?k0x$Nxh|K0$RjE`e1PgeyW%`jQtbd9MB zG7t@wAP5mAB_^qhn%91U%H|a zhI4xj2yP7sPJ3%H&ax>&Btmg+v>_Ofb#07rKU{BBV^&U-H8pNE5pPaObi!kMhICkd ze$TyzmLeELG%%EufF2-rlvfwZjEA=Y*Wz#t{Gi|Cm8t?amE_F;YS~ zg#Z8lA^!_OL{CCRI!RJ7E-(V#?EoS91OWg5KL9KM0000?08Ib@2LHgHa7Zi~kI1BQ z$!t2G(5Q4uty+&Zn`7%Jbh(b~b*$8O3k42j&1Q4Z-Y}VLMz19jl%&D$>+vRQaAI>( zT6QLTd<=|@j*NYHf?kA$ONV!hkB)ttkrEJZa+XMkYI~jy5`i2Rtr#pOC5nxFl4zr( zLuU}EoF*JD6~hz76FA7o2?;9~1`Uv^foPS5S!uqI5*!o5#Ky(RI0@q`%gv|_dJwoa zmYCTMCc@qo$Km4%8O!|q0n7oMMG8e}jtw*>P&krMpq{;A8TLs$x1!>T02ea`*oZ(8 z9#QVD9OMv>L%nbjmszl|0>gz17-DXmN%JDd9wAh1D_G@V0sj-w7)i+B%~(noD=(Nx zRHA7K6FV*hq=^7Q0IO9IJX^&sSCo<2Ae@{K5osU;FJ5?1>!GcO6fZ)cD6s=UkE>X- zRxJ^ND^Dngd^Irnt*nKFY~6b3u$XbcKZx(gCv${;(F{Y*Fg#t zOnBdmC3NM$B@XlgO#?0%GnxekFo2qQ2`0$kf(;U>po8u$ha3g=y?6r!Cg8F}7oRck z-!UH!_#=BI8hK=qCZhMCk`y>;n*s)4mxLDFb(aA|2^_{2kY9RfCy8E?s2q!C-k?B~ z84__&mE4e(fD0JRY2FB7-U;TTUZS`_3NGHKfC4>GlSCJ&gpf>}D}>k>mtvxqB!o)J zrzCQWp0~h($&GM8rDswAfo@oA=N~frh^JP84$hDwbHpCED1s!i$LEU*P>^YMMR0m! z2KiJ}+@h|=$J%M9F~%IL$T~us}1;C+Pja)(^nI zqKjZtV1wXoTFdrLTbU_a(6v!y!BbdN~1}tzuLgx=mOm*i1kU)Y48aSXq1eP1GHwrB#@9zNx zH2*`5C^QfPMjP!=LiGy^SGIV-gWwT>128Zk2)w5`it*qC5fC2%2~dFc&A@nkiw*$5 zMnC&KZ+|oC!T*58AO+=(1m3IN3|Qbm2vUw~!OOt|$_IxEwl8mb6M(E@n4=RRi72%z8v2I#?Tz{vm`3;>lsI9VR- zQyrc;azXlvPbTYTvmE3uj{l&OVp@Lrq%nrTj6fv9c6!l+`kd(i>>*W&oVHSyy7Prp z%$ps35SJ3n1_1m#+5kR^$omECIm{~PNlWOe6&m$sAh;tObr%7PdcXjb0Vf%USykR7 z!ZuB!0M8EkrB^YrtSx9kS@(+9yyms6f1F`iPw)Z;OlCIxJU~aM3R33DvX@0F6R{|Q5QSg|SAnWxLom$7VnP;Xk}I+(YQoLh5sR>uB5XC=#|X55uty6( zUHrv>13+M^1E{JHd;$Rz(5i=w!rLQ__rlycS9j2@r2DX_*9LeX1Q)1_XnX5XstOkq z5HNt5#E4RCeo||nOaE%#&WlIT`2eq-^?+eH(yZP}fU%7of+d?43J&Kj*$TlV61S_WrrRdw^_<`pK|lmDA3t4uL`~{Xaitj#WJ7-z|F6q zc)_o%rT~Y!L}{I33CC?lKm;HzYy)5t+Qc59yTP5XpnTGU7ST$KBiN+-E{Dxs_K~`I zRR{xKz+-(zl>xt%FlT(?FVcOD0xuYWAKSO&CBGKIEg*q)r_AH4MD+kSm9UUawgnOh z&C5`Q3n$0?T<2CUi+&Y>3e>^?>|$UeMSk$|Qaoo3*?_-BhAUKY;sF@wF1D|=<6iyR z0zt3&Xl>r7V*kmg137=i1|_(&i}u;0wV>bxl+$Zjaco;0iy#6g$e(-*T>=cWgv9mj zZI-o6g(7!Z0UC@APT=AJ6gc|?(8e{iPoRSQ6&4Z(h{>U!I%+Ecm#SAV!2wha9c6dZ zM{G$;TI9>_DTkm0Fu4c@9Nb$g)qv4t5I4D@1Dn?vASY7}_>}c$0C>kl-c{l4s7>(g zAU3)Qf};Th5^H2+%SJYJ*})E8QvwmHEh^eR^i^Q<=H7B(0HyZs7$RPP5R7r$M*d}1 zHWCvA$VB8;8M$b?9RdfWe5zz4!`RL!?w8+rptRBLRn%w~sFqyVHTb#13lVW3I=}#< z9wR^f#hdSPlU!(uu6GG+@N<=0qUt~_0M>i^a-(k@>^80Us3j2LZ=0PIX#c1KOb`OO z*PHE)==P{XV1ggm{qDL5oZyBD^cp?G#3ly3VjGYqf9jy@h)=u_7SH&52XQ2xS;{oR zaPLxMe(IV>0_Qz{_^Fm1^Y{&V>Xm?YAh!PYA9eV{XJ3Sf43n3VVR-D8sHgXUyp~kIBhkv1JVwC^? z|NsC0A^!_OL{CCRI!RJ7E-(V#?EoS91OWg5KL9KM0000?08Ib@2LHgHa7Zi~kI1BQ z$!t2G(5Q4uty+_qYz(vAX0PC;HfAWB&*hl<8*cy9v<{*v1zC z?(gmK0PO%3-kEA{S!KF~=+wpl;HX!@fx&_ZE68{^@0~phHNepd;|Z39X~2rPGw5K% zhzB4;HW<-hgFzW68E(`NF%6q4YCtKwknvbSj}JKL+{u%J$o~co3MgC%U||IiEhkpN zkjoH>U^YAEa-3;?@OFsA?naC@jO0lBq;=g_0eeoosq z-vWKHkKhrmEEA@{&k4g(;iFp&Nb(_xIn0s4znU zqd8C-0xG1&Tx;ze;GlyaeDL6e@45G!1SrsO*>(Cg5dT0pVw6*eF9nt+00_&;HerM; zMo8g{?O}-DZP)=7z#2<@R>%tkw&Q?tIiR?p0`Rri;)@WnNMVM1?Y99?N?{?Q1=s-4 zky|OO_F9rgx=3GiTq^nC2OM~%-;*A0a)e-okbq5jSgN+=0bP12A8fL*xWEEO()oc7 zdU04lR}SPOC2$sGQiYIfvt6BN`t2$1(3w3 z4v1?UYCV{15&@tEIJ5&NTzJkm@Ps`? zfF}>p643C&eA0QY#CzVGTLHYD;H?o{$fQ9)S8~wk1nrIdU6kns=TO#%Y3Kk5X6ib5X{LI}^bwy??sL_q7j3pf}fkz;;fE5$YD1j3pz z0M{{FIhg>Pz{+M20)4Gza5Mo*GtfZ?IWS$HxqfDfLUx1Zu0{?@?nQvZ!#T=k;;maJeHyo^X z${j=?f!vuwz=8uPRjyMEx8p8}3h!Jg*Y6{%P&V;LAAP*7dlId}`lHvnz|#vr@WBaS zZD3pgFyuePZ=`JAv+sZtQ@~*3fx{s#UMxeO1*XNP7Dx+y@}l4DN`pWB34wna@SnxL z7dNIk$OQy6;0hQ}I<}$j1`)88${@G^3Cf^r0;pj2-jIt7ilqS>dJdPCWdJ;l4r%c! z9sJO@rxa$Y0|c;@>0HRIs>pB%;8B4FP*MiC_-wCU;H3& zgA)`*1{OO`0N^-7rhI~q6&RGo@JON18NdTYdshvP$2N3bNCFX3K;Gn{jPY*(1urVQSPscOCKwkKO#!cahtda%5 z4C*me%VL(En!QCF%(NdG(Dqu^vMq9<7d_L(kRArIECZ+sTr8-;0Pu`$hjeh%YSq@e z$-NbLn+pL1qyV}jQ2#AXtE&WDkc38q(t!zY06p-c@mjSFuM$nCf`Al+0}OC0Yg>!A z7zCgz@O^-MyL(?fHJG{Nl~;eEYtzeSHn^Qo!$B?p+!vgW=Fe4Cmx|*1^n!ec5vg>9b<>7{5JvMkwK>8OkDMUX=U%o32HfaoNIQQqFgKX1T^XKSCBVzRDZSa-3?bx?uoxhL2>>4O zhBw>-B$%h2SImifW0amTAb|=j;P8OI*=iFfc)^Px?VM(o3#u@M%46WIkgIs)ODMU^ lXC87W!`uk>ra8^ycylM@T<4V3?A3bCgxgtM+O`M+06SJcV>kc+ literal 0 HcmV?d00001 diff --git a/test/jdk/java/awt/Dialog/FileDialogIconTest/T4.gif b/test/jdk/java/awt/Dialog/FileDialogIconTest/T4.gif new file mode 100644 index 0000000000000000000000000000000000000000..67876264d8f7f4d350815a4e08f6eb1ec6f1bb0e GIT binary patch literal 2721 zcmV;S3SRX`Nk%w1VN3u`0M-8h+uPd)OKmeRut%%b1&+)A-T-Zurw|d6O-8tt((P<) zYz_@)Gcz*;cdh~~KPiZ@1!t2pn8s_m+m@J_dV0=4NK3e)FSWL|o{U1!v?7X#hXsVa z23d`eeNRtob!~@{7#O8&Z@wCJo}8_&OK_A%PmxkbYh(#A^!_OL{CCRI!RJ7E-(V#?EoS91OWg5KL9KM0000?08Ib@2LHgHa7Zi~kI1BQ z$!t2G(5Q4uty+_pY<6_vX0PDpwl*ni&S*_}QuBu2!qLbKgDH55*NgYMD-?BVY+rCv zTXcLC6%34xjf#4BFlse57llrT8Ze2Do{Ec(kdl;ym`7a`8hN3j9xxvUva=r~9<7Rh zlM`I0MO`(kFRcs}9tJ20%FD_&&d)mrx5azAZN5UOoW#e;%+KJ@5;o&5J3GS_)oQ(k zS;2XZ9wW>N&Jy?%1N;0g{{HyeM-4X9N;J*^IC%=BG!8da)WsVUw{y$Ye`gRNb4 zKKR3qq#>d_8l_Z*&!UL7QXRAi&?7~P5-dtQPJx(i-3IHPr?~|b#0y7$%U};MT zZWTZF5F!Kx3aw+uhymI0)R_%1XWr^_mnkv9L^BvnZa~Yn4g#bg;rcaf*|TSdh=Cx+ z3d*>3?hEcfrn-iTvVO| z=s5=)dk6@Spa2Xm_?~+u;BZxa_u)4PaG^2sLNer7g#TO#=}p%jgAA&0!-*=WprC^8 zu_(X_IMkIJ0W{LM!3P?&@f|7?C=d#V5?J(QVRPduf6YC3Q%GfTEI4a*&&LS2kdPB|8pr0hgmGb(~Zz1d2e4QNCBAlPt!7K><3H zZ~zFao_NEOEjSA4l_Xq)MURVAfC5Ahlvm(%47%E22o|8KfB>Yjs6hc46kx%s2dt{- z4T|D0V~sRHV1SlHjIatLA2?&2pUTM=ER!j=Xa7MC9W;A_p{3?v!3`Z05G@EYNXulj z)Sg}gIN`fqgHt!QXnX`YpPg42PbBb!!9$5Um0= zGgz+*2k=k;4?X)Fx5hZ!cjZ$f3tW^jysFH?+i*WEt(rPuK&=2dWWeCgte%>$#*%;C zLId_49stos@OKgk5_qI^3nj1@xz|rSS^sYdn-@?50yQ&<^8$h2E3MB5kd7^CB=8u| z4r})cmF%#0>Vg}>l}w9hDnc22v}D21b{cJMGI%dd*8mG zwSdtD5GGO?fdRWEj2EmV0uA6m3J~QquSttd(J26`GEl6C;h|>48{XHV)w2fZ1cl`> zzzl|HsZ|(bA2e_YR8}w|2YSs(?x|O^P;~+fSYV1W%)kj`z`vjIumvm#;0A&?#1a0$ zTY2yRM=X-U6fm(w8e~$bBsj$raR04m3+RCfPSC6z^uT-2+9B5tz=FJp&jAxCV-bs@ zMjEj3c?)8gz97h~8|bV67|5Z<{ANecxex@vTR<3fvVo{LK!`+)LyunI0p7p_2XBnt zn%?s;R?(~gJqRT6tT?=0a*&WYp#ca3paB4+@(27;KqG1JfE03I1#gODgQydOD{8D* z>?(l+H<>d)4sHQ55Ty(BVoC!T(~O`|<`2h~LTI*-W2CAM267-nyMaJ^nUkSDad`lm zaZixIlYs~ZkdqXerv@`HrlnM&&L7g`nQ4-wq8fCn4)7ocIxvv{>eT}kG)o6O$Ynn> z=1D-_@c~^)nRxayg9yY(6C9xErpdxu)SRU^8DapO3uqEA_xHX~rT~dbb3g?WddxGb z0tQp1DhH6Y&51H7W-!nwJ#}ybdh!f-lgmLT_ouN?7LuU7a)1LoV9cjx%^lg%W*TAr~T@+SXKTLTv1;Z0Mj?f|})^1UM~# z-7p4P5?NqsgA|@o7mxzfi;T z1n+Pi@Bs2AHo53M@Gs^tfo7&yY%K_!Nee3j9#~PI7U;ld??}AQMVSOBNS}`vo8=`a zWCAbw*x2~iwJ{sj!+`BC_dM)@)**JO4j^%m?OX{1&_vG-2(y^;HRiwtI>*BWo(XN> zI^;T_z^v6W$^S-B1E)}EvJFr{C_6kzOG`P^3wS{}jKhMZp101KxRj|sCd@FinbpB1 zUX(*wXikp{(aKHlelB1DtYBs<5m>>c@yJ6>4m-*W_&_;!&=N#X0KLij2984d)R<>_X`YQFvQN8&fo^axbJq&Fa7VLbrJ}<-wJn$9{xCA3R z;YdeZ(5$+EsJtb$-gyO*z34ZT@d6`H&Rk4>k&N(UBN5;>TUzjRP)8jTWgM7dI^ozT;}AyxgPqI8EmesNq6<&z?dR6nbZ literal 0 HcmV?d00001 diff --git a/test/jdk/java/awt/Dialog/FileDialogIconTest/loading-msg.gif b/test/jdk/java/awt/Dialog/FileDialogIconTest/loading-msg.gif new file mode 100644 index 0000000000000000000000000000000000000000..6c7570a6d84358d4c81bbb4177d50410bd464674 GIT binary patch literal 1518 zcmV6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~EC2ui06YLZ000R80RIUbNU)&6g9sBUT*$DY!-o(fN}NcsqQ#3CGiuz( zv7^U`zbbzF_U_rofdDH0`ST0NNr5R1h8+0r*EfRCzO5|y&E&wG7h?|m1mh2kPyc=u zg#zc_Hy~hu6m9tr2oN|-ox+G(w4zXf5Z?WJ2jL$}m}Z;)o9YtCpRr~CsCDZVCyaqW zp1u2IG$oLkE2;iPJJ{@7ieI0(6bM5xlvm&U0%qBEreuLT5f=;#_a6YU&r&{8%eJcJ zf1?FLIXn@7YuCSs8bulvD~M0;U|=m>IAw0ztToOQ_{(HZfg=}=90}&p%Zf^40}=b2 z;9Thm|F@*k8Xu@W?NLE#{eLzw~I6Q;%2$qiHe<^p{+!y~SB*_{{{zJJWS`+Fx%5j+0GxNxH@}D#=ZD{vMchpT{Wu<8H@di| zLwlX|=b(gg4%z~`~_*$hJV2UfR1hU=%r!*fFRa84hrhmhGsQsq)!IA z1Vv-t+y#Z4F_ya0AIz?_<+dQ`#g~|%Ph_X-%#bg35vaQyPhye1a3ld)qpMIn<>lI83_PZIP9yTv-Flt4ieS*k%h z$p*rPwLx*4QLv&%rkMmqW>S7*Z3PAxAhZ Date: Wed, 16 Apr 2025 13:08:58 +0000 Subject: [PATCH 194/846] 8340366: Open source several AWT Dialog tests - Batch 3 Backport-of: a7d2077fe20d73f49a003c15469c2aa9bda1b30f --- test/jdk/ProblemList.txt | 2 + .../java/awt/Dialog/DialogModalityTest.java | 114 +++++++++++++ .../java/awt/Dialog/DialogResizeTest2.java | 105 ++++++++++++ .../awt/Dialog/FileDialogUserFilterTest.java | 150 ++++++++++++++++++ test/jdk/java/awt/Dialog/HideDialogTest.java | 138 ++++++++++++++++ test/jdk/java/awt/Dialog/ModalDialogTest.java | 147 +++++++++++++++++ 6 files changed, 656 insertions(+) create mode 100644 test/jdk/java/awt/Dialog/DialogModalityTest.java create mode 100644 test/jdk/java/awt/Dialog/DialogResizeTest2.java create mode 100644 test/jdk/java/awt/Dialog/FileDialogUserFilterTest.java create mode 100644 test/jdk/java/awt/Dialog/HideDialogTest.java create mode 100644 test/jdk/java/awt/Dialog/ModalDialogTest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 7a81a208e1f53..65885891eec64 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -496,6 +496,8 @@ java/awt/Window/GetScreenLocation/GetScreenLocationTest.java 8225787 linux-x64 java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 8266243 macosx-aarch64 java/awt/Dialog/PrintToFileTest/PrintToFileRevoked.java 8029249 macosx-all java/awt/Dialog/PrintToFileTest/PrintToFileGranted.java 8029249 macosx-all +java/awt/Dialog/FileDialogUserFilterTest.java 8001142 generic-all + java/awt/dnd/DragSourceMotionListenerTest.java 8225131 windows-all java/awt/dnd/RejectDragTest.java 7124259 macosx-all java/awt/dnd/DnDHTMLToOutlookTest/DnDHTMLToOutlookTest.java 8027424 generic-all diff --git a/test/jdk/java/awt/Dialog/DialogModalityTest.java b/test/jdk/java/awt/Dialog/DialogModalityTest.java new file mode 100644 index 0000000000000..d8ac9e4620b42 --- /dev/null +++ b/test/jdk/java/awt/Dialog/DialogModalityTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Event; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Window; +import java.util.List; + +/* + * @test + * @bug 4058370 + * @summary Test to verify Modality of Dialog + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DialogModalityTest + */ + +public class DialogModalityTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. When the test is running, there will be a Frame, a Modal Dialog + and a Window that is Modal Dialog's parent. + 2. Verify that it is impossible to bring up the menu in Frame before + closing the Modal Dialog. + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .build() + .awaitAndCheck(); + } + + public static List initialize() { + Frame f = new Frame("Parent Frame"); + DialogTest dlg = new DialogTest(f, "Modal Dialog"); + f.add(new Button("push me")); + f.setSize(200, 200); + f.setLocation(210, 1); + dlg.setBounds(210, 203, 200, 200); + return List.of(f, dlg); + } +} + +class DialogTest extends Dialog { + Button closeButton; + Frame parent; + + public DialogTest(Frame parent, String title) { + this(parent, title, true); + } + + public DialogTest(Frame parent, String title, boolean modal) { + super(parent, title, modal); + this.parent = parent; + setLayout(new BorderLayout()); + Panel buttonPanel = new Panel(); + closeButton = new Button("Close"); + buttonPanel.add(closeButton); + add("Center", buttonPanel); + pack(); + } + + public boolean action(Event e, Object arg) { + if (e.target == closeButton) { + Dialog dialog = null; + Component c = (Component) e.target; + + while (c != null && !(c instanceof Dialog)) { + c = c.getParent(); + } + + if (c != null) { + dialog = (Dialog) c; + } + + if (dialog == null) { + return false; + } + + dialog.setVisible(false); + dialog.dispose(); + return true; + } + return false; + } +} diff --git a/test/jdk/java/awt/Dialog/DialogResizeTest2.java b/test/jdk/java/awt/Dialog/DialogResizeTest2.java new file mode 100644 index 0000000000000..3124719637a1d --- /dev/null +++ b/test/jdk/java/awt/Dialog/DialogResizeTest2.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.GridLayout; + +/* + * @test + * @bug 4172302 + * @summary Test to make sure non-resizable Dialogs can be resized with the + * setSize() method. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DialogResizeTest2 + */ + +public class DialogResizeTest2 { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + This tests the programmatic resizability of non-resizable Dialogs + Even when a Dialog is set to be non-resizable, it should be + programmatically resizable using the setSize() method. + + 1. Initially the Dialog will be resizable. Try using the \\"Smaller\\" + and \\"Larger\\" buttons to verify that the Dialog resizes correctly + 2. Then, click the \\"Toggle\\" button to make the Dialog non-resizable + 3. Again, verify that clicking the \\"Larger\\" and \\"Smaller\\" buttons + causes the Dialog to get larger and smaller. If the Dialog does + not change size, or does not re-layout correctly, the test FAILS + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .logArea(8) + .build() + .awaitAndCheck(); + } + + public static Frame initialize() { + Frame frame = new Frame("Parent Frame"); + frame.add(new Button("Button")); + frame.setSize(100, 100); + new dlg(frame).setVisible(true); + return frame; + } + + static class dlg extends Dialog { + public dlg(Frame f_) { + super(f_, "Dialog", false); + setSize(200, 200); + Button bLarger = new Button("Larger"); + bLarger.addActionListener(e -> setSize(400, 400)); + Button bSmaller = new Button("Smaller"); + bSmaller.addActionListener(e -> setSize(200, 100)); + Button bCheck = new Button("Resizable?"); + bCheck.addActionListener(e -> { + if (isResizable()) { + PassFailJFrame.log("Dialog is resizable"); + } else { + PassFailJFrame.log("Dialog is not resizable"); + } + }); + Button bToggle = new Button("Toggle"); + bToggle.addActionListener(e -> { + if (isResizable()) { + setResizable(false); + PassFailJFrame.log("Dialog is now not resizable"); + } else { + setResizable(true); + PassFailJFrame.log("Dialog is now resizable"); + } + }); + setLayout(new GridLayout(1, 4)); + add(bSmaller); + add(bLarger); + add(bCheck); + add(bToggle); + } + } +} diff --git a/test/jdk/java/awt/Dialog/FileDialogUserFilterTest.java b/test/jdk/java/awt/Dialog/FileDialogUserFilterTest.java new file mode 100644 index 0000000000000..80ff9ed0bde60 --- /dev/null +++ b/test/jdk/java/awt/Dialog/FileDialogUserFilterTest.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Checkbox; +import java.awt.Component; +import java.awt.Container; +import java.awt.Event; +import java.awt.FileDialog; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.Panel; +import java.awt.TextField; +import java.io.File; +import java.io.FilenameFilter; + +/* + * @test + * @bug 4293697 4416433 4417139 4409600 + * @summary Test to verify that user filter always gets called on changing the + * directory in FileDialog + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual FileDialogUserFilterTest + */ + +public class FileDialogUserFilterTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Enter a mask into the field, a directory into + the field (or leave the default values). + 2. Then click the button, file dialog will appear. + Output of the user filter will be shown in the output + area. Enter several different directories to the file dialog + via double-clicking on the directory list. The output + area should show some filtering output on each directory + change. If any output was only given on dialog startup, + the test is FAILED. + 3. Look at the list of files accepted by the filter. + If some files do not match the filter, + the test is FAILED. + 4. Open dialog with an empty filter. + Enter some directories with a lot of files (like /usr/bin). + If dialog crashes the test is FAILED. + Enter the directory that contain files and other directories. + If the directories are shown in the files box along with files + then the test is FAILED. + 5. Click in checkbox 'do not use filter', make it checked. + Open dialog, enter the directory with some files. + If no files is shown in the File list box (while you are sure + there are some files there) the test is FAILED + Otherwise it is PASSED." + """; + + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(new DialogFilterTest()) + .build() + .awaitAndCheck(); + } +} + +class DialogFilterTest extends Frame implements FilenameFilter { + FileDialog fd; + static TextField tfDirectory = new TextField(); + static TextField tfFile = new TextField(); + static TextField tfFilter = new TextField(); + static Checkbox useFilterCheck = new Checkbox("do not use filter"); + + public DialogFilterTest() { + setTitle("File Dialog User Filter test"); + add("North", new Button("Load")); + Panel p = new Panel(); + p.setLayout(new GridBagLayout()); + addRow(p, new Label("directory:", Label.RIGHT), tfDirectory); + addRow(p, new Label("file:", Label.RIGHT), tfFile); + addRow(p, new Label("filter:", Label.RIGHT), tfFilter); + addRow(p, new Label(""), useFilterCheck); + tfFilter.setText(".java"); + tfDirectory.setText("."); + add("Center", p); + setSize(300, 200); + } + + static void addRow(Container cont, Component c1, Component c2) { + GridBagLayout gbl = (GridBagLayout) cont.getLayout(); + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.BOTH; + cont.add(c1); + gbl.setConstraints(c1, c); + + c.gridwidth = GridBagConstraints.REMAINDER; + c.weightx = 1.0; + cont.add(c2); + gbl.setConstraints(c2, c); + } + + public boolean accept(File dir, String name) { + System.out.println("File " + dir + " String " + name); + if (fd.getMode() == FileDialog.LOAD) { + return name.lastIndexOf(tfFilter.getText()) > 0; + } + return true; + } + + public boolean action(Event evt, Object what) { + boolean load = "Load".equals(what); + + if (load || "Save".equals(what)) { + fd = new FileDialog(new Frame(), null, + load ? FileDialog.LOAD : FileDialog.SAVE); + fd.setDirectory(tfDirectory.getText()); + fd.setFile(tfFile.getText()); + if (!useFilterCheck.getState()) { + fd.setFilenameFilter(this); + } + fd.setVisible(true); + tfDirectory.setText(fd.getDirectory()); + tfFile.setText(fd.getFile()); + + return true; + } + return false; + } +} diff --git a/test/jdk/java/awt/Dialog/HideDialogTest.java b/test/jdk/java/awt/Dialog/HideDialogTest.java new file mode 100644 index 0000000000000..78d0344a6cf8e --- /dev/null +++ b/test/jdk/java/awt/Dialog/HideDialogTest.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.Dialog; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/* + * @test + * @bug 4048664 4065506 4122094 4171979 + * @summary Test if Dialog can be successfully hidden, see that no other app + * comes to front, see if hide + dispose causes assertion failure + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual HideDialogTest + */ + +public class HideDialogTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. A Frame should appear with a "test" button in it + 2. Click on the "test" button. A Dialog will appear with a "dismiss" button + and a "dismiss-with-dispose" button + 3. First, click on the "dismiss-with-dispose" button. Verify that + no assertion failure appears. + 4. Now, click on the "dismiss" button. The Dialog should go away. + 5. Repeat from (2) 10-20 times. + 6. When the dialog goes away check that the frame window does not briefly + get obscured by another app or repaint it's entire area. There should be + no flicker at all in areas obscured by the dialog. (4065506 4122094) + If there is the test fails. + 7. If the Dialog is successfully hidden each time, the test passed. If the + Dialog did not hide, the test failed (4048664). + + NOTE: When the dialog does not go away (meaning the bug has manifested itself), + the "dismiss-with-dispose" button can be used to get rid of it. + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(40) + .testUI(new MyFrame()) + .build() + .awaitAndCheck(); + } +} + +class MyDialog extends Dialog { + public MyDialog(Frame f) { + super(f, "foobar", true); + setSize(200, 200); + setLayout(new BorderLayout()); + Panel p = new Panel(); + p.setLayout(new FlowLayout(FlowLayout.CENTER)); + Button okButton; + okButton = new Button("dismiss"); + p.add(okButton); + okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + System.out.println("Calling setVisible(false)"); + setVisible(false); + } + }); + Button newButton; + p.add(newButton = new Button("dismiss-with-dispose")); + newButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + System.out.println("Calling setVisible(false) + dispose()"); + setVisible(false); + dispose(); + } + }); + add("South", p); + pack(); + } +} + +class MyFrame extends Frame implements ActionListener { + public MyFrame() { + super(); + setSize(600, 400); + setTitle("HideDialogTest"); + setLayout(new BorderLayout()); + Panel toolbar = new Panel(); + toolbar.setLayout(new FlowLayout(FlowLayout.LEFT)); + Button testButton = new Button("test"); + testButton.addActionListener(this); + toolbar.add(testButton); + add("North", toolbar); + } + + public void actionPerformed(ActionEvent e) { + String s = e.getActionCommand(); + if (s.equals("test")) { + System.out.println("Begin test"); + MyDialog d = new MyDialog(this); + d.setVisible(true); + System.out.println("End test"); + } + } + + public void paint(Graphics g) { + for (int i = 0; i < 10; i++) { + g.setColor(Color.red); + g.fillRect(0, 0, 2000, 2000); + g.setColor(Color.blue); + g.fillRect(0, 0, 2000, 2000); + } + } +} diff --git a/test/jdk/java/awt/Dialog/ModalDialogTest.java b/test/jdk/java/awt/Dialog/ModalDialogTest.java new file mode 100644 index 0000000000000..aceacc9209a80 --- /dev/null +++ b/test/jdk/java/awt/Dialog/ModalDialogTest.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Checkbox; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +/* + * @test + * @bug 4078176 + * @summary Test to verify Modal dialogs don't act modal if addNotify() + * is called before setModal(true). + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ModalDialogTest + */ + +public class ModalDialogTest implements ActionListener { + public boolean modal = true; + Button closeBtn = new Button("Close me"); + Button createBtn = new Button("Create Dialog"); + Button createNewBtn = new Button("Create Modal Dialog"); + Button lastBtn = new Button("Show Last Dialog"); + Dialog dialog; + Dialog newDialog; + Frame testFrame; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Use 'Modal' checkbox to select which dialog you're + going to create - modal or non-modal. + (this checkbox affects only new created dialog but + not existing one) + 2. Use 'Create Dialog' button to create a dialog. + If you have selected 'Modal' checkbox then dialog has to + be created modal - you can make sure of that clicking + on any other control (i.e. 'Modal' checkbox) - they + should not work. + 3. Use 'Show Last Dialog' button to bring up last + created dialog - to make sure that if you show/hide + modal dialog several times it stays modal. + 4. On the appearing dialog there are two buttons: + 'Close Me' which closes the dialog, + and 'Create Modal Dialog' which creates one more + MODAL dialog just to make sure that + in situation with two modal dialogs all is fine. + 5. If created modal dialogs are really modal + (which means that they blocks the calling app) + then test is PASSED, otherwise it's FAILED." + """; + ModalDialogTest test = new ModalDialogTest(); + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(test.initialize()) + .build() + .awaitAndCheck(); + } + + public Frame initialize() { + testFrame = new Frame("Parent Frame"); + Frame frame = new Frame("Modal Dialog test"); + Panel panel = new Panel(); + panel.setLayout(new BorderLayout()); + + createBtn.addActionListener(this); + createNewBtn.addActionListener(this); + closeBtn.addActionListener(this); + lastBtn.addActionListener(this); + panel.add("Center", createBtn); + panel.add("South", lastBtn); + Checkbox cb = new Checkbox("Modal", modal); + cb.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + modal = ((Checkbox) e.getSource()).getState(); + } + }); + panel.add("North", cb); + panel.setSize(200, 100); + + frame.add(panel); + frame.pack(); + return frame; + } + + public void actionPerformed(ActionEvent e) { + if (e.getSource() == createBtn) { + if (dialog != null) { + dialog.dispose(); + } + dialog = new Dialog(testFrame, "Modal Dialog"); + dialog.add("North", closeBtn); + dialog.add("South", createNewBtn); + createBtn.setEnabled(false); + dialog.pack(); + dialog.setModal(modal); + dialog.setVisible(true); + } else if (e.getSource() == closeBtn && dialog != null) { + createBtn.setEnabled(true); + dialog.setVisible(false); + } else if (e.getSource() == lastBtn && dialog != null) { + dialog.setVisible(true); + } else if (e.getSource() == createNewBtn && newDialog == null) { + newDialog = new Dialog(testFrame, "New Modal Dialog"); + Button clsBtn = new Button("Close Me"); + clsBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + newDialog.dispose(); + newDialog = null; + } + }); + newDialog.add("North", clsBtn); + newDialog.pack(); + newDialog.setModal(true); + newDialog.setVisible(true); + } + } +} From 772333031e9fd21efe337ebfa54b050a75ab2bb2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 16 Apr 2025 13:10:21 +0000 Subject: [PATCH 195/846] 8341972: java/awt/dnd/DnDRemoveFocusOwnerCrashTest.java timed out after JDK-8341257 Backport-of: 1f6bd0c3e509029bbf524b0ba34ce44601ac0b6a --- test/jdk/ProblemList.txt | 1 + .../awt/dnd/DnDRemoveFocusOwnerCrashTest.java | 49 +++++++++---------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 65885891eec64..880a3bfd630d3 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -204,6 +204,7 @@ java/awt/event/KeyEvent/ExtendedModifiersTest/ExtendedModifiersTest.java 8129778 java/awt/event/KeyEvent/KeyMaskTest/KeyMaskTest.java 8129778 generic-all java/awt/event/MouseEvent/MouseButtonsAndKeyMasksTest/MouseButtonsAndKeyMasksTest.java 8129778 generic-all +java/awt/dnd/DnDRemoveFocusOwnerCrashTest.java 8242805 macosx-all java/awt/dnd/DnDCursorCrashTest.java 8242805 macosx-all java/awt/dnd/DnDClipboardDeadlockTest.java 8079553 linux-all java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListToFileListBetweenJVMsTest.java 8194947 generic-all diff --git a/test/jdk/java/awt/dnd/DnDRemoveFocusOwnerCrashTest.java b/test/jdk/java/awt/dnd/DnDRemoveFocusOwnerCrashTest.java index 27cf54e184558..1fc7c2e82b89c 100644 --- a/test/jdk/java/awt/dnd/DnDRemoveFocusOwnerCrashTest.java +++ b/test/jdk/java/awt/dnd/DnDRemoveFocusOwnerCrashTest.java @@ -64,10 +64,13 @@ public class DnDRemoveFocusOwnerCrashTest { public static Frame frame; public static Robot robot; public static DragSourceButton dragSourceButton; + static volatile Point p; public static void main(String[] args) throws Exception { try { robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.delay(FRAME_ACTIVATION_TIMEOUT); EventQueue.invokeAndWait(() -> { frame = new Frame(); dragSourceButton = new DragSourceButton(); @@ -79,37 +82,33 @@ public static void main(String[] args) throws Exception { frame.add(dropTargetPanel); frame.pack(); frame.setVisible(true); + }); - try { - robot.delay(FRAME_ACTIVATION_TIMEOUT); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("The test failed."); - } + robot.waitForIdle(); + robot.delay(FRAME_ACTIVATION_TIMEOUT); - Point p = dragSourceButton.getLocationOnScreen(); + EventQueue.invokeAndWait(() -> { + p = dragSourceButton.getLocationOnScreen(); p.translate(10, 10); + }); - try { - Robot robot = new Robot(); - robot.mouseMove(p.x, p.y); - robot.keyPress(KeyEvent.VK_CONTROL); - robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - for (int dy = 0; dy < 50; dy++) { - robot.mouseMove(p.x, p.y + dy); - robot.delay(10); - } - robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); - robot.keyRelease(KeyEvent.VK_CONTROL); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("The test failed."); + robot.delay(FRAME_ACTIVATION_TIMEOUT); + robot.mouseMove(p.x, p.y); + robot.delay(FRAME_ACTIVATION_TIMEOUT); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (int dy = 0; dy < 50; dy++) { + robot.mouseMove(p.x, p.y + dy); + robot.delay(10); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); } }); - } finally { - if (frame != null) { - EventQueue.invokeAndWait(() -> frame.dispose()); - } } } From 197adc22920574f6e212befe1c9c4d671c92db7c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 16 Apr 2025 13:11:48 +0000 Subject: [PATCH 196/846] 8342633: javax/management/security/HashedPasswordFileTest.java creates tmp file in src dir Backport-of: de441c2b6891ad475f516d14b793efbe65f1477c --- .../jdk/javax/management/security/HashedPasswordFileTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/jdk/javax/management/security/HashedPasswordFileTest.java b/test/jdk/javax/management/security/HashedPasswordFileTest.java index 195a9cd344993..f84e00abd4ede 100644 --- a/test/jdk/javax/management/security/HashedPasswordFileTest.java +++ b/test/jdk/javax/management/security/HashedPasswordFileTest.java @@ -110,9 +110,7 @@ private String[] getHash(String algorithm, String password) { } private String getPasswordFilePath() { - String testDir = System.getProperty("test.src"); - String testFileName = "jmxremote.password"; - return testDir + File.separator + testFileName; + return "jmxremote.password"; } private File createNewPasswordFile() throws IOException { From eb0c0104aa19b9026a1d2221af383b31b9f7b6cd Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 16 Apr 2025 13:13:12 +0000 Subject: [PATCH 197/846] 8305010: Test vmTestbase/nsk/jvmti/scenarios/sampling/SP05/sp05t003/TestDescription.java timed out: thread not suspended Backport-of: 2ddaa460545e043008aaf0b7ce33191b7c588833 --- .../sampling/SP05/sp05t003/sp05t003.cpp | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP05/sp05t003/sp05t003.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP05/sp05t003/sp05t003.cpp index 455f88db20c20..b0f78dc35fa39 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP05/sp05t003/sp05t003.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP05/sp05t003/sp05t003.cpp @@ -74,6 +74,7 @@ static volatile int eventsEnd = 0; /* testcase(s) */ static int prepare(); static int checkThreads(const char* kind); +static int waitSuspended(const char* kind); static int resumeThreads(const char* kind); static int clean(); @@ -125,7 +126,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) { nsk_jvmti_setFailStatus(); } - /* check if all threads suspended on THREAD_START events */ + /* check if all THREAD_START events are generated */ if (eventsStart != THREADS_COUNT) { NSK_COMPLAIN2("Unexpected number of THREAD_START events:\n" "# received: %d\n" @@ -133,6 +134,11 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) { eventsStart, THREADS_COUNT); } + /* wait until all threads are suspended */ + if (!NSK_VERIFY(waitSuspended("starting"))) { + return; + } + NSK_DISPLAY0("Testcase #1: check threads on THREAD_START\n"); if (!NSK_VERIFY(checkThreads("starting"))) return; @@ -175,7 +181,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) { nsk_jvmti_setFailStatus(); } - /* check ia all threads suspended on THREAD_END event */ + /* check if all THREAD_END event are generated */ if (eventsEnd != THREADS_COUNT) { NSK_COMPLAIN2("Unexpected number of THREAD_END events:\n" "# received: %d\n" @@ -183,6 +189,11 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) { eventsEnd, THREADS_COUNT); } + /* wait until all threads are suspended */ + if (!NSK_VERIFY(waitSuspended("finishing"))) { + return; + } + NSK_DISPLAY0("Testcase #2: check threads on THREAD_END\n"); if (!NSK_VERIFY(checkThreads("finishing"))) return; @@ -210,6 +221,31 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) { /* ============================================================================= */ +static int waitSuspended(const char* kind) { + NSK_DISPLAY1("Wait for %s threads to be suspended\n", kind); + for (int i = 0; i < THREADS_COUNT; i++) { + for (int j = 0; j * TIMEOUT_DELTA < timeout; j++) { + jint state = 0; + if (!NSK_JVMTI_VERIFY(jvmti->GetThreadState(threadsList[i], &state))) { + nsk_jvmti_setFailStatus(); + break; + } + if ((state & JVMTI_THREAD_STATE_ALIVE) == 0) { + NSK_COMPLAIN3("%s thread %s is not alive: %x\n", kind, threadsName[i], (int)state); + nsk_jvmti_setFailStatus(); + break; + } + if ((state & JVMTI_THREAD_STATE_SUSPENDED) != 0) { + NSK_DISPLAY2(" OK: %s thread %s is suspended\n", kind, threadsName[i]); + break; + } + NSK_DISPLAY2(" %s thread %s is not suspended, waiting\n", kind, threadsName[i]); + nsk_jvmti_sleep(TIMEOUT_DELTA); + } + } + return NSK_TRUE; // continue execution +} + /** * Resume all threads in given state. */ From ab64a3e9e229f401222c923b081d6253bd4d0553 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 16 Apr 2025 13:14:45 +0000 Subject: [PATCH 198/846] 8350924: javax/swing/JMenu/4213634/bug4213634.java fails Backport-of: daf0213abc2c860246564b361061dbda9bd9982f --- .../javax/swing/JMenu/4213634/bug4213634.java | 90 ++++++++----------- 1 file changed, 39 insertions(+), 51 deletions(-) diff --git a/test/jdk/javax/swing/JMenu/4213634/bug4213634.java b/test/jdk/javax/swing/JMenu/4213634/bug4213634.java index dd699b7e5bc1f..ad26ff2bc5950 100644 --- a/test/jdk/javax/swing/JMenu/4213634/bug4213634.java +++ b/test/jdk/javax/swing/JMenu/4213634/bug4213634.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -21,103 +21,91 @@ * questions. */ -import java.awt.AWTException; import java.awt.Robot; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.KeyEvent; -import java.lang.reflect.InvocationTargetException; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; -import javax.swing.JTextArea; import javax.swing.SwingUtilities; /* * @test * @key headful * @bug 4213634 8017187 - * @author Scott Violet * @library ../../regtesthelpers * @build Util + * @summary Verifies if Alt+mnemonic char works when + * menu & menuitem have same mnemonic char * @run main bug4213634 */ - public class bug4213634 { - private JMenu menu; - - private JFrame frame; + private static JMenu menu; + private static JFrame frame; + private static Robot robot; - public static void main(String[] args) throws Throwable { - new bug4213634(); - } + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + SwingUtilities.invokeAndWait(bug4213634::createAndShowGUI); - bug4213634() throws AWTException, InterruptedException, InvocationTargetException { - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { - createAndShowGUI(); - } - }); - - test(); + robot.waitForIdle(); + robot.delay(1000); + test(); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } } - public void createAndShowGUI() { - frame = new JFrame("TEST"); + public static void createAndShowGUI() { + frame = new JFrame("bug4213634"); JMenuBar mb = new JMenuBar(); menu = mb.add(createMenu("1 - First Menu", true)); mb.add(createMenu("2 - Second Menu", false)); frame.setJMenuBar(mb); - JTextArea ta = new JTextArea("This test dedicated to Nancy and Kathleen, testers and bowlers extraordinaire\n\n\nNo exception means pass."); - frame.getContentPane().add("Center", ta); JButton button = new JButton("Test"); frame.getContentPane().add("South", button); - frame.setBounds(100, 100, 400, 400); + frame.setSize(300, 300); + frame.setLocationRelativeTo(null); frame.setVisible(true); button.requestFocusInWindow(); } - private void test() throws AWTException, InterruptedException, InvocationTargetException { - Robot robot = new Robot(); - robot.setAutoDelay(50); - robot.waitForIdle(); - + private static void test() throws Exception { Util.hitMnemonics(robot, KeyEvent.VK_1); robot.waitForIdle(); + robot.delay(100); - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { - if (!menu.isSelected()) { - throw new RuntimeException( - "Failed: Menu didn't remain posted at end of test"); - } else { - System.out.println("Test passed!"); - frame.dispose(); - } + SwingUtilities.invokeAndWait(() -> { + if (!menu.isSelected()) { + throw new RuntimeException( + "Failed: Menu didn't remain posted at end of test"); + } else { + System.out.println("Test passed!"); } }); } - private JMenu createMenu(String str, boolean bFlag) { + + private static JMenu createMenu(String str, boolean bFlag) { JMenuItem menuitem; JMenu menu = new JMenu(str); menu.setMnemonic(str.charAt(0)); - for(int i = 0; i < 10; i ++) { + for (int i = 0; i < 10; i++) { menuitem = new JMenuItem("JMenuItem" + i); - menuitem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - throw new RuntimeException( - "Failed: Mnemonic activated"); - } + menuitem.addActionListener(e -> { + throw new RuntimeException("Failed: Mnemonic activated"); }); - if(bFlag) + if (bFlag) { menuitem.setMnemonic('0' + i); + } menu.add(menuitem); } return menu; From 45b84aeec31085efe7a839292c0545121038d3b0 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 16 Apr 2025 13:16:42 +0000 Subject: [PATCH 199/846] 8286204: [Accessibility,macOS,VoiceOver] VoiceOver reads the spinner value 10 as 1 when user iterates to 10 for the first time on macOS Backport-of: cd9f1d3d921531511a7552807d099d5d3cce01a6 --- .../classes/sun/lwawt/macosx/CAccessible.java | 7 +- .../TestJSpinnerAccessibility.java | 75 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 test/jdk/javax/accessibility/TestJSpinnerAccessibility.java diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java index 8f67a06a13d88..babe899296f1d 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java @@ -32,6 +32,7 @@ import javax.accessibility.Accessible; import javax.accessibility.AccessibleContext; +import javax.swing.JSpinner; import javax.swing.JTabbedPane; import static javax.accessibility.AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY; @@ -121,7 +122,11 @@ public void propertyChange(PropertyChangeEvent e) { if (name.equals(ACCESSIBLE_CARET_PROPERTY)) { selectedTextChanged(ptr); } else if (name.equals(ACCESSIBLE_TEXT_PROPERTY)) { - valueChanged(ptr); + AccessibleContext thisAC = accessible.getAccessibleContext(); + Accessible parentAccessible = thisAC.getAccessibleParent(); + if (!(parentAccessible instanceof JSpinner.NumberEditor)) { + valueChanged(ptr); + } } else if (name.equals(ACCESSIBLE_SELECTION_PROPERTY)) { selectionChanged(ptr); } else if (name.equals(ACCESSIBLE_TABLE_MODEL_CHANGED)) { diff --git a/test/jdk/javax/accessibility/TestJSpinnerAccessibility.java b/test/jdk/javax/accessibility/TestJSpinnerAccessibility.java new file mode 100644 index 0000000000000..4926e5b17fab2 --- /dev/null +++ b/test/jdk/javax/accessibility/TestJSpinnerAccessibility.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; + +import javax.swing.JFrame; +import javax.swing.JSpinner; +import javax.swing.SpinnerModel; +import javax.swing.SpinnerNumberModel; + +/* + * @test + * @bug 8286204 + * @summary Verifies that VoiceOver announces the JSpinner's value correctly + * @requires os.family == "mac" + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual TestJSpinnerAccessibility + */ + +public class TestJSpinnerAccessibility { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Test UI contains a JSpinner with minimum value 0, maximum value 20 + and current value 5. On press of up / down arrow, value will be + incremented / decremented by 1. + + Follow these steps to test the behaviour: + + 1. Start the VoiceOver (Press Command + F5) application + 2. Move focus on test window if it is not focused + 3. Press Up / Down arrow to increase / decrease Spinner value + 4. VO should announce correct values in terms of percentage + (e.g. For JSpinner's value 10, VO should announce 50%) + 5. Press Pass if you are able to hear correct announcements + else Fail"""; + + PassFailJFrame.builder() + .title("TestJSpinnerAccessibility Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(TestJSpinnerAccessibility::createUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createUI() { + JFrame frame = new JFrame("A Frame with JSpinner"); + SpinnerModel spinnerModel = new SpinnerNumberModel(5, 0, 20, 1); + JSpinner spinner = new JSpinner(spinnerModel); + frame.getContentPane().add(spinner, BorderLayout.CENTER); + frame.setSize(200, 100); + return frame; + } +} From 85d0ab55d6bae2aea4368e6668e361db8a9cbd1c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 16 Apr 2025 13:17:59 +0000 Subject: [PATCH 200/846] 8353138: Screen capture for test TaskbarPositionTest.java, failure case Backport-of: 05ff557dee6adc679d85bfe8fb49f69053a6aaba --- .../swing/Popup/TaskbarPositionTest.java | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/test/jdk/javax/swing/Popup/TaskbarPositionTest.java b/test/jdk/javax/swing/Popup/TaskbarPositionTest.java index 5378f61c96f77..a649956748360 100644 --- a/test/jdk/javax/swing/Popup/TaskbarPositionTest.java +++ b/test/jdk/javax/swing/Popup/TaskbarPositionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 @@ -37,7 +37,11 @@ import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; import javax.swing.AbstractAction; import javax.swing.JComboBox; import javax.swing.JFrame; @@ -337,11 +341,11 @@ public static void main(String[] args) throws Throwable { } } - try { - // Use Robot to automate the test - Robot robot = new Robot(); - robot.setAutoDelay(50); + // Use Robot to automate the test + Robot robot = new Robot(); + robot.setAutoDelay(50); + try { SwingUtilities.invokeAndWait(TaskbarPositionTest::new); robot.waitForIdle(); @@ -442,6 +446,9 @@ public static void main(String[] args) throws Throwable { hidePopup(robot); robot.waitForIdle(); + } catch (Throwable t) { + saveScreenCapture(robot, screens); + throw t; } finally { SwingUtilities.invokeAndWait(() -> { if (frame != null) { @@ -450,4 +457,17 @@ public static void main(String[] args) throws Throwable { }); } } + + private static void saveScreenCapture(Robot robot, GraphicsDevice[] screens) { + for (int i = 0; i < screens.length; i++) { + Rectangle bounds = screens[i].getDefaultConfiguration() + .getBounds(); + BufferedImage image = robot.createScreenCapture(bounds); + try { + ImageIO.write(image, "png", new File("Screenshot.png")); + } catch (IOException e) { + e.printStackTrace(); + } + } + } } From ae176b140044d5e7f40fdb0d93cc8acd5238d22f Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 17 Apr 2025 13:49:34 +0000 Subject: [PATCH 201/846] 8300658: memory_and_swap_limit() reporting wrong values on systems with swapaccount=0 Backport-of: e47e9ec05b630c82182c7843365dfd90fdaa18a0 --- .../os/linux/cgroupV1Subsystem_linux.cpp | 49 +++++++++++++------ .../os/linux/cgroupV1Subsystem_linux.hpp | 1 + .../os/linux/cgroupV2Subsystem_linux.cpp | 6 +++ .../docker/TestMemoryAwareness.java | 25 ++++++++++ .../docker/TestMemoryWithCgroupV1.java | 4 +- 5 files changed, 68 insertions(+), 17 deletions(-) diff --git a/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp index 8008994fe5fc5..0c4a67c484e0f 100644 --- a/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp @@ -111,7 +111,19 @@ jlong CgroupV1Subsystem::read_memory_limit_in_bytes() { } } -jlong CgroupV1Subsystem::memory_and_swap_limit_in_bytes() { +/* read_mem_swap + * + * Determine the memory and swap limit metric. Returns a positive limit value strictly + * lower than the physical memory and swap limit iff there is a limit. Otherwise a + * negative value is returned indicating the determined status. + * + * returns: + * * A number > 0 if the limit is available and lower than a physical upper bound. + * * OSCONTAINER_ERROR if the limit cannot be retrieved (i.e. not supported) or + * * -1 if there isn't any limit in place (note: includes values which exceed a physical + * upper bound) + */ +jlong CgroupV1Subsystem::read_mem_swap() { julong host_total_memsw; GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.memsw.limit_in_bytes", "Memory and Swap Limit is: ", JULONG_FORMAT, JULONG_FORMAT, memswlimit); @@ -126,29 +138,36 @@ jlong CgroupV1Subsystem::memory_and_swap_limit_in_bytes() { if (hier_memswlimit >= host_total_memsw) { log_trace(os, container)("Hierarchical Memory and Swap Limit is: Unlimited"); } else { - jlong swappiness = read_mem_swappiness(); - if (swappiness == 0) { - const char* matchmemline = "hierarchical_memory_limit"; - GET_CONTAINER_INFO_LINE(julong, _memory->controller(), "/memory.stat", matchmemline, - "Hierarchical Memory Limit is : " JULONG_FORMAT, JULONG_FORMAT, hier_memlimit) - log_trace(os, container)("Memory and Swap Limit has been reset to " JULONG_FORMAT " because swappiness is 0", hier_memlimit); - return (jlong)hier_memlimit; - } return (jlong)hier_memswlimit; } } return (jlong)-1; } else { - jlong swappiness = read_mem_swappiness(); - if (swappiness == 0) { - jlong memlimit = read_memory_limit_in_bytes(); - log_trace(os, container)("Memory and Swap Limit has been reset to " JULONG_FORMAT " because swappiness is 0", memlimit); - return memlimit; - } return (jlong)memswlimit; } } +jlong CgroupV1Subsystem::memory_and_swap_limit_in_bytes() { + jlong memory_swap = read_mem_swap(); + if (memory_swap == -1) { + return memory_swap; + } + // If there is a swap limit, but swappiness == 0, reset the limit + // to the memory limit. Do the same for cases where swap isn't + // supported. + jlong swappiness = read_mem_swappiness(); + if (swappiness == 0 || memory_swap == OSCONTAINER_ERROR) { + jlong memlimit = read_memory_limit_in_bytes(); + if (memory_swap == OSCONTAINER_ERROR) { + log_trace(os, container)("Memory and Swap Limit has been reset to " JLONG_FORMAT " because swap is not supported", memlimit); + } else { + log_trace(os, container)("Memory and Swap Limit has been reset to " JLONG_FORMAT " because swappiness is 0", memlimit); + } + return memlimit; + } + return memory_swap; +} + jlong CgroupV1Subsystem::read_mem_swappiness() { GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.swappiness", "Swappiness is: ", JULONG_FORMAT, JULONG_FORMAT, swappiness); diff --git a/src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp b/src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp index 07fac4a9461cd..f0ac338957a11 100644 --- a/src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp +++ b/src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp @@ -114,6 +114,7 @@ class CgroupV1Subsystem: public CgroupSubsystem { char * pids_max_val(); jlong read_mem_swappiness(); + jlong read_mem_swap(); public: CgroupV1Subsystem(CgroupV1Controller* cpuset, diff --git a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp index d3f47d147efd4..fb08eac1c2210 100644 --- a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp @@ -152,6 +152,12 @@ char* CgroupV2Subsystem::mem_soft_limit_val() { // without also setting a memory limit is not allowed. jlong CgroupV2Subsystem::memory_and_swap_limit_in_bytes() { char* mem_swp_limit_str = mem_swp_limit_val(); + if (mem_swp_limit_str == nullptr) { + // Some container tests rely on this trace logging to happen. + log_trace(os, container)("Memory and Swap Limit is: %d", OSCONTAINER_ERROR); + // swap disabled at kernel level, treat it as no swap + return read_memory_limit_in_bytes(); + } jlong swap_limit = limit_from_str(mem_swp_limit_str); if (swap_limit >= 0) { jlong memory_limit = read_memory_limit_in_bytes(); diff --git a/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java b/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java index f6826a17ead24..553ba692ee73b 100644 --- a/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java +++ b/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java @@ -77,6 +77,8 @@ public static void main(String[] args) throws Exception { testMemorySoftLimit("1g", "1073741824"); testMemorySwapLimitSanity(); + testMemorySwapNotSupported("500m", "520m", "512000 k", "532480 k"); + // Add extra 10 Mb to allocator limit, to be sure to cause OOM testOOM("256m", 256 + 10); @@ -154,6 +156,29 @@ private static void testMemorySoftLimit(String valueToSet, String expectedTraceV .shouldMatch("Memory Soft Limit.*" + expectedTraceValue); } + /* + * Verifies that PrintContainerInfo prints the memory + * limit - without swap - iff swap is disabled (e.g. via swapaccount=0). It must + * not print 'not supported' for that value in that case. It'll always pass + * on systems with swap accounting enabled. + */ + private static void testMemorySwapNotSupported(String valueToSet, String swapToSet, String expectedMem, String expectedSwap) + throws Exception { + Common.logNewTestCase("memory swap not supported: " + valueToSet); + + DockerRunOptions opts = Common.newOpts(imageName, "PrintContainerInfo"); + Common.addWhiteBoxOpts(opts); + opts.addDockerOpts("--memory=" + valueToSet); + opts.addDockerOpts("--memory-swap=" + swapToSet); + + Common.run(opts) + .shouldMatch("memory_limit_in_bytes:.*" + expectedMem) + .shouldNotMatch("memory_and_swap_limit_in_bytes:.*not supported") + // On systems with swapaccount=0 this returns the memory limit. + // On systems with swapaccount=1 this returns the set memory+swap value. + .shouldMatch("memory_and_swap_limit_in_bytes:.*(" + expectedMem + "|" + expectedSwap + ")"); + } + /* * This test verifies that no confusingly large positive numbers get printed on * systems with swapaccount=0 kernel option. On some systems -2 were converted diff --git a/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java b/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java index cf62ef9ecba8c..f8c8b34135de5 100644 --- a/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java +++ b/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java @@ -86,8 +86,8 @@ private static void testMemoryLimitWithSwappiness(String dockerMemLimit, String // capabilities or the cgroup is not mounted. Memory limited without swap." // we only have 'Memory and Swap Limit is: -2' in the output try { - if (out.getOutput().contains("memory_and_swap_limit_in_bytes: not supported")) { - System.out.println("memory_and_swap_limit_in_bytes not supported, avoiding Memory and Swap Limit check"); + if (out.getOutput().contains("Memory and Swap Limit is: -2")) { + System.out.println("System doesn't seem to allow swap, avoiding Memory and Swap Limit check"); } else { out.shouldContain("Memory and Swap Limit is: " + expectedReadLimit) .shouldContain( From bfe6fe226f4ac7a71480e0a7265b615619fd2010 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 17 Apr 2025 13:51:01 +0000 Subject: [PATCH 202/846] 8315721: CloseRace.java#id0 fails transiently on libgraal Reviewed-by: rrich Backport-of: 1be355734da94243e29f0899b53aa1ebdf3bcb79 --- test/jdk/java/lang/ProcessBuilder/CloseRace.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/jdk/java/lang/ProcessBuilder/CloseRace.java b/test/jdk/java/lang/ProcessBuilder/CloseRace.java index 1fa6d8d5e1562..f6391b099ffd9 100644 --- a/test/jdk/java/lang/ProcessBuilder/CloseRace.java +++ b/test/jdk/java/lang/ProcessBuilder/CloseRace.java @@ -23,10 +23,12 @@ /** * @test - * @bug 8024521 + * @bug 8024521 8315721 * @summary Closing ProcessPipeInputStream at the time the process exits is racy * and leads to data corruption. Run this test manually (as * an ordinary java program) with -Xmx8M to repro bug 8024521. + * @comment Don't allow -Xcomp, it disturbs the timing + * @requires (vm.compMode != "Xcomp") * @run main/othervm -Xmx8M -Dtest.duration=2 CloseRace */ From 9bad4b45f08f369d6a55cbd2bafda10438dc93ed Mon Sep 17 00:00:00 2001 From: Daniel Hu Date: Fri, 18 Apr 2025 18:24:01 +0000 Subject: [PATCH 203/846] 8316156: ByteArrayInputStream.transferTo causes MaxDirectMemorySize overflow Backport-of: 5cacf212f066f5694d01f0891adfbe8b38660175 --- .../classes/java/io/ByteArrayInputStream.java | 13 +++- .../ChunkedTransferTo.java | 72 +++++++++++++++++++ 2 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 test/jdk/java/io/ByteArrayInputStream/ChunkedTransferTo.java diff --git a/src/java.base/share/classes/java/io/ByteArrayInputStream.java b/src/java.base/share/classes/java/io/ByteArrayInputStream.java index 39401d6d45243..e9b1415205b08 100644 --- a/src/java.base/share/classes/java/io/ByteArrayInputStream.java +++ b/src/java.base/share/classes/java/io/ByteArrayInputStream.java @@ -44,6 +44,7 @@ * @since 1.0 */ public class ByteArrayInputStream extends InputStream { + private static final int MAX_TRANSFER_SIZE = 128*1024; /** * An array of bytes that was provided @@ -205,8 +206,16 @@ public int readNBytes(byte[] b, int off, int len) { public synchronized long transferTo(OutputStream out) throws IOException { int len = count - pos; - out.write(buf, pos, len); - pos = count; + if (len > 0) { + int nwritten = 0; + while (nwritten < len) { + int nbyte = Integer.min(len - nwritten, MAX_TRANSFER_SIZE); + out.write(buf, pos, nbyte); + pos += nbyte; + nwritten += nbyte; + } + assert pos == count; + } return len; } diff --git a/test/jdk/java/io/ByteArrayInputStream/ChunkedTransferTo.java b/test/jdk/java/io/ByteArrayInputStream/ChunkedTransferTo.java new file mode 100644 index 0000000000000..fc334dd780461 --- /dev/null +++ b/test/jdk/java/io/ByteArrayInputStream/ChunkedTransferTo.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 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. + */ + +/* @test + * @bug 8316156 + * @summary Ensure ByteArrayInputStream.transferTo does not cause direct memory + * to overflow MaxDirectMemorySize + * @run junit/othervm -XX:MaxDirectMemorySize=5M ChunkedTransferTo + */ + +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.channels.Channels; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Random; + +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; +import static java.nio.file.StandardOpenOption.*; + +import org.junit.jupiter.api.Test; + +public class ChunkedTransferTo { + // this value must exceed MaxDirectMemorySize + private static final int SIZE = 10_000_000; + + @Test + public void byteArrayInputStream() throws IOException { + byte[] src = new byte[SIZE]; + Random rnd = new Random(System.nanoTime()); + rnd.nextBytes(src); + try (ByteArrayInputStream bais = new ByteArrayInputStream(src)) { + Path target = Files.createTempFile("SNA", "FU"); + FileChannel fc = FileChannel.open(target, CREATE, WRITE); + bais.transferTo(Channels.newOutputStream(fc)); + byte[] dst = new byte[SIZE + 1]; + try (FileInputStream fis = new FileInputStream(target.toFile())) { + int n = -1; + if ((n = fis.read(dst)) != SIZE) + throw new RuntimeException(n + " != " + SIZE); + } + Files.delete(target); + if (!Arrays.equals(src, 0, SIZE, dst, 0, SIZE)) + throw new RuntimeException("Arrays are not equal"); + } catch (OutOfMemoryError oome) { + throw new RuntimeException(oome); + } + } +} From e38a5f6964a3fb0b43ac69b1c6c6294b4f410104 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Sat, 19 Apr 2025 09:04:06 +0000 Subject: [PATCH 204/846] 8349974: [JMH,17u] MaskQueryOperationsBenchmark fails java.lang.NoClassDefFoundError Reviewed-by: phh --- .../jdk/incubator/vector/MaskQueryOperationsBenchmark.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskQueryOperationsBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskQueryOperationsBenchmark.java index 5fa4741fad2c1..18cff1c3cc826 100644 --- a/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskQueryOperationsBenchmark.java +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskQueryOperationsBenchmark.java @@ -1,5 +1,5 @@ // -// Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2003, 2025, 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 @@ -31,6 +31,7 @@ @OutputTimeUnit(TimeUnit.MILLISECONDS) @State(Scope.Thread) +@Fork(jvmArgs = {"--add-modules=jdk.incubator.vector"}) public class MaskQueryOperationsBenchmark { @Param({"128","256","512"}) int bits; From 28455f0688d2c3f0d11a56e3a9cc7e42f778e605 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 21 Apr 2025 08:14:37 +0000 Subject: [PATCH 205/846] 8292064: Convert java/lang/management/MemoryMXBean shell tests to java version Backport-of: 7ea9ba1f6c18ace5aa0896ab8676926fdc0d64ea --- .../MemoryMXBean/LowMemoryTest2.java | 20 ++++- .../management/MemoryMXBean/LowMemoryTest2.sh | 80 ------------------- .../MemoryMXBean/MemoryManagement.java | 23 +++++- .../MemoryManagementParallelGC.sh | 54 ------------- .../MemoryMXBean/MemoryManagementSerialGC.sh | 54 ------------- .../management/MemoryMXBean/MemoryTest.java | 2 +- .../MemoryMXBean/MemoryTestAllGC.sh | 58 -------------- .../lang/management/MemoryMXBean/Pending.java | 4 +- .../management/MemoryMXBean/PendingAllGC.sh | 57 ------------- 9 files changed, 43 insertions(+), 309 deletions(-) delete mode 100644 test/jdk/java/lang/management/MemoryMXBean/LowMemoryTest2.sh delete mode 100644 test/jdk/java/lang/management/MemoryMXBean/MemoryManagementParallelGC.sh delete mode 100644 test/jdk/java/lang/management/MemoryMXBean/MemoryManagementSerialGC.sh delete mode 100644 test/jdk/java/lang/management/MemoryMXBean/MemoryTestAllGC.sh delete mode 100644 test/jdk/java/lang/management/MemoryMXBean/PendingAllGC.sh diff --git a/test/jdk/java/lang/management/MemoryMXBean/LowMemoryTest2.java b/test/jdk/java/lang/management/MemoryMXBean/LowMemoryTest2.java index 01a8a3b47c444..917e8226bb131 100644 --- a/test/jdk/java/lang/management/MemoryMXBean/LowMemoryTest2.java +++ b/test/jdk/java/lang/management/MemoryMXBean/LowMemoryTest2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -31,6 +31,24 @@ * is generated. */ +/* + * @test + * @bug 4982128 + * @summary Test low memory detection of non-heap memory pool + * + * @run main/othervm/timeout=600 -noclassgc -XX:MaxMetaspaceSize=32m + * LowMemoryTest2 + */ + +/* + * @test + * @bug 4982128 + * @summary Test low memory detection of non-heap memory pool + * + * @run main/othervm/timeout=600 -noclassgc -XX:MaxMetaspaceSize=16m + * -XX:CompressedClassSpaceSize=4m LowMemoryTest2 + */ + import java.lang.management.*; import javax.management.*; import javax.management.openmbean.CompositeData; diff --git a/test/jdk/java/lang/management/MemoryMXBean/LowMemoryTest2.sh b/test/jdk/java/lang/management/MemoryMXBean/LowMemoryTest2.sh deleted file mode 100644 index e549d74cef002..0000000000000 --- a/test/jdk/java/lang/management/MemoryMXBean/LowMemoryTest2.sh +++ /dev/null @@ -1,80 +0,0 @@ -# -# Copyright (c) 2004, 2019, 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 4982128 -# @summary Test low memory detection of non-heap memory pool -# -# @requires vm.gc=="null" -# -# @run build LowMemoryTest2 MemoryUtil -# @run shell/timeout=600 LowMemoryTest2.sh -# - -if [ ! -z "${TESTJAVA}" ] ; then - JAVA=${TESTJAVA}/bin/java - CLASSPATH=${TESTCLASSES} - export CLASSPATH -else - echo "--Error: TESTJAVA must be defined as the pathname of a jdk to test." - exit 1 -fi - -# Test execution - -failures=0 - -go() { - echo '' - sh -xc "$JAVA $TESTVMOPTS $*" 2>&1 - if [ $? != 0 ]; then failures=`expr $failures + 1`; fi -} - -# Run test with each GC configuration -# -# Notes: To ensure that metaspace fills up we disable class unloading. -# Also we set the max metaspace to 16MB/32MB - otherwise the test takes too -# long to run. The 32MB setting is required for running with CDS archive. - -go -noclassgc -XX:MaxMetaspaceSize=32m -XX:+UseSerialGC LowMemoryTest2 -go -noclassgc -XX:MaxMetaspaceSize=32m -XX:+UseParallelGC LowMemoryTest2 - -# Test class metaspace - might hit MaxMetaspaceSize instead if -# UseCompressedClassPointers is off or if 32 bit. -# -# (note: This is very shaky and that shakiness exposes a problem with MemoryMXBean: -# -# MemoryMXBean defines "used" "committed" and "max" (see java/lang/management/MemoryUsage.java) -# This abstraction misses a definition for "address space exhausted" which with the new Metaspace (jep387) -# can happen before committed/used hits any trigger. We now commit only on demand and therefore class loaders -# can sit atop of uncommitted address space, denying new loaders address space. In the old Metaspace, -# we would have committed the space right away and therefore the MemoryMXBean "committed" trigger -# would have fired. In the new Metaspace, we don't commit, so the MemoryMXBean does not fire. -go -noclassgc -XX:MaxMetaspaceSize=16m -XX:CompressedClassSpaceSize=4m LowMemoryTest2 - -echo '' -if [ $failures -gt 0 ]; - then echo "$failures test(s) failed"; - else echo "All test(s) passed"; fi -exit $failures diff --git a/test/jdk/java/lang/management/MemoryMXBean/MemoryManagement.java b/test/jdk/java/lang/management/MemoryMXBean/MemoryManagement.java index bf457cd477b13..b136b724b7102 100644 --- a/test/jdk/java/lang/management/MemoryMXBean/MemoryManagement.java +++ b/test/jdk/java/lang/management/MemoryMXBean/MemoryManagement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -30,9 +30,26 @@ * * @author Mandy Chung * + * @requires vm.gc == null | vm.gc == "G1" + * * @modules jdk.management - * @build MemoryManagement MemoryUtil - * @run main/othervm/timeout=600 -Xmn8m -XX:+IgnoreUnrecognizedVMOptions -XX:G1HeapRegionSize=1 -XX:-UseLargePages MemoryManagement + * + * @run main/othervm/timeout=600 -Xmn8m -XX:+IgnoreUnrecognizedVMOptions + * -XX:G1HeapRegionSize=1 -XX:-UseLargePages MemoryManagement + */ + +/* + * @test + * @bug 4530538 6980984 + * @summary Basic unit test of memory management testing: + * 1) setUsageThreshold() and getUsageThreshold() + * 2) test low memory detection on the old generation. + * + * @author Mandy Chung + * + * @modules jdk.management + * + * @run main/timeout=600 MemoryManagement */ import java.lang.management.*; diff --git a/test/jdk/java/lang/management/MemoryMXBean/MemoryManagementParallelGC.sh b/test/jdk/java/lang/management/MemoryMXBean/MemoryManagementParallelGC.sh deleted file mode 100644 index ebe7e52ca3bc2..0000000000000 --- a/test/jdk/java/lang/management/MemoryMXBean/MemoryManagementParallelGC.sh +++ /dev/null @@ -1,54 +0,0 @@ -# -# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# -# @test -# @bug 4530538 -# @summary Run MemoryManagement test with parallel GC -# @author Mandy Chung -# -# @requires vm.gc=="Parallel" | vm.gc=="null" -# -# @run build MemoryManagement -# @run shell/timeout=600 MemoryManagementParallelGC.sh -# - -#Set appropriate jdk - -if [ ! -z "${TESTJAVA}" ] ; then - jdk="$TESTJAVA" -else - echo "--Error: TESTJAVA must be defined as the pathname of a jdk to test." - exit 1 -fi - -runOne() -{ - echo "runOne $@" - $TESTJAVA/bin/java ${TESTVMOPTS} -classpath $TESTCLASSES $@ || exit 2 -} - -# Test MemoryManagement with parallel collector -runOne -XX:+UseParallelGC MemoryManagement - -exit 0 diff --git a/test/jdk/java/lang/management/MemoryMXBean/MemoryManagementSerialGC.sh b/test/jdk/java/lang/management/MemoryMXBean/MemoryManagementSerialGC.sh deleted file mode 100644 index f9de8f575bd0e..0000000000000 --- a/test/jdk/java/lang/management/MemoryMXBean/MemoryManagementSerialGC.sh +++ /dev/null @@ -1,54 +0,0 @@ -# -# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# -# @test -# @bug 4530538 -# @summary Run MemoryManagement test with serial GC -# @author Mandy Chung -# -# @requires vm.gc=="Serial" | vm.gc=="null" -# -# @run build MemoryManagement -# @run shell/timeout=600 MemoryManagementSerialGC.sh -# - -#Set appropriate jdk - -if [ ! -z "${TESTJAVA}" ] ; then - jdk="$TESTJAVA" -else - echo "--Error: TESTJAVA must be defined as the pathname of a jdk to test." - exit 1 -fi - -runOne() -{ - echo "runOne $@" - $TESTJAVA/bin/java ${TESTVMOPTS} -classpath $TESTCLASSES $@ || exit 2 -} - -# Test MemoryManagement with serial collector -runOne -XX:+UseSerialGC MemoryManagement - -exit 0 diff --git a/test/jdk/java/lang/management/MemoryMXBean/MemoryTest.java b/test/jdk/java/lang/management/MemoryMXBean/MemoryTest.java index a0828dc63bd15..d07f2f93fa0aa 100644 --- a/test/jdk/java/lang/management/MemoryMXBean/MemoryTest.java +++ b/test/jdk/java/lang/management/MemoryMXBean/MemoryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 diff --git a/test/jdk/java/lang/management/MemoryMXBean/MemoryTestAllGC.sh b/test/jdk/java/lang/management/MemoryMXBean/MemoryTestAllGC.sh deleted file mode 100644 index ed330b2840e8e..0000000000000 --- a/test/jdk/java/lang/management/MemoryMXBean/MemoryTestAllGC.sh +++ /dev/null @@ -1,58 +0,0 @@ -# -# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# -# @test -# @bug 4530538 -# @summary -# @author Mandy Chung -# -# @requires vm.gc=="Parallel" | vm.gc=="null" -# -# @run compile MemoryTest.java -# @run shell MemoryTestAllGC.sh -# - -#Set appropriate jdk - -if [ ! -z "${TESTJAVA}" ] ; then - jdk="$TESTJAVA" -else - echo "--Error: TESTJAVA must be defined as the pathname of a jdk to test." - exit 1 -fi - -runOne() -{ - echo "runOne $@" - $TESTJAVA/bin/java ${TESTVMOPTS} -classpath $TESTCLASSES $@ || exit 2 -} - -# Test MemoryTest with default collector -runOne MemoryTest 2 3 - -# Test MemoryTest with parallel scavenger collector -runOne -XX:+UseParallelGC MemoryTest 2 3 - - -exit 0 diff --git a/test/jdk/java/lang/management/MemoryMXBean/Pending.java b/test/jdk/java/lang/management/MemoryMXBean/Pending.java index fb7a9e609e6c7..77e8eb9d35639 100644 --- a/test/jdk/java/lang/management/MemoryMXBean/Pending.java +++ b/test/jdk/java/lang/management/MemoryMXBean/Pending.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -35,6 +35,8 @@ * * @modules java.base/jdk.internal.misc * java.management + * + * @run main Pending */ import java.lang.management.*; diff --git a/test/jdk/java/lang/management/MemoryMXBean/PendingAllGC.sh b/test/jdk/java/lang/management/MemoryMXBean/PendingAllGC.sh deleted file mode 100644 index d1fbf2384cd99..0000000000000 --- a/test/jdk/java/lang/management/MemoryMXBean/PendingAllGC.sh +++ /dev/null @@ -1,57 +0,0 @@ -# -# Copyright (c) 2003, 2019, 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 4530538 -# @summary -# @author Mandy Chung -# @requires vm.gc=="null" -# @modules java.base/jdk.internal.misc -# java.management -# @run compile Pending.java -# @run shell PendingAllGC.sh -# - -#Set appropriate jdk - -if [ ! -z "${TESTJAVA}" ] ; then - jdk="$TESTJAVA" -else - echo "--Error: TESTJAVA must be defined as the pathname of a jdk to test." - exit 1 -fi - -runOne() -{ - echo "runOne $@" - $TESTJAVA/bin/java ${TESTVMOPTS} -classpath $TESTCLASSES $@ || exit 2 -} - -# Test Pending with default collector -runOne Pending - -# Test Pending with parallel scavenger collector -runOne -XX:+UseParallelGC Pending - -exit 0 From 0e663da343831e53b9283998623f87e0597178e8 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 21 Apr 2025 08:15:33 +0000 Subject: [PATCH 206/846] 8335684: Test ThreadCpuTime.java should pause like ThreadCpuTimeArray.java Backport-of: 1f6e106b45e5109224e13d70f1a40c9e666ec2ab --- .../lang/management/ThreadMXBean/ThreadCpuTime.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/test/jdk/java/lang/management/ThreadMXBean/ThreadCpuTime.java b/test/jdk/java/lang/management/ThreadMXBean/ThreadCpuTime.java index 61fff63936382..f8cab540465a5 100644 --- a/test/jdk/java/lang/management/ThreadMXBean/ThreadCpuTime.java +++ b/test/jdk/java/lang/management/ThreadMXBean/ThreadCpuTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -177,6 +177,8 @@ private static void waitUntilThreadBlocked() } } } + // Account for threads using CPU for a few millis after their WAITING state is visible: + goSleep(500); } static class MyThread extends Thread { @@ -228,15 +230,6 @@ public void run() { " CurrentThreadCpuTime = " + time1 + " > ThreadCpuTime = " + time2); } -/************* - * FIXME: Seems that on Solaris-sparc, - * It occasionally returns a different current thread user time > thread user time - if (utime1 > utime2) { - throw new RuntimeException("TEST FAILED: " + getName() + - " CurrentThreadUserTime = " + utime1 + - " > ThreadUserTime = " + utime2); - } -*/ } } From 8a03f719dae97caa03af3ced417f04e7a08b9115 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 21 Apr 2025 08:16:49 +0000 Subject: [PATCH 207/846] 8340332: Open source mixed AWT tests - Set3 Backport-of: bfdeb33e6f1d4f9f0cc65925ea792be98b1f4d61 --- .../ContainerResizeMousePositionTest.java | 141 +++++++++++ .../awt/color/XAWTDifference/XAWTColors.jpg | Bin 0 -> 10774 bytes .../color/XAWTDifference/XAWTDifference.java | 223 ++++++++++++++++++ 3 files changed, 364 insertions(+) create mode 100644 test/jdk/java/awt/MouseInfo/ContainerResizeMousePositionTest.java create mode 100644 test/jdk/java/awt/color/XAWTDifference/XAWTColors.jpg create mode 100644 test/jdk/java/awt/color/XAWTDifference/XAWTDifference.java diff --git a/test/jdk/java/awt/MouseInfo/ContainerResizeMousePositionTest.java b/test/jdk/java/awt/MouseInfo/ContainerResizeMousePositionTest.java new file mode 100644 index 0000000000000..72aa4d93a5c71 --- /dev/null +++ b/test/jdk/java/awt/MouseInfo/ContainerResizeMousePositionTest.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/* + * @test + * @key headful + * @bug 4009555 + * @summary Unit test for a new method in Container class: getMousePosition(boolean) + * while Container resized. + */ + +public class ContainerResizeMousePositionTest { + private static Frame frame; + private static Button button; + private static Robot robot; + private static volatile Point frameLocation; + private static volatile Point newLoc; + private static boolean testSucceeded = false; + + private static final CountDownLatch eventCaught = new CountDownLatch(1); + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + EventQueue.invokeAndWait(() -> createAndShowUI()); + robot.waitForIdle(); + robot.delay(1000); + testUI(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + frame = new Frame("Testing getMousePosition() after resize"); + button = new Button("Button"); + frame.setLayout(new BorderLayout()); + frame.add(button); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + private static void testUI() throws Exception { + EventQueue.invokeAndWait(() -> { + frameLocation = frame.getLocationOnScreen(); + newLoc = new Point(frame.getWidth() + 10, frame.getHeight() + 10); + }); + + robot.mouseMove(frameLocation.x + newLoc.x, frameLocation.y + newLoc.y); + EventQueue.invokeAndWait(() -> { + button.addComponentListener(new ResizeAdapter()); + frame.setSize(frame.getWidth() * 2, frame.getHeight() * 2); + frame.validate(); + }); + robot.waitForIdle(); + robot.delay(500); + + if (!eventCaught.await(2, TimeUnit.SECONDS)) { + throw new RuntimeException("componentResized Event isn't" + + " received within a timeout"); + } + + if (!testSucceeded) { + throw new RuntimeException("Container.getMousePosition(boolean)" + + " returned incorrect result while Container resized"); + } + } + + static class ResizeAdapter extends ComponentAdapter { + int testStageCounter = 0; + @Override + public void componentResized(ComponentEvent e) { + Point pTrue = frame.getMousePosition(true); + if (frame.getMousePosition(false) == null) { + testStageCounter++; + System.out.println(""" + TEST STAGE 1 PASSED: + Container.getMousePosition(false) + returned NULL over Child Component + during resize. + """); + } + if (pTrue != null) { + testStageCounter++; + System.out.println(""" + TEST STAGE 2 PASSED: + Container.getMousePosition(true) + returned NON-NULL over Child Component + during resize. + """); + } + if (pTrue != null && pTrue.x == newLoc.x && pTrue.y == newLoc.y) { + testStageCounter++; + System.out.println(""" + TEST STAGE 3 PASSED: + Container.getMousePosition(true) + returned correct result over Child Component + during resize. + """); + } + testSucceeded = testStageCounter == 3; + eventCaught.countDown(); + } + } +} diff --git a/test/jdk/java/awt/color/XAWTDifference/XAWTColors.jpg b/test/jdk/java/awt/color/XAWTDifference/XAWTColors.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f53b30407cc28676f9a91a9690c20b499f9ffbca GIT binary patch literal 10774 zcmch7XIN89*C+x~R1mvBC>E67dkYpoiU>#*q)3w%454>W5kbJCRH-5n=}ibl5_*Kt zkpPka8WV&-C?WK~-FV)6@B4k<{qz1fH_tQKd(Eu9X7--d*Ss_~(&aeDbBuw3fkW@k zZBqt@Bkvg)7~iom0zDV=psv7$33gM@jE#+L>c_oV0Oa=5w(`60nNXSx41x@Lw{MsQWiR3Hdh)s>t5&C;qHb6WmcUQ&TpN+im~?S` znt5gPV!Mbpn(KEWMXMD;n&KaFSnLaw2bwun5^Iym) z#TJa$x;UgUta;k(O^KO#?SzLvg~=K^wXZvZqR+#22{v=nq+Omy&nQCe$6}`oe$M!qT(v zK{uS|2F@sUEHwAP(oZ-`rV^kAC*v$YdW}xit<;mH;=wtLf$QInq1zAp$Y+A~9aDvv zJgfFr8>CA?yZ3y|QmL!&UL0J+ilX;NdCg_)ZtcTE!?UkH$-U(@Ol8%~wK3exx9Jla zOkH4*Ui|s0vGUlS>_DAwbn;w;?%yL_3|yXPJVA58dAi9j)!jrj(94$xUWXX5W#|s! z2vL|EZZ?~>(~-}{w6ppBukUP{Yn;(I{!;nYg36^?>-^?3O}G8p(?Bwj69Px>3}Ssy z^lmzVA+8hnW78!t+|l`Ot-d^EA)wj1l7*r05xFQYqBn$(i&$ET>hHB;@z+f-Dxv7BRw@DF*!P|1wq%vlR22h z-E0mjm2yPkDZV^5NeWBW?BbIP!Rb!4k9y)kSE{3Z+?>yaoh#lvidbx;f5dBkt$0QS-rKU8xQXzROX!`P{1dhzMni=Lu)~e{J;QA|hEqo_fjJ(O~5%Dhl z`)&$6b?<6IMypWM`yCq83!Z((wYZ~}o(ktaBbXJrr0=aOS6GxksO5XZO|Q5(Q4hT8 zXs(Ai?6Ra+HR%KbL1}hlfRwtidJqPAX{{#%Xj?z_few@2(KH z-}r}TTrFpwXy3XBd?xQhe)0ts;UR7<*VtC5gWyQom}R*|0!PX{!m5?Xm`9zFkx`A^ zg`iY@_-asg>7efst@eLcME}%%eX41i3w@6|XkE#EGbcOy6`D{s&L~{C6uCzbu&(T2 z0X9~@*tItEkl#=9-a#=p)|ID-remxtyLBETrYKLuNrPYT5CIUVDjMt5$kEBAHdjwO z(D`6ePrj6Uph4Z+hEXwiJf2MUg!OiHJ>SjXNU1-k#O3Qb72fG^NnWgDQ^>E)F#f3+d{^(|Yq zH!XPl!%dlHuu3P3s60=)1~s47)1wz47USTRfAa&BTMo^}bLF|MBhxv)L`=p(FO$x( z#&#A_)ks2icba{NwL_-S6^H%khg086CZC#HSbz>L-bet60B_?~%<(L2RcT=1Ze1>I zcGZJLLzli8DOQ9I{mK=v{rK0NXpYaC2Ht|dFpqXiHgCmEg14BOT~DwB67eso2|9S? zlqX7F|7KcL?<8L4IHdr)_|pd2j3cs$H=bA28A{^?COVzc&CdvBe?hjh)BG$A>TUODUT=FbRpz zb3F6v^uaATNI&tgDcZd68ksDC@sRgWaG`yS_7Nm1C%Mp4)L<(%f_~e89`Pt*I#`bh zUHhe1fN}cYkAwLwOD*tMa3m-t+FQ-SM|G)KXXX7xH1rignL}5_Xei7P6Ud{0ZlW2U z{b|sEI-oBfmwd&M^5wP?SIsFDbS&226R8KHKX=M2QL2ZhxS$&A=;{2pmX5x_*fY}h z6Kev;vf1EgdD+-Lw+4^>EwNO$Ly6_>tS{XOM*E6~=8Nz4FX7#rZwwAESB0k0udSSZ zo=+5mm)TVYgam#cs6hTDZ+PcCFWX9jGXLhRRgFcRPf>kf`_oEDs;NGAt#z$lFWBZ4 zai%+w9eOaipImk4X?I!kG(qO`<%nfPhK*VbSGNoCTDf@ zvBYkdLC_)AB}L=+8V#BhKsK$*(XnEw`h?YnF%NCj^9e2MmyLkzZ69ux=i9-;?70TEdK>GL%d<1_@E`IUo)Psf>wUWu?>-TcY+~M)0(V}~ldm>)B=kE1X zM_W|K0@KGg>5?cEN|3suRQTQ+5z}N*CXEvq2vU#O+kzIG#Uq!kVkWep&VXKFZJPrH z1O^I#Bl;S`*>@7dzxMyF;Tru>l{F#eAZr*>yRQ`yA zm#wi&L-u$S;175=kIp~&VGb}^l)0A}oL?g(1#ob_Im)CmEV(^WPjlP!;CT?#U1jb6kP3QOa!hC!x%|sK?P8!4E49NqF z%TG|&NY#t}3+&=G)2ot2)7(PUvm9r>EA#Qt?GZOz!`rVl**D4EmS(y>{XsYRXP;uG zA!*=)CtTNDzj!sMi~uhJW{TWeX)DW6!-s(~RFq;uTc6+}NDqpiwKs1|hG9y5}Ec9+3?# zVjUvYlDPW7T5`b~&o#JHy(v>4rk42m_`2-#RjNi-d6LmhQIsuA4kg%&bI8_JV{mY= z|5dkr=}-MICXT_4tP(k%F&cqR641%nfzFLZP`#`U*J533zx)MUA+E@9!gjHP``xl= z&hT#2h=LjI>6Vzpp_wBYxy)u5b$v>;9!%sx!|x`4Va$9UZ!NZQ@2&Kgg;L8vS}{mq z9Ag=7UTK+>EJh?v-q2Opr48)PnpmKM56)9hP;Q>*mAysZGKYf=*9Xn7CMYCbaS0|R zHKvg!P0W8Ze~xog266805(5FtLMYz3(K3mfv7`+Mdx2#i6)E^tcb`aQ3T#USo1INe zaHGkj9~4U5YAnpqSOX;|=;b*MHGkr5`0y@9A8xw*WwXd5C;(d-sKYlVuC$wwSHNad zrqZ!;5L;3qr?iLam%tT_qcaH&#BRS2!*?$9)1{(q-f1H81<1$Ma0U~8e_P9vh&^DA`X|vh&+j_0&?sJt<&hhZx4cSj zAh%qu72AnwzpTqFkX)18FMIyY_;cyAEMLnq23~7U&1ODk5nHTw+upH#7ReH+L`+<^ zn9<@-C2TGaZeWNX_iLuP{nrI4R?8nOlGJE)(q!8%fne#j3mYiak;1CoDpCmro7=UN z_^coou#e?K)_)Hd6m?Yd?}+pB3M1B8Jn9}?zkc1i^7xl^6gDjF_&*bV{P(bCY9|s8 zQ5qd<1p$7w%9MU_kF&3zUkdG=AYhHHcy>z|u4XNjYKE)}Ptl@goMoW`wb8y`ae$8W z-aN%CZrOyda63rhNDJg6Qg&8;Jl!TvPv@%P!@Z1F`vlr-Q{3X! zhUL1be9>$w9=46PiYQQ`4#jV?TBS=ak{M=_D?+(Fcy=)Gndw4T!UYO}N`)!O|B3Um zU}^gBmX;RN;=(z3``<`hwlaURe~HaSpS$VaLwd4BUJ# zlgE)gn)92*=-zOLmJ&?L?#qhh$vF4>N$B7L5;u#ayy$HnM%JgN>=|W&{h^(0o+pPB>&cR7|bPNHc!Js+yfwZ zNrR;6wP&DX7-IR&_RefjzZ@@@F0vcys9tnC-73cI)p$g#Z!lL>uc?fbgupAcmXg%>%6`QRYaqUs7cJEXr8Ng){5Qj zPQ?(1AOFhxU@IvG?<-nAo4%Xk)&%5V-c-LfEtcm`CaBYXb{*eb-QI4@l7=;Xv_Dtv zoc}uwgbsc)7oms2>YZ!@%pbRGzgJqO^n=*Da&tl1l<~*%Ystf}Ss^Gu^L3Xp{yL2& zFsmN&N)|y4)-)%gRU*Xe#!3DOD!KKu4|X&(G}IA|{|RggbAm_qoR-Z5R4EDV(giD# zUu@t-6RLVhfG>U`-7RuL^)RD@>=+)oS)L$5A zklvsv8B!hB5lQ-nA`}N2Xuz6kpG#cwis=0Iujux8&^)4pt}JO3vaaq3lT_t9{_-uq z#=VK`1S3}FSt_6x{!_R4KgFLK2sz5Y4tyVMX_SM_hhbr|KSR`KFNH&Q^T_+}OB_zt2m6m>1}CFF*CBm8G}Qw=tV0>h&z3S%W{BM#unD1Dg9+ zl?9K0sCrpo55SjGLgDcE79>)!$kx_YctC|g&rv=-w~^Hwa4OM+Rlp&;9v0tygk4od z1@N+%0X+?y8{Vw~lyx3Baznj~24#r%4h$R*FWbC#SDsU=y7BsDvmxVm-A9C_VO&MQ zvA)v;sEv&cg)r~8V3ciCM7d8{uiE}AHf6Xyf+H_Zmk#NUWXGtk8FJ zpKwp1*_>EE)v-F+UASCP=Ky&3nQkVMEnktzG6MJ`FssRSQx4rwZBlU^`ZQu_1n}E7q z|4K>aJ{e_p5dW2X@2PUXx+r2{wLzjIKH((g^rI($s|3yKink zww$|w;vG1Du|5pG)4yg-q(3$@2^`%mJt+peJOGCsnFF0yZ6FOS2fs@BO@N4Qv?&Be z3_6wJfw!{5cfozbY^CgJ<}G$AniVNoZmfJ`i{om`VmG9g>}h25hj`Q8@XUyU>BdU) zuWRNla!pbXx@w~?10m8zWJ%lE6>G_G%}XnL?t=F?*loYBZ$E3L7CBPIKEyIh-tYMF zWMW1N)tqMv&Y)LLdr_84L)^|v-_(|ZRw z5$A$9^oG__O=(6&YZS_t1#4nz)D`IQAIK|O`uw29aZxm|qG|S%$dJku)8347&8)(` z+Agboe0)YAf;uS3Lr`XTGyHGuC@zq>vCGXUT3aTGNpLcpur4@27f+ufLHE%(sB`~+ z0hx_m3G2EwI9@v)0wsf71b#!DUXkSqL^FRL3OC=3K#>v$`qdJi1on9~Ztg1h_(7(v zpEWx%#uK0n&WDNy(2~>I{>h`kkm&jCeg!LVOTq$w5f#TcO3m_&>i^|!+ea;=6tisp zy2T^LiprSN!{6ti^t|{se&Vapa(I-+y{!8U3a+HRV%ef6o`$W-0O9|q#!K)3UDzZ6 zjS&V-?z?=+qqShd@~Ge>eGb%TG{av8V z+6-87r7nI@TkDg`=GSj3qw0Z78#uwyNR%PvLuOfPsPjU$dv5cQP{`|fl>N2M;m&Ir zwUs=ITgP@6J^JSF=ugawE!LLG6fr&W8q5=lt&-t!LS(b?evk=x8q^~%NqTb9`lSkv z>6aeq%L2~+C;Z~5iw8w&)%4Z8U`ike(WxP&QFK-vJ-atr9WO))o>zg-s<6!Eao#!Y zpWOG{NU*B8iDfvj?UiP9D@9cC%s2zn>sQ@J{^RDg`|FppI=@>B4;zqlv1n8NhjQ!x z!?`70Naojw&+wPcEc_yy@e~N7J*KGs6T5|f;x9N-HRA=)_bePpWBfa-{`-A!WilBk zG?cOYe8hC*c<@j|k8`_!VQ@DKdef?(V{;QW`3lMG%f<|yXWCJTU@Mk^~S+C#jN%y*32c#7^TWEx)fJ?|=; zY25UA-Yk4?OXjkhqh`e3o%z=d?eYWVQ=-R*rHcIApOEW&Z?0oR_)eQebqkp)oq-!z zT=thUQN1cWo@np|a!nu6)Jb+N@Vj%{h&SB>Z|t5AO-T_aD}{L)!p7+ zc*9^xeD@)`qA_FQ2MB+#7@t2i-;dV?-feMoleo2|6~&*oFfebAk#Ny0HiORbMZYu z#j{Euz~nJjJ;Df#VZDY&Ob`km{GM;*L%&Jfg6iwyWpB?P^S~-Eq@8hue}Jgmm_O!b zBT`pedkgQ|C7xrtu(I;Hi5PFK`U|(5VydL1gohxemRwt88-VKS3^Ke_z~0Wz?&0Cj zrCDDZxU@t76|1_|u-fo3x4~QyxF0DgDXGRrpszk=`f^3ly*yE%i<6VH#!9O1cX>X7 zZEd+tg;hVjytOG)_+kAgn^Q+^)o#vXeIURlK*NL4Q^vpatITRm5S58 zjH|#CeEw#oPg!1K^Z_3I3leV+=a*loXFt7#f0{BNMFrp-0skq`OFE~!ei5+*V9g>E z#ND@6gwJ;+A415k-+uw0vp?kt0E<1mwBY*vGXURB(Y|3YKDvYYU$$h;nT`Oka2TEyls2H!(v`T^5g7l`F?8)uBVMv7g$g< z1tYP?^UmY_WSmhe8?6eL5 z@jj=4E}qMNBXQK%6yTt1*MV)dGPC0;aiB3m|QgKGW?klA6>cBm@TtUKLtS96c@0=WlQ;2Ee&vA;VLY35NwEUuoe-T+;@K z+p>)Qw|D?eqo$??)Q=d~zaztUEx^wap{E%b*mDlg0&D@rc_*awes(Y{C@6y_Dy~(z zL>{lCJzYi}Xp)W-2H86i^t^+;IkZ4zAE2yE8pig2ybu6#tp$}k1c8IC!N`5N=VN-7 zr!0402t+7@!Gj?ZudBS_-;`#;fcmXh+Scwk5AWmtpUd`F4qVZMcm1yQFN6~XTmohE_lYC!{xz*(=mr>@2SbjOv7ua zy)}bQkyDDsv79GQf`L>rxf128U-*PS+ma8+Z&__w)O< z6!4)E;>c8<$KNRe2UxtKqT*ujIfGUjbSWT|PLAH1(9#M+VM2~7=BUMu0%8%dO-w&A z&dN^_G*VMmK6LHnYz4%D5CSlqEm#2i z4%zbVvd*wM5|rsuS)&u*zsv5wY_9XPky8kD7zo~6F&YAQuFje1b5Ky`t>SH^fv9hj z-#HfFt**CLjPXQr206}d0%c~7(2Y*70-tTDh51p=GXVhs)5!2Cj-r%!P;Yhg2wn^L zx|Q}QgY*6+SVMeSQX5=v=32NnEroHa+kQv-SE+RV)pV$af zO_VTDspST`6u;CmmrehvoNb)O6f1z>CG}Ji78$B$okU#UAKz_{TPE%Yhgz(x5z0KO zva+(=WS&VyaTJ>3wScX?=M+~f?CkkI+`M!SnI(?#P)6vR3-n1}#NDk4Y5A(HJ-F>K z^WI|$n??{8^9_771pCH|UPBgoOw~zXAj-YI;&b&2k&d04vin~gG4`(JsruyHaIgGM zMdND9;VG41jt6E}$Lp z$)A`J^V?3STriwqXSGC3-CalKdgW)7s-6jGZ}a!}?+VwTN==dpWp=oSF~3!Ebo#3) z8>t^p`E-ZYdC(x4C+!rfywMAHi!{#F=*XZfC)U!f#!gg6`y!)Xe_`gG>r@}9{+hiy zSD{$O>eD?5oYpXFsg{8MDR_U|JZ8NwTlx;D5e+DDnVuR}#zerT*fh?ala3tpr3`rF zU_(wFI1J>BF3>!R0_WNn7qarTgDopPW~ME?H}^7~XyO_=RZAri)72mhe~|sfxzOhl zk4Tkz5G`semw!dMW-%&I7e%9QLxt&Zf$5CU2h^WRBVaVkTmjkPHT7 zQ0G9CH9UWbMjnUF9qjKeqjo83fuq^k*@dVi-XfrEKDCrCWnVw#P3Ii(d4ZxY`Pd`F zUIwL_mf#^5<^xaa7gX}~gh+7d+pE2yJrFz+c1_?vPbcC6ukz0CX|i68otYD4NyHeg zFT;KZGz0F^mFL{?`{A6HmX`POG=-jTqmdqp5D4T?CFOzOHzJXkx4&Kl6x7-Cp}~c$ zQ0vO0H|KBIVm+g+9^1MCG7Gw;!u{BmA{~cOVS#qtB-C^oOU_;F1xkQx&u`cc$i#_( zc+zEJeO1uL6~7d3IKC zr=vvpwKv=hG1VWUp!juoc(_2yQP)4`&=lJpz3Q%*lohJ#12~2x(zU;)9B?>X8S*t~ z1f2aFj0Y5`@0Er|-55X_N=ZqbY2@ezKElHBo=fzOm;0lD|0o-C#&sWA5OUobq%k*RfZd+0i6-_2S6v{)8Z8}PJ~A=+2H%R|)9xN_)4K^LM7bK!GsesDc#g6TD)&-FD|#r@4_Z;I!=TkSpU$ z5hL#_wa$j!41SAWE?o%Bk5DpgDlD^8N{?V&2)qI}IOcz5Fmxb#L`bOZ&^<8yG!@H+ z40twDei?q~j);Dm(s|j$G9k|Q)9M!9&~=`R)qhHh3dX=^s&`&JyBz$N>~_Yx2=s#7 z>G)sT1rXlH*oH<+pGLW7c+v^cmkG1&eJvrFoam`+?b*u>9G}Y@a;%X{e||14=Xsrn z^ESG=wDmn>Zm;Zu{^!}I|9;l#pMvXiXvY{@-#jSC;({N8qHgZ2&yP~)2Cuj_G&C3k ziL4t-6pGHE7J=dHRFFDnXfHmIn9US*vk8ez3c}(O;XvLCVCSPoN`u-%$_(1)6jS8> z+#Mwe^ae``zlSm$>jS4yZH;dNB(hXesP^X!|Ib|?4XX9%XV_;pcj13ktA~{ZC4h5T zWb+AI-~_{k3m2jVmI|O+jJ?FQKbgLS{sM5xISuV$We5LPvskJ9!7xvG9(a=|!|O`} zrHrp%g_}DF^}EUe1O#)8+=kPKlpV~8zA6CB2GITKs_*z1^g1ezcVxjv#m?Ry9K7b7 z=xKH}Pcz&%Qs0rvoGX|3wEKwrBp%O~j3(6;1KO!41n!Hb{{Vy&oh*>95C6^EArTMb z)LQ$y;QXaC>73s@X&SAr$-{c}Ws}h5wh`bpxW7q2U#27hIYZz}0zA!~j4pLP1cUbX zRFwGi^h(Db5XG4jncl4aT~5B=#9a5F9LPoL9u)j;1Xg)fKRxdD!bgBsa0uDIzC^S=P6gy5(E literal 0 HcmV?d00001 diff --git a/test/jdk/java/awt/color/XAWTDifference/XAWTDifference.java b/test/jdk/java/awt/color/XAWTDifference/XAWTDifference.java new file mode 100644 index 0000000000000..ef0f5aacf4479 --- /dev/null +++ b/test/jdk/java/awt/color/XAWTDifference/XAWTDifference.java @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.Canvas; +import java.awt.Checkbox; +import java.awt.Choice; +import java.awt.Component; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Image; +import java.awt.Label; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.PopupMenu; +import java.awt.ScrollPane; +import java.awt.Scrollbar; +import java.awt.TextArea; +import java.awt.TextField; +import java.awt.Window; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; + +/* + * @test + * @bug 5092883 6513478 7154025 + * @requires (os.family == "linux") + * @summary REGRESSION: SystemColor class gives back wrong values under Linux + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual XAWTDifference + */ + +public class XAWTDifference { + + private static final String INSTRUCTIONS = """ + You would see a frame with title "XAWTDifference Test Frame". + + Test Frame (1) + + a) It has three columns in it. The 1st one with ordinary components. + The 2nd one with disabled components. + The 3rd one with uneditable components (only text components + are there). Verify that the difference between different states + is visible. + + Standard Frame (2) + + b) You would also see a frame named StandardFrame (2) + with a lot of components in it. Actually this is just a jpg-image + in a frame. Verify that every component in the frame (1) looks + similar to the same component in (2). + + They might differ in colors and be darker or brighter but + the whole picture should be the same. + + c) Also check the color of the MenuBar Items in the MenuBar and + the PopupMenu assigned to TextArea. + As you can't compare the colors of menu items with the picture + so just look if the are adequate enough. + """; + private static final int HGAP = 20; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(XAWTDifference::createAndShowUI) + .positionTestUI(XAWTDifference::positionMultiTestUI) + .build() + .awaitAndCheck(); + } + + private static Panel addComponentsIntoPanel(boolean enabled, boolean editable) { + TextField tf = new TextField("TextField"); + TextArea ta = new TextArea("TextArea", 10, 10); + + Choice levelChooser = new Choice(); + levelChooser.add("Item #1"); + levelChooser.add("Item #2"); + + Button b = new Button("BUTTON"); + Label label = new Label("LABEL"); + java.awt.List list = new java.awt.List(4, false); + list.add("one"); + list.add("two"); + list.add("three"); + + Checkbox chb = new Checkbox(); + Scrollbar sb = new Scrollbar(Scrollbar.HORIZONTAL); + ScrollPane sp = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS); + sp.add(new TextArea("this is a textarea in scrollpane")); + sp.setSize(200, 200); + Canvas canvas = new Canvas(); + canvas.setSize(100, 100); + + //add popup menu to Button + final PopupMenu pm = new PopupMenu(); + MenuItem i1 = new MenuItem("Item1"); + MenuItem i2 = new MenuItem("Item2"); + MenuItem i3 = new MenuItem("Item3"); + i3.setEnabled(false); + pm.add(i1); + pm.add(i2); + pm.add(i3); + canvas.add(pm); + + ta.add(pm); + ta.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + if (me.isPopupTrigger()) { + pm.show(me.getComponent(), me.getX(), me.getY()); + } + } + }); + + ArrayList componentList = new ArrayList<>(); + + componentList.add(tf); + componentList.add(ta); + if (editable){ + componentList.add(levelChooser); + componentList.add(b); + componentList.add(label); + componentList.add(list); + componentList.add(chb); + componentList.add(sb); + componentList.add(sp); + componentList.add(canvas); + } else { + tf.setEditable(false); + ta.setEditable(false); + } + + Panel panel = new Panel(); + panel.setLayout(new GridLayout(0, 1)); + for (Component c : componentList) { + if (!enabled) { + c.setEnabled(false); + } + panel.add(c); + } + return panel; + } + + private static List createAndShowUI() { + Frame testFrame = new Frame("XAWTDifference Test Frame"); + StandardFrame standardFrame = new StandardFrame("StandardFrame"); + standardFrame.pack(); + + testFrame.setLayout(new GridLayout(1, 3)); + testFrame.add(addComponentsIntoPanel(true, true)); + testFrame.add(addComponentsIntoPanel(false, true)); + testFrame.add(addComponentsIntoPanel(true, false)); + + MenuItem mi1 = new MenuItem("Item1"); + MenuItem mi2 = new MenuItem("Item2"); + MenuItem mi3 = new MenuItem("Disabled Item3"); + mi3.setEnabled(false); + + MenuBar mb = new MenuBar(); + Menu enabledMenu = new Menu("Enabled Menu"); + Menu disabledMenu = new Menu("Disabled Menu"); + disabledMenu.setEnabled(false); + mb.add(enabledMenu); + mb.add(disabledMenu); + enabledMenu.add(mi1); + enabledMenu.add(mi2); + enabledMenu.add(mi3); + + testFrame.setMenuBar(mb); + testFrame.setSize(standardFrame.getWidth(), standardFrame.getHeight()); + return List.of(testFrame, standardFrame); + } + + private static void positionMultiTestUI(List windows, + PassFailJFrame.InstructionUI instructionUI) { + int x = instructionUI.getLocation().x + instructionUI.getSize().width + HGAP; + for (Window w : windows) { + w.setLocation(x, instructionUI.getLocation().y); + x += w.getWidth() + HGAP; + } + } + + private static class StandardFrame extends Frame { + public StandardFrame(String name) { + super(name); + String testPath = System.getProperty("test.src", "."); + Panel panel = new Panel(); + panel.add(new JLabel(new ImageIcon(testPath + File.separator + "XAWTColors.jpg"))); + add(panel); + } + } +} From 5fc2e566902757e317f577dd90eb6190b4048d40 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 21 Apr 2025 08:22:54 +0000 Subject: [PATCH 208/846] 8051591: Test javax/swing/JTabbedPane/8007563/Test8007563.java fails Backport-of: 780de009224b048fa51a119e1db6cc52daddaaf8 --- test/jdk/ProblemList.txt | 1 - .../JTabbedPane/8007563/Test8007563.java | 137 ------------------ .../TestJTabbedPaneBackgroundColor.java | 137 ++++++++++++++++++ 3 files changed, 137 insertions(+), 138 deletions(-) delete mode 100644 test/jdk/javax/swing/JTabbedPane/8007563/Test8007563.java create mode 100644 test/jdk/javax/swing/JTabbedPane/TestJTabbedPaneBackgroundColor.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 880a3bfd630d3..24e33f61c102f 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -701,7 +701,6 @@ javax/swing/AbstractButton/6711682/bug6711682.java 8060765 windows-all,macosx-al javax/swing/JFileChooser/6396844/TwentyThousandTest.java 8198003 generic-all javax/swing/JFileChooser/8194044/FileSystemRootTest.java 8327236 windows-all javax/swing/JPopupMenu/6800513/bug6800513.java 7184956 macosx-all -javax/swing/JTabbedPane/8007563/Test8007563.java 8051591 generic-all javax/swing/JTabbedPane/4624207/bug4624207.java 8064922 macosx-all javax/swing/SwingUtilities/TestBadBreak/TestBadBreak.java 8160720 generic-all javax/swing/JFileChooser/6798062/bug6798062.java 8146446 windows-all diff --git a/test/jdk/javax/swing/JTabbedPane/8007563/Test8007563.java b/test/jdk/javax/swing/JTabbedPane/8007563/Test8007563.java deleted file mode 100644 index 25d3ad41eca59..0000000000000 --- a/test/jdk/javax/swing/JTabbedPane/8007563/Test8007563.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.awt.*; -import java.util.ArrayList; -import java.util.concurrent.CountDownLatch; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JTabbedPane; - -import static javax.swing.UIManager.*; -import static javax.swing.SwingUtilities.*; - -/* - * @test - * @key headful - * @bug 8007563 - * @summary Tests JTabbedPane background - * @author Sergey Malenkov - */ - -public class Test8007563 implements Runnable { - private static final ArrayList LIST = new ArrayList<>(); - private static final LookAndFeelInfo[] INFO = getInstalledLookAndFeels(); - private static final CountDownLatch LATCH = new CountDownLatch(INFO.length); - private static Robot ROBOT; - - public static void main(String[] args) throws Exception { - ROBOT = new Robot(); - invokeLater(new Test8007563()); - LATCH.await(); - if (!LIST.isEmpty()) { - throw new Error(LIST.toString()); - } - } - - private static void addOpaqueError(boolean opaque) { - LIST.add(getLookAndFeel().getName() + " opaque=" + opaque); - } - - private static boolean updateLookAndFeel() { - int index = (int) LATCH.getCount() - 1; - if (index >= 0) { - try { - LookAndFeelInfo info = INFO[index]; - System.err.println("L&F: " + info.getName()); - setLookAndFeel(info.getClassName()); - return true; - } catch (Exception exception) { - exception.printStackTrace(); - } - } - return false; - } - - private JFrame frame; - private JTabbedPane pane; - - public void run() { - if (this.frame == null) { - if (!updateLookAndFeel()) { - return; - } - this.pane = new JTabbedPane(); - this.pane.setOpaque(false); - this.pane.setBackground(Color.RED); - for (int i = 0; i < 3; i++) { - this.pane.addTab("Tab " + i, new JLabel("Content area " + i)); - } - this.frame = new JFrame(getClass().getSimpleName()); - this.frame.getContentPane().setBackground(Color.BLUE); - this.frame.add(this.pane); - this.frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - this.frame.setSize(400, 200); - this.frame.setLocationRelativeTo(null); - this.frame.setVisible(true); - } else { - Point point = new Point(this.pane.getWidth() - 2, 2); - convertPointToScreen(point, this.pane); - Color actual = ROBOT.getPixelColor(point.x, point.y); - - boolean opaque = this.pane.isOpaque(); - Color expected = opaque - ? this.pane.getBackground() - : this.frame.getContentPane().getBackground(); - - if (!expected.equals(actual)){ - addOpaqueError(opaque); - } - if (!opaque) { - this.pane.setOpaque(true); - this.pane.repaint(); - } else { - this.frame.dispose(); - this.frame = null; - this.pane = null; - LATCH.countDown(); - } - - } - SecondaryLoop secondaryLoop = - Toolkit.getDefaultToolkit().getSystemEventQueue() - .createSecondaryLoop(); - new Thread() { - @Override - public void run() { - try { - Thread.sleep(200); - } catch (InterruptedException e) { - } - secondaryLoop.exit(); - invokeLater(Test8007563.this); - } - }.start(); - secondaryLoop.enter(); - } -} diff --git a/test/jdk/javax/swing/JTabbedPane/TestJTabbedPaneBackgroundColor.java b/test/jdk/javax/swing/JTabbedPane/TestJTabbedPaneBackgroundColor.java new file mode 100644 index 0000000000000..d4bed5ac2dafa --- /dev/null +++ b/test/jdk/javax/swing/JTabbedPane/TestJTabbedPaneBackgroundColor.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.util.ArrayList; + +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +/* + * @test + * @key headful + * @bug 8007563 + * @summary Tests JTabbedPane background + */ + +public class TestJTabbedPaneBackgroundColor { + private static ArrayList lafList = new ArrayList<>(); + private static JFrame frame; + private static JTabbedPane pane; + private static Robot robot; + private static volatile Dimension dim; + private static volatile Point loc; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + + for (UIManager.LookAndFeelInfo laf : + UIManager.getInstalledLookAndFeels()) { + System.out.println("Testing: " + laf.getName()); + setLookAndFeel(laf); + + try { + SwingUtilities.invokeAndWait(TestJTabbedPaneBackgroundColor::createAndShowUI); + robot.waitForIdle(); + robot.delay(500); + + SwingUtilities.invokeAndWait(() -> { + loc = pane.getLocationOnScreen(); + dim = pane.getSize(); + }); + + loc = new Point(loc.x + dim.width - 2, loc.y + 2); + doTesting(loc, laf); + + if (!pane.isOpaque()) { + pane.setOpaque(true); + pane.repaint(); + } + robot.waitForIdle(); + robot.delay(500); + + doTesting(loc, laf); + + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + if (!lafList.isEmpty()) { + throw new RuntimeException(lafList.toString()); + } + } + + private static void setLookAndFeel(UIManager.LookAndFeelInfo laf) { + try { + UIManager.setLookAndFeel(laf.getClassName()); + } catch (UnsupportedLookAndFeelException ignored) { + System.out.println("Unsupported LAF: " + laf.getClassName()); + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + private static void createAndShowUI() { + pane = new JTabbedPane(); + pane.setOpaque(false); + pane.setBackground(Color.RED); + for (int i = 0; i < 3; i++) { + pane.addTab("Tab " + i, new JLabel("Content area " + i)); + } + frame = new JFrame("Test Background Color"); + frame.getContentPane().setBackground(Color.BLUE); + frame.add(pane); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.setSize(400, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + private static void doTesting(Point p, UIManager.LookAndFeelInfo laf) { + boolean isOpaque = pane.isOpaque(); + Color actual = robot.getPixelColor(p.x, p.y); + Color expected = isOpaque + ? pane.getBackground() + : frame.getContentPane().getBackground(); + + if (!expected.equals(actual)) { + addOpaqueError(laf.getName(), isOpaque); + } + } + + private static void addOpaqueError(String lafName, boolean opaque) { + lafList.add(lafName + " opaque=" + opaque); + } +} From 8c35f3957df471a7ec24cbdc79a8b7e66aa44e27 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 21 Apr 2025 08:24:19 +0000 Subject: [PATCH 209/846] 8343124: Tests fails with java.lang.IllegalAccessException: class com.sun.javatest.regtest.agent.MainWrapper$MainTask cannot access Backport-of: dafa2e55adb6b054c342d5e723e51087d771e6d6 --- .../awt/print/Dialog/PrintDlgPageable.java | 161 ++++++++--------- .../print/StreamPrintingOrientation.java | 170 ++++++++++-------- 2 files changed, 169 insertions(+), 162 deletions(-) diff --git a/test/jdk/java/awt/print/Dialog/PrintDlgPageable.java b/test/jdk/java/awt/print/Dialog/PrintDlgPageable.java index eadd3cf9cb6bc..ba13ea9682542 100644 --- a/test/jdk/java/awt/print/Dialog/PrintDlgPageable.java +++ b/test/jdk/java/awt/print/Dialog/PrintDlgPageable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,105 +25,98 @@ * @test * @bug 4869502 4869539 * @key printer - * @summary Confirm that ToPage is populated for argument =2. Range is disabled for argument = 0. - * @run main/manual PrintDlgPageable + * @summary Confirm that ToPage is populated for argument = 2. Range is disabled for argument = 0. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual PrintDlgPageable 0 + * @run main/manual PrintDlgPageable 2 */ -import java.awt.*; -import java.awt.print.*; -import java.util.Locale; -import javax.print.*; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.print.PageFormat; +import java.awt.print.Pageable; +import java.awt.print.Printable; +import java.awt.print.PrinterJob; +import java.awt.print.PrinterException; + +public class PrintDlgPageable implements Printable { -class PrintDlgPageable implements Printable { public static int arg; - /** - * Constructor - */ - public PrintDlgPageable() { - super(); + public PrintDlgPageable() { + super(); + } + + public static void main(String[] args) throws Exception { + if (args.length < 1) { + System.out.println("usage: java PrintDlgPageable { 0 | 2}"); + return; } - /** - * Starts the application. - */ - public static void main(java.lang.String[] args) { - if (args.length < 1) { - System.out.println("usage: java PrintDlgPageable { 0 | 2}"); - return; - } - arg = Integer.parseInt(args[0]); - PrintDlgPageable pd = new PrintDlgPageable(); - PrinterJob pj = PrinterJob.getPrinterJob(); - PageableHandler handler = new PageableHandler(); - pj.setPageable(handler); - - System.out.println("open PrintDialog.."); - if (pj.printDialog()) { - try { - System.out.println("About to print the data ..."); - pj.print(); - System.out.println("Printed"); - } - catch (PrinterException pe) { - pe.printStackTrace(); - } - } + arg = Integer.parseInt(args[0]); + String INSTRUCTIONS = " A pagedialog will be shown."; + + if (arg == 0) { + INSTRUCTIONS += "\n Confirm that page range is disabled."; + } else if (arg == 2) { + INSTRUCTIONS += "\n Confirm ToPage is populated with pagerange 2"; } + INSTRUCTIONS += "\nCancel the print dialog. Press PASS if it so seen else press FAIL."; + + PrinterJob pj = PrinterJob.getPrinterJob(); + PageableHandler handler = new PageableHandler(); + pj.setPageable(handler); + + PassFailJFrame passFailJFrame = PassFailJFrame.builder() + .title("Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .build(); - //printable interface - public int print(Graphics g, PageFormat pf, int pi) throws -PrinterException { - - /*if (pi > 0) { - System.out.println("pi is greater than 0"); - return Printable.NO_SUCH_PAGE; - }*/ - // Simply draw two rectangles - Graphics2D g2 = (Graphics2D)g; - g2.setColor(Color.black); - g2.translate(pf.getImageableX(), pf.getImageableY()); - g2.drawRect(1,1,200,300); - g2.drawRect(1,1,25,25); - System.out.println("print method called "+pi + " Orientation "+pf.getOrientation()); - return Printable.PAGE_EXISTS; + if (pj.printDialog()) { + try { + pj.print(); + } catch (PrinterException pe) { + pe.printStackTrace(); + } } + passFailJFrame.awaitAndCheck(); + } + + //printable interface + public int print(Graphics g, PageFormat pf, int pi) throws PrinterException { + + // Simply draw two rectangles + Graphics2D g2 = (Graphics2D) g; + g2.setColor(Color.black); + g2.translate(pf.getImageableX(), pf.getImageableY()); + g2.drawRect(1, 1, 200, 300); + g2.drawRect(1, 1, 25, 25); + return Printable.PAGE_EXISTS; + } } class PageableHandler implements Pageable { - PageFormat pf = new PageFormat(); + PageFormat pf = new PageFormat(); - public int getNumberOfPages() { - return PrintDlgPageable.arg; - //return 0; - } + public int getNumberOfPages() { + return PrintDlgPageable.arg; + } - public Printable getPrintable(int pageIndex) { - return new PrintDlgPageable(); - } + public Printable getPrintable(int pageIndex) { + return new PrintDlgPageable(); + } - public PageFormat getPageFormat(int pageIndex) { - System.out.println("getPageFormat called "+pageIndex); - if (pageIndex == 0) { - pf.setOrientation(PageFormat.PORTRAIT); - System.out.println("Orientation returned from Pageable "+findOrientation(pf.getOrientation())); - return pf; - } else { - pf.setOrientation(PageFormat.LANDSCAPE); - System.out.println("Orientation returned from Pageable "+findOrientation(pf.getOrientation())); - return pf; - } + public PageFormat getPageFormat(int pageIndex) { + if (pageIndex == 0) { + pf.setOrientation(PageFormat.PORTRAIT); + return pf; + } else { + pf.setOrientation(PageFormat.LANDSCAPE); + return pf; } + } - public String findOrientation(int orient) { - if (orient == PageFormat.LANDSCAPE) { - return "LANDSCAPE"; - }else if (orient == PageFormat.PORTRAIT) { - return "PORTRAIT"; - } else if (orient == PageFormat.REVERSE_LANDSCAPE) { - return "REVERSE LANDSCAPE"; - } else { - return null; - } - } } diff --git a/test/jdk/javax/print/StreamPrintingOrientation.java b/test/jdk/javax/print/StreamPrintingOrientation.java index d7736aa4f620e..77dd8f4cae04f 100644 --- a/test/jdk/javax/print/StreamPrintingOrientation.java +++ b/test/jdk/javax/print/StreamPrintingOrientation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,95 +24,109 @@ /* * @test * @bug 4904236 - * @summary You would see a cross-platform print dialog being popped up. Check whether orientation is shown as LANDSCAPE. Click 'OK'. 'streamexample.ps' will be created in the same dir where this application was executed. Pass if the orientation in the ps file is landscape. - * @run main/manual StreamPrintingOrientation + * @key printer + * @summary StreamPrintService ignores the PrintReqAttrSet when printing through 2D Printing + * @run main StreamPrintingOrientation */ -import java.awt.*; -import java.awt.print.*; -import javax.print.*; -import javax.print.attribute.standard.*; -import javax.print.attribute.*; -import java.io.FileOutputStream; import java.io.File; -import java.util.Locale; +import java.io.FileOutputStream; +import java.nio.file.Files; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import javax.print.attribute.Attribute; +import javax.print.PrintService; +import javax.print.StreamPrintServiceFactory; +import javax.print.attribute.standard.Copies; +import javax.print.attribute.standard.JobName; +import javax.print.attribute.standard.OrientationRequested; +import javax.print.attribute.HashPrintRequestAttributeSet; + +public class StreamPrintingOrientation implements Printable { + + public static void main(String[] args) throws Exception { + StreamPrintingOrientation pd = new StreamPrintingOrientation(); + PrinterJob pj = PrinterJob.getPrinterJob(); + HashPrintRequestAttributeSet prSet = new HashPrintRequestAttributeSet(); + PrintService service = null; + + FileOutputStream fos = null; + String mType = "application/postscript"; -class StreamPrintingOrientation implements Printable { - /** - * Constructor - */ - public StreamPrintingOrientation() { - super(); + File fl = new File("stream_landscape.ps"); + fl.deleteOnExit(); + fos = new FileOutputStream(fl); + StreamPrintServiceFactory[] factories = PrinterJob.lookupStreamPrintServices(mType); + if (factories.length > 0) { + service = factories[0].getPrintService(fos); } - /** - * Starts the application. - */ - public static void main(java.lang.String[] args) { - StreamPrintingOrientation pd = new StreamPrintingOrientation(); - PrinterJob pj = PrinterJob.getPrinterJob(); - HashPrintRequestAttributeSet prSet = new HashPrintRequestAttributeSet(); - PrintService service = null; - FileOutputStream fos = null; - File f = null, f1 = null; - String mType = "application/postscript"; + if (service != null) { + System.out.println("Stream Print Service " + service); + pj.setPrintService(service); + } else { + throw new RuntimeException("No stream Print Service available."); + } + + pj.setPrintable(pd); + prSet.add(OrientationRequested.LANDSCAPE); + prSet.add(new Copies(1)); + prSet.add(new JobName("orientation test", null)); + System.out.println("open PrintDialog.."); - try { - f = new File("streamexample.ps"); - fos = new FileOutputStream(f); - StreamPrintServiceFactory[] factories = PrinterJob.lookupStreamPrintServices(mType); - if (factories.length > 0) - service = factories[0].getPrintService(fos); + System.out.println("\nValues in attr set passed to print method"); + Attribute attr[] = prSet.toArray(); + for (int x = 0; x < attr.length; x++) { + System.out.println("Name " + attr[x].getName() + " " + attr[x]); + } + System.out.println("About to print the data ..."); + if (service != null) { + System.out.println("TEST: calling Print"); + pj.print(prSet); + System.out.println("TEST: Printed"); + } - if (service != null) { - System.out.println("Stream Print Service "+service); - pj.setPrintService(service); - } else { - throw new RuntimeException("No stream Print Service available."); - } - } catch (Exception e) { - e.printStackTrace(); - } + File fp = new File("stream_portrait.ps"); + fp.deleteOnExit(); + fos = new FileOutputStream(fp); + if (factories.length > 0) { + service = factories[0].getPrintService(fos); + } - pj.setPrintable(pd); - prSet.add(OrientationRequested.LANDSCAPE); - prSet.add(new Copies(3)); - prSet.add(new JobName("orientation test", null)); - System.out.println("open PrintDialog.."); - if (pj.printDialog(prSet)) { - try { - System.out.println("\nValues in attr set passed to print method"); - Attribute attr[] = prSet.toArray(); - for (int x = 0; x < attr.length; x ++) { - System.out.println("Name "+attr[x].getName()+" "+attr[x]); - } - System.out.println("About to print the data ..."); - if (service != null) { - System.out.println("TEST: calling Print"); - pj.print(prSet); - System.out.println("TEST: Printed"); - } - } - catch (PrinterException pe) { - pe.printStackTrace(); - } - } + pj.setPrintService(service); + pj.setPrintable(pd); + prSet.add(OrientationRequested.PORTRAIT); + prSet.add(new Copies(1)); + prSet.add(new JobName("orientation test", null)); + if (service != null) { + pj.print(prSet); + } + if (Files.mismatch(fl.toPath(), fp.toPath()) == -1) { + throw new RuntimeException("Printing stream orientation is same " + + "for both PORTRAIT and LANDSCAPE"); } + } - //printable interface - public int print(Graphics g, PageFormat pf, int pi) throws PrinterException { + //printable interface + public int print(Graphics g, PageFormat pf, int pi) throws PrinterException { - if (pi > 0) { - return Printable.NO_SUCH_PAGE; - } - // Simply draw two rectangles - Graphics2D g2 = (Graphics2D)g; - g2.setColor(Color.black); - g2.translate(pf.getImageableX(), pf.getImageableY()); - System.out.println("StreamPrinting Test Width "+pf.getWidth()+" Height "+pf.getHeight()); - g2.drawRect(1,1,200,300); - g2.drawRect(1,1,25,25); - return Printable.PAGE_EXISTS; + if (pi > 0) { + return Printable.NO_SUCH_PAGE; } + // Simply draw two rectangles + Graphics2D g2 = (Graphics2D) g; + g2.setColor(Color.black); + g2.translate(pf.getImageableX(), pf.getImageableY()); + System.out.println("StreamPrinting Test Width " + pf.getWidth() + " Height " + pf.getHeight()); + g2.drawRect(1, 1, 200, 300); + g2.drawRect(1, 1, 25, 25); + return Printable.PAGE_EXISTS; + } } From 0295161bb5e39b299021912ab91e3048ebe48193 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 21 Apr 2025 08:25:54 +0000 Subject: [PATCH 210/846] 8253440: serviceability/sa/TestJhsdbJstackLineNumbers.java failed with "Didn't find enough line numbers" Backport-of: 0b1f57105d5af72b2cd47fa5c9a2b4e2961318cd --- .../sa/TestJhsdbJstackLineNumbers.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLineNumbers.java b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLineNumbers.java index 5d9c3982fb644..87e664ef308f0 100644 --- a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLineNumbers.java +++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLineNumbers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ /** * @test + * @bug 8214226 8243500 * @requires vm.hasSA * @requires os.arch=="amd64" | os.arch=="x86_64" * @requires os.family=="windows" | os.family == "linux" | os.family == "mac" @@ -53,7 +54,7 @@ * * The test works by spawning a process that sits in a 10 line loop in the busywork() method, * all while the main test does repeated jstacks on the process. The expectation is - * that at least 5 of the lines in the busywork() loop will eventually show up in at + * that at least 4 of the lines in the busywork() loop will eventually show up in at * least one of the jstack runs. */ @@ -94,8 +95,11 @@ public static void main(String... args) { public class TestJhsdbJstackLineNumbers { // This is the number of lines in the busywork main loop static final int TOTAL_BUSYWORK_LOOP_LINES = 10; - // The minimum number of lines that we must at some point see in the jstack output - static final int MIN_BUSYWORK_LOOP_LINES = 5; + // The minimum number of lines that we must see at some point in the jstack output. + // There's always a chance we could see fewer, but the chances are so low that + // it is unlikely to ever happen. We can always decrease the odds by lowering + // the required number of lines or increasing the number of jstack runs. + static final int MIN_BUSYWORK_LOOP_LINES = 4; static final int MAX_NUMBER_OF_JSTACK_RUNS = 25; From b73dd0cd758036a57706e3a2f42ff407a6cdfcf2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 21 Apr 2025 08:26:56 +0000 Subject: [PATCH 211/846] 8352109: java/awt/Desktop/MailTest.java fails in platforms where Action.MAIL is not supported Backport-of: c7f333888be052aa37fe878bfc2785fc47fbeaaa --- test/jdk/java/awt/Desktop/MailTest.java | 40 ++++++++++++------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/test/jdk/java/awt/Desktop/MailTest.java b/test/jdk/java/awt/Desktop/MailTest.java index 15e5c0769a0dc..2775a671310ee 100644 --- a/test/jdk/java/awt/Desktop/MailTest.java +++ b/test/jdk/java/awt/Desktop/MailTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, 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 @@ -21,21 +21,23 @@ * questions. */ +import java.awt.Desktop; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import javax.swing.JPanel; + +import jtreg.SkippedException; + /* * @test * @bug 6255196 * @summary Verifies the function of methods mail() and mail(java.net.URI uri). - * @library /java/awt/regtesthelpers - * @build PassFailJFrame + * @library /java/awt/regtesthelpers /test/lib + * @build PassFailJFrame jtreg.SkippedException * @run main/manual MailTest */ -import java.awt.Desktop; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import javax.swing.JPanel; - public class MailTest extends JPanel { static final String INSTRUCTIONS = """ @@ -48,18 +50,7 @@ public class MailTest extends JPanel { """; private MailTest() { - if (!Desktop.isDesktopSupported()) { - PassFailJFrame.log("Class java.awt.Desktop is not supported on " + - "current platform. Farther testing will not be performed"); - PassFailJFrame.forcePass(); - } - Desktop desktop = Desktop.getDesktop(); - if (!desktop.isSupported(Desktop.Action.MAIL)) { - PassFailJFrame.log("Action.MAIL is not supported."); - PassFailJFrame.forcePass(); - } - /* * Part 1: launch the mail composing window without a mailto URI. */ @@ -103,6 +94,15 @@ private MailTest() { public static void main(String[] args) throws InterruptedException, InvocationTargetException { + if (!Desktop.isDesktopSupported()) { + throw new SkippedException("Class java.awt.Desktop is not supported " + + "on current platform. Further testing will not be performed"); + } + + if (!Desktop.getDesktop().isSupported(Desktop.Action.MAIL)) { + throw new SkippedException("Action.MAIL is not supported."); + } + PassFailJFrame.builder() .title("Mail Test") .splitUI(MailTest::new) From 5a4b8cfdaafc4baa0488bbcac793b78197aab1a3 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 21 Apr 2025 08:27:49 +0000 Subject: [PATCH 212/846] 8349348: Refactor ClassLoaderDeadlock.sh and Deadlock.sh to run fully in java Backport-of: 32d6d031514be9cfee5b0fd778cb738b7ff9d770 --- .../ClassLoaderDeadlock.java | 11 +- .../ClassLoaderDeadlock.sh | 106 ------------------ .../ClassLoaderDeadlock/Deadlock.java | 11 +- .../Security/ClassLoaderDeadlock/Deadlock.sh | 66 ----------- 4 files changed, 17 insertions(+), 177 deletions(-) delete mode 100644 test/jdk/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh delete mode 100644 test/jdk/java/security/Security/ClassLoaderDeadlock/Deadlock.sh diff --git a/test/jdk/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.java b/test/jdk/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.java index f5af071654c61..d2794e70a2d9e 100644 --- a/test/jdk/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.java +++ b/test/jdk/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, 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 @@ -21,7 +21,14 @@ * questions. */ -// See bug 5094825 / ClassLoadDeadlock.sh +/* +* @test +* @bug 5094825 +* @summary verify no deadlock if crypto provider in other classloader is used to verify signed jars +* @library ./Deadlock.jar +* @compile provider/HashProvider.java +* @run main/othervm/timeout=30 ClassLoaderDeadlock +*/ import java.net.*; diff --git a/test/jdk/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh b/test/jdk/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh deleted file mode 100644 index e2e573928535e..0000000000000 --- a/test/jdk/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh +++ /dev/null @@ -1,106 +0,0 @@ -# -# Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# 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 5094825 -# @summary verify no deadlock if crypto provider in other classloader is used to verify signed jars -# -# @run shell/timeout=30 ClassLoaderDeadlock.sh - -# set a few environment variables so that the shell-script can run stand-alone -# in the source directory -if [ "${TESTSRC}" = "" ] ; then - TESTSRC="." -fi - -if [ "${TESTCLASSES}" = "" ] ; then - TESTCLASSES="." -fi - -if [ "${TESTJAVA}" = "" ] ; then - echo "TESTJAVA not set. Test cannot execute." - echo "FAILED!!!" - exit 1 -fi - -if [ "${COMPILEJAVA}" = "" ]; then - COMPILEJAVA="${TESTJAVA}" -fi - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - Linux ) - PATHSEP=":" - FILESEP="/" - ;; - Darwin ) - PATHSEP=":" - FILESEP="/" - ;; - AIX ) - PATHSEP=":" - FILESEP="/" - ;; - CYGWIN* ) - PATHSEP=";" - FILESEP="/" - ;; - Windows* ) - PATHSEP=";" - FILESEP="\\" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -cd ${TESTCLASSES}${FILESEP} -if [ ! -d provider ] ; then - mkdir provider -fi - -# compile the test program -${COMPILEJAVA}${FILESEP}bin${FILESEP}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \ - -d ${TESTCLASSES}${FILESEP} \ - ${TESTSRC}${FILESEP}ClassLoaderDeadlock.java - -${COMPILEJAVA}${FILESEP}bin${FILESEP}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \ - -d ${TESTCLASSES}${FILESEP}provider${FILESEP} \ - ${TESTSRC}${FILESEP}provider${FILESEP}HashProvider.java - -# run the test -${TESTJAVA}${FILESEP}bin${FILESEP}java ${TESTVMOPTS} ${TESTJAVAOPTS} \ - -classpath "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}Deadlock.jar" \ - -Djava.awt.headless=true \ - ClassLoaderDeadlock - -STATUS=$? - -# clean up -rm -f 'ClassLoaderDeadlock.class' 'ClassLoaderDeadlock$1.class' \ -'ClassLoaderDeadlock$DelayClassLoader.class' \ -provider${FILESEP}HashProvider.class - -exit $STATUS diff --git a/test/jdk/java/security/Security/ClassLoaderDeadlock/Deadlock.java b/test/jdk/java/security/Security/ClassLoaderDeadlock/Deadlock.java index 5693f4933aa96..0d46b5c8660a8 100644 --- a/test/jdk/java/security/Security/ClassLoaderDeadlock/Deadlock.java +++ b/test/jdk/java/security/Security/ClassLoaderDeadlock/Deadlock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -21,8 +21,13 @@ * questions. */ - -// see Deadlock.sh +/* + * @test + * @bug 4944382 + * @summary make sure we do not deadlock loading signed JAR with getInstance() + * @library ./Deadlock.jar + * @run main/othervm/timeout=30 Deadlock + */ import java.security.*; diff --git a/test/jdk/java/security/Security/ClassLoaderDeadlock/Deadlock.sh b/test/jdk/java/security/Security/ClassLoaderDeadlock/Deadlock.sh deleted file mode 100644 index 7013c4cc33a1a..0000000000000 --- a/test/jdk/java/security/Security/ClassLoaderDeadlock/Deadlock.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# 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 4944382 -# @summary make sure we do not deadlock loading signed JAR with getInstance() -# @author Andreas Sterbenz -# @build Deadlock -# @run shell/timeout=30 Deadlock.sh - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - Linux ) - PATHSEP=":" - FILESEP="/" - ;; - Darwin ) - PATHSEP=":" - FILESEP="/" - ;; - AIX ) - PATHSEP=":" - FILESEP="/" - ;; - CYGWIN* ) - PATHSEP=";" - FILESEP="/" - ;; - Windows* ) - PATHSEP=";" - FILESEP="\\" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -JAVA="${TESTJAVA}${FILESEP}bin${FILESEP}java" - -${JAVA} ${TESTVMOPTS} ${TESTJAVAOPTS} -cp "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}Deadlock.jar" Deadlock - From 6b4fe753e2ba03e93bd2dc7dbb04984f9c206179 Mon Sep 17 00:00:00 2001 From: Michael De Vera Date: Mon, 21 Apr 2025 19:02:40 +0000 Subject: [PATCH 213/846] 8314120: Add tests for FileDescriptor.sync Reviewed-by: phh Backport-of: e22d333febe9edbb961fee9b51759d4cd28684fd --- test/jdk/java/io/FileDescriptor/Sync.java | 90 +++++++++++++++++++ .../bench/java/io/FileDescriptorSync.java | 70 +++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 test/jdk/java/io/FileDescriptor/Sync.java create mode 100644 test/micro/org/openjdk/bench/java/io/FileDescriptorSync.java diff --git a/test/jdk/java/io/FileDescriptor/Sync.java b/test/jdk/java/io/FileDescriptor/Sync.java new file mode 100644 index 0000000000000..fa89d16b06370 --- /dev/null +++ b/test/jdk/java/io/FileDescriptor/Sync.java @@ -0,0 +1,90 @@ +/* + * Copyright Amazon.com Inc. 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 8314120 + * @summary Sanity test for FileDescriptor.sync + * @library /test/lib + * @run main Sync + */ + +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.SyncFailedException; + +public class Sync { + + static final String TEST_DIR = System.getProperty("test.dir", "."); + static final int TRIES = 10_000; + + public static void testWith(File file) throws Exception { + try (FileOutputStream fos = new FileOutputStream(file)) { + FileDescriptor fd = fos.getFD(); + for (int t = 0; t < TRIES; t++) { + fd.sync(); + } + } catch (SyncFailedException sfe) { + // Can happen on some filesystems, print it in the log + System.out.println("Sync failed (acceptable)"); + sfe.printStackTrace(); + } + } + + public static void main(String[] args) throws Exception { + // Run on platform threads + System.out.println("With platform threads"); + run(); + + System.out.println("Complete"); + } + + private static class AutoDelete implements AutoCloseable { + private final File file; + + public AutoDelete(File file) { + this.file = file; + } + + public File file() { + return file; + } + + @Override + public void close() throws Exception { + file.delete(); + } + } + + public static void run() throws Exception { + try (var w = new AutoDelete(new File(TEST_DIR, "FileDescriptorSync1"))) { + testWith(w.file()); + } + + try (var w = new AutoDelete(File.createTempFile("FileDescriptorSync2", "tmp"))) { + testWith(w.file()); + } + } +} diff --git a/test/micro/org/openjdk/bench/java/io/FileDescriptorSync.java b/test/micro/org/openjdk/bench/java/io/FileDescriptorSync.java new file mode 100644 index 0000000000000..ee6f5fce2f93d --- /dev/null +++ b/test/micro/org/openjdk/bench/java/io/FileDescriptorSync.java @@ -0,0 +1,70 @@ +/* + * Copyright Amazon.com Inc. 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 org.openjdk.bench.java.io; + +import org.openjdk.jmh.annotations.*; + +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.SyncFailedException; +import java.util.concurrent.TimeUnit; + +/** + * Tests the cost of FileDescriptor.sync + */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Fork(3) +public class FileDescriptorSync { + + private FileOutputStream fos; + private FileDescriptor fd; + + @Setup + public void setup() throws IOException { + File tmp = File.createTempFile("FileDescriptorSync", "bin"); + fos = new FileOutputStream(tmp); + fd = fos.getFD(); + } + + @TearDown + public void tearDown() throws IOException { + fos.close(); + } + + @Benchmark + public void sync() { + try { + fd.sync(); + } catch (SyncFailedException e) { + // The test assumes the temp filesystem accepts syncs. + // Avoid failing if it does not, measure the exceptional path then. + } + } + +} From 18d5503fde59248503e6aeed86d37c0d9f815171 Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Thu, 24 Apr 2025 18:52:14 +0000 Subject: [PATCH 214/846] 8321479: java -D-D crashes Backport-of: dcdcd48d8fbf076e12841e557ebbe70228c8a92b --- src/hotspot/share/runtime/arguments.cpp | 1 - .../CommandLine/UnrecognizedProperty.java | 45 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 test/hotspot/jtreg/runtime/CommandLine/UnrecognizedProperty.java diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index c6acbbc39f57d..02e31a2454d93 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -339,7 +339,6 @@ static bool matches_property_suffix(const char* option, const char* property, si // any of the reserved module properties. // property should be passed without the leading "-D". bool Arguments::is_internal_module_property(const char* property) { - assert((strncmp(property, "-D", 2) != 0), "Unexpected leading -D"); if (strncmp(property, MODULE_PROPERTY_PREFIX, MODULE_PROPERTY_PREFIX_LEN) == 0) { const char* property_suffix = property + MODULE_PROPERTY_PREFIX_LEN; if (matches_property_suffix(property_suffix, ADDEXPORTS, ADDEXPORTS_LEN) || diff --git a/test/hotspot/jtreg/runtime/CommandLine/UnrecognizedProperty.java b/test/hotspot/jtreg/runtime/CommandLine/UnrecognizedProperty.java new file mode 100644 index 0000000000000..4b1d4fa386737 --- /dev/null +++ b/test/hotspot/jtreg/runtime/CommandLine/UnrecognizedProperty.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 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. + */ + +/* + * @test + * @bug 8321479 + * @summary VM should not crash with property "-D-D" + * @requires vm.flagless + * @library /test/lib + * @run driver UnrecognizedProperty + */ + +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class UnrecognizedProperty { + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-D-D"); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("Usage: java"); + output.shouldHaveExitValue(1); + } +} From d132468950815df952e38869f304445502631f52 Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Thu, 24 Apr 2025 18:52:37 +0000 Subject: [PATCH 215/846] 8325680: Uninitialised memory in deleteGSSCB of GSSLibStub.c:179 Backport-of: 419191c653f787b5dc3032f9da31d8c9b9a08235 --- .../share/native/libj2gss/GSSLibStub.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/java.security.jgss/share/native/libj2gss/GSSLibStub.c b/src/java.security.jgss/share/native/libj2gss/GSSLibStub.c index d6e1712a24fb6..cc9e8c3cbf1ae 100644 --- a/src/java.security.jgss/share/native/libj2gss/GSSLibStub.c +++ b/src/java.security.jgss/share/native/libj2gss/GSSLibStub.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -197,7 +197,10 @@ gss_channel_bindings_t newGSSCB(JNIEnv *env, jobject jcb) { return GSS_C_NO_CHANNEL_BINDINGS; } - cb = malloc(sizeof(struct gss_channel_bindings_struct)); + // initialize cb as zeroes to avoid uninitialized pointer being + // freed when deleteGSSCB is called at cleanup. + cb = calloc(1, sizeof(struct gss_channel_bindings_struct)); + if (cb == NULL) { throwOutOfMemoryError(env,NULL); return NULL; @@ -217,9 +220,6 @@ gss_channel_bindings_t newGSSCB(JNIEnv *env, jobject jcb) { cb->initiator_addrtype = GSS_C_AF_NULLADDR; cb->acceptor_addrtype = GSS_C_AF_NULLADDR; } - // addresses needs to be initialized to empty - memset(&cb->initiator_address, 0, sizeof(cb->initiator_address)); - memset(&cb->acceptor_address, 0, sizeof(cb->acceptor_address)); /* set up initiator address */ jinetAddr = (*env)->CallObjectMethod(env, jcb, From 80cfe11224ef0b994bd84ccce3e34766bbeb247d Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Mon, 28 Apr 2025 16:46:01 +0000 Subject: [PATCH 216/846] 8321204: C2: assert(false) failed: node should be in igvn hash table Reviewed-by: phh Backport-of: d1aad71209092013a89b3b85a258dd4d2e31224a --- src/hotspot/share/opto/compile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index c69208089f835..6404050b8285f 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -4610,7 +4610,7 @@ void Compile::remove_speculative_types(PhaseIterGVN &igvn) { const Type* t_no_spec = t->remove_speculative(); if (t_no_spec != t) { bool in_hash = igvn.hash_delete(n); - assert(in_hash, "node should be in igvn hash table"); + assert(in_hash || n->hash() == Node::NO_HASH, "node should be in igvn hash table"); tn->set_type(t_no_spec); igvn.hash_insert(n); igvn._worklist.push(n); // give it a chance to go away From 1133187ec89f99e80ecc7fc3bd01d73e0ff81223 Mon Sep 17 00:00:00 2001 From: Daniel Hu Date: Mon, 28 Apr 2025 16:46:24 +0000 Subject: [PATCH 217/846] 8314236: Overflow in Collections.rotate Backport-of: 3828dc913a3ea28d622b69bd07f26949128eb5f7 --- .../share/classes/java/util/Collections.java | 9 +- .../jdk/java/util/Collections/RotateHuge.java | 83 +++++++++++++++++++ 2 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 test/jdk/java/util/Collections/RotateHuge.java diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 473de05f9e58f..31e83060e5532 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -792,15 +792,16 @@ private static void rotate1(List list, int distance) { if (distance == 0) return; - for (int cycleStart = 0, nMoved = 0; nMoved != size; cycleStart++) { + int bound = size - distance; + for (int cycleStart = 0, nMoved = 0; nMoved < size; cycleStart++) { T displaced = list.get(cycleStart); int i = cycleStart; do { - i += distance; - if (i >= size) + if (i >= bound) i -= size; + i += distance; displaced = list.set(i, displaced); - nMoved ++; + nMoved++; } while (i != cycleStart); } } diff --git a/test/jdk/java/util/Collections/RotateHuge.java b/test/jdk/java/util/Collections/RotateHuge.java new file mode 100644 index 0000000000000..44368aff266d2 --- /dev/null +++ b/test/jdk/java/util/Collections/RotateHuge.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 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. + */ + +/* + * @test + * @bug 8314236 + * @summary Overflow in Collections.rotate + */ + +import java.util.AbstractList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.RandomAccess; + +public class RotateHuge { + + private static final class MockList extends AbstractList + implements RandomAccess { + private final int size; + + public MockList(final int size) { + if (size < 0) + throw new IllegalArgumentException("Illegal size: " + size); + this.size = size; + } + + @Override + public Object get(final int index) { + Objects.checkIndex(index, size); + return null; + } + + @Override + public Object set(final int index, final Object element) { + Objects.checkIndex(index, size); + return null; + } + + @Override + public int size() { + return size; + } + } + + public static void main(final String[] args) { + testRotate((1 << 30) + 1, -(1 << 30) - 2); + testRotate((1 << 30) + 1, 1 << 30); + testRotate(Integer.MAX_VALUE, Integer.MIN_VALUE); + testRotate(Integer.MAX_VALUE, Integer.MIN_VALUE + 3); + testRotate(Integer.MAX_VALUE, 2); + testRotate(Integer.MAX_VALUE, Integer.MAX_VALUE - 1); + } + + /* + * This test covers only index computations. + * Correctness of elements rotation is not checked. + */ + private static void testRotate(final int size, final int distance) { + final List list = new MockList(size); + Collections.rotate(list, distance); + } +} From 2636676bafe0baef4c7ace2f307911dab4b3b85b Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Mon, 28 Apr 2025 16:47:49 +0000 Subject: [PATCH 218/846] 8318700: MacOS Zero cannot run gtests due to wrong JVM path Backport-of: 744e0893100d402b2b51762d57bcc2e99ab7fdcc --- src/hotspot/os/bsd/os_bsd.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index 073fde86d22c9..a216c31858615 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -212,11 +212,13 @@ static char cpu_arch[] = "ppc"; #error Add appropriate cpu_arch setting #endif -// Compiler variant -#ifdef COMPILER2 - #define COMPILER_VARIANT "server" +// JVM variant +#if defined(ZERO) + #define JVM_VARIANT "zero" +#elif defined(COMPILER2) + #define JVM_VARIANT "server" #else - #define COMPILER_VARIANT "client" + #define JVM_VARIANT "client" #endif @@ -1538,10 +1540,10 @@ void os::jvm_path(char *buf, jint buflen) { snprintf(jrelib_p, buflen-len, "/lib"); } - // Add the appropriate client or server subdir + // Add the appropriate JVM variant subdir len = strlen(buf); jrelib_p = buf + len; - snprintf(jrelib_p, buflen-len, "/%s", COMPILER_VARIANT); + snprintf(jrelib_p, buflen-len, "/%s", JVM_VARIANT); if (0 != access(buf, F_OK)) { snprintf(jrelib_p, buflen-len, "%s", ""); } From bd69deee8cbb087b3d36b29436b3cadf52b4ceda Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Mon, 28 Apr 2025 16:48:07 +0000 Subject: [PATCH 219/846] 8319690: [AArch64] C2 compilation hits offset_ok_for_immed: assert "c2 compiler bug" Backport-of: 98f0b86641d84048949ed3da1cb14f3820b01c12 --- src/hotspot/cpu/aarch64/aarch64.ad | 4 - .../compiler/c2/TestUnalignedAccess.java | 172 ++++++++++++++++++ 2 files changed, 172 insertions(+), 4 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/c2/TestUnalignedAccess.java diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 8b758653e39e2..967392b7eedde 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -2736,10 +2736,6 @@ typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, { Address addr = mem2address(opcode, base, index, scale, disp); if (addr.getMode() == Address::base_plus_offset) { - /* If we get an out-of-range offset it is a bug in the compiler, - so we assert here. */ - assert(Address::offset_ok_for_immed(addr.offset(), exact_log2(size_in_memory)), - "c2 compiler bug"); /* Fix up any out-of-range offsets. */ assert_different_registers(rscratch1, base); assert_different_registers(rscratch1, reg); diff --git a/test/hotspot/jtreg/compiler/c2/TestUnalignedAccess.java b/test/hotspot/jtreg/compiler/c2/TestUnalignedAccess.java new file mode 100644 index 0000000000000..d05dbad4a73ba --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestUnalignedAccess.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, Arm Limited. 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 compiler.c2; + +import jdk.internal.misc.Unsafe; +import jdk.test.lib.Asserts; + +/** + * @test TestUnalignedAccess + * @summary AArch64: C2 compilation hits offset_ok_for_immed: assert "c2 compiler bug". + * @bug 8319690 + * @library /test/lib + * @modules java.base/jdk.internal.misc + * @run main/othervm compiler.c2.TestUnalignedAccess + * @run main/othervm -Xcomp -XX:-TieredCompilation -Xmx1g + * -XX:CompileCommand=compileonly,compiler.c2.TestUnalignedAccess*:: + * compiler.c2.TestUnalignedAccess + */ + +public class TestUnalignedAccess { + + public static final int LEN = 2040; + + static final Unsafe UNSAFE = Unsafe.getUnsafe(); + static void sink(int x) {} + + public static long lseed = 1; + public static int iseed = 2; + public static short sseed = 3; + public static byte bseed = 4; + public static long lres = lseed; + public static int ires = iseed; + public static short sres = sseed; + public static byte bres = bseed; + + public static class TestLong { + + private static final byte[] BYTES = new byte[LEN]; + private static final long rawdata = 0xbeef; + private static final long data; + + static { + sink(2); + // Signed immediate byte offset: range -256 to 255 + // Positive immediate byte offset: a multiple of 8 in the range 0 to 32760 + // Other immediate byte offsets can't be encoded in the instruction field. + + // 1030 can't be encoded as "base + offset" mode into the instruction field. + UNSAFE.putLongUnaligned(BYTES, 1030, rawdata); + lres += UNSAFE.getLongUnaligned(BYTES, 1030); + // 127 can be encoded into simm9 field. + UNSAFE.putLongUnaligned(BYTES, 127, lres); + lres += UNSAFE.getLongUnaligned(BYTES, 127); + // 1096 can be encoded into uimm12 field. + UNSAFE.putLongUnaligned(BYTES, 1096, lres); + data = UNSAFE.getLongUnaligned(BYTES, 1096); + } + + } + + public static class TestInt { + + private static final byte[] BYTES = new byte[LEN]; + private static final int rawdata = 0xbeef; + private static final int data; + static { + sink(2); + // Signed immediate byte offset: range -256 to 255 + // Positive immediate byte offset, a multiple of 4 in the range 0 to 16380 + // Other immediate byte offsets can't be encoded in the instruction field. + + // 274 can't be encoded as "base + offset" mode into the instruction field. + UNSAFE.putIntUnaligned(BYTES, 274, rawdata); + ires += UNSAFE.getIntUnaligned(BYTES, 274); + // 255 can be encoded into simm9 field. + UNSAFE.putIntUnaligned(BYTES, 255, ires); + ires += UNSAFE.getIntUnaligned(BYTES, 255); + // 528 can be encoded into uimm12 field. + UNSAFE.putIntUnaligned(BYTES, 528, ires); + data = UNSAFE.getIntUnaligned(BYTES, 528); + } + + } + + public static class TestShort { + + private static final byte[] BYTES = new byte[LEN]; + private static final short rawdata = (short)0xbeef; + private static final short data; + static { + sink(2); + // Signed immediate byte offset: range -256 to 255 + // Positive immediate byte offset: a multiple of 2 in the range 0 to 8190 + // Other immediate byte offsets can't be encoded in the instruction field. + + // 257 can't be encoded as "base + offset" mode into the instruction field. + UNSAFE.putShortUnaligned(BYTES, 257, rawdata); + sres = (short) (sres + UNSAFE.getShortUnaligned(BYTES, 257)); + // 253 can be encoded into simm9 field. + UNSAFE.putShortUnaligned(BYTES, 253, sres); + sres = (short) (sres + UNSAFE.getShortUnaligned(BYTES, 253)); + // 272 can be encoded into uimm12 field. + UNSAFE.putShortUnaligned(BYTES, 272, sres); + data = UNSAFE.getShortUnaligned(BYTES, 272); + } + + } + + public static class TestByte { + + private static final byte[] BYTES = new byte[LEN]; + private static final byte rawdata = (byte)0x3f; + private static final byte data; + static { + sink(2); + // Signed immediate byte offset: range -256 to 255 + // Positive immediate byte offset: range 0 to 4095 + // Other immediate byte offsets can't be encoded in the instruction field. + + // 272 can be encoded into simm9 field. + UNSAFE.putByte(BYTES, 272, rawdata); + bres = (byte) (bres + UNSAFE.getByte(BYTES, 272)); + // 53 can be encoded into simm9 field. + UNSAFE.putByte(BYTES, 53, bres); + bres = (byte) (bres + UNSAFE.getByte(BYTES, 53)); + // 1027 can be encoded into uimm12 field. + UNSAFE.putByte(BYTES, 1027, bres); + data = UNSAFE.getByte(BYTES, 1027); + } + + } + + static void test() { + TestLong ta = new TestLong(); + Asserts.assertEquals(ta.data, (ta.rawdata + lseed) * 2, "putUnaligned long failed!"); + + TestInt tb = new TestInt(); + Asserts.assertEquals(tb.data, (tb.rawdata + iseed) * 2, "putUnaligned int failed!"); + + TestShort tc = new TestShort(); + Asserts.assertEquals(tc.data, (short) (((short) (tc.rawdata + sseed)) * 2), "putUnaligned short failed!"); + + TestByte td = new TestByte(); + Asserts.assertEquals(td.data, (byte) (((byte) (td.rawdata + bseed)) * 2), "put byte failed!"); + } + + public static void main(String[] strArr) { + test(); + } +} From f153824875054c8d533951ae41e15f1f39ddd8bb Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Mon, 28 Apr 2025 16:48:31 +0000 Subject: [PATCH 220/846] 8320687: sun.jvmstat.monitor.MonitoredHost.getMonitoredHost() throws unexpected exceptions when invoked concurrently Backport-of: 81484d8c0520cf55ec58fc7b4c81880e69537674 --- .../sun/jvmstat/monitor/MonitoredHost.java | 16 ++-- .../ConcurrentGetMonitoredHost.java | 90 +++++++++++++++++++ 2 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java diff --git a/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java b/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java index b119a00452090..fafcce1c47fab 100644 --- a/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java +++ b/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -50,7 +50,7 @@ * @see HostListener */ public abstract class MonitoredHost { - private static Map monitoredHosts = + private static final Map monitoredHosts = new HashMap(); /* @@ -133,13 +133,6 @@ public static MonitoredHost getMonitoredHost(VmIdentifier vmid) return getMonitoredHost(hostId); } - - /* - * Load the MonitoredHostServices - */ - private static ServiceLoader monitoredHostServiceLoader = - ServiceLoader.load(MonitoredHostService.class, MonitoredHostService.class.getClassLoader()); - /** * Factory method to construct a MonitoredHost instance to manage the * connection to the host indicated by {@code hostId}. @@ -167,9 +160,12 @@ public static MonitoredHost getMonitoredHost(HostIdentifier hostId) hostId = resolveHostId(hostId); - for (MonitoredHostService mhs : monitoredHostServiceLoader) { + ServiceLoader services = ServiceLoader.load( + MonitoredHostService.class, MonitoredHostService.class.getClassLoader()); + for (MonitoredHostService mhs : services) { if (mhs.getScheme().equals(hostId.getScheme())) { mh = mhs.getMonitoredHost(hostId); + break; } } diff --git a/test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java b/test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java new file mode 100644 index 0000000000000..333981bd1ff02 --- /dev/null +++ b/test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 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. + */ + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import sun.jvmstat.monitor.MonitoredHost; +import sun.jvmstat.monitor.VmIdentifier; + +/* + * @test + * @bug 8320687 + * @summary verify that sun.jvmstat.monitor.MonitoredHost.getMonitoredHost() doesn't + * unexpectedly throw an exception when invoked by concurrent threads + * + * @run main/othervm ConcurrentGetMonitoredHost + */ +public class ConcurrentGetMonitoredHost { + + /* + * Launches multiple concurrent threads and invokes MonitoredHost.getMonitoredHost() + * in each of these threads and expects the call to return successfully without any + * exceptions. + */ + public static void main(final String[] args) throws Exception { + final String pidStr = "12345"; + final VmIdentifier vmid = new VmIdentifier(pidStr); + final int numTasks = 100; + final List tasks = new ArrayList<>(); + for (int i = 0; i < numTasks; i++) { + tasks.add(new Task(vmid)); + } + System.out.println("Submitting " + numTasks + " concurrent tasks to" + + " get MonitoredHost for " + vmid); + try (ExecutorService executor = Executors.newCachedThreadPool()) { + // wait for all tasks to complete + final List> results = executor.invokeAll(tasks); + // verify each one successfully completed and each of + // the returned MonitoredHost is not null + for (final Future result : results) { + final MonitoredHost mh = result.get(); + if (mh == null) { + throw new AssertionError("MonitoredHost.getMonitoredHost() returned" + + " null for vmid " + vmid); + } + } + } + System.out.println("All " + numTasks + " completed successfully"); + } + + // a task which just calls MonitoredHost.getMonitoredHost(VmIdentifier) and + // returns the resultant MonitoredHost + private static final class Task implements Callable { + private final VmIdentifier vmid; + + private Task(final VmIdentifier vmid) { + this.vmid = Objects.requireNonNull(vmid); + } + + @Override + public MonitoredHost call() throws Exception { + return MonitoredHost.getMonitoredHost(this.vmid); + } + } +} From c269609dad26a6b25b7a154a9ee3627b8b256500 Mon Sep 17 00:00:00 2001 From: Paul Hohensee Date: Mon, 28 Apr 2025 17:10:10 +0000 Subject: [PATCH 221/846] 8347995: Race condition in jdk/java/net/httpclient/offline/FixedResponseHttpClient.java Backport-of: a62a870150cf199f16277b478af2f5d937255b3c --- .../offline/FixedResponseHttpClient.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/test/jdk/java/net/httpclient/offline/FixedResponseHttpClient.java b/test/jdk/java/net/httpclient/offline/FixedResponseHttpClient.java index 13f7f4f6d8331..8be37044afb9e 100644 --- a/test/jdk/java/net/httpclient/offline/FixedResponseHttpClient.java +++ b/test/jdk/java/net/httpclient/offline/FixedResponseHttpClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, 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 @@ -189,8 +189,11 @@ public HttpClient.Version version() { if (obp.isPresent()) { ConsumingSubscriber subscriber = new ConsumingSubscriber(); obp.get().subscribe(subscriber); + // wait for our subscriber to be completed and get the + // list of ByteBuffers it received. + var buffers = subscriber.getBuffers().join(); if (responseBodyBytes == ECHO_SENTINAL) { - responseBody = subscriber.buffers; + responseBody = buffers; } } @@ -226,6 +229,13 @@ public HttpClient.Version version() { */ private static class ConsumingSubscriber implements Flow.Subscriber { final List buffers = Collections.synchronizedList(new ArrayList<>()); + // A CompletableFuture that will be completed with a list of ByteBuffers that the + // ConsumingSubscriber has consumed. + final CompletableFuture> consumed = new CompletableFuture<>(); + + public final CompletableFuture> getBuffers() { + return consumed; + } @Override public void onSubscribe(Flow.Subscription subscription) { @@ -236,8 +246,8 @@ public void onSubscribe(Flow.Subscription subscription) { buffers.add(item.duplicate()); } - @Override public void onError(Throwable throwable) { assert false : "Unexpected"; } + @Override public void onError(Throwable throwable) { consumed.completeExceptionally(throwable); } - @Override public void onComplete() { /* do nothing */ } + @Override public void onComplete() { consumed.complete(buffers.stream().toList()); } } } From 31cd9c3b4c82b8d051d488958bac023cf1c9c9ba Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 29 Apr 2025 14:53:16 +0000 Subject: [PATCH 222/846] 8355914: [17u] Backout backport of JDK-8320687 Reviewed-by: mbaesken --- .../sun/jvmstat/monitor/MonitoredHost.java | 16 ++-- .../ConcurrentGetMonitoredHost.java | 90 ------------------- 2 files changed, 10 insertions(+), 96 deletions(-) delete mode 100644 test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java diff --git a/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java b/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java index fafcce1c47fab..b119a00452090 100644 --- a/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java +++ b/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ * @see HostListener */ public abstract class MonitoredHost { - private static final Map monitoredHosts = + private static Map monitoredHosts = new HashMap(); /* @@ -133,6 +133,13 @@ public static MonitoredHost getMonitoredHost(VmIdentifier vmid) return getMonitoredHost(hostId); } + + /* + * Load the MonitoredHostServices + */ + private static ServiceLoader monitoredHostServiceLoader = + ServiceLoader.load(MonitoredHostService.class, MonitoredHostService.class.getClassLoader()); + /** * Factory method to construct a MonitoredHost instance to manage the * connection to the host indicated by {@code hostId}. @@ -160,12 +167,9 @@ public static MonitoredHost getMonitoredHost(HostIdentifier hostId) hostId = resolveHostId(hostId); - ServiceLoader services = ServiceLoader.load( - MonitoredHostService.class, MonitoredHostService.class.getClassLoader()); - for (MonitoredHostService mhs : services) { + for (MonitoredHostService mhs : monitoredHostServiceLoader) { if (mhs.getScheme().equals(hostId.getScheme())) { mh = mhs.getMonitoredHost(hostId); - break; } } diff --git a/test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java b/test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java deleted file mode 100644 index 333981bd1ff02..0000000000000 --- a/test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 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. - */ - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -import sun.jvmstat.monitor.MonitoredHost; -import sun.jvmstat.monitor.VmIdentifier; - -/* - * @test - * @bug 8320687 - * @summary verify that sun.jvmstat.monitor.MonitoredHost.getMonitoredHost() doesn't - * unexpectedly throw an exception when invoked by concurrent threads - * - * @run main/othervm ConcurrentGetMonitoredHost - */ -public class ConcurrentGetMonitoredHost { - - /* - * Launches multiple concurrent threads and invokes MonitoredHost.getMonitoredHost() - * in each of these threads and expects the call to return successfully without any - * exceptions. - */ - public static void main(final String[] args) throws Exception { - final String pidStr = "12345"; - final VmIdentifier vmid = new VmIdentifier(pidStr); - final int numTasks = 100; - final List tasks = new ArrayList<>(); - for (int i = 0; i < numTasks; i++) { - tasks.add(new Task(vmid)); - } - System.out.println("Submitting " + numTasks + " concurrent tasks to" + - " get MonitoredHost for " + vmid); - try (ExecutorService executor = Executors.newCachedThreadPool()) { - // wait for all tasks to complete - final List> results = executor.invokeAll(tasks); - // verify each one successfully completed and each of - // the returned MonitoredHost is not null - for (final Future result : results) { - final MonitoredHost mh = result.get(); - if (mh == null) { - throw new AssertionError("MonitoredHost.getMonitoredHost() returned" + - " null for vmid " + vmid); - } - } - } - System.out.println("All " + numTasks + " completed successfully"); - } - - // a task which just calls MonitoredHost.getMonitoredHost(VmIdentifier) and - // returns the resultant MonitoredHost - private static final class Task implements Callable { - private final VmIdentifier vmid; - - private Task(final VmIdentifier vmid) { - this.vmid = Objects.requireNonNull(vmid); - } - - @Override - public MonitoredHost call() throws Exception { - return MonitoredHost.getMonitoredHost(this.vmid); - } - } -} From ba0104a51478f9be3a8d27bca76bcb7444fedbc8 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 29 Apr 2025 14:54:46 +0000 Subject: [PATCH 223/846] 8315484: java/awt/dnd/RejectDragDropActionTest.java timed out Backport-of: 61ce739ac8453eaa0107241444c35c2f7e9c47dd --- .../awt/dnd/RejectDragDropActionTest.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/jdk/java/awt/dnd/RejectDragDropActionTest.java b/test/jdk/java/awt/dnd/RejectDragDropActionTest.java index f8d53ac45bfa6..9ff3c00ead006 100644 --- a/test/jdk/java/awt/dnd/RejectDragDropActionTest.java +++ b/test/jdk/java/awt/dnd/RejectDragDropActionTest.java @@ -27,10 +27,9 @@ @summary tests that DropTargetDragEvent.getDropAction() returns correct value after DropTargetDragEvent.rejectDrag() @key headful - @run main RejectDragDropActionTest + @run main/timeout=300 RejectDragDropActionTest */ -import java.awt.AWTException; import java.awt.EventQueue; import java.awt.Frame; import java.awt.Point; @@ -46,14 +45,13 @@ import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.InputEvent; -import java.lang.reflect.InvocationTargetException; public class RejectDragDropActionTest { private static volatile boolean incorrectActionDetected = false; - private static final int FRAME_ACTIVATION_TIMEOUT = 3000; + private static final int DELAY_TIME = 500; private static Frame frame; private static DragSource ds; @@ -74,21 +72,23 @@ public void drop(DropTargetDropEvent dtde) { }; private final DropTarget dt = new DropTarget(frame, dtl); - public static void main(String[] args) throws InterruptedException, - InvocationTargetException, AWTException { + public static void main(String[] args) throws Exception { EventQueue.invokeAndWait(() -> { frame = new Frame("RejectDragDropActionTest"); ds = DragSource.getDefaultDragSource(); dgl = dge -> dge.startDrag(null, new StringSelection("OOKK")); - dgr = ds.createDefaultDragGestureRecognizer(frame, DnDConstants.ACTION_COPY, dgl); - frame.setBounds(100, 100, 200, 200); + dgr = ds.createDefaultDragGestureRecognizer(frame, + DnDConstants.ACTION_COPY, dgl); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); frame.setVisible(true); }); try { Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); robot.waitForIdle(); - robot.delay(FRAME_ACTIVATION_TIMEOUT); + robot.delay(DELAY_TIME); Point startPoint = frame.getLocationOnScreen(); Point endPoint = new Point(startPoint); @@ -97,11 +97,11 @@ public static void main(String[] args) throws InterruptedException, robot.mouseMove(startPoint.x, startPoint.y); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - for (Point p = new Point(startPoint); !p.equals(endPoint); + for (Point p = new Point(startPoint); + !p.equals(endPoint) && !incorrectActionDetected; p.translate(sign(endPoint.x - p.x), - sign(endPoint.y - p.y))) { + sign(endPoint.y - p.y))) { robot.mouseMove(p.x, p.y); - robot.delay(50); } robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); From 547f3cb9a85c6a27e8f8c9e68fa9ae30d07b97ca Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 29 Apr 2025 14:56:23 +0000 Subject: [PATCH 224/846] 8318915: Enhance checks in BigDecimal.toPlainString() Reviewed-by: phh Backport-of: a6785e4d633908596ddb6de6d2eeab1c9ebdf2c3 --- .../share/classes/java/math/BigDecimal.java | 32 ++++++++------- .../math/BigDecimal/ToPlainStringTests.java | 41 ++++++++++++++++++- 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/src/java.base/share/classes/java/math/BigDecimal.java b/src/java.base/share/classes/java/math/BigDecimal.java index 73138d5f3639b..22cfc937c711b 100644 --- a/src/java.base/share/classes/java/math/BigDecimal.java +++ b/src/java.base/share/classes/java/math/BigDecimal.java @@ -3473,21 +3473,21 @@ public String toPlainString() { return "0"; } int trailingZeros = checkScaleNonZero((-(long)scale)); - StringBuilder buf; - if(intCompact!=INFLATED) { - buf = new StringBuilder(20+trailingZeros); - buf.append(intCompact); - } else { - String str = intVal.toString(); - buf = new StringBuilder(str.length()+trailingZeros); - buf.append(str); + String str = intCompact != INFLATED + ? Long.toString(intCompact) + : intVal.toString(); + int len = str.length() + trailingZeros; + if (len < 0) { + throw new OutOfMemoryError("too large to fit in a String"); } - for (int i = 0; i < trailingZeros; i++) { + StringBuilder buf = new StringBuilder(len); + buf.append(str); + for (; trailingZeros>0; trailingZeros--) { buf.append('0'); } return buf.toString(); } - String str ; + String str; if(intCompact!=INFLATED) { str = Long.toString(Math.abs(intCompact)); } else { @@ -3497,11 +3497,11 @@ public String toPlainString() { } /* Returns a digit.digit string */ - private String getValueString(int signum, String intString, int scale) { + private static String getValueString(int signum, String intString, int scale) { /* Insert decimal point */ StringBuilder buf; int insertionPoint = intString.length() - scale; - if (insertionPoint == 0) { /* Point goes right before intVal */ + if (insertionPoint == 0) { /* Point goes just before intVal */ return (signum<0 ? "-0." : "0.") + intString; } else if (insertionPoint > 0) { /* Point goes inside intVal */ buf = new StringBuilder(intString); @@ -3509,9 +3509,13 @@ private String getValueString(int signum, String intString, int scale) { if (signum < 0) buf.insert(0, '-'); } else { /* We must insert zeros between point and intVal */ - buf = new StringBuilder(3-insertionPoint + intString.length()); + int len = (signum < 0 ? 3 : 2) + scale; + if (len < 0) { + throw new OutOfMemoryError("too large to fit in a String"); + } + buf = new StringBuilder(len); buf.append(signum<0 ? "-0." : "0."); - for (int i=0; i<-insertionPoint; i++) { + for (; insertionPoint<0; insertionPoint++) { // insertionPoint != MIN_VALUE buf.append('0'); } buf.append(intString); diff --git a/test/jdk/java/math/BigDecimal/ToPlainStringTests.java b/test/jdk/java/math/BigDecimal/ToPlainStringTests.java index 7c7928ca85caa..0a1f617c0e578 100644 --- a/test/jdk/java/math/BigDecimal/ToPlainStringTests.java +++ b/test/jdk/java/math/BigDecimal/ToPlainStringTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 4984872 + * @bug 4984872 8318915 * @summary Basic tests of toPlainString method * @run main ToPlainStringTests * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox -XX:AutoBoxCacheMax=20000 ToPlainStringTests @@ -67,6 +67,11 @@ public static void main(String argv[]) { {"12345678901234567890", "12345678901234567890"}, {"12345678901234567890e22", "123456789012345678900000000000000000000000"}, {"12345678901234567890e-22", "0.0012345678901234567890"}, + + {"12345e-1", "1234.5"}, + {"12345e-2", "123.45"}, + {"12345e-3", "12.345"}, + {"12345e-4", "1.2345"}, }; int errors = 0; @@ -89,6 +94,38 @@ public static void main(String argv[]) { } } + String[] failingCases = { + "1E-" + (Integer.MAX_VALUE - 0), // MAX_VALUE + 2 chars + "1E-" + (Integer.MAX_VALUE - 1), // MAX_VALUE + 1 chars + + "-1E-" + (Integer.MAX_VALUE - 0), // MAX_VALUE + 3 chars + "-1E-" + (Integer.MAX_VALUE - 1), // MAX_VALUE + 2 chars + "-1E-" + (Integer.MAX_VALUE - 2), // MAX_VALUE + 1 chars + + "123456789E-" + (Integer.MAX_VALUE - 0), // MAX_VALUE + 2 chars + "123456789E-" + (Integer.MAX_VALUE - 1), // MAX_VALUE + 1 chars + + "-123456789E-" + (Integer.MAX_VALUE - 0), // MAX_VALUE + 3 chars + "-123456789E-" + (Integer.MAX_VALUE - 1), // MAX_VALUE + 2 chars + "-123456789E-" + (Integer.MAX_VALUE - 2), // MAX_VALUE + 1 chars + + "1E" + Integer.MAX_VALUE, // MAX_VALUE + 1 chars + "123456789E" + Integer.MAX_VALUE, // MAX_VALUE + 9 chars + + "-1E" + Integer.MAX_VALUE, // MAX_VALUE + 2 chars + "-123456789E" + Integer.MAX_VALUE, // MAX_VALUE + 10 chars + }; + /* We expect pre-emptive OutOfMemoryErrors, nothing else */ + for (String failingCase : failingCases) { + try { + new BigDecimal(failingCase).toPlainString(); + } catch (OutOfMemoryError expected) { + continue; + } catch (Throwable ignored) { + } + ++errors; + } + if(errors > 0) throw new RuntimeException(errors + " errors during run."); } From 055b866a06d4a3a149b649f9662853414a42f335 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 29 Apr 2025 14:58:56 +0000 Subject: [PATCH 225/846] 8321713: Harmonize executeTestJvm with create[Limited]TestJavaProcessBuilder Reviewed-by: rschmelter Backport-of: e7ebae54a7e0250cb9f645bd2bdc04a60f6b0cba --- .../jtreg/compiler/c2/Test8062950.java | 8 +-- .../compiler/c2/cr7200264/TestDriver.java | 2 +- .../jtreg/compiler/ciReplay/CiReplayBase.java | 4 +- .../compilercontrol/commands/OptionTest.java | 16 +++--- .../parser/HugeDirectiveUtil.java | 2 +- .../parser/TestCompileOnly.java | 2 +- .../share/scenario/Executor.java | 2 +- .../TestAESIntrinsicsOnSupportedConfig.java | 10 ++-- .../TestAESIntrinsicsOnUnsupportedConfig.java | 4 +- .../gcbarriers/TestMembarDependencies.java | 2 +- .../intrinsics/bmi/BMITestRunner.java | 2 +- .../ir_framework/driver/FlagVMProcess.java | 2 +- .../ir_framework/driver/TestVMProcess.java | 2 +- .../UseCountedLoopSafepointsTest.java | 7 +-- .../loopstripmining/CheckLoopStripMining.java | 4 +- .../runtime/TestConstantsInError.java | 4 +- .../vectorapi/TestVectorErgonomics.java | 14 +++--- .../gc/arguments/TestSoftMaxHeapSizeFlag.java | 28 +++++------ .../jtreg/gc/g1/ihop/TestIHOPErgo.java | 2 +- .../jtreg/gc/g1/ihop/TestIHOPStatic.java | 2 +- .../gc/g1/logging/TestG1LoggingFailure.java | 2 +- .../gc/g1/plab/TestPLABEvacuationFailure.java | 2 +- .../jtreg/gc/g1/plab/TestPLABPromotion.java | 2 +- .../jtreg/gc/g1/plab/TestPLABResize.java | 2 +- .../TestExcessGCLockerCollections.java | 2 +- test/hotspot/jtreg/gc/z/TestHighUsage.java | 16 +++--- .../LoadLibrary/TestSunBootLibraryPath.java | 10 ++-- .../jtreg/runtime/Shutdown/ShutdownTest.java | 2 +- .../jni/FindClass/FindClassFromBoot.java | 2 +- .../jni/FindClassUtf8/FindClassUtf8.java | 8 +-- .../jtreg/runtime/jni/atExit/TestAtExit.java | 4 +- .../TestCheckedEnsureLocalCapacity.java | 20 ++++---- .../checked/TestCheckedJniExceptionCheck.java | 6 +-- .../TestCheckedReleaseArrayElements.java | 2 +- .../jni/nativeStack/TestNativeStack.java | 14 +++--- .../TestRegisterNativesWarning.java | 12 ++--- .../stringtable/StringTableCleaningTest.java | 2 +- test/hotspot/jtreg/sanity/BasicVMTest.java | 2 +- .../TestLambdaFormRetransformation.java | 2 +- .../TestRedefineWithUnresolvedClass.java | 2 +- .../agentonunload001/TestDriver.java | 2 +- .../general_functions/GF08/gf08t.java | 4 +- .../multienv/MA02/ma02t001/TestDriver.java | 2 +- .../nsk/jvmti/unit/extcallback/Test.java | 2 +- test/jdk/com/sun/jdi/BadAgentPath.java | 2 +- test/jdk/com/sun/jdi/DoubleAgentTest.java | 2 +- test/jdk/com/sun/jdi/OnJcmdTest.java | 4 +- test/jdk/com/sun/jdi/SuspendNoFlagTest.java | 2 +- .../DcmdMBeanTestCheckJni.java | 2 +- test/jdk/com/sun/tools/attach/BasicTests.java | 2 +- .../com/sun/tools/attach/PermissionTest.java | 4 +- .../com/sun/tools/attach/ProviderTest.java | 2 +- .../jdk/com/sun/tools/attach/TempDirTest.java | 2 +- .../jdk/java/io/FilePermission/MergeName.java | 2 +- .../io/FilePermission/ReadFileOnPath.java | 2 +- .../securityManager/ClassLoaderTest.java | 2 +- .../RuntimeTests/shutdown/ShutdownHooks.java | 2 +- .../ExtensiblePolicyWithJarTest.java | 2 +- .../Policy/SignedJar/SignedJarTest.java | 6 +-- .../Provider/SecurityProviderModularTest.java | 2 +- .../Security/signedfirst/DynStatic.java | 4 +- .../spi-calendar-provider/TestSPISigned.java | 2 +- .../java/util/Currency/PropertiesTestRun.java | 4 +- .../java/util/Locale/UseOldISOCodesTest.java | 2 +- .../util/prefs/CheckUserPrefsStorage.java | 2 +- test/jdk/java/util/zip/EntryCount64k.java | 2 +- .../util/zip/ZipFile/DeleteTempJarTest.java | 2 +- .../login/modules/JaasModularClientTest.java | 2 +- .../JaasModularDefaultHandlerTest.java | 2 +- .../jdk/internal/ref/Cleaner/ExitOnThrow.java | 6 +-- .../security/TestStreamingRemote.java | 2 +- .../jdk/jfr/event/io/TestInstrumentation.java | 2 +- .../pkcs11/Config/ReadConfInUTF16Env.java | 2 +- .../CertPathRestrictions/TLSRestrictions.java | 2 +- .../EngineArgs/DebugReportsOneExtraByte.java | 2 +- .../SSLLogger/LoggingFormatConsistency.java | 4 +- .../IgnorableExceptionMessages.java | 4 +- .../multiRelease/MVJarSigningTest.java | 2 +- .../util/Resources/early/EarlyResources.java | 2 +- .../jdk/test/lib/RandomGeneratorTest.java | 4 +- ...rocessToolsExecuteLimitedTestJavaTest.java | 45 +++++++++++++++++ .../jdk/test/lib/process/ProcessTools.java | 50 ++++++++++++++----- 82 files changed, 252 insertions(+), 180 deletions(-) create mode 100644 test/lib-test/jdk/test/lib/process/ProcessToolsExecuteLimitedTestJavaTest.java diff --git a/test/hotspot/jtreg/compiler/c2/Test8062950.java b/test/hotspot/jtreg/compiler/c2/Test8062950.java index 3d7db33b6d4c9..951626fcab995 100644 --- a/test/hotspot/jtreg/compiler/c2/Test8062950.java +++ b/test/hotspot/jtreg/compiler/c2/Test8062950.java @@ -36,10 +36,10 @@ public class Test8062950 { private static final String CLASSNAME = "DoesNotExist"; public static void main(String[] args) throws Exception { - ProcessTools.executeTestJvm("-Xcomp", - "-XX:-TieredCompilation", - "-XX:-UseOptoBiasInlining", - CLASSNAME) + ProcessTools.executeTestJava("-Xcomp", + "-XX:-TieredCompilation", + "-XX:-UseOptoBiasInlining", + CLASSNAME) .shouldHaveExitValue(1) .shouldContain("Error: Could not find or load main class " + CLASSNAME) .shouldNotContain("A fatal error has been detected") diff --git a/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java b/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java index 8fc1fa0580ddd..9975fd7511c86 100644 --- a/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java +++ b/test/hotspot/jtreg/compiler/c2/cr7200264/TestDriver.java @@ -44,7 +44,7 @@ public void run() throws Throwable { } private List executeApplication() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( "-Xbatch", "-XX:-TieredCompilation", "-XX:+PrintCompilation", diff --git a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java index 356f549d231df..86e976e1a0569 100644 --- a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java +++ b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java @@ -92,9 +92,9 @@ static void test(int i) { static { try { - CLIENT_VM_AVAILABLE = ProcessTools.executeTestJvm(CLIENT_VM_OPTION, VERSION_OPTION) + CLIENT_VM_AVAILABLE = ProcessTools.executeTestJava(CLIENT_VM_OPTION, VERSION_OPTION) .getOutput().contains("Client"); - SERVER_VM_AVAILABLE = ProcessTools.executeTestJvm(SERVER_VM_OPTION, VERSION_OPTION) + SERVER_VM_AVAILABLE = ProcessTools.executeTestJava(SERVER_VM_OPTION, VERSION_OPTION) .getOutput().contains("Server"); } catch(Throwable t) { throw new Error("Initialization failed: " + t, t); diff --git a/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java b/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java index c65c3b4846b58..9833bb7235ec0 100644 --- a/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java +++ b/test/hotspot/jtreg/compiler/compilercontrol/commands/OptionTest.java @@ -36,13 +36,13 @@ public class OptionTest { public static void main(String[] args) throws Exception { - ProcessTools.executeTestJvm("-XX:CompileCommand=option,package/class,ccstrlist,ControlIntrinsic,+_id", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,package/class,ccstrlist,ControlIntrinsic,+_id", "-version") .shouldHaveExitValue(0) .shouldContain("CompileCommand: An error occurred during parsing") .shouldContain("Error: Did not specify any method name") .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); - ProcessTools.executeTestJvm("-XX:CompileCommand=option,*,ccstrlist,ControlIntrinsic,+_id", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,*,ccstrlist,ControlIntrinsic,+_id", "-version") .shouldHaveExitValue(0) .shouldContain("CompileCommand: An error occurred during parsing") .shouldContain("Error: Did not specify any method name") @@ -50,35 +50,35 @@ public static void main(String[] args) throws Exception { // corner case: // ccstrlist could be a valid method name, so it is accepted in the well-formed case. - ProcessTools.executeTestJvm("-XX:CompileCommand=option,*.ccstrlist,ccstrlist,ControlIntrinsic,+_id", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,*.ccstrlist,ccstrlist,ControlIntrinsic,+_id", "-version") .shouldContain("CompileCommand: ControlIntrinsic *.ccstrlist const char* ControlIntrinsic") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); - ProcessTools.executeTestJvm("-XX:CompileCommand=option,*.*,ccstrlist,ControlIntrinsic,+_id", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,*.*,ccstrlist,ControlIntrinsic,+_id", "-version") .shouldContain("CompileCommand: ControlIntrinsic *.* const char* ControlIntrinsic") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); - ProcessTools.executeTestJvm("-XX:CompileCommand=option,class,PrintIntrinsics", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,class,PrintIntrinsics", "-version") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); // corner case: // PrintIntrinsics could be a valid method name, so it is accepted in the well-formed case. - ProcessTools.executeTestJvm("-XX:CompileCommand=option,class.PrintIntrinsics,PrintIntrinsics", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=option,class.PrintIntrinsics,PrintIntrinsics", "-version") .shouldContain("CompileCommand: PrintIntrinsics class.PrintIntrinsics bool PrintIntrinsics = true") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); // corner case: // _dontinline_* is a valid method pattern, so it should be accepted - ProcessTools.executeTestJvm("-XX:CompileCommand=dontinline,*::dontinline_*", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=dontinline,*::dontinline_*", "-version") .shouldContain("CompileCommand: dontinline *.dontinline_* bool dontinline = true") .shouldHaveExitValue(0) .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); - ProcessTools.executeTestJvm("-XX:CompileCommand=dontinline,*.dontinline", "-version") + ProcessTools.executeTestJava("-XX:CompileCommand=dontinline,*.dontinline", "-version") .shouldContain("CompileCommand: dontinline *.dontinline bool dontinline = true") .shouldHaveExitValue(0) .shouldNotContain("Error: Did not specify any method name") diff --git a/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java b/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java index 6db9a99586296..d337266dd50d9 100644 --- a/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java +++ b/test/hotspot/jtreg/compiler/compilercontrol/parser/HugeDirectiveUtil.java @@ -121,7 +121,7 @@ private static List getRandomDescriptors( protected static OutputAnalyzer execute(String fileName) { OutputAnalyzer output; try { - output = ProcessTools.executeTestJvm( + output = ProcessTools.executeTestJava( "-XX:+UnlockDiagnosticVMOptions", "-XX:CompilerDirectivesLimit=1000", "-XX:CompilerDirectivesFile=" + fileName, diff --git a/test/hotspot/jtreg/compiler/compilercontrol/parser/TestCompileOnly.java b/test/hotspot/jtreg/compiler/compilercontrol/parser/TestCompileOnly.java index e129bf7ab481e..2b4845a34dfed 100644 --- a/test/hotspot/jtreg/compiler/compilercontrol/parser/TestCompileOnly.java +++ b/test/hotspot/jtreg/compiler/compilercontrol/parser/TestCompileOnly.java @@ -46,7 +46,7 @@ public static void main(String[] args) throws Exception { } public static void test(String compileOnlyCommand) throws Exception { - OutputAnalyzer output = ProcessTools.executeTestJvm("-XX:CompileOnly=" + compileOnlyCommand, "-version"); + OutputAnalyzer output = ProcessTools.executeTestJava("-XX:CompileOnly=" + compileOnlyCommand, "-version"); output.shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java index 8a868e89ee6c9..30222ace4a2e4 100644 --- a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java +++ b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Executor.java @@ -105,7 +105,7 @@ public List execute() { vmInputArgs.length + vmOptions.size()); System.arraycopy(vmOptions.toArray(), 0, cmds, vmInputArgs.length, vmOptions.size()); - output = ProcessTools.executeTestJvm(cmds); + output = ProcessTools.executeTestJava(cmds); } catch (Throwable thr) { throw new Error("Execution failed: " + thr.getMessage(), thr); } diff --git a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java index 4c56daebfb888..ac3a6d9a8c6b1 100644 --- a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java +++ b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java @@ -72,7 +72,7 @@ private boolean isTieredLevelGreaterThan(int level) { * @throws Throwable */ private void testUseAES() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES, true))); final String errorMessage = "Case testUseAES failed"; @@ -103,7 +103,7 @@ private void testUseAES() throws Throwable { */ private void testUseAESUseSSE2() throws Throwable { if (Platform.isX86() || Platform.isX64()) { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES_INTRINSICS, true), prepareNumericFlag(AESIntrinsicsBase.USE_SSE, 2))); @@ -132,7 +132,7 @@ private void testUseAESUseSSE2() throws Throwable { */ private void testNoUseAESUseSSE2() throws Throwable { if (Platform.isX86() || Platform.isX64()) { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES, false), prepareNumericFlag(AESIntrinsicsBase.USE_SSE, 2))); @@ -158,7 +158,7 @@ private void testNoUseAESUseSSE2() throws Throwable { * @throws Throwable */ private void testNoUseAES() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES, false))); final String errorMessage = "Case testNoUseAES failed"; @@ -180,7 +180,7 @@ private void testNoUseAES() throws Throwable { * @throws Throwable */ private void testNoUseAESIntrinsic() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( prepareArguments(prepareBooleanFlag(AESIntrinsicsBase .USE_AES_INTRINSICS, false))); final String errorMessage = "Case testNoUseAESIntrinsic failed"; diff --git a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java index 03016ea3dd6ac..fdc8f63f9e0f4 100644 --- a/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java +++ b/test/hotspot/jtreg/compiler/cpuflags/TestAESIntrinsicsOnUnsupportedConfig.java @@ -65,7 +65,7 @@ protected void runTestCases() throws Throwable { * @throws Throwable */ private void testUseAESIntrinsics() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( AESIntrinsicsBase.prepareArguments(prepareBooleanFlag( AESIntrinsicsBase.USE_AES_INTRINSICS, true))); final String errorMessage = "Case testUseAESIntrinsics failed"; @@ -89,7 +89,7 @@ private void testUseAESIntrinsics() throws Throwable { * @throws Throwable */ private void testUseAES() throws Throwable { - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( AESIntrinsicsBase.prepareArguments(prepareBooleanFlag (AESIntrinsicsBase.USE_AES, true))); final String errorMessage = "Case testUseAES failed"; diff --git a/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java b/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java index bbd518c67565f..3678691b21860 100644 --- a/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java +++ b/test/hotspot/jtreg/compiler/gcbarriers/TestMembarDependencies.java @@ -43,7 +43,7 @@ public class TestMembarDependencies { public static void main(String args[]) throws Exception { if (args.length == 0) { // For debugging, add "-XX:+TraceOptoPipelining" - OutputAnalyzer oa = ProcessTools.executeTestJvm("-XX:+IgnoreUnrecognizedVMOptions", + OutputAnalyzer oa = ProcessTools.executeTestJava("-XX:+IgnoreUnrecognizedVMOptions", "-XX:-TieredCompilation", "-XX:-BackgroundCompilation", "-XX:+PrintOpto", "-XX:CompileCommand=compileonly,compiler.membars.TestMembarDependencies::test*", "-XX:CompileCommand=dontinline,compiler.membars.TestMembarDependencies::test_m1", diff --git a/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java b/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java index 4060bacbfbaf9..159e471e3fcef 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java +++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/BMITestRunner.java @@ -146,7 +146,7 @@ public static OutputAnalyzer runTest(Class expr, new Integer(iterations).toString() }); - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm(vmOpts); + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(vmOpts); outputAnalyzer.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java index c39b045b07f39..ec57979ca8ed4 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java @@ -112,7 +112,7 @@ private void prepareVMFlags(Class testClass, List additionalFlags) { private void start() { try { // Run "flag" VM with White Box access to determine the test VM flags and if IR verification should be done. - oa = ProcessTools.executeTestJvm(cmds); + oa = ProcessTools.executeTestJava(cmds); } catch (Exception e) { throw new TestRunException("Failed to execute TestFramework flag VM", e); } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java index 771f18d6b96f1..52dbc72fc4cbb 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java @@ -149,7 +149,7 @@ private void start() { ProcessBuilder process = ProcessTools.createLimitedTestJavaProcessBuilder(cmds); try { // Calls 'main' of TestVM to run all specified tests with commands 'cmds'. - // Use executeProcess instead of executeTestJvm as we have already added the JTreg VM and + // Use executeProcess instead of executeTestJava as we have already added the JTreg VM and // Java options in prepareTestVMFlags(). oa = ProcessTools.executeProcess(process); } catch (Exception e) { diff --git a/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java b/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java index a971c947ff466..effbbbe46bd28 100644 --- a/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java +++ b/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java @@ -59,9 +59,10 @@ public static void main (String args[]) { private static void check(boolean enabled) { OutputAnalyzer oa; try { - oa = ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions", "-Xbootclasspath/a:.", - "-XX:" + (enabled ? "+" : "-") + "UseCountedLoopSafepoints", - "-XX:+WhiteBoxAPI", + oa = ProcessTools.executeTestJava( + "-XX:+UnlockDiagnosticVMOptions", "-Xbootclasspath/a:.", + "-XX:" + (enabled ? "+" : "-") + "UseCountedLoopSafepoints", + "-XX:+WhiteBoxAPI", "-XX:-Inline", "-Xbatch", "-XX:+PrintIdeal", "-XX:LoopUnrollLimit=0", "-XX:CompileOnly=" + UseCountedLoopSafepoints.class.getName() + "::testMethod", UseCountedLoopSafepoints.class.getName()); diff --git a/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java b/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java index c76ce6459df63..938129ba30f68 100644 --- a/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java +++ b/test/hotspot/jtreg/compiler/loopstripmining/CheckLoopStripMining.java @@ -38,7 +38,7 @@ public class CheckLoopStripMining { public static void main(String args[]) throws Exception { - ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions", + ProcessTools.executeTestJava("-XX:+UnlockDiagnosticVMOptions", // to prevent biased locking handshakes from changing the timing of this test "-XX:-UseBiasedLocking", "-XX:+SafepointTimeout", @@ -56,7 +56,7 @@ public static void main(String args[]) throws Exception { .shouldHaveExitValue(0) .stdoutShouldContain("sum: 715827882"); - ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions", + ProcessTools.executeTestJava("-XX:+UnlockDiagnosticVMOptions", // to prevent biased locking handshakes from changing the timing of this test "-XX:-UseBiasedLocking", "-XX:+SafepointTimeout", diff --git a/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java b/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java index 85fd3fa938dfd..889c07942eae3 100644 --- a/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java +++ b/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java @@ -259,7 +259,7 @@ static void run(TestConstantsInError test) throws Exception { c1Args.addAll(List.of("-XX:+TieredCompilation", "-XX:TieredStopAtLevel=1", "-XX:+TracePatching")); c1Args.addAll(commonArgs); - OutputAnalyzer outputC1 = ProcessTools.executeTestJvm(c1Args) + OutputAnalyzer outputC1 = ProcessTools.executeTestJava(c1Args) .shouldHaveExitValue(0); test.process(outputC1, true); @@ -268,7 +268,7 @@ static void run(TestConstantsInError test) throws Exception { c2Args.add("-XX:-TieredCompilation"); c2Args.addAll(commonArgs); - OutputAnalyzer outputC2 = ProcessTools.executeTestJvm(c2Args) + OutputAnalyzer outputC2 = ProcessTools.executeTestJava(c2Args) .shouldHaveExitValue(0); test.process(outputC2, false); diff --git a/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java b/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java index eb25472370f92..99722bc4ce95e 100644 --- a/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java +++ b/test/hotspot/jtreg/compiler/vectorapi/TestVectorErgonomics.java @@ -37,42 +37,42 @@ public class TestVectorErgonomics { public static void main(String[] args) throws Throwable { - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:+EnableVectorReboxing", "-Xlog:compilation", "-version") .shouldHaveExitValue(0) .shouldContain("EnableVectorReboxing=true"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:+EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version") .shouldHaveExitValue(0) .shouldContain("EnableVectorAggressiveReboxing=true"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:-EnableVectorReboxing", "-Xlog:compilation", "-version") .shouldHaveExitValue(0) .shouldContain("EnableVectorReboxing=false") .shouldContain("EnableVectorAggressiveReboxing=false"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:-EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version") .shouldHaveExitValue(0) .shouldContain("EnableVectorAggressiveReboxing=false"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:-EnableVectorSupport", "-Xlog:compilation", "-version") .shouldHaveExitValue(0) .shouldContain("EnableVectorSupport=false") .shouldContain("EnableVectorReboxing=false") .shouldContain("EnableVectorAggressiveReboxing=false"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:-EnableVectorSupport", "-XX:+EnableVectorReboxing", "-Xlog:compilation", "-version") .shouldHaveExitValue(0) .shouldContain("EnableVectorSupport=false") .shouldContain("EnableVectorReboxing=false") .shouldContain("EnableVectorAggressiveReboxing=false"); - ProcessTools.executeTestJvm("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", + ProcessTools.executeTestJava("--add-modules=jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:-EnableVectorSupport", "-XX:+EnableVectorAggressiveReboxing", "-Xlog:compilation", "-version") .shouldHaveExitValue(0) .shouldContain("EnableVectorSupport=false") diff --git a/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java b/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java index a61e7545522d1..3d8f31db864d5 100644 --- a/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java +++ b/test/hotspot/jtreg/gc/arguments/TestSoftMaxHeapSizeFlag.java @@ -42,36 +42,36 @@ public class TestSoftMaxHeapSizeFlag { public static void main(String args[]) throws Exception { // Test default value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:+PrintFlagsFinal", "-version") .shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + Xmx) .shouldHaveExitValue(0); // Test setting small value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:SoftMaxHeapSize=" + Xms, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:SoftMaxHeapSize=" + Xms, + "-XX:+PrintFlagsFinal", "-version") .shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + Xms) .shouldHaveExitValue(0); // Test setting middle value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:SoftMaxHeapSize=" + betweenXmsAndXmx, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:SoftMaxHeapSize=" + betweenXmsAndXmx, + "-XX:+PrintFlagsFinal", "-version") .shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + betweenXmsAndXmx) .shouldHaveExitValue(0); // Test setting largest value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:SoftMaxHeapSize=" + Xmx, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:SoftMaxHeapSize=" + Xmx, + "-XX:+PrintFlagsFinal", "-version") .shouldMatch("SoftMaxHeapSize[ ]+=[ ]+" + Xmx) .shouldHaveExitValue(0); // Test setting a too large value - ProcessTools.executeTestJvm("-Xms" + Xms, "-Xmx" + Xmx, - "-XX:SoftMaxHeapSize=" + greaterThanXmx, - "-XX:+PrintFlagsFinal", "-version") + ProcessTools.executeTestJava("-Xms" + Xms, "-Xmx" + Xmx, + "-XX:SoftMaxHeapSize=" + greaterThanXmx, + "-XX:+PrintFlagsFinal", "-version") .shouldContain("SoftMaxHeapSize must be less than or equal to the maximum heap size") .shouldHaveExitValue(1); } diff --git a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java index a93232dd82e01..a962efba4602e 100644 --- a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java +++ b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPErgo.java @@ -129,7 +129,7 @@ private static void runTest(int heapSize, int sleepTime, boolean isIhopAdaptive) } private static OutputAnalyzer executeTest(List options) throws Throwable, RuntimeException { - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); if (out.getExitValue() != 0) { System.out.println(out.getOutput()); throw new RuntimeException("AppIHOP failed with exit code" + out.getExitValue()); diff --git a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java index c84374fa359c0..7f5259a0855b3 100644 --- a/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java +++ b/test/hotspot/jtreg/gc/g1/ihop/TestIHOPStatic.java @@ -129,7 +129,7 @@ private static void runTest(int ihop, long pctToFill, long heapSize, boolean exp Collections.addAll(options, COMMON_OPTIONS); options.add(AppIHOP.class.getName()); - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); if (out.getExitValue() != 0) { System.out.println(out.getOutput()); diff --git a/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java b/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java index 3165cfd53e445..0d6af4ae47a29 100644 --- a/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java +++ b/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java @@ -63,7 +63,7 @@ public static void main(String[] args) throws Throwable { } private static void startVM(List options) throws Throwable, RuntimeException { - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); out.shouldNotContain("pure virtual method called"); diff --git a/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java b/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java index 0cebc72526134..da22714d95014 100644 --- a/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java +++ b/test/hotspot/jtreg/gc/g1/plab/TestPLABEvacuationFailure.java @@ -108,7 +108,7 @@ private static void runTest(int wastePct, int plabSize, int parGCThreads, int he "-XX:" + (plabIsFixed ? "-" : "+") + "ResizePLAB", "-XX:MaxHeapSize=" + heapSize + "m"); testOptions.add(AppPLABEvacuationFailure.class.getName()); - OutputAnalyzer out = ProcessTools.executeTestJvm(testOptions); + OutputAnalyzer out = ProcessTools.executeTestJava(testOptions); appPlabEvacFailureOutput = out.getOutput(); if (out.getExitValue() != 0) { diff --git a/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java b/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java index 0a9bd24b5f58a..95740559cc0f2 100644 --- a/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java +++ b/test/hotspot/jtreg/gc/g1/plab/TestPLABPromotion.java @@ -116,7 +116,7 @@ public static void main(String[] args) throws Throwable { testCase.print(System.out); List options = PLABUtils.prepareOptions(testCase.toOptions()); options.add(AppPLABPromotion.class.getName()); - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); PLABUtils.commonCheck(out); output = out.getOutput(); checkResults(testCase); diff --git a/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java b/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java index 245326ec0bf30..48423218868a3 100644 --- a/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java +++ b/test/hotspot/jtreg/gc/g1/plab/TestPLABResize.java @@ -87,7 +87,7 @@ public static void main(String[] args) throws Throwable { testCase.print(System.out); List options = PLABUtils.prepareOptions(testCase.toOptions()); options.add(AppPLABResize.class.getName()); - OutputAnalyzer out = ProcessTools.executeTestJvm(options); + OutputAnalyzer out = ProcessTools.executeTestJava(options); PLABUtils.commonCheck(out); checkResults(out.getOutput(), testCase); } diff --git a/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java b/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java index 8b6326b1cae65..1e65a80bd3cb2 100644 --- a/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java +++ b/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java @@ -173,7 +173,7 @@ public static void main(String args[]) throws Exception { finalArgs.addAll(Arrays.asList(args)); // GC and other options obtained from test framework. - OutputAnalyzer output = ProcessTools.executeTestJvm(finalArgs); + OutputAnalyzer output = ProcessTools.executeTestJava(finalArgs); output.shouldHaveExitValue(0); //System.out.println("------------- begin stdout ----------------"); //System.out.println(output.getStdout()); diff --git a/test/hotspot/jtreg/gc/z/TestHighUsage.java b/test/hotspot/jtreg/gc/z/TestHighUsage.java index af24d0b450c95..d695c6241a5f7 100644 --- a/test/hotspot/jtreg/gc/z/TestHighUsage.java +++ b/test/hotspot/jtreg/gc/z/TestHighUsage.java @@ -85,14 +85,14 @@ public static void main(String[] args) throws Exception { } public static void main(String[] args) throws Exception { - ProcessTools.executeTestJvm("-XX:+UseZGC", - "-XX:-ZProactive", - "-Xms128M", - "-Xmx128M", - "-XX:ParallelGCThreads=1", - "-XX:ConcGCThreads=1", - "-Xlog:gc,gc+start", - Test.class.getName()) + ProcessTools.executeTestJava("-XX:+UseZGC", + "-XX:-ZProactive", + "-Xms128M", + "-Xmx128M", + "-XX:ParallelGCThreads=1", + "-XX:ConcGCThreads=1", + "-Xlog:gc,gc+start", + Test.class.getName()) .shouldNotContain("Allocation Stall") .shouldContain("High Usage") .shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java b/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java index 356064d79a486..deb2a000d3d52 100644 --- a/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java +++ b/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java @@ -46,11 +46,11 @@ public static void main(String[] args) throws Exception { // Start a java process with this property set, and check that: // 1) The process failed and // 2) The error message was correct. - ProcessTools.executeTestJvm("-Dsun.boot.library.path=" + tooLongPath, - "TestSunBootLibraryPath", - "'Do-Nothing'") - .shouldNotHaveExitValue(0) - .stdoutShouldContain(expectedErrorMessage); + ProcessTools.executeTestJava("-Dsun.boot.library.path=" + tooLongPath, + "TestSunBootLibraryPath", + "'Do-Nothing'") + .shouldNotHaveExitValue(0) + .stdoutShouldContain(expectedErrorMessage); } else if (!args[0].equals("Do-Nothing")) { // Fail, to prevent accidental args from causing accidental test passing. throw new IllegalArgumentException("Test was launched with an invalid argument."); diff --git a/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java b/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java index 30b1ebe252aa8..68dc6b2e1a7e9 100644 --- a/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java +++ b/test/hotspot/jtreg/runtime/Shutdown/ShutdownTest.java @@ -66,7 +66,7 @@ public static void main(String args[]) { private static void startVM(String... options) throws Throwable { // Combine VM flags given from command-line and your additional options - OutputAnalyzer output = ProcessTools.executeTestJvm(options); + OutputAnalyzer output = ProcessTools.executeTestJava(options); output.shouldContain("- ShutdownTest -"); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java b/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java index 06db9c07c73da..4f59af310bf52 100644 --- a/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java +++ b/test/hotspot/jtreg/runtime/jni/FindClass/FindClassFromBoot.java @@ -42,7 +42,7 @@ public static void main(String... args) throws Exception { Path patches = Paths.get(System.getProperty("test.classes"), "patches", "java.base"); String syspaths = System.getProperty("sun.boot.library.path") + File.pathSeparator + System.getProperty("java.library.path"); - ProcessTools.executeTestJvm("-Dsun.boot.library.path=" + syspaths, + ProcessTools.executeTestJava("-Dsun.boot.library.path=" + syspaths, "--patch-module", "java.base=" + patches.toString(), "BootLoaderTest") .shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java b/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java index 4f90838c10705..7b0a4cc46bf77 100644 --- a/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java +++ b/test/hotspot/jtreg/runtime/jni/FindClassUtf8/FindClassUtf8.java @@ -43,10 +43,10 @@ public final class FindClassUtf8 { public static void main(String... args) throws Exception { if (args.length == 1) { // run java -Xcheck:jni FindClassUtf8 and check that the -Xcheck:jni message comes out. - ProcessTools.executeTestJvm("-Djava.library.path=" + Utils.TEST_NATIVE_PATH, - "-Xcheck:jni", - "-XX:-CreateCoredumpOnCrash", - "FindClassUtf8") + ProcessTools.executeTestJava("-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "-Xcheck:jni", + "-XX:-CreateCoredumpOnCrash", + "FindClassUtf8") .shouldContain("JNI class name is not a valid UTF8 string") .shouldNotHaveExitValue(0); // you get a core dump from -Xcheck:jni failures } else { diff --git a/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java b/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java index a54eaedbad4b6..82d834c869cc1 100644 --- a/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java +++ b/test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java @@ -61,13 +61,13 @@ public static void main(String[] args) throws Exception { String jlp = "-Djava.library.path=" + Utils.TEST_NATIVE_PATH; // First run will terminate via DestroyJavaVM - OutputAnalyzer output = ProcessTools.executeTestJvm(jlp, main); + OutputAnalyzer output = ProcessTools.executeTestJava(jlp, main); output.shouldNotContain("Unexpected"); output.shouldHaveExitValue(0); output.reportDiagnosticSummary(); // Second run will terminate via System.exit() - output = ProcessTools.executeTestJvm(jlp, main, "doExit"); + output = ProcessTools.executeTestJava(jlp, main, "doExit"); output.shouldNotContain("Unexpected"); output.shouldHaveExitValue(0); output.reportDiagnosticSummary(); diff --git a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedEnsureLocalCapacity.java b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedEnsureLocalCapacity.java index 975ac0091c524..ac40fbb4c3645 100644 --- a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedEnsureLocalCapacity.java +++ b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedEnsureLocalCapacity.java @@ -65,11 +65,11 @@ public static void main(String[] args) throws Throwable { } // No warning - ProcessTools.executeTestJvm("-Xcheck:jni", - "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, - "TestCheckedEnsureLocalCapacity", - Integer.toString(testArgs[0][0]), - Integer.toString(testArgs[0][1])). + ProcessTools.executeTestJava("-Xcheck:jni", + "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "TestCheckedEnsureLocalCapacity", + Integer.toString(testArgs[0][0]), + Integer.toString(testArgs[0][1])). shouldHaveExitValue(0). // check no capacity warning stdoutShouldNotMatch(EXCEED_WARNING). @@ -78,11 +78,11 @@ public static void main(String[] args) throws Throwable { reportDiagnosticSummary(); // Warning - ProcessTools.executeTestJvm("-Xcheck:jni", - "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, - "TestCheckedEnsureLocalCapacity", - Integer.toString(testArgs[1][0]), - Integer.toString(testArgs[1][1])). + ProcessTools.executeTestJava("-Xcheck:jni", + "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "TestCheckedEnsureLocalCapacity", + Integer.toString(testArgs[1][0]), + Integer.toString(testArgs[1][1])). shouldHaveExitValue(0). // check for capacity warning stdoutShouldMatch(EXCEED_WARNING). diff --git a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java index e731bab63744c..3c6efeb9a2ddd 100644 --- a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java +++ b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedJniExceptionCheck.java @@ -205,9 +205,9 @@ public static void main(String[] args) throws Throwable { } // launch and check output - checkOuputForCorrectWarnings(ProcessTools.executeTestJvm("-Xcheck:jni", - "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, - "TestCheckedJniExceptionCheck")); + checkOuputForCorrectWarnings(ProcessTools.executeTestJava("-Xcheck:jni", + "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "TestCheckedJniExceptionCheck")); } } diff --git a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java index d8bbe0659c2ab..cff5fc3b6d628 100644 --- a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java +++ b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java @@ -44,7 +44,7 @@ public static void main(String[] args) throws Throwable { if (args == null || args.length == 0) { test(); } else { - // Uses executeProcess() instead of executeTestJvm() to avoid passing options + // Uses executeProcess() instead of executeTestJava() to avoid passing options // that might generate output on stderr (which should be empty for this test). ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xcheck:jni", diff --git a/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java b/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java index 36880fe256c6c..e5e32bedb2537 100644 --- a/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java +++ b/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java @@ -52,19 +52,19 @@ public class TestNativeStack { public static void main(String[] args) throws Throwable { // case 1: Trigger a JNI warning with Xcheck:jni OutputAnalyzer oa = - ProcessTools.executeTestJvm("-Xcheck:jni", - "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, - "TestNativeStack$Main"); + ProcessTools.executeTestJava("-Xcheck:jni", + "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "TestNativeStack$Main"); oa.shouldHaveExitValue(0); oa.shouldContain("WARNING in native method"); oa.shouldContain("thread_start"); oa.reportDiagnosticSummary(); // Case 2: Trigger a JNI FatalError call - oa = ProcessTools.executeTestJvm("-XX:-CreateCoredumpOnCrash", - "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, - "TestNativeStack$Main", - "error"); + oa = ProcessTools.executeTestJava("-XX:-CreateCoredumpOnCrash", + "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + "TestNativeStack$Main", + "error"); oa.shouldNotHaveExitValue(0); oa.shouldContain("FATAL ERROR in native method"); oa.shouldContain("thread_start"); diff --git a/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java b/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java index 77aabcc7a01bb..a377487bcc807 100644 --- a/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java +++ b/test/hotspot/jtreg/runtime/jni/registerNativesWarning/TestRegisterNativesWarning.java @@ -65,17 +65,17 @@ public static void main(String[] args) throws Exception { String cp = Utils.TEST_CLASS_PATH; String libp = Utils.TEST_NATIVE_PATH; - OutputAnalyzer output = ProcessTools.executeTestJvm("-Djava.library.path=" + libp, - Tester.class.getName()); + OutputAnalyzer output = ProcessTools.executeTestJava("-Djava.library.path=" + libp, + Tester.class.getName()); output.shouldContain(warning); output.shouldHaveExitValue(0); output.reportDiagnosticSummary(); // If we run everything from the "boot" loader there should be no warning - output = ProcessTools.executeTestJvm("-Djava.library.path=" + libp, - "-Xbootclasspath/a:" + cp, - "-Dsun.boot.library.path=" + libp, - Tester.class.getName()); + output = ProcessTools.executeTestJava("-Djava.library.path=" + libp, + "-Xbootclasspath/a:" + cp, + "-Dsun.boot.library.path=" + libp, + Tester.class.getName()); output.shouldNotContain(warning); output.shouldHaveExitValue(0); output.reportDiagnosticSummary(); diff --git a/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java b/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java index 10eb3a14ddbd4..59d8bfbea4f0c 100644 --- a/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java +++ b/test/hotspot/jtreg/runtime/stringtable/StringTableCleaningTest.java @@ -58,7 +58,7 @@ public static void main(String[] args) throws Exception { subargs.addAll(List.of("-Xlog:gc,gc+start,stringtable*=trace", "-Xmx1g")); subargs.add(Tester.class.getName()); subargs.addAll(Arrays.asList(args)); - OutputAnalyzer output = ProcessTools.executeTestJvm(subargs); + OutputAnalyzer output = ProcessTools.executeTestJava(subargs); output.shouldHaveExitValue(0); checkOutput(output); } diff --git a/test/hotspot/jtreg/sanity/BasicVMTest.java b/test/hotspot/jtreg/sanity/BasicVMTest.java index a128cdfea379b..47773d63df42e 100644 --- a/test/hotspot/jtreg/sanity/BasicVMTest.java +++ b/test/hotspot/jtreg/sanity/BasicVMTest.java @@ -42,7 +42,7 @@ public static void main(String[] args) throws Exception { "-X", "-help"); for (String flag : flags) { - ProcessTools.executeTestJvm(flag) + ProcessTools.executeTestJava(flag) .shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java index feacea07aab25..48c9ad1328e17 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java +++ b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java @@ -60,7 +60,7 @@ public class TestLambdaFormRetransformation { public static void main(String args[]) throws Throwable { Path agent = TestLambdaFormRetransformation.buildAgent(); - OutputAnalyzer oa = ProcessTools.executeTestJvm("-javaagent:" + + OutputAnalyzer oa = ProcessTools.executeTestJava("-javaagent:" + agent.toAbsolutePath().toString(), "-version"); oa.shouldHaveExitValue(ExitCode.OK.value); } diff --git a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java index 2e36e33ce837b..4bcd2a4458872 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java +++ b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestRedefineWithUnresolvedClass.java @@ -79,7 +79,7 @@ private static void buildJar(String jarName) throws Throwable { } private static void launchTest() throws Throwable { - OutputAnalyzer output = ProcessTools.executeTestJvm( + OutputAnalyzer output = ProcessTools.executeTestJava( "-javaagent:" + testClasses + "UnresolvedClassAgent.jar", "-Dtest.classes=" + testClasses, "UnresolvedClassAgent"); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java index 9d8bb71cbc503..4824569871230 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Agent_OnUnload/agentonunload001/TestDriver.java @@ -53,7 +53,7 @@ public class TestDriver { public static void main(String[] args) throws Exception { - OutputAnalyzer oa = ProcessTools.executeTestJvm( + OutputAnalyzer oa = ProcessTools.executeTestJava( "-agentlib:agentonunload001=-waittime=5", nsk.jvmti.Agent_OnUnload.agentonunload001.class.getName()); oa.shouldHaveExitValue(95); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java index 9f0281533421a..964283d2b013f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t.java @@ -38,13 +38,13 @@ public static void main(String[] args) throws Exception { .skip(3) .collect(Collectors.joining(" ")); - OutputAnalyzer oa = ProcessTools.executeTestJvm( + OutputAnalyzer oa = ProcessTools.executeTestJava( "-agentlib:" + libName + "=-waittime=5 setVerboseMode=yes", className); oa.shouldHaveExitValue(95); oa.stdoutShouldContain(phrase); - oa = ProcessTools.executeTestJvm( + oa = ProcessTools.executeTestJava( "-agentlib:" + libName + "=-waittime=5 setVerboseMode=no", "-verbose:" + verboseType, className); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java index 2aae25104fece..3d474c4e14913 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/multienv/MA02/ma02t001/TestDriver.java @@ -47,7 +47,7 @@ public class TestDriver { public static void main(String[] args) throws Exception { - OutputAnalyzer oa = ProcessTools.executeTestJvm( + OutputAnalyzer oa = ProcessTools.executeTestJava( "-agentlib:ma02t001=-waittime=5", "-agentlib:ma02t001a=-waittime=5", nsk.jvmti.scenarios.multienv.MA02.ma02t001.class.getName()); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/extcallback/Test.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/extcallback/Test.java index 90cf3cc146b55..1d06fb54a9f90 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/extcallback/Test.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/extcallback/Test.java @@ -41,7 +41,7 @@ public class Test { public static void main(String[] args) throws Exception { - ProcessTools.executeTestJvm("-agentlib:extcallback", Test1.class.getName()) + ProcessTools.executeTestJava("-agentlib:extcallback", Test1.class.getName()) .shouldHaveExitValue(0) .shouldContain("callbackClassUnload called"); } diff --git a/test/jdk/com/sun/jdi/BadAgentPath.java b/test/jdk/com/sun/jdi/BadAgentPath.java index 68f28701cdc83..3ef0adadc84cf 100644 --- a/test/jdk/com/sun/jdi/BadAgentPath.java +++ b/test/jdk/com/sun/jdi/BadAgentPath.java @@ -38,7 +38,7 @@ public class BadAgentPath { public static void main(String[] args) throws Throwable { - OutputAnalyzer output = ProcessTools.executeTestJvm("-agentpath:/badAgent/agent", "-version"); + OutputAnalyzer output = ProcessTools.executeTestJava("-agentpath:/badAgent/agent", "-version"); output.shouldContain("Could not find agent library /badAgent/agent"); } } diff --git a/test/jdk/com/sun/jdi/DoubleAgentTest.java b/test/jdk/com/sun/jdi/DoubleAgentTest.java index 99ec6091aafea..ea2a109ed9b5f 100644 --- a/test/jdk/com/sun/jdi/DoubleAgentTest.java +++ b/test/jdk/com/sun/jdi/DoubleAgentTest.java @@ -44,7 +44,7 @@ public static void main(String[] args) throws Throwable { String jdwpOption = "-agentlib:jdwp=transport=dt_socket" + ",server=y" + ",suspend=n" + ",address=*:0"; - OutputAnalyzer output = ProcessTools.executeTestJvm("-classpath", + OutputAnalyzer output = ProcessTools.executeTestJava("-classpath", TEST_CLASSES, jdwpOption, // Notice jdwpOption specified twice jdwpOption, diff --git a/test/jdk/com/sun/jdi/OnJcmdTest.java b/test/jdk/com/sun/jdi/OnJcmdTest.java index 6cc417497c676..c7f93e6fb3167 100644 --- a/test/jdk/com/sun/jdi/OnJcmdTest.java +++ b/test/jdk/com/sun/jdi/OnJcmdTest.java @@ -51,12 +51,12 @@ private static String getListenerAddress() throws Exception { public static void main(String[] args) throws Throwable { // First check if we get the expected errors. - OutputAnalyzer output = ProcessTools.executeTestJvm( + OutputAnalyzer output = ProcessTools.executeTestJava( "-agentlib:jdwp=transport=dt_socket,address=any,onjcmd=y"); output.shouldContain("Can only use onjcmd with server=y"); output.shouldHaveExitValue(1); - output = ProcessTools.executeTestJvm( + output = ProcessTools.executeTestJava( "-agentlib:jdwp=transport=dt_socket,address=any,onjcmd=y,onthrow=a,launch=a"); output.shouldContain("Cannot combine onjcmd and launch suboptions"); output.shouldHaveExitValue(1); diff --git a/test/jdk/com/sun/jdi/SuspendNoFlagTest.java b/test/jdk/com/sun/jdi/SuspendNoFlagTest.java index 98b32063c74b2..31e717a63d0d3 100644 --- a/test/jdk/com/sun/jdi/SuspendNoFlagTest.java +++ b/test/jdk/com/sun/jdi/SuspendNoFlagTest.java @@ -38,7 +38,7 @@ public class SuspendNoFlagTest { "test.classes", "."); public static void main(String[] args) throws Throwable { - OutputAnalyzer output = ProcessTools.executeTestJvm("-classpath", + OutputAnalyzer output = ProcessTools.executeTestJava("-classpath", TEST_CLASSES, "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n", "HelloWorld"); diff --git a/test/jdk/com/sun/management/DiagnosticCommandMBean/DcmdMBeanTestCheckJni.java b/test/jdk/com/sun/management/DiagnosticCommandMBean/DcmdMBeanTestCheckJni.java index 73e53da63f1ca..5e2b86ceacbb5 100644 --- a/test/jdk/com/sun/management/DiagnosticCommandMBean/DcmdMBeanTestCheckJni.java +++ b/test/jdk/com/sun/management/DiagnosticCommandMBean/DcmdMBeanTestCheckJni.java @@ -45,7 +45,7 @@ public class DcmdMBeanTestCheckJni { public static void main(String[] args) throws Exception { - OutputAnalyzer out = ProcessTools.executeTestJvm( + OutputAnalyzer out = ProcessTools.executeTestJava( "-Xcheck:jni", DcmdMBeanRunner.class.getName()); out.shouldNotMatch("WARNING: JNI local refs: \\d+, exceeds capacity: \\d+\\s+" + diff --git a/test/jdk/com/sun/tools/attach/BasicTests.java b/test/jdk/com/sun/tools/attach/BasicTests.java index 6002dc2115b98..4dc7065630fad 100644 --- a/test/jdk/com/sun/tools/attach/BasicTests.java +++ b/test/jdk/com/sun/tools/attach/BasicTests.java @@ -101,7 +101,7 @@ private static void runTests(long pid) throws Throwable { testClassDir + "Agent.jar", testClassDir + "BadAgent.jar", testClassDir + "RedefineAgent.jar" }; - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/com/sun/tools/attach/PermissionTest.java b/test/jdk/com/sun/tools/attach/PermissionTest.java index 3a4128a94724d..bf9473b0c8c3b 100644 --- a/test/jdk/com/sun/tools/attach/PermissionTest.java +++ b/test/jdk/com/sun/tools/attach/PermissionTest.java @@ -86,7 +86,7 @@ private static void runTests(long pid) throws Throwable { "PermissionTest$TestMain", Long.toString(pid), "true" }; - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); // Use a policy that will allow attach. @@ -98,7 +98,7 @@ private static void runTests(long pid) throws Throwable { "PermissionTest$TestMain", Long.toString(pid), "false" }; - output = ProcessTools.executeTestJvm(args); + output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/com/sun/tools/attach/ProviderTest.java b/test/jdk/com/sun/tools/attach/ProviderTest.java index 575420722d3ed..c7249a54b269e 100644 --- a/test/jdk/com/sun/tools/attach/ProviderTest.java +++ b/test/jdk/com/sun/tools/attach/ProviderTest.java @@ -79,7 +79,7 @@ private static void runTests() throws Throwable { "-classpath", classpath, "ProviderTest$TestMain" }; - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/com/sun/tools/attach/TempDirTest.java b/test/jdk/com/sun/tools/attach/TempDirTest.java index 2d932ffcf0e87..b9ce4acb14155 100644 --- a/test/jdk/com/sun/tools/attach/TempDirTest.java +++ b/test/jdk/com/sun/tools/attach/TempDirTest.java @@ -140,7 +140,7 @@ private static void launchTests(long pid, Path clientTmpDir) throws Throwable { classpath, "TempDirTest$TestMain", Long.toString(pid) }); - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/java/io/FilePermission/MergeName.java b/test/jdk/java/io/FilePermission/MergeName.java index c2eff765f2d1e..715b98512097d 100644 --- a/test/jdk/java/io/FilePermission/MergeName.java +++ b/test/jdk/java/io/FilePermission/MergeName.java @@ -81,7 +81,7 @@ private static void test(String file, String... actions) throws Exception { } content.add("};"); Files.write(Paths.get(file), content); - ProcessTools.executeTestJvm("-Djava.security.manager", + ProcessTools.executeTestJava("-Djava.security.manager", "-Djava.security.policy=" + file, "MergeName", "x", diff --git a/test/jdk/java/io/FilePermission/ReadFileOnPath.java b/test/jdk/java/io/FilePermission/ReadFileOnPath.java index acc66dac6abda..06e2c6c435ae0 100644 --- a/test/jdk/java/io/FilePermission/ReadFileOnPath.java +++ b/test/jdk/java/io/FilePermission/ReadFileOnPath.java @@ -87,7 +87,7 @@ static void test(String... args) throws Exception { cmds.addAll(List.of( "x", "modules/m", "modules/m/base", "modules/m/p/child", "-", "child", "/base", "../base")); - ProcessTools.executeTestJvm(cmds.toArray(new String[cmds.size()])) + ProcessTools.executeTestJava(cmds.toArray(new String[cmds.size()])) .shouldHaveExitValue(0); } } diff --git a/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java b/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java index efb243bde979e..298285ac5ae66 100644 --- a/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java +++ b/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java @@ -237,7 +237,7 @@ private void execute(String[] args, String status, String msg) throws Exception if (s.contains(" ")) { throw new RuntimeException("No spaces in args");} return !s.isEmpty(); }).toArray(String[]::new); - String out = ProcessTools.executeTestJvm(safeArgs).getOutput(); + String out = ProcessTools.executeTestJava(safeArgs).getOutput(); // Handle response. if ("PASS".equals(status) && out.contains(msg)) { System.out.println("PASS: Expected Result: " + msg); diff --git a/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java b/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java index 6b2dc7b4dbfe7..36d3878fb41d5 100644 --- a/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java +++ b/test/jdk/java/lang/RuntimeTests/shutdown/ShutdownHooks.java @@ -61,7 +61,7 @@ public void testShutdownHooks() throws Exception { // Run in a new process in order to evaluate shutdown hook results String[] testCommand = new String[] {"-classpath", TEST_CLASSES, ShutdownHooksProcess.class.getName()}; - ProcessTools.executeTestJvm(testCommand).shouldHaveExitValue(0); + ProcessTools.executeTestJava(testCommand).shouldHaveExitValue(0); String errorMsg = "File exists despite shutdown hook has been run"; assertFalse(Files.exists(TEST_FILE.toPath()), errorMsg); diff --git a/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java b/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java index 8fdd787863927..fdbe44fb03c58 100644 --- a/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java +++ b/test/jdk/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java @@ -94,7 +94,7 @@ public static void main(String args[]) throws Throwable { "-Djava.security.manager", "-Djava.security.policy=" + POL, "ExtensiblePolicyTest_orig$TestMain"}; - ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0); } catch (Exception ex) { System.out.println("ExtensiblePolicyWithJarTest Failed"); } diff --git a/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java b/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java index c93337d73d0c3..cd06cc15691b0 100644 --- a/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java +++ b/test/jdk/java/security/Policy/SignedJar/SignedJarTest.java @@ -121,7 +121,7 @@ public static void main(String args[]) throws Throwable { System.out.println("Test Case 1"); //copy policy file into current directory String[] cmd = constructCMD("first.jar", POLICY1, "false", "true"); - ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0); //test case 2, test with both.jar //setIO permission granted to code that was signed by first signer @@ -131,7 +131,7 @@ public static void main(String args[]) throws Throwable { //Expect no AccessControlException System.out.println("Test Case 2"); cmd = constructCMD("both.jar", POLICY1, "false", "false"); - ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0); //test case 3 //setIO permission granted to code that was signed by first signer @@ -141,7 +141,7 @@ public static void main(String args[]) throws Throwable { //Expect AccessControlException for setFactory permission System.out.println("Test Case 3"); cmd = constructCMD("both.jar", POLICY2, "false", "true"); - ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmd).shouldHaveExitValue(0); } diff --git a/test/jdk/java/security/Provider/SecurityProviderModularTest.java b/test/jdk/java/security/Provider/SecurityProviderModularTest.java index 560331e3ada94..7c08f3faf6be3 100644 --- a/test/jdk/java/security/Provider/SecurityProviderModularTest.java +++ b/test/jdk/java/security/Provider/SecurityProviderModularTest.java @@ -253,7 +253,7 @@ private void execute(String args, String msgKey) throws Exception { } return !s.isEmpty(); }).toArray(String[]::new); - String out = ProcessTools.executeTestJvm(safeArgs).getOutput(); + String out = ProcessTools.executeTestJava(safeArgs).getOutput(); // Handle response. if ((msgKey != null && out.contains(MSG_MAP.get(msgKey)))) { System.out.printf("PASS: Expected Result: %s.%n", diff --git a/test/jdk/java/security/Security/signedfirst/DynStatic.java b/test/jdk/java/security/Security/signedfirst/DynStatic.java index 5256564064b34..59e30de54623f 100644 --- a/test/jdk/java/security/Security/signedfirst/DynStatic.java +++ b/test/jdk/java/security/Security/signedfirst/DynStatic.java @@ -78,7 +78,7 @@ public static void main(String[] args) throws Exception { CompilerUtils.compile(DYN_SRC, TEST_CLASSES, "-classpath", "exp.jar"); // Run the DynSignedProvFirst test program - ProcessTools.executeTestJvm("-classpath", + ProcessTools.executeTestJava("-classpath", TEST_CLASSES.toString() + File.pathSeparator + "exp.jar", "DynSignedProvFirst") .shouldContain("test passed"); @@ -87,7 +87,7 @@ public static void main(String[] args) throws Exception { CompilerUtils.compile(STATIC_SRC, TEST_CLASSES, "-classpath", "exp.jar"); // Run the StaticSignedProvFirst test program - ProcessTools.executeTestJvm("-classpath", + ProcessTools.executeTestJava("-classpath", TEST_CLASSES.toString() + File.pathSeparator + "exp.jar", "-Djava.security.properties=file:" + STATIC_PROPS, "StaticSignedProvFirst") diff --git a/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java b/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java index 69fe8effe70aa..83c2d85f6e444 100644 --- a/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java +++ b/test/jdk/java/security/SignedJar/spi-calendar-provider/TestSPISigned.java @@ -100,7 +100,7 @@ public static void main(String[] args) throws Throwable { testRun.add(classPath); testRun.add(TestSPISigned.class.getSimpleName()); testRun.add("run-test"); - OutputAnalyzer out = ProcessTools.executeTestJvm(testRun); + OutputAnalyzer out = ProcessTools.executeTestJava(testRun); out.shouldHaveExitValue(0); out.shouldContain("DEBUG: Getting xx language"); } diff --git a/test/jdk/java/util/Currency/PropertiesTestRun.java b/test/jdk/java/util/Currency/PropertiesTestRun.java index 6f2ea28a90d3a..baec22f3e86f6 100644 --- a/test/jdk/java/util/Currency/PropertiesTestRun.java +++ b/test/jdk/java/util/Currency/PropertiesTestRun.java @@ -116,7 +116,7 @@ private static Stream PropertiesTestMethods() { // Launch a PropertiesTest method using the TEST JDK private static void executeTestJDKMethod(String... params) throws Throwable { - int exitStatus = ProcessTools.executeTestJvm(params).getExitValue(); + int exitStatus = ProcessTools.executeTestJava(params).getExitValue(); if (exitStatus != 0) { fail("Process started with: " + Arrays.toString(params) + " failed"); } @@ -126,7 +126,7 @@ private static void executeTestJDKMethod(String... params) throws Throwable { private static void executeWritableJDKMethod(String... params) throws Throwable { // Need to include WritableJDK javapath, TEST JDK classpath String[] allParams = new String[3+params.length+Utils.getTestJavaOpts().length]; - // We don't use executeTestJvm() because we want to point to separate JDK java path + // We don't use executeTestJava() because we want to point to separate JDK java path allParams[0] = WRITABLE_JDK_JAVA_PATH; allParams[1] = "-cp"; allParams[2] = System.getProperty("java.class.path"); diff --git a/test/jdk/java/util/Locale/UseOldISOCodesTest.java b/test/jdk/java/util/Locale/UseOldISOCodesTest.java index 38008e9f66294..d4f7b53f0c6b8 100644 --- a/test/jdk/java/util/Locale/UseOldISOCodesTest.java +++ b/test/jdk/java/util/Locale/UseOldISOCodesTest.java @@ -41,7 +41,7 @@ public class UseOldISOCodesTest { // Ensure java.locale.useOldISOCodes is only interpreted at runtime startup @Test public void staticInitializationTest() throws Exception { - ProcessTools.executeTestJvm("-Djava.locale.useOldISOCodes=true", "UseOldISOCodesTest$Runner") + ProcessTools.executeTestJava("-Djava.locale.useOldISOCodes=true", "UseOldISOCodesTest$Runner") .outputTo(System.out) .errorTo(System.err) .shouldHaveExitValue(0); diff --git a/test/jdk/java/util/prefs/CheckUserPrefsStorage.java b/test/jdk/java/util/prefs/CheckUserPrefsStorage.java index 51ecae932d17b..1f772f4811aaa 100644 --- a/test/jdk/java/util/prefs/CheckUserPrefsStorage.java +++ b/test/jdk/java/util/prefs/CheckUserPrefsStorage.java @@ -42,7 +42,7 @@ public static void main(String[] args) throws Throwable { } public static void run(String testName) throws Exception { - ProcessTools.executeTestJvm("-Djava.util.prefs.userRoot=.", testName) + ProcessTools.executeTestJava("-Djava.util.prefs.userRoot=.", testName) .outputTo(System.out) .errorTo(System.out) .shouldHaveExitValue(0); diff --git a/test/jdk/java/util/zip/EntryCount64k.java b/test/jdk/java/util/zip/EntryCount64k.java index 08d896a124a2a..2dac7643de2a7 100644 --- a/test/jdk/java/util/zip/EntryCount64k.java +++ b/test/jdk/java/util/zip/EntryCount64k.java @@ -160,7 +160,7 @@ static void checkCanRead(File zipFile, int entryCount) throws Throwable { } // Check java -jar - OutputAnalyzer a = ProcessTools.executeTestJvm("-jar", zipFile.getName()); + OutputAnalyzer a = ProcessTools.executeTestJava("-jar", zipFile.getName()); a.shouldHaveExitValue(0); a.stdoutShouldMatch("\\AMain\\Z"); a.stderrShouldMatch("\\A\\Z"); diff --git a/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java b/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java index e0a987f8bdc31..cafc17accf8d4 100644 --- a/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java +++ b/test/jdk/java/util/zip/ZipFile/DeleteTempJarTest.java @@ -42,7 +42,7 @@ public class DeleteTempJarTest { public static void main(String[] args) throws Exception { - String tmpFile = ProcessTools.executeTestJvm(DeleteTempJar.class.getName()) + String tmpFile = ProcessTools.executeTestJava(DeleteTempJar.class.getName()) .shouldHaveExitValue(0) .getStdout(); diff --git a/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java b/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java index 987c0e2e66adf..c4bb44db3addc 100644 --- a/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java +++ b/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java @@ -183,7 +183,7 @@ private void execute(String args) throws Exception { } return !s.isEmpty(); }).toArray(String[]::new); - OutputAnalyzer out = ProcessTools.executeTestJvm(safeArgs); + OutputAnalyzer out = ProcessTools.executeTestJava(safeArgs); // Handle response. if (out.getExitValue() != 0) { System.out.printf("OUTPUT: %s", out.getOutput()); diff --git a/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java b/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java index 5752c4e3c5d7d..faab81afb0db5 100644 --- a/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java +++ b/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java @@ -167,7 +167,7 @@ private void execute(String args) throws Exception { } return !s.isEmpty(); }).toArray(String[]::new); - OutputAnalyzer out = ProcessTools.executeTestJvm(safeArgs); + OutputAnalyzer out = ProcessTools.executeTestJava(safeArgs); // Handle response. if (out.getExitValue() != 0) { System.out.printf("OUTPUT: %s", out.getOutput()); diff --git a/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java b/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java index 02346414cd3f4..7651c92bf77b2 100644 --- a/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java +++ b/test/jdk/jdk/internal/ref/Cleaner/ExitOnThrow.java @@ -44,9 +44,9 @@ public class ExitOnThrow { public static void main(String[] args) throws Exception { if (args.length == 0) { - ProcessTools.executeTestJvm("--add-exports", "java.base/jdk.internal.ref=ALL-UNNAMED", - "ExitOnThrow", - "-executeCleaner") + ProcessTools.executeTestJava("--add-exports", "java.base/jdk.internal.ref=ALL-UNNAMED", + "ExitOnThrow", + "-executeCleaner") .outputTo(System.out) .errorTo(System.out) .shouldHaveExitValue(1) diff --git a/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java b/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java index 6b97613f4ab36..f5a32e0b45a6d 100644 --- a/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java +++ b/test/jdk/jdk/jfr/api/consumer/security/TestStreamingRemote.java @@ -81,7 +81,7 @@ public static void main(String... args) throws Exception { c[1] = "-Djava.security.policy=" + escapeBackslashes(policy.toString()); c[2] = Test.class.getName(); c[3] = repository; - OutputAnalyzer oa = ProcessTools.executeTestJvm(c); + OutputAnalyzer oa = ProcessTools.executeTestJava(c); oa.shouldContain(SUCCESS); } } diff --git a/test/jdk/jdk/jfr/event/io/TestInstrumentation.java b/test/jdk/jdk/jfr/event/io/TestInstrumentation.java index 5e08f45cb5550..ddbc120649762 100644 --- a/test/jdk/jdk/jfr/event/io/TestInstrumentation.java +++ b/test/jdk/jdk/jfr/event/io/TestInstrumentation.java @@ -283,7 +283,7 @@ private static void launchTest() throws Throwable { "-classpath", classpath, "-javaagent:" + testClassDir + "TestInstrumentation.jar", "jdk.jfr.event.io.TestInstrumentation$TestMain" }; - OutputAnalyzer output = ProcessTools.executeTestJvm(args); + OutputAnalyzer output = ProcessTools.executeTestJava(args); output.shouldHaveExitValue(0); } diff --git a/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java b/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java index b5ca601c011d6..11a6a781e01d3 100644 --- a/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java +++ b/test/jdk/sun/security/pkcs11/Config/ReadConfInUTF16Env.java @@ -40,7 +40,7 @@ public class ReadConfInUTF16Env { public void testReadConfInUTF16Env() throws Exception { String[] testCommand = new String[] { "-Dfile.encoding=UTF-16", TestSunPKCS11Provider.class.getName()}; - ProcessTools.executeTestJvm(testCommand).shouldHaveExitValue(0); + ProcessTools.executeTestJava(testCommand).shouldHaveExitValue(0); } static class TestSunPKCS11Provider { diff --git a/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java b/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java index b9fb72b8faf0e..476dc95488495 100644 --- a/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java +++ b/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java @@ -231,7 +231,7 @@ static void testConstraint(String[] trustNames, String[] certNames, // Run client on another JVM so that its properties cannot be in conflict // with server's. - OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm( + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( "-Dcert.dir=" + CERT_DIR, "-Djava.security.debug=certpath", "-classpath", diff --git a/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java b/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java index 1ce50662f4647..7632fcf462f9a 100644 --- a/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java +++ b/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java @@ -93,7 +93,7 @@ public class DebugReportsOneExtraByte extends SSLEngineTemplate { public static void main(String args[]) throws Exception { if (args.length == 0) { - OutputAnalyzer output = ProcessTools.executeTestJvm( + OutputAnalyzer output = ProcessTools.executeTestJava( "-Dtest.src=" + System.getProperty("test.src"), "-Djavax.net.debug=all", "DebugReportsOneExtraByte", "p"); output.shouldContain("WRITE: TLSv1 application_data, length = 8"); diff --git a/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java b/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java index c614ca62f29a9..5cfa9c9a68008 100644 --- a/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java +++ b/test/jdk/sun/security/ssl/SSLLogger/LoggingFormatConsistency.java @@ -50,7 +50,7 @@ public class LoggingFormatConsistency extends SSLSocketTemplate { public static void main(String[] args) throws Exception { if (args.length != 0) { // A non-empty set of arguments occurs when the "runTest" argument - // is passed to the test via ProcessTools::executeTestJvm. + // is passed to the test via ProcessTools::executeTestJava. // // This is done because an OutputAnalyzer is unable to read // the output of the current running JVM, and must therefore create @@ -71,7 +71,7 @@ public static void main(String[] args) throws Exception { System.out.println("TESTING " + expectedTLSVersion); var activeTLSProtocol = "-Djdk.tls.client.protocols=" + expectedTLSVersion; - var output = ProcessTools.executeTestJvm( + var output = ProcessTools.executeTestJava( testSrc, activeTLSProtocol, javaxNetDebug, diff --git a/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java b/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java index 708b8f0d11bb8..a1c9cad22711a 100644 --- a/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java +++ b/test/jdk/sun/security/ssl/SSLSocketImpl/IgnorableExceptionMessages.java @@ -49,7 +49,7 @@ public class IgnorableExceptionMessages extends SSLSocketTemplate { public static void main(String[] args) throws Exception { if (args.length > 0) { // A non-empty set of arguments occurs when the "runTest" argument - // is passed to the test via ProcessTools::executeTestJvm. + // is passed to the test via ProcessTools::executeTestJava. // // This is done because an OutputAnalyzer is unable to read // the output of the current running JVM, and must therefore create @@ -67,7 +67,7 @@ public static void main(String[] args) throws Exception { className, extraArgument); - OutputAnalyzer output = ProcessTools.executeTestJvm(jvmArgs); + OutputAnalyzer output = ProcessTools.executeTestJava(jvmArgs); if (output.getExitValue() != 0) { output.asLines().forEach(System.out::println); // No need to dump the output unless the test fails diff --git a/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java b/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java index ccc4b4051470d..9c9a8590ac74c 100644 --- a/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java +++ b/test/jdk/sun/security/tools/jarsigner/multiRelease/MVJarSigningTest.java @@ -120,7 +120,7 @@ public static void main(String[] args) throws Throwable { "-Djava.security.policy=" + TEST_SRC + File.separator + POLICY_FILE, "version.Main"}; - ProcessTools.executeTestJvm(cmd) + ProcessTools.executeTestJava(cmd) .shouldHaveExitValue(0) .shouldContain(VERSION_MESSAGE); } diff --git a/test/jdk/sun/security/util/Resources/early/EarlyResources.java b/test/jdk/sun/security/util/Resources/early/EarlyResources.java index 12da50e311f9e..3ee0a9f576c62 100644 --- a/test/jdk/sun/security/util/Resources/early/EarlyResources.java +++ b/test/jdk/sun/security/util/Resources/early/EarlyResources.java @@ -42,7 +42,7 @@ public static void main(String[] args) throws Exception { String fs = File.separator; String policyPath = testSrc + fs + "malformed.policy"; - OutputAnalyzer out = ProcessTools.executeTestJvm( + OutputAnalyzer out = ProcessTools.executeTestJava( "-Djava.security.manager", "-Djava.security.policy=" + policyPath, "EarlyResources$TestMain"); diff --git a/test/lib-test/jdk/test/lib/RandomGeneratorTest.java b/test/lib-test/jdk/test/lib/RandomGeneratorTest.java index ce57ebfe65f34..71e36bdc9c471 100644 --- a/test/lib-test/jdk/test/lib/RandomGeneratorTest.java +++ b/test/lib-test/jdk/test/lib/RandomGeneratorTest.java @@ -69,7 +69,7 @@ public static void main( String[] args) throws Throwable { jvmArgs.add(origFileName); int fileNameIndex = jvmArgs.size() - 1; String[] cmdLineArgs = jvmArgs.toArray(new String[jvmArgs.size()]); - ProcessTools.executeTestJvm(cmdLineArgs).shouldHaveExitValue(0); + ProcessTools.executeTestJava(cmdLineArgs).shouldHaveExitValue(0); String etalon = Utils.fileAsString(origFileName).trim(); cmdLineArgs[fileNameIndex] = seedOpt.name(); seedOpt.verify(etalon, cmdLineArgs); @@ -143,7 +143,7 @@ public void verify(String orig, String[] cmdLine) { String output; OutputAnalyzer oa; try { - oa = ProcessTools.executeTestJvm(cmdLine); + oa = ProcessTools.executeTestJava(cmdLine); } catch (Throwable t) { throw new Error("TESTBUG: Unexpedted exception during jvm execution.", t); } diff --git a/test/lib-test/jdk/test/lib/process/ProcessToolsExecuteLimitedTestJavaTest.java b/test/lib-test/jdk/test/lib/process/ProcessToolsExecuteLimitedTestJavaTest.java new file mode 100644 index 0000000000000..4331f9ab374f7 --- /dev/null +++ b/test/lib-test/jdk/test/lib/process/ProcessToolsExecuteLimitedTestJavaTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 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. + */ + +/* + * @test + * @summary Unit test for ProcessTools.executeLimitedTestJava() + * @library /test/lib + * @run main/othervm -Dtest.java.opts=-XX:MaxMetaspaceSize=123456789 ProcessToolsExecuteLimitedTestJavaTest + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class ProcessToolsExecuteLimitedTestJavaTest { + public static void main(String[] args) throws Exception { + if (args.length > 0) { + // Do nothing. Just let the JVM log its output. + } else { + // In comparison to executeTestJava, executeLimitedTestJava should not add the + // -Dtest.java.opts flags. Check that it doesn't. + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+PrintFlagsFinal", "-version"); + output.stdoutShouldNotMatch(".*MaxMetaspaceSize.* = 123456789.*"); + } + } +} diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java index cad9d9ecd57a6..c508af1036eb9 100644 --- a/test/lib/jdk/test/lib/process/ProcessTools.java +++ b/test/lib/jdk/test/lib/process/ProcessTools.java @@ -517,43 +517,69 @@ public static ProcessBuilder createLimitedTestJavaProcessBuilder(String... comma } /** - * Executes a test jvm process, waits for it to finish and returns + * Executes a process using the java launcher from the jdk to + * be tested, waits for it to finish and returns * the process output. * *

The process is created using runtime flags set up by: * {@link #createTestJavaProcessBuilder(String...)}. The * jvm process will have exited before this method returns. * - * @param cmds User specified arguments. + * @param command User specified arguments. * @return The output from the process. */ - public static OutputAnalyzer executeTestJvm(List cmds) throws Exception { - return executeTestJvm(cmds.toArray(String[]::new)); + public static OutputAnalyzer executeTestJava(List command) throws Exception { + return executeTestJava(command.toArray(String[]::new)); } /** - * Executes a test jvm process, waits for it to finish and returns + * Executes a process using the java launcher from the jdk to + * be tested, waits for it to finish and returns * the process output. * *

The process is created using runtime flags set up by: * {@link #createTestJavaProcessBuilder(String...)}. The * jvm process will have exited before this method returns. * - * @param cmds User specified arguments. + * @param command User specified arguments. * @return The output from the process. */ - public static OutputAnalyzer executeTestJvm(String... cmds) throws Exception { - ProcessBuilder pb = createTestJavaProcessBuilder(cmds); + public static OutputAnalyzer executeTestJava(String... command) throws Exception { + ProcessBuilder pb = createTestJavaProcessBuilder(command); return executeProcess(pb); } /** - * @param cmds User specified arguments. + * Executes a process using the java launcher from the jdk to + * be tested, waits for it to finish and returns + * the process output. + * + *

The process is created using runtime flags set up by: + * {@link #createLimitedTestJavaProcessBuilder(String...)}. The + * jvm process will have exited before this method returns. + * + * @param command User specified arguments. + * @return The output from the process. + */ + public static OutputAnalyzer executeLimitedTestJava(List command) throws Exception { + return executeLimitedTestJava(command.toArray(String[]::new)); + } + + /** + * Executes a process using the java launcher from the jdk to + * be tested, waits for it to finish and returns + * the process output. + * + *

The process is created using runtime flags set up by: + * {@link #createLimitedTestJavaProcessBuilder(String...)}. The + * jvm process will have exited before this method returns. + * + * @param command User specified arguments. * @return The output from the process. - * @see #executeTestJvm(String...) */ - public static OutputAnalyzer executeTestJava(String... cmds) throws Exception { - return executeTestJvm(cmds); + public static OutputAnalyzer executeLimitedTestJava(String... command) throws Exception { + ProcessBuilder pb = createLimitedTestJavaProcessBuilder(command); + return executeProcess(pb); } /** From a014be6718ad16a762e371ac73961d02fed273f2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 29 Apr 2025 15:00:15 +0000 Subject: [PATCH 226/846] 8340176: Replace usage of -noclassgc with -Xnoclassgc in test/jdk/java/lang/management/MemoryMXBean/LowMemoryTest2.java Backport-of: 3e03e6673acfea543d0dbbc64b7a4f52e3292c2b --- .../java/lang/management/MemoryMXBean/LowMemoryTest2.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/jdk/java/lang/management/MemoryMXBean/LowMemoryTest2.java b/test/jdk/java/lang/management/MemoryMXBean/LowMemoryTest2.java index 917e8226bb131..de1b22c4075a4 100644 --- a/test/jdk/java/lang/management/MemoryMXBean/LowMemoryTest2.java +++ b/test/jdk/java/lang/management/MemoryMXBean/LowMemoryTest2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ * @bug 4982128 * @summary Test low memory detection of non-heap memory pool * - * @run main/othervm/timeout=600 -noclassgc -XX:MaxMetaspaceSize=32m + * @run main/othervm/timeout=600 -Xnoclassgc -XX:MaxMetaspaceSize=32m * LowMemoryTest2 */ @@ -45,7 +45,7 @@ * @bug 4982128 * @summary Test low memory detection of non-heap memory pool * - * @run main/othervm/timeout=600 -noclassgc -XX:MaxMetaspaceSize=16m + * @run main/othervm/timeout=600 -Xnoclassgc -XX:MaxMetaspaceSize=16m * -XX:CompressedClassSpaceSize=4m LowMemoryTest2 */ From cd02a16a0bec1ee87a8f2da5fdc90a3d0bf46b6e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 29 Apr 2025 15:02:36 +0000 Subject: [PATCH 227/846] 8344316: security/auth/callback/TextCallbackHandler/Password.java make runnable with JTReg and add the UI Backport-of: 82bc0a7f8c7ee63d2f8c3db57dc22f39963ae022 --- .../TextCallbackHandler/Password.java | 127 +++++++++++++++--- 1 file changed, 105 insertions(+), 22 deletions(-) diff --git a/test/jdk/com/sun/security/auth/callback/TextCallbackHandler/Password.java b/test/jdk/com/sun/security/auth/callback/TextCallbackHandler/Password.java index f9231a0b36edc..297b40109ee50 100644 --- a/test/jdk/com/sun/security/auth/callback/TextCallbackHandler/Password.java +++ b/test/jdk/com/sun/security/auth/callback/TextCallbackHandler/Password.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2025, 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 @@ -25,35 +25,118 @@ * @test * @bug 6825240 6829785 * @summary Password.readPassword() echos the input when System.Console is null - * @run main/manual Password - */ - -/* - * This scenario cannot be automated because util/Password.java verifies the given input stream is - * equal to the initialSystemIn. This prevents the test from providing a custom input stream. - * - * Steps to run the test: - * 1) Compile the class using the JDK version being tested: '/javac Password.java' - * 2) Run the test using the JDK version being tested: '/java -cp . Password' - * 3) Type in the first password, it should not be visible in the console - * 4) Type in the second password, it should be visible in the console - * 5) The final output line displays the entered passwords, both should be visible + * @library /test/lib + * @run main/manual/othervm Password */ import com.sun.security.auth.callback.TextCallbackHandler; + + import javax.security.auth.callback.*; +import javax.swing.*; + +import jdk.test.lib.UIBuilder; + +import java.util.Arrays; public class Password { - public static void main(String args[]) throws Exception { - TextCallbackHandler h = new TextCallbackHandler(); - PasswordCallback nc = new PasswordCallback("Invisible: ", false); - PasswordCallback nc2 = new PasswordCallback("Visible: ", true); - System.out.println("Two passwords will be prompted for. The first one " + - "should have echo off, the second one on. Otherwise, this test fails"); - Callback[] callbacks = { nc, nc2 }; + private static final int TIMEOUT_MS = 240000; + private volatile boolean failed = false; + private volatile boolean aborted = false; + private Thread currentThread = null; + + public static void password() throws Exception { + + TextCallbackHandler h = new TextCallbackHandler(); + PasswordCallback nc = + new PasswordCallback("Please input something, your input should be VISIBLE: ", true); + PasswordCallback nc2 = + new PasswordCallback("Please input something again, your input should be INVISIBLE: ", false); + Callback[] callbacks = {nc, nc2}; h.handle(callbacks); System.out.println("You input " + new String(nc.getPassword()) + " and " + new String(nc2.getPassword())); - } + } + + public static void main(String[] args) throws Exception { + if (Arrays.asList(args).contains("--password")) { + password(); + } else { + final String instructions = String.format("%s/bin/java -cp \"%s\" Password --password", + System.getProperty("java.home").replace("\\","/"), + System.getProperty("java.class.path").replace("\\","/") + ); + + boolean testFailed = new Password().validate( + "Please copy and execute the following script in the terminal / Windows Command Prompt window. " + + "Two passwords will be prompted for.\n" + + "Enter something at each prompt and press Enter/Return.\n" + + "If the first input is visible and the second is invisible, this test PASSES. Otherwise, this test FAILS.\n" + + "Once the test is complete please select whether the test has passed.\n", + instructions); + + if (testFailed) { + throw new RuntimeException("Test has failed"); + } + } + } + + public boolean validate(String instruction, String message) { + failed = false; + currentThread = Thread.currentThread(); + final JDialog dialog = new UIBuilder.DialogBuilder() + .setTitle("Password") + .setInstruction(instruction) + .setMessage(message) + .setPassAction(e -> pass()) + .setFailAction(e -> fail()) + .setCloseAction(this::abort) + .build(); + + SwingUtilities.invokeLater(() -> { + try { + dialog.setVisible(true); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + + try { + Thread.sleep(TIMEOUT_MS); + //Timed out, so fail the test + throw new RuntimeException( + "Timed out after " + TIMEOUT_MS / 1000 + " seconds"); + } catch (final InterruptedException e) { + if (aborted) { + throw new RuntimeException("TEST ABORTED"); + } + + if (failed) { + System.out.println("TEST FAILED"); + System.out.println(message); + } else { + System.out.println("TEST PASSED"); + } + } finally { + dialog.dispose(); + } + + return failed; + } + + public void pass() { + failed = false; + currentThread.interrupt(); + } + + public void fail() { + failed = true; + currentThread.interrupt(); + } + + public void abort() { + aborted = true; + currentThread.interrupt(); + } } From 74f72b6504418650f1e411cbeec9dac93abee7d4 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 29 Apr 2025 15:04:26 +0000 Subject: [PATCH 228/846] 8350224: Test javax/swing/JComboBox/TestComboBoxComponentRendering.java fails in ubuntu 23.x and later Reviewed-by: phh Backport-of: 69fb68abca69acb54c48283a7b67e637f1d7c2d5 --- .../javax/swing/JComboBox/TestComboBoxComponentRendering.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/jdk/javax/swing/JComboBox/TestComboBoxComponentRendering.java b/test/jdk/javax/swing/JComboBox/TestComboBoxComponentRendering.java index 0e176a911a39c..da914314670ad 100644 --- a/test/jdk/javax/swing/JComboBox/TestComboBoxComponentRendering.java +++ b/test/jdk/javax/swing/JComboBox/TestComboBoxComponentRendering.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -33,6 +33,7 @@ import java.awt.Color; import java.awt.Component; import java.awt.image.BufferedImage; +import java.awt.Font; import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; @@ -137,6 +138,7 @@ class ComboBoxCustomRenderer extends JLabel implements ListCellRenderer { public ComboBoxCustomRenderer() { + setFont(new Font("SansSerif", Font.BOLD, 32)); setOpaque(true); setHorizontalAlignment(CENTER); setVerticalAlignment(CENTER); From 21cecc1cafba424f0588a1b4287dbe6546aaca03 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 29 Apr 2025 15:06:05 +0000 Subject: [PATCH 229/846] 8351086: (fc) Make java/nio/channels/FileChannel/BlockDeviceSize.java test manual Backport-of: 08929134b3533362133139c4e964b1b28de6ebfb --- test/jdk/java/nio/channels/FileChannel/BlockDeviceSize.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/jdk/java/nio/channels/FileChannel/BlockDeviceSize.java b/test/jdk/java/nio/channels/FileChannel/BlockDeviceSize.java index 84e0bf0dd3964..d4ee633c416be 100644 --- a/test/jdk/java/nio/channels/FileChannel/BlockDeviceSize.java +++ b/test/jdk/java/nio/channels/FileChannel/BlockDeviceSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, 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 @@ -25,7 +25,10 @@ * @bug 8054029 * @requires (os.family == "linux") * @summary FileChannel.size() should be equal to RandomAccessFile.size() and > 0 for block devs on Linux + * @comment The test must be launched with sudo or the block devices listed in + * the BLK_FNAMES array must be readable by the user running the test. * @library /test/lib + * @run main/manual BlockDeviceSize */ import java.io.RandomAccessFile; From 3a9b28f59095ecee861a037c237a194e0218397a Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 29 Apr 2025 15:07:27 +0000 Subject: [PATCH 230/846] 8343891: Test javax/swing/JTabbedPane/TestJTabbedPaneBackgroundColor.java failed Backport-of: c2e14b1b304796753bea2eca81aa24ab4b3bf6db --- .../TestJTabbedPaneBackgroundColor.java | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/test/jdk/javax/swing/JTabbedPane/TestJTabbedPaneBackgroundColor.java b/test/jdk/javax/swing/JTabbedPane/TestJTabbedPaneBackgroundColor.java index d4bed5ac2dafa..cc4ca41802cdf 100644 --- a/test/jdk/javax/swing/JTabbedPane/TestJTabbedPaneBackgroundColor.java +++ b/test/jdk/javax/swing/JTabbedPane/TestJTabbedPaneBackgroundColor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -48,6 +48,9 @@ public class TestJTabbedPaneBackgroundColor { private static Robot robot; private static volatile Dimension dim; private static volatile Point loc; + private static volatile boolean isOpaque; + private static volatile Color c1 = null; + private static volatile Color c2 = null; public static void main(String[] args) throws Exception { robot = new Robot(); @@ -55,10 +58,12 @@ public static void main(String[] args) throws Exception { for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { System.out.println("Testing: " + laf.getName()); - setLookAndFeel(laf); try { - SwingUtilities.invokeAndWait(TestJTabbedPaneBackgroundColor::createAndShowUI); + SwingUtilities.invokeAndWait(() -> { + setLookAndFeel(laf); + createAndShowUI(); + }); robot.waitForIdle(); robot.delay(500); @@ -70,10 +75,12 @@ public static void main(String[] args) throws Exception { loc = new Point(loc.x + dim.width - 2, loc.y + 2); doTesting(loc, laf); - if (!pane.isOpaque()) { - pane.setOpaque(true); - pane.repaint(); - } + SwingUtilities.invokeAndWait(() -> { + if (!pane.isOpaque()) { + pane.setOpaque(true); + pane.repaint(); + } + }); robot.waitForIdle(); robot.delay(500); @@ -119,14 +126,18 @@ private static void createAndShowUI() { frame.setVisible(true); } - private static void doTesting(Point p, UIManager.LookAndFeelInfo laf) { - boolean isOpaque = pane.isOpaque(); + private static void doTesting(Point p, UIManager.LookAndFeelInfo laf) throws Exception { + SwingUtilities.invokeAndWait(() -> { + isOpaque = pane.isOpaque(); + c1 = pane.getBackground(); + c2 = frame.getContentPane().getBackground(); + }); Color actual = robot.getPixelColor(p.x, p.y); - Color expected = isOpaque - ? pane.getBackground() - : frame.getContentPane().getBackground(); + Color expected = isOpaque ? c1 : c2; if (!expected.equals(actual)) { + System.out.println("Expected Color : " + expected); + System.out.println("Actual Color : " + actual); addOpaqueError(laf.getName(), isOpaque); } } From 1edd6660f657300337bdcdc6d78618e02b60592d Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 29 Apr 2025 15:10:47 +0000 Subject: [PATCH 231/846] 8352706: httpclient HeadTest does not run on HTTP2 Reviewed-by: mbaesken Backport-of: e32a0c90feb231d791e6c17e6360f629189cab8b --- test/jdk/java/net/httpclient/HeadTest.java | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/test/jdk/java/net/httpclient/HeadTest.java b/test/jdk/java/net/httpclient/HeadTest.java index 81eeb61207354..506b59b6c776c 100644 --- a/test/jdk/java/net/httpclient/HeadTest.java +++ b/test/jdk/java/net/httpclient/HeadTest.java @@ -111,22 +111,21 @@ public class HeadTest implements HttpServerAdapters { @DataProvider(name = "positive") public Object[][] positive() { return new Object[][] { + // HTTP/1.1 { httpURI, "GET", HTTP_NOT_MODIFIED, HTTP_1_1 }, { httpsURI, "GET", HTTP_NOT_MODIFIED, HTTP_1_1 }, - { httpURI, "GET", HTTP_NOT_MODIFIED, HttpClient.Version.HTTP_2 }, - { httpsURI, "GET", HTTP_NOT_MODIFIED, HttpClient.Version.HTTP_2 }, { httpURI, "HEAD", HTTP_OK, HTTP_1_1 }, { httpsURI, "HEAD", HTTP_OK, HTTP_1_1 }, - { httpURI, "HEAD", HTTP_OK, HttpClient.Version.HTTP_2 }, - { httpsURI, "HEAD", HTTP_OK, HttpClient.Version.HTTP_2 }, { httpURI + "transfer/", "GET", HTTP_NOT_MODIFIED, HTTP_1_1 }, { httpsURI + "transfer/", "GET", HTTP_NOT_MODIFIED, HTTP_1_1 }, - { httpURI + "transfer/", "GET", HTTP_NOT_MODIFIED, HttpClient.Version.HTTP_2 }, - { httpsURI + "transfer/", "GET", HTTP_NOT_MODIFIED, HttpClient.Version.HTTP_2 }, { httpURI + "transfer/", "HEAD", HTTP_OK, HTTP_1_1 }, { httpsURI + "transfer/", "HEAD", HTTP_OK, HTTP_1_1 }, - { httpURI + "transfer/", "HEAD", HTTP_OK, HttpClient.Version.HTTP_2 }, - { httpsURI + "transfer/", "HEAD", HTTP_OK, HttpClient.Version.HTTP_2 } + // HTTP/2 + { http2URI, "GET", HTTP_NOT_MODIFIED, HttpClient.Version.HTTP_2 }, + { https2URI, "GET", HTTP_NOT_MODIFIED, HttpClient.Version.HTTP_2 }, + { http2URI, "HEAD", HTTP_OK, HttpClient.Version.HTTP_2 }, + { https2URI, "HEAD", HTTP_OK, HttpClient.Version.HTTP_2 }, + // HTTP2 forbids transfer-encoding }; } @@ -145,11 +144,9 @@ void test(String uriString, String method, HttpRequest.Builder requestBuilder = HttpRequest .newBuilder(uri) + .version(version) .method(method, HttpRequest.BodyPublishers.noBody()); - if (version != null) { - requestBuilder.version(version); - } HttpRequest request = requestBuilder.build(); out.println("Initial request: " + request.uri()); @@ -160,6 +157,7 @@ void test(String uriString, String method, assertEquals(response.statusCode(), expResp); assertEquals(response.body(), ""); assertEquals(response.headers().firstValue("Content-length").get(), CONTENT_LEN); + assertEquals(response.version(), request.version().get()); } // -- Infrastructure @@ -182,7 +180,7 @@ public void setup() throws Exception { http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new HeadHandler(), "/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/"; - https2TestServer = HttpTestServer.create(HTTP_2, SSLContext.getDefault()); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new HeadHandler(), "/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/"; From af0de21b9bac2b593e2b50703e2995cd7a9cfb42 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 29 Apr 2025 15:11:05 +0000 Subject: [PATCH 232/846] 8330598: java/net/httpclient/Http1ChunkedTest.java fails with java.util.MissingFormatArgumentException: Format specifier '%s' Backport-of: c9c3c1536880d81ab84d5cb55f4fd0fe3bbf60a2 --- test/jdk/java/net/httpclient/Http1ChunkedTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/java/net/httpclient/Http1ChunkedTest.java b/test/jdk/java/net/httpclient/Http1ChunkedTest.java index 2df4c9e854dfd..f51ccf9fd3845 100644 --- a/test/jdk/java/net/httpclient/Http1ChunkedTest.java +++ b/test/jdk/java/net/httpclient/Http1ChunkedTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, 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 @@ -97,7 +97,7 @@ private static void test(String name, String headers, List body, long de } } if (!received) { - System.out.printf("%s: Unexpected headers received: dropping request.%n"); + System.out.printf("%s: Unexpected headers received: dropping request.%n", name); continue; } OutputStream os = serverConn.getOutputStream(); From 6d38efa475588ad1d74ebf7cc5536f53ee7f97e1 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 5 May 2025 13:09:40 +0000 Subject: [PATCH 233/846] 8288707: javax/swing/JToolBar/4529206/bug4529206.java: setFloating does not work correctly Backport-of: feb223aacfd89d598a27b27c4b8be4601cc5eaff --- .../swing/JToolBar/4529206/bug4529206.java | 83 ++++++++++++------- 1 file changed, 54 insertions(+), 29 deletions(-) diff --git a/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java b/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java index 0b05ded2f3f69..8756e79d061ca 100644 --- a/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java +++ b/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -28,27 +28,34 @@ * @key headful * @bug 4529206 * @summary JToolBar - setFloating does not work correctly - * @author Konstantin Eremin * @run main bug4529206 */ -import javax.swing.*; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Robot; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.JToolBar; +import javax.swing.SwingUtilities; -public class bug4529206 extends JFrame { +public class bug4529206 { static JFrame frame; static JToolBar jToolBar1; - public bug4529206() { - setDefaultCloseOperation(EXIT_ON_CLOSE); - JPanel jPanFrame = (JPanel) this.getContentPane(); + static JButton jButton1; + + private static void test() { + frame = new JFrame(); + JPanel jPanFrame = (JPanel) frame.getContentPane(); jPanFrame.setLayout(new BorderLayout()); - this.setSize(new Dimension(200, 100)); - this.setLocation(125, 75); - this.setTitle("Test Floating Toolbar"); + frame.setSize(new Dimension(200, 100)); + frame.setTitle("Test Floating Toolbar"); jToolBar1 = new JToolBar(); - JButton jButton1 = new JButton("Float"); + jButton1 = new JButton("Float"); jPanFrame.add(jToolBar1, BorderLayout.NORTH); JTextField tf = new JTextField("click here"); jPanFrame.add(tf); @@ -58,11 +65,13 @@ public void actionPerformed(ActionEvent e) { buttonPressed(e); } }); - makeToolbarFloat(); - setVisible(true); + + frame.setUndecorated(true); + frame.setLocationRelativeTo(null); + frame.setVisible(true); } - private void makeToolbarFloat() { + private static void makeToolbarFloat() { javax.swing.plaf.basic.BasicToolBarUI ui = (javax.swing.plaf.basic.BasicToolBarUI) jToolBar1.getUI(); if (!ui.isFloating()) { ui.setFloatingLocation(100, 100); @@ -70,24 +79,40 @@ private void makeToolbarFloat() { } } - private void buttonPressed(ActionEvent e) { + private static void buttonPressed(ActionEvent e) { makeToolbarFloat(); } public static void main(String[] args) throws Exception { - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - frame = new bug4529206(); - } - }); - Robot robot = new Robot(); - robot.waitForIdle(); - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - if (frame.isFocused()) { - throw (new RuntimeException("setFloating does not work correctly")); + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + test(); } - } - }); + }); + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + makeToolbarFloat(); + }); + + robot.waitForIdle(); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + if (frame.isFocused()) { + throw + new RuntimeException("setFloating does not work correctly"); + } + } + }); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } } } From 23901f36d243a180d3cddcb72fb90ae0cdc5a45b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 5 May 2025 13:11:47 +0000 Subject: [PATCH 234/846] 8333680: com/sun/tools/attach/BasicTests.java fails with "SocketException: Permission denied: connect" Backport-of: 17bd483ff01e463cef45824f0c1296a8f3e782c8 --- test/jdk/com/sun/tools/attach/Agent.java | 5 +++-- test/jdk/com/sun/tools/attach/BasicTests.java | 8 ++++++-- test/jdk/com/sun/tools/attach/RedefineAgent.java | 5 +++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/test/jdk/com/sun/tools/attach/Agent.java b/test/jdk/com/sun/tools/attach/Agent.java index 9090ea7351969..510ff787fa76f 100644 --- a/test/jdk/com/sun/tools/attach/Agent.java +++ b/test/jdk/com/sun/tools/attach/Agent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ * the given port. */ import java.net.Socket; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.io.IOException; @@ -38,7 +39,7 @@ public static void agentmain(String args) throws IOException { int port = Integer.parseInt(args); System.out.println("Agent connecting back to Tool...."); Socket s = new Socket(); - s.connect( new InetSocketAddress(port) ); + s.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), port)); System.out.println("Agent connected to Tool."); s.close(); } diff --git a/test/jdk/com/sun/tools/attach/BasicTests.java b/test/jdk/com/sun/tools/attach/BasicTests.java index 4dc7065630fad..9ae454368106e 100644 --- a/test/jdk/com/sun/tools/attach/BasicTests.java +++ b/test/jdk/com/sun/tools/attach/BasicTests.java @@ -23,6 +23,8 @@ import java.io.File; import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.List; @@ -213,7 +215,8 @@ public static void main(String args[]) throws Exception { System.out.println(" - Test: End-to-end connection with agent"); - ServerSocket ss = new ServerSocket(0); + ServerSocket ss = new ServerSocket(); + ss.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); int port = ss.getLocalPort(); System.out.println(" - Loading Agent.jar into target VM ..."); @@ -231,7 +234,8 @@ public static void main(String args[]) throws Exception { System.out.println(" - Test: End-to-end connection with RedefineAgent"); - ServerSocket ss2 = new ServerSocket(0); + ServerSocket ss2 = new ServerSocket(); + ss2.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); int port2 = ss2.getLocalPort(); System.out.println(" - Loading RedefineAgent.jar into target VM ..."); diff --git a/test/jdk/com/sun/tools/attach/RedefineAgent.java b/test/jdk/com/sun/tools/attach/RedefineAgent.java index af01df427628e..cc0e7d269df35 100644 --- a/test/jdk/com/sun/tools/attach/RedefineAgent.java +++ b/test/jdk/com/sun/tools/attach/RedefineAgent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ * 6446941 java.lang.instrument: multiple agent attach fails (first agent chooses capabilities) */ import java.net.Socket; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.io.IOException; import java.util.Arrays; @@ -104,7 +105,7 @@ public static void agentmain(String args, Instrumentation inst) throws Exception int port = Integer.parseInt(args); System.out.println("RedefineAgent connecting back to Tool...."); Socket s = new Socket(); - s.connect( new InetSocketAddress(port) ); + s.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), port)); System.out.println("RedefineAgent connected to Tool."); testRedefine(inst); From 83291051acddc0942c5a2917418205969faa274e Mon Sep 17 00:00:00 2001 From: Daniel Hu Date: Thu, 8 May 2025 06:14:17 +0000 Subject: [PATCH 235/846] 8316629: j.text.DateFormatSymbols setZoneStrings() exception is unhelpful Backport-of: ef49e6c0d7e4e3a2d7d3d8dcb1edf195b23ce12c --- src/java.base/share/classes/java/text/DateFormatSymbols.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/text/DateFormatSymbols.java b/src/java.base/share/classes/java/text/DateFormatSymbols.java index e7919e33e69c7..582fe64b9c190 100644 --- a/src/java.base/share/classes/java/text/DateFormatSymbols.java +++ b/src/java.base/share/classes/java/text/DateFormatSymbols.java @@ -605,7 +605,8 @@ public void setZoneStrings(String[][] newZoneStrings) { for (int i = 0; i < newZoneStrings.length; ++i) { int len = newZoneStrings[i].length; if (len < 5) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException(String.format( + "Row %s of the input array does not have a length of at least 5", i)); } aCopy[i] = Arrays.copyOf(newZoneStrings[i], len); } From 203533211aee6d43f509bd8b8d58c17d3981078f Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 07:22:34 +0000 Subject: [PATCH 236/846] 8295470: Update openjdk.java.net => openjdk.org URLs in test code Reviewed-by: mbaesken Backport-of: d5a1521fde3f6ff7e810e8257a4722a09c9ef60b --- .../jtreg/applications/jcstress/README | 4 +-- .../applications/jcstress/TestGenerator.java | 2 +- .../jtreg/compiler/c2/Test6880034.java | 2 +- .../ci/hotspot/test/TestDynamicConstant.java | 6 ++--- .../jtreg/compiler/lib/ir_framework/README.md | 4 +-- .../jtreg/compiler/membars/DekkerTest.java | 2 +- .../gc/g1/logging/TestG1LoggingFailure.java | 4 +-- .../jtreg/gc/testlibrary/PerfCounter.java | 4 +-- .../libs/jaxp/library/JAXPTestPolicy.java | 4 +-- .../libs/jaxp/library/NetAccessPolicy.java | 4 +-- .../catalog/files/delegatecatalog.xml | 20 +++++++------- .../HierarchyBoundsListenerMixingTest.java | 2 +- .../JGlassPaneInternalFrameOverlapping.java | 6 ++--- .../AWT_Mixing/JGlassPaneMoveOverlapping.java | 6 ++--- .../AWT_Mixing/MixingPanelsResizing.java | 4 +-- .../Mixing/AWT_Mixing/OpaqueOverlapping.java | 4 +-- .../awt/Toolkit/Headless/HeadlessToolkit.java | 6 ++--- .../IsReachableViaLoopbackTest.java | 25 ++++++++++++++++- .../httpclient/offline/OfflineTesting.java | 12 ++++----- test/jdk/java/util/Base64/TestBase64.java | 4 +-- .../locks/LockSupport/ParkLoops.java | 4 +-- .../tck/ConcurrentLinkedDequeTest.java | 4 +-- .../util/concurrent/tck/JSR166TestCase.java | 4 +-- .../util/concurrent/tck/LockSupportTest.java | 2 +- .../jdk/java/util/concurrent/tck/MapTest.java | 2 +- .../concurrent/tck/ScheduledExecutorTest.java | 2 +- .../logging/LogManagerAppContextDeadlock.java | 4 +-- .../parse/EntityCharacterEventOrder.java | 2 +- .../testng/parse/XMLEntityScannerLoad.java | 27 +++++++++++++++++-- .../parse/jdk7156085/UTF8ReaderBug.java | 2 +- .../src/org/jtregext/GuiTestListener.java | 4 +-- test/jdk/sanity/client/lib/SwingSet2/README | 2 +- test/jdk/sanity/client/lib/jemmy/README | 2 +- .../ServerHandshaker/HelloExtensionsTest.java | 4 +-- test/jdk/tools/jpackage/run_tests.sh | 4 +-- .../testModules/TestModulePackages.java | 4 +-- .../javac/MethodParameters/LambdaTest.java | 4 +-- .../LegacyOutputTest/LegacyOutputTest.java | 2 +- .../api/ToolProvider/ToolProviderTest.java | 4 +-- .../lambda/MethodReferenceGenericTarget.java | 4 +-- 40 files changed, 129 insertions(+), 83 deletions(-) diff --git a/test/hotspot/jtreg/applications/jcstress/README b/test/hotspot/jtreg/applications/jcstress/README index 659938514bca6..842b047a77686 100644 --- a/test/hotspot/jtreg/applications/jcstress/README +++ b/test/hotspot/jtreg/applications/jcstress/README @@ -1,4 +1,4 @@ -Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 2017, 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 @@ -37,5 +37,5 @@ The */Test.java files should never be modified directly, because they are generated by TestGenerator and therefore all required changes must be made in that class. -[1] https://wiki.openjdk.java.net/display/CodeTools/jcstress +[1] https://wiki.openjdk.org/display/CodeTools/jcstress diff --git a/test/hotspot/jtreg/applications/jcstress/TestGenerator.java b/test/hotspot/jtreg/applications/jcstress/TestGenerator.java index 5252ba2a75bb9..81d8da356d68e 100644 --- a/test/hotspot/jtreg/applications/jcstress/TestGenerator.java +++ b/test/hotspot/jtreg/applications/jcstress/TestGenerator.java @@ -56,7 +56,7 @@ * added to classpath. One can replace @notest by @test in jtreg test * description above to run this class with jtreg. * - * @see jcstress + * @see jcstress */ public class TestGenerator { private static final String COPYRIGHT; diff --git a/test/hotspot/jtreg/compiler/c2/Test6880034.java b/test/hotspot/jtreg/compiler/c2/Test6880034.java index 628e7b230acb0..c69c902ecaf6b 100644 --- a/test/hotspot/jtreg/compiler/c2/Test6880034.java +++ b/test/hotspot/jtreg/compiler/c2/Test6880034.java @@ -52,7 +52,7 @@ // an incorrect result on 32-bit server VMs on SPARC due to a regression // introduced by the change: "6420645: Create a vm that uses compressed oops // for up to 32gb heapsizes" -// (http://hg.openjdk.java.net/jdk7/jdk7/hotspot/rev/ba764ed4b6f2). Further +// (https://git.openjdk.org/jdk/commit/4a831d4). Further // investigation showed that change 6420645 is not really the root cause of // this error but only reveals a problem with the float register encodings in // sparc.ad which was hidden until now. diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestDynamicConstant.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestDynamicConstant.java index 0764c87a7e945..83b464519dc53 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestDynamicConstant.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestDynamicConstant.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -63,8 +63,8 @@ /** * Tests support for Dynamic constants. * - * @see "https://openjdk.java.net/jeps/309" - * @see "https://bugs.openjdk.java.net/browse/JDK-8177279" + * @see "https://openjdk.org/jeps/309" + * @see "https://bugs.openjdk.org/browse/JDK-8177279" */ public class TestDynamicConstant implements Opcodes { diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/README.md b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md index d07760a1fcc32..c321e07a657ae 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/README.md +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md @@ -123,7 +123,7 @@ More information about the internals and the workflow of the framework can be fo ## 4. Internal Framework Tests There are various tests to verify the correctness of the test framework. These tests can be found in [ir_framework](../../../testlibrary_tests/ir_framework) and can directly be run with JTreg. The tests are part of the normal JTreg tests of HotSpot and should be run upon changing the framework code as a minimal form of testing. -Additional testing was performed by converting all compiler Inline Types tests that used the currently present IR test framework in Valhalla (see [JDK-8263024](https://bugs.openjdk.java.net/browse/JDK-8263024)). It is strongly advised to make sure a change to the framework still lets these converted tests in Valhalla pass as part of an additional testing step. +Additional testing was performed by converting all compiler Inline Types tests that used the currently present IR test framework in Valhalla (see [JDK-8263024](https://bugs.openjdk.org/browse/JDK-8263024)). It is strongly advised to make sure a change to the framework still lets these converted tests in Valhalla pass as part of an additional testing step. ## 5. Framework Package Structure A user only needs to import classes from the package `compiler.lib.ir_framework` (e.g. `import compiler.lib.ir_framework.*;`) which represents the interface classes to the framework. The remaining framework internal classes are kept in separate subpackages and should not directly be imported: @@ -134,4 +134,4 @@ A user only needs to import classes from the package `compiler.lib.ir_framework` - `compiler.lib.ir_framework.shared`: These classes can be called from either the driver, flag, or test VM. ## 6. Summary -The initial design and feature set was kept simple and straight forward and serves well for small to medium sized tests. There are a lot of possibilities to further enhance the framework and make it more powerful. This can be tackled in additional RFEs. A few ideas can be found as subtasks of the [initial RFE](https://bugs.openjdk.java.net/browse/JDK-8254129) for this framework. +The initial design and feature set was kept simple and straight forward and serves well for small to medium sized tests. There are a lot of possibilities to further enhance the framework and make it more powerful. This can be tackled in additional RFEs. A few ideas can be found as subtasks of the [initial RFE](https://bugs.openjdk.org/browse/JDK-8254129) for this framework. diff --git a/test/hotspot/jtreg/compiler/membars/DekkerTest.java b/test/hotspot/jtreg/compiler/membars/DekkerTest.java index 6036ea2249a27..2f329588abefb 100644 --- a/test/hotspot/jtreg/compiler/membars/DekkerTest.java +++ b/test/hotspot/jtreg/compiler/membars/DekkerTest.java @@ -47,7 +47,7 @@ public class DekkerTest { /* Read After Write Test (basically a simple Dekker test with volatile variables) Derived from the original jcstress test, available at: - http://hg.openjdk.java.net/code-tools/jcstress/file/6c339a5aa00d/ + hhttps://git.openjdk.org/jcstress/commit/15acd86 tests-custom/src/main/java/org/openjdk/jcstress/tests/volatiles/DekkerTest.java */ diff --git a/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java b/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java index 0d6af4ae47a29..eb008f04e521c 100644 --- a/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java +++ b/test/hotspot/jtreg/gc/g1/logging/TestG1LoggingFailure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -55,7 +55,7 @@ public static void main(String[] args) throws Throwable { options.add(Alloc.class.getName()); - // According to https://bugs.openjdk.java.net/browse/JDK-8146009 failure happens not every time. + // According to https://bugs.openjdk.org/browse/JDK-8146009 failure happens not every time. // Will try to reproduce this failure. for (int iteration = 0; iteration < 40; ++iteration) { startVM(options); diff --git a/test/hotspot/jtreg/gc/testlibrary/PerfCounter.java b/test/hotspot/jtreg/gc/testlibrary/PerfCounter.java index 90e9290e43a30..f42e69c67b6fb 100644 --- a/test/hotspot/jtreg/gc/testlibrary/PerfCounter.java +++ b/test/hotspot/jtreg/gc/testlibrary/PerfCounter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -28,7 +28,7 @@ /** * Represents a performance counter in the JVM. * - * See http://openjdk.java.net/groups/hotspot/docs/Serviceability.html#bjvmstat + * See https://openjdk.org/groups/hotspot/docs/Serviceability.html#bjvmstat * for more details about performance counters. */ public class PerfCounter { diff --git a/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPTestPolicy.java b/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPTestPolicy.java index 060d65de360f0..200405bc59672 100644 --- a/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPTestPolicy.java +++ b/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPTestPolicy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 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 @@ -53,7 +53,7 @@ public void onStart(ITestContext arg0) { policyManager.addPermission(new RuntimePermission("accessClassInPackage.com.sun.org.apache.xalan.internal.xsltc.trax")); policyManager.addPermission(new RuntimePermission("accessClassInPackage.com.sun.xml.internal.stream")); - policyManager.addPermission(new SocketPermission("openjdk.java.net:80", "connect,resolve")); + policyManager.addPermission(new SocketPermission("openjdk.org:80", "connect,resolve")); policyManager.addPermission(new SocketPermission("www.w3.org:80", "connect,resolve")); } } diff --git a/test/jaxp/javax/xml/jaxp/libs/jaxp/library/NetAccessPolicy.java b/test/jaxp/javax/xml/jaxp/libs/jaxp/library/NetAccessPolicy.java index f7037cffe9967..928003a2ecea9 100644 --- a/test/jaxp/javax/xml/jaxp/libs/jaxp/library/NetAccessPolicy.java +++ b/test/jaxp/javax/xml/jaxp/libs/jaxp/library/NetAccessPolicy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -36,7 +36,7 @@ public void onStart(ITestContext arg0) { // suppose to only run othervm mode if (isRunWithSecurityManager()) { JAXPPolicyManager policyManager = JAXPPolicyManager.getJAXPPolicyManager(true); - policyManager.addPermission(new SocketPermission("openjdk.java.net:80", "connect,resolve")); + policyManager.addPermission(new SocketPermission("openjdk.org:80", "connect,resolve")); policyManager.addPermission(new SocketPermission("www.w3.org:80", "connect,resolve")); } } diff --git a/test/jaxp/javax/xml/jaxp/unittest/catalog/files/delegatecatalog.xml b/test/jaxp/javax/xml/jaxp/unittest/catalog/files/delegatecatalog.xml index b398f5ba30de2..ca02c9eafe15c 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/catalog/files/delegatecatalog.xml +++ b/test/jaxp/javax/xml/jaxp/unittest/catalog/files/delegatecatalog.xml @@ -2,24 +2,24 @@ - - - - - + + - - - + - + - + diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java b/test/jdk/java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java index c11f0476bc74c..3dfdfd8b6b84d 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java @@ -51,7 +51,7 @@ /** * AWT Mixing test for HierarchyBoundsListener ancestors. - *

See CR6768230 for details. + *

See CR6768230 for details. */ /* * @test diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java b/test/jdk/java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java index 843b4e8832fa6..5331fb11d39e2 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -35,8 +35,8 @@ /** * AWT/Swing overlapping test with JInternalFrame being put in GlassPane. - * See JDK-6637655 and - * JDK-6985776. + * See JDK-6637655 and + * JDK-6985776. *

See base class for details. */ /* diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java b/test/jdk/java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java index 4c917485e1d3c..5ac719d70a8e4 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -36,8 +36,8 @@ /** * AWT/Swing overlapping test with JInternalFrame being moved in GlassPane. - * See JDK-6637655 and - * JDK-6981919. + * See JDK-6637655 and + * JDK-6981919. *

See base class for details. */ /* diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java b/test/jdk/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java index 1d827ce569fa1..39a59dc2a5c2a 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -30,7 +30,7 @@ /** * AWT/Swing overlapping test for Panel and JPanel behavior during resizing. - *

See JDK-6786219 for details + *

See JDK-6786219 for details */ /* * @test diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java b/test/jdk/java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java index 8587454f301a9..4975cc165c294 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -37,7 +37,7 @@ /** * AWT/Swing overlapping test for opaque Swing components. *

This test verify if AWT components are drawn correctly under opaque components. - *

See JDK-6776743 for details + *

See JDK-6776743 for details *

See base class for test info. */ /* diff --git a/test/jdk/java/awt/Toolkit/Headless/HeadlessToolkit.java b/test/jdk/java/awt/Toolkit/Headless/HeadlessToolkit.java index 0076bdb2067d1..87970aab10a25 100644 --- a/test/jdk/java/awt/Toolkit/Headless/HeadlessToolkit.java +++ b/test/jdk/java/awt/Toolkit/Headless/HeadlessToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -277,10 +277,10 @@ void doTest() throws IOException { } - im = tk.getImage(new URL("http://openjdk.java.net/images/openjdk.png")); + im = tk.getImage(new URL("https://openjdk.org/images/openjdk.png")); im.flush(); - im = tk.createImage(new URL("http://openjdk.java.net/images/openjdk.png")); + im = tk.createImage(new URL("https://openjdk.org/images/openjdk.png")); im.flush(); MemoryImageSource mis; diff --git a/test/jdk/java/net/InetAddress/IsReachableViaLoopbackTest.java b/test/jdk/java/net/InetAddress/IsReachableViaLoopbackTest.java index 5364ba7895ec1..4d340a72fba21 100644 --- a/test/jdk/java/net/InetAddress/IsReachableViaLoopbackTest.java +++ b/test/jdk/java/net/InetAddress/IsReachableViaLoopbackTest.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2015, 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. + */ + import java.io.*; import java.net.*; import java.util.*; @@ -13,7 +36,7 @@ public class IsReachableViaLoopbackTest { public static void main(String[] args) { try { InetAddress addr = InetAddress.getByName("localhost"); - InetAddress remoteAddr = InetAddress.getByName("bugs.openjdk.java.net"); + InetAddress remoteAddr = InetAddress.getByName("bugs.openjdk.org"); if (!addr.isReachable(10000)) throw new RuntimeException("Localhost should always be reachable"); NetworkInterface inf = NetworkInterface.getByInetAddress(addr); diff --git a/test/jdk/java/net/httpclient/offline/OfflineTesting.java b/test/jdk/java/net/httpclient/offline/OfflineTesting.java index d33f806d31c9e..c747f5b2b88c8 100644 --- a/test/jdk/java/net/httpclient/offline/OfflineTesting.java +++ b/test/jdk/java/net/httpclient/offline/OfflineTesting.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 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 @@ -66,7 +66,7 @@ public void testResponseAsString() { HttpClient client = getClient(); HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create("http://openjdk.java.net/")) + .uri(URI.create("https://openjdk.org/")) .build(); client.sendAsync(request, BodyHandlers.ofString()) @@ -83,7 +83,7 @@ public void testResponseAsByteArray() { HttpClient client = getClient(); HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create("http://openjdk.java.net/")) + .uri(URI.create("https://openjdk.org/")) .build(); client.sendAsync(request, BodyHandlers.ofByteArray()) @@ -115,7 +115,7 @@ public void testFileNotFound() { ""); HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create("http://openjdk.java.net/notFound")) + .uri(URI.create("https://openjdk.org/notFound")) .build(); client.sendAsync(request, BodyHandlers.ofString()) @@ -136,7 +136,7 @@ public void testEcho() { headersOf("Connection", "keep-alive")); HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create("http://openjdk.java.net/echo")) + .uri(URI.create("https://openjdk.org/echo")) .POST(BodyPublishers.ofString("Hello World")) .build(); @@ -156,7 +156,7 @@ public void testEchoBlocking() throws IOException, InterruptedException { headersOf("Connection", "keep-alive")); HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create("http://openjdk.java.net/echo")) + .uri(URI.create("https://openjdk.org/echo")) .POST(BodyPublishers.ofString("Hello chegar!!")) .build(); diff --git a/test/jdk/java/util/Base64/TestBase64.java b/test/jdk/java/util/Base64/TestBase64.java index e360a2c584d2b..81d2aa8580656 100644 --- a/test/jdk/java/util/Base64/TestBase64.java +++ b/test/jdk/java/util/Base64/TestBase64.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -146,7 +146,7 @@ public static void main(String args[]) throws Throwable { testDecoderKeepsAbstinence(Base64.getMimeDecoder()); // tests patch addressing JDK-8222187 - // https://bugs.openjdk.java.net/browse/JDK-8222187 + // https://bugs.openjdk.org/browse/JDK-8222187 testJDK_8222187(); } diff --git a/test/jdk/java/util/concurrent/locks/LockSupport/ParkLoops.java b/test/jdk/java/util/concurrent/locks/LockSupport/ParkLoops.java index dc20490655157..8ae162d674d90 100644 --- a/test/jdk/java/util/concurrent/locks/LockSupport/ParkLoops.java +++ b/test/jdk/java/util/concurrent/locks/LockSupport/ParkLoops.java @@ -53,7 +53,7 @@ public final class ParkLoops { static class Parker implements Runnable { static { // Reduce the risk of rare disastrous classloading in first call to - // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773 + // LockSupport.park: https://bugs.openjdk.org/browse/JDK-8074773 Class ensureLoaded = LockSupport.class; } @@ -84,7 +84,7 @@ public void run() { static class Unparker implements Runnable { static { // Reduce the risk of rare disastrous classloading in first call to - // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773 + // LockSupport.park: https://bugs.openjdk.org/browse/JDK-8074773 Class ensureLoaded = LockSupport.class; } diff --git a/test/jdk/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java b/test/jdk/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java index 58e4a32143bd7..62041e1d88763 100644 --- a/test/jdk/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java +++ b/test/jdk/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java @@ -941,7 +941,7 @@ void runAsync(Runnable r1, Runnable r2) { /** * Non-traversing Deque operations are linearizable. - * https://bugs.openjdk.java.net/browse/JDK-8188900 + * https://bugs.openjdk.org/browse/JDK-8188900 * ant -Djsr166.expensiveTests=true -Djsr166.tckTestClass=ConcurrentLinkedDequeTest -Djsr166.methodFilter=testBug8188900 tck */ public void testBug8188900() { @@ -998,7 +998,7 @@ public void testBug8188900_reverse() { /** * Non-traversing Deque operations (that return null) are linearizable. * Don't return null when the deque is observably never empty. - * https://bugs.openjdk.java.net/browse/JDK-8189387 + * https://bugs.openjdk.org/browse/JDK-8189387 * ant -Djsr166.expensiveTests=true -Djsr166.tckTestClass=ConcurrentLinkedDequeTest -Djsr166.methodFilter=testBug8189387 tck */ public void testBug8189387() { diff --git a/test/jdk/java/util/concurrent/tck/JSR166TestCase.java b/test/jdk/java/util/concurrent/tck/JSR166TestCase.java index 2cfa99866c573..43e8cfe94272c 100644 --- a/test/jdk/java/util/concurrent/tck/JSR166TestCase.java +++ b/test/jdk/java/util/concurrent/tck/JSR166TestCase.java @@ -309,7 +309,7 @@ private static float systemPropertyValue(String name) { * May be initialized from any of: * - the "jsr166.delay.factor" system property * - the "test.timeout.factor" system property (as used by jtreg) - * See: http://openjdk.java.net/jtreg/tag-spec.html + * See: https://openjdk.org/jtreg/tag-spec.html * - hard-coded fuzz factor when using a known slowpoke VM */ private static final float delayFactor = delayFactor(); @@ -776,7 +776,7 @@ T chooseRandomly(T... choices) { * Returns the shortest timed delay. This can be scaled up for * slow machines using the jsr166.delay.factor system property, * or via jtreg's -timeoutFactor: flag. - * http://openjdk.java.net/jtreg/command-help.html + * https://openjdk.org/jtreg/command-help.html */ protected long getShortDelay() { return (long) (50 * delayFactor); diff --git a/test/jdk/java/util/concurrent/tck/LockSupportTest.java b/test/jdk/java/util/concurrent/tck/LockSupportTest.java index 653e3591f7f93..1010ef0f77aa6 100644 --- a/test/jdk/java/util/concurrent/tck/LockSupportTest.java +++ b/test/jdk/java/util/concurrent/tck/LockSupportTest.java @@ -54,7 +54,7 @@ public static Test suite() { static { // Reduce the risk of rare disastrous classloading in first call to - // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773 + // LockSupport.park: https://bugs.openjdk.org/browse/JDK-8074773 Class ensureLoaded = LockSupport.class; } diff --git a/test/jdk/java/util/concurrent/tck/MapTest.java b/test/jdk/java/util/concurrent/tck/MapTest.java index 61579f3e7c378..8f3a2bc418253 100644 --- a/test/jdk/java/util/concurrent/tck/MapTest.java +++ b/test/jdk/java/util/concurrent/tck/MapTest.java @@ -121,7 +121,7 @@ public void testImplSanity() { /** * Tests and extends the scenario reported in - * https://bugs.openjdk.java.net/browse/JDK-8186171 + * https://bugs.openjdk.org/browse/JDK-8186171 * HashMap: Entry.setValue may not work after Iterator.remove() called for previous entries * ant -Djsr166.tckTestClass=HashMapTest -Djsr166.methodFilter=testBug8186171 -Djsr166.runsPerTest=1000 tck */ diff --git a/test/jdk/java/util/concurrent/tck/ScheduledExecutorTest.java b/test/jdk/java/util/concurrent/tck/ScheduledExecutorTest.java index c100ea0e8f04b..26510b3bfdd16 100644 --- a/test/jdk/java/util/concurrent/tck/ScheduledExecutorTest.java +++ b/test/jdk/java/util/concurrent/tck/ScheduledExecutorTest.java @@ -1337,7 +1337,7 @@ public String realCall() { /** * A fixed delay task with overflowing period should not prevent a * one-shot task from executing. - * https://bugs.openjdk.java.net/browse/JDK-8051859 + * https://bugs.openjdk.org/browse/JDK-8051859 */ @SuppressWarnings("FutureReturnValueIgnored") public void testScheduleWithFixedDelay_overflow() throws Exception { diff --git a/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java b/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java index 4116d69620e83..f39b46b43d138 100644 --- a/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java +++ b/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -206,7 +206,7 @@ public static void main(String[] args) throws Exception { // If we don't initialize LogManager here, there will be // a deadlock. - // See + // See // for more details. Logger.getLogger("main").info("starting..."); try { diff --git a/test/jdk/javax/xml/jaxp/testng/parse/EntityCharacterEventOrder.java b/test/jdk/javax/xml/jaxp/testng/parse/EntityCharacterEventOrder.java index 5a5f57baa9b8b..313fa29a97434 100644 --- a/test/jdk/javax/xml/jaxp/testng/parse/EntityCharacterEventOrder.java +++ b/test/jdk/javax/xml/jaxp/testng/parse/EntityCharacterEventOrder.java @@ -16,7 +16,7 @@ /** * JDK-6770436: Entity callback order differs between Java1.5 and Java1.6 - * https://bugs.openjdk.java.net/browse/JDK-6770436 + * https://bugs.openjdk.org/browse/JDK-6770436 * */ diff --git a/test/jdk/javax/xml/jaxp/testng/parse/XMLEntityScannerLoad.java b/test/jdk/javax/xml/jaxp/testng/parse/XMLEntityScannerLoad.java index 36abd0c1458d8..308f17382fcf8 100644 --- a/test/jdk/javax/xml/jaxp/testng/parse/XMLEntityScannerLoad.java +++ b/test/jdk/javax/xml/jaxp/testng/parse/XMLEntityScannerLoad.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2014, 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. + */ + package parse; import java.io.ByteArrayInputStream; @@ -13,11 +36,11 @@ /** * JDK-8059327: XML parser returns corrupt attribute value - * https://bugs.openjdk.java.net/browse/JDK-8059327 + * https://bugs.openjdk.org/browse/JDK-8059327 * * Also: * JDK-8061550: XMLEntityScanner can corrupt corrupt content during parsing - * https://bugs.openjdk.java.net/browse/JDK-8061550 + * https://bugs.openjdk.org/browse/JDK-8061550 * * @Summary: verify that the character cache in XMLEntityScanner is reset properly */ diff --git a/test/jdk/javax/xml/jaxp/testng/parse/jdk7156085/UTF8ReaderBug.java b/test/jdk/javax/xml/jaxp/testng/parse/jdk7156085/UTF8ReaderBug.java index 993fc61b87992..587d36e921f9b 100644 --- a/test/jdk/javax/xml/jaxp/testng/parse/jdk7156085/UTF8ReaderBug.java +++ b/test/jdk/javax/xml/jaxp/testng/parse/jdk7156085/UTF8ReaderBug.java @@ -33,7 +33,7 @@ /** * JDK-7156085: ArrayIndexOutOfBoundsException throws in UTF8Reader of SAXParser - * https://bugs.openjdk.java.net/browse/JDK-7156085 + * https://bugs.openjdk.org/browse/JDK-7156085 * * XERCESJ-1257: buffer overflow in UTF8Reader for characters out of BMP * https://issues.apache.org/jira/browse/XERCESJ-1257 diff --git a/test/jdk/sanity/client/lib/Extensions/src/org/jtregext/GuiTestListener.java b/test/jdk/sanity/client/lib/Extensions/src/org/jtregext/GuiTestListener.java index 407fd52d292c6..751551fc25b23 100644 --- a/test/jdk/sanity/client/lib/Extensions/src/org/jtregext/GuiTestListener.java +++ b/test/jdk/sanity/client/lib/Extensions/src/org/jtregext/GuiTestListener.java @@ -1,7 +1,7 @@ package org.jtregext; /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -30,7 +30,7 @@ import org.testng.ITestListener; import org.testng.ITestResult; -// TODO: Remove this once https://bugs.openjdk.java.net/browse/JDK-8151671 is fixed +// TODO: Remove this once https://bugs.openjdk.org/browse/JDK-8151671 is fixed public class GuiTestListener implements ITestListener { private void afterTest() { diff --git a/test/jdk/sanity/client/lib/SwingSet2/README b/test/jdk/sanity/client/lib/SwingSet2/README index 2016753dd7d19..87d7ec5e58830 100644 --- a/test/jdk/sanity/client/lib/SwingSet2/README +++ b/test/jdk/sanity/client/lib/SwingSet2/README @@ -1,4 +1,4 @@ -The content of this src folder was originally taken from openjdk SwingSet2 demo: http://hg.openjdk.java.net/jdk/jdk/file/2d5d75263e77/src/demo/share/jfc/SwingSet2. +The content of this src folder was originally taken from openjdk SwingSet2 demo: https://git.openjdk.org/jdk/tree/92ec4c5/src/demo/share/jfc/SwingSet2. Then it was modified to increase testability and removed extra content and extra dependencies. This is NOT the official location of the SwingSet2 demo. \ No newline at end of file diff --git a/test/jdk/sanity/client/lib/jemmy/README b/test/jdk/sanity/client/lib/jemmy/README index 629e529220075..98fdcf650f2a4 100644 --- a/test/jdk/sanity/client/lib/jemmy/README +++ b/test/jdk/sanity/client/lib/jemmy/README @@ -1,3 +1,3 @@ -This src folder contains a copy of Jemmy 2 library sources from http://hg.openjdk.java.net/code-tools/jemmy/v2 +This src folder contains a copy of Jemmy 2 library sources from https://git.openjdk.org/jemmy-v2 If a change to Jemmy library is needed, please first suggest it to that repository. diff --git a/test/jdk/sun/security/ssl/ServerHandshaker/HelloExtensionsTest.java b/test/jdk/sun/security/ssl/ServerHandshaker/HelloExtensionsTest.java index bb84d5f01f924..392e882a19ae5 100644 --- a/test/jdk/sun/security/ssl/ServerHandshaker/HelloExtensionsTest.java +++ b/test/jdk/sun/security/ssl/ServerHandshaker/HelloExtensionsTest.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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -121,7 +121,7 @@ SHA256withECDSA, SHA256withRSA, Unknown (hash:0x3, signature:0x3), Unknown (hash:0x3, signature:0x1), SHA1withECDSA, SHA1withRSA, SHA1withDSA Extension server_name, server_name: - [host_name: bugs.openjdk.java.net] + [host_name: bugs.openjdk.org] */ String hello = "16030300df010000db03035898b7826c8c0cc" + diff --git a/test/jdk/tools/jpackage/run_tests.sh b/test/jdk/tools/jpackage/run_tests.sh index 2639f38cd6816..55e46fc7e3488 100644 --- a/test/jdk/tools/jpackage/run_tests.sh +++ b/test/jdk/tools/jpackage/run_tests.sh @@ -29,7 +29,7 @@ # Fail fast set -e; set -o pipefail; -# $JT_BUNDLE_URL (Link can be obtained from https://openjdk.java.net/jtreg/ page) +# $JT_BUNDLE_URL (Link can be obtained from https://openjdk.org/jtreg/ page) jtreg_bundle=$JT_BUNDLE_URL workdir=/tmp/jpackage_jtreg_testing jtreg_jar=$workdir/jtreg/lib/jtreg.jar @@ -231,7 +231,7 @@ fi if [ -z "$JT_HOME" ]; then if [ -z "$JT_BUNDLE_URL" ]; then - fatal 'JT_HOME or JT_BUNDLE_URL environment variable is not set. Link to JTREG bundle can be found at https://openjdk.java.net/jtreg/'. + fatal 'JT_HOME or JT_BUNDLE_URL environment variable is not set. Link to JTREG bundle can be found at https://openjdk.org/jtreg/'. fi fi diff --git a/test/langtools/jdk/javadoc/doclet/testModules/TestModulePackages.java b/test/langtools/jdk/javadoc/doclet/testModules/TestModulePackages.java index 59ab70c810485..b2353809c8e69 100644 --- a/test/langtools/jdk/javadoc/doclet/testModules/TestModulePackages.java +++ b/test/langtools/jdk/javadoc/doclet/testModules/TestModulePackages.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -57,7 +57,7 @@ public TestModulePackages() { tb = new ToolBox(); } - // @Test: See: https://bugs.openjdk.java.net/browse/JDK-8193107 + // @Test: See: https://bugs.openjdk.org/browse/JDK-8193107 public void empty(Path base) throws Exception { Path src = base.resolve("src"); new ModuleBuilder(tb, "m") diff --git a/test/langtools/tools/javac/MethodParameters/LambdaTest.java b/test/langtools/tools/javac/MethodParameters/LambdaTest.java index 66ec67c7fa4e2..0326888b6e6a2 100644 --- a/test/langtools/tools/javac/MethodParameters/LambdaTest.java +++ b/test/langtools/tools/javac/MethodParameters/LambdaTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -32,7 +32,7 @@ */ /** - * Post https://bugs.openjdk.java.net/browse/JDK-8138729, this test verifies + * Post https://bugs.openjdk.org/browse/JDK-8138729, this test verifies * that MethodParameters attribute are NOT emitted for lambdas. */ class LambdaTest { diff --git a/test/langtools/tools/javac/MethodParameters/LegacyOutputTest/LegacyOutputTest.java b/test/langtools/tools/javac/MethodParameters/LegacyOutputTest/LegacyOutputTest.java index 49a54d0a42b8f..759fd90baefa6 100644 --- a/test/langtools/tools/javac/MethodParameters/LegacyOutputTest/LegacyOutputTest.java +++ b/test/langtools/tools/javac/MethodParameters/LegacyOutputTest/LegacyOutputTest.java @@ -48,7 +48,7 @@ import javax.tools.ToolProvider; /** - * Post https://bugs.openjdk.java.net/browse/JDK-8190452, the test verifies that MethodParameters + * Post https://bugs.openjdk.org/browse/JDK-8190452, the test verifies that MethodParameters * attributes are not emitted when targeting --release < 8. */ public class LegacyOutputTest { diff --git a/test/langtools/tools/javac/api/ToolProvider/ToolProviderTest.java b/test/langtools/tools/javac/api/ToolProvider/ToolProviderTest.java index ceedbcb50e5bb..a212cd9a5c6e6 100644 --- a/test/langtools/tools/javac/api/ToolProvider/ToolProviderTest.java +++ b/test/langtools/tools/javac/api/ToolProvider/ToolProviderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -41,7 +41,7 @@ public class ToolProviderTest { public static void main(String... args) { // The following code allows the test to be skipped when run on // an exploded image. - // See https://bugs.openjdk.java.net/browse/JDK-8155858 + // See https://bugs.openjdk.org/browse/JDK-8155858 Path javaHome = Paths.get(System.getProperty("java.home")); Path image = javaHome.resolve("lib").resolve("modules"); Path modules = javaHome.resolve("modules"); diff --git a/test/langtools/tools/javac/lambda/MethodReferenceGenericTarget.java b/test/langtools/tools/javac/lambda/MethodReferenceGenericTarget.java index 2683d32e840de..3f20fe6c79207 100644 --- a/test/langtools/tools/javac/lambda/MethodReferenceGenericTarget.java +++ b/test/langtools/tools/javac/lambda/MethodReferenceGenericTarget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -59,7 +59,7 @@ class E { } } -// snippet from https://bugs.openjdk.java.net/browse/JDK-8065303 +// snippet from https://bugs.openjdk.org/browse/JDK-8065303 class MethodReferenceTestPrivateTypeConversion { class MethodReferenceTestTypeConversion_E { From 22c205d3f1f342306fd391197c005a39a812cd20 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 07:23:54 +0000 Subject: [PATCH 237/846] 8295670: Remove duplication in java/util/Formatter/Basic*.java Reviewed-by: mbaesken Backport-of: f84b0ad07c73c305d21c71ec6b8195dc1ee31a3e --- .../java/util/Formatter/Basic-X.java.template | 97 - test/jdk/java/util/Formatter/Basic.java | 109 +- .../java/util/Formatter/BasicBigDecimal.java | 1849 ++++------------- .../java/util/Formatter/BasicBigInteger.java | 1609 +------------- .../jdk/java/util/Formatter/BasicBoolean.java | 1548 +------------- .../util/Formatter/BasicBooleanObject.java | 1548 +------------- test/jdk/java/util/Formatter/BasicByte.java | 1497 +------------ .../java/util/Formatter/BasicByteObject.java | 1556 +------------- test/jdk/java/util/Formatter/BasicChar.java | 1548 +------------- .../java/util/Formatter/BasicCharObject.java | 1548 +------------- .../java/util/Formatter/BasicDateTime.java | 1550 +------------- test/jdk/java/util/Formatter/BasicDouble.java | 1710 +++------------ .../util/Formatter/BasicDoubleObject.java | 1730 +++------------ test/jdk/java/util/Formatter/BasicFloat.java | 1193 +---------- .../java/util/Formatter/BasicFloatObject.java | 1716 ++------------- test/jdk/java/util/Formatter/BasicInt.java | 1485 +------------ .../java/util/Formatter/BasicIntObject.java | 1556 +------------- test/jdk/java/util/Formatter/BasicLong.java | 1485 +------------ .../java/util/Formatter/BasicLongObject.java | 1556 +------------- test/jdk/java/util/Formatter/BasicShort.java | 1445 +------------ .../java/util/Formatter/BasicShortObject.java | 1556 +------------- test/jdk/java/util/Formatter/genBasic.sh | 2 +- 22 files changed, 1758 insertions(+), 28135 deletions(-) diff --git a/test/jdk/java/util/Formatter/Basic-X.java.template b/test/jdk/java/util/Formatter/Basic-X.java.template index 599a3621b5984..9976badac22a1 100644 --- a/test/jdk/java/util/Formatter/Basic-X.java.template +++ b/test/jdk/java/util/Formatter/Basic-X.java.template @@ -43,103 +43,6 @@ import java.util.regex.Pattern; #end[datetime] public class Basic$Type$ extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - #if[datetime] private static void testDateTime(String fs, String exp, Calendar c) { testDateTime(fs, exp, c, true); diff --git a/test/jdk/java/util/Formatter/Basic.java b/test/jdk/java/util/Formatter/Basic.java index 099ff13b39dde..af8814328d235 100644 --- a/test/jdk/java/util/Formatter/Basic.java +++ b/test/jdk/java/util/Formatter/Basic.java @@ -21,18 +21,119 @@ * questions. */ +import java.io.*; +import java.util.Formatter; +import java.util.Locale; + public class Basic { private static int fail = 0; + private static int pass = 0; private static Throwable first; - static void pass() { + protected static void test(String fs, String exp, Object ... args) { + Formatter f = new Formatter(new StringBuilder(), Locale.US); + f.format(fs, args); + ck(fs, exp, f.toString()); + + f = new Formatter(new StringBuilder(), Locale.US); + f.format("foo " + fs + " bar", args); + ck(fs, "foo " + exp + " bar", f.toString()); + } + + protected static void test(Locale l, String fs, String exp, Object ... args) + { + Formatter f = new Formatter(new StringBuilder(), l); + f.format(fs, args); + ck(fs, exp, f.toString()); + + f = new Formatter(new StringBuilder(), l); + f.format("foo " + fs + " bar", args); + ck(fs, "foo " + exp + " bar", f.toString()); + } + + protected static void test(String fs, Object ... args) { + Formatter f = new Formatter(new StringBuilder(), Locale.US); + f.format(fs, args); + ck(fs, "fail", f.toString()); + } + + protected static void test(String fs) { + Formatter f = new Formatter(new StringBuilder(), Locale.US); + f.format(fs, "fail"); + ck(fs, "fail", f.toString()); + } + + protected static void testSysOut(String fs, String exp, Object ... args) { + FileOutputStream fos = null; + FileInputStream fis = null; + try { + PrintStream saveOut = System.out; + fos = new FileOutputStream("testSysOut"); + System.setOut(new PrintStream(fos)); + System.out.format(Locale.US, fs, args); + fos.close(); + + fis = new FileInputStream("testSysOut"); + byte [] ba = new byte[exp.length()]; + int len = fis.read(ba); + String got = new String(ba); + if (len != ba.length) + fail(fs, exp, got); + ck(fs, exp, got); + + System.setOut(saveOut); + } catch (FileNotFoundException ex) { + fail(fs, ex.getClass()); + } catch (IOException ex) { + fail(fs, ex.getClass()); + } finally { + try { + if (fos != null) + fos.close(); + if (fis != null) + fis.close(); + } catch (IOException ex) { + fail(fs, ex.getClass()); + } + } + } + + protected static void tryCatch(String fs, Class ex) { + boolean caught = false; + try { + test(fs); + } catch (Throwable x) { + if (ex.isAssignableFrom(x.getClass())) + caught = true; + } + if (!caught) + fail(fs, ex); + else + pass(); + } + + protected static void tryCatch(String fs, Class ex, Object ... args) { + boolean caught = false; + try { + test(fs, args); + } catch (Throwable x) { + if (ex.isAssignableFrom(x.getClass())) + caught = true; + } + if (!caught) + fail(fs, ex); + else + pass(); + } + + private static void pass() { pass++; } - static void fail(String fs, Class ex) { + private static void fail(String fs, Class ex) { String message = "'%s': %s not thrown".formatted(fs, ex.getName()); if (first == null) { setFirst(message); @@ -41,7 +142,7 @@ static void fail(String fs, Class ex) { fail++; } - static void fail(String fs, String exp, String got) { + private static void fail(String fs, String exp, String got) { String message = "'%s': Expected '%s', got '%s'".formatted(fs, exp, got); if (first == null) { setFirst(message); @@ -58,7 +159,7 @@ private static void setFirst(String s) { } } - static void ck(String fs, String exp, String got) { + private static void ck(String fs, String exp, String got) { if (!exp.equals(got)) { fail(fs, exp, got); } else { diff --git a/test/jdk/java/util/Formatter/BasicBigDecimal.java b/test/jdk/java/util/Formatter/BasicBigDecimal.java index b2c42b8173347..51cd19141287b 100644 --- a/test/jdk/java/util/Formatter/BasicBigDecimal.java +++ b/test/jdk/java/util/Formatter/BasicBigDecimal.java @@ -38,215 +38,7 @@ import static java.util.Calendar.*; - - - - public class BasicBigDecimal extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static BigDecimal create(double v) { @@ -265,76 +57,6 @@ private static BigDecimal recip(BigDecimal v) { return BigDecimal.ONE.divide(v); } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static void test() { TimeZone.setDefault(TimeZone.getTimeZone("GMT-0800")); @@ -522,1152 +244,410 @@ public static void test() { + //--------------------------------------------------------------------- + // %s - BigDecimal + //--------------------------------------------------------------------- + BigDecimal one = BigDecimal.ONE; + BigDecimal ten = BigDecimal.TEN; + BigDecimal pi = new BigDecimal(Math.PI); + BigDecimal piToThe300 = pi.pow(300); + test("%s", "3.141592653589793115997963468544185161590576171875", pi); + //--------------------------------------------------------------------- + // flag/conversion errors + //--------------------------------------------------------------------- + tryCatch("%d", IllegalFormatConversionException.class, one); + tryCatch("%,.4e", FormatFlagsConversionMismatchException.class, one); + //--------------------------------------------------------------------- + // %e + // + // Floating-point conversions applicable to float, double, and + // BigDecimal. + //--------------------------------------------------------------------- + test("%e", "null", (Object)null); + //--------------------------------------------------------------------- + // %e - float and double + //--------------------------------------------------------------------- + // double PI = 3.141 592 653 589 793 238 46; + test("%e", "3.141593e+00", pi); + test("%.0e", "1e+01", ten); + test("%#.0e", "1.e+01", ten); + test("%E", "3.141593E+00", pi); + test("%10.3e", " 3.142e+00", pi); + test("%10.3e", "-3.142e+00", negate(pi)); + test("%010.3e", "03.142e+00", pi); + test("%010.3e", "-3.142e+00", negate(pi)); + test("%-12.3e", "3.142e+00 ", pi); + test("%-12.3e", "-3.142e+00 ", negate(pi)); + test("%.3e", "3.142e+00", pi); + test("%.3e", "-3.142e+00", negate(pi)); + test("%.3e", "3.142e+06", mult(pi, 1000000.0)); + test("%.3e", "-3.142e+06", mult(pi, -1000000.0)); + test(Locale.FRANCE, "%e", "3,141593e+00", pi); + // double PI^300 + // = 13962455701329742638131355433930076081862072808 ... e+149 + //--------------------------------------------------------------------- + // %e - BigDecimal + //--------------------------------------------------------------------- + test("%.3e", "1.396e+149", piToThe300); + test("%.3e", "-1.396e+149", piToThe300.negate()); + test("%.3e", "1.000e-100", recip(ten.pow(100))); + test("%.3e", "-1.000e-100", negate(recip(ten.pow(100)))); + test("%3.0e", "1e-06", new BigDecimal("0.000001")); + test("%3.0e", "1e-05", new BigDecimal("0.00001")); + test("%3.0e", "1e-04", new BigDecimal("0.0001")); + test("%3.0e", "1e-03", new BigDecimal("0.001")); + test("%3.0e", "1e-02", new BigDecimal("0.01")); + test("%3.0e", "1e-01", new BigDecimal("0.1")); + test("%3.0e", "9e-01", new BigDecimal("0.9")); + test("%3.1e", "9.0e-01", new BigDecimal("0.9")); + test("%3.0e", "1e+00", new BigDecimal("1.00")); + test("%3.0e", "1e+01", new BigDecimal("10.00")); + test("%3.0e", "1e+02", new BigDecimal("99.19")); + test("%3.1e", "9.9e+01", new BigDecimal("99.19")); + test("%3.0e", "1e+02", new BigDecimal("99.99")); + test("%3.0e", "1e+02", new BigDecimal("100.00")); + test("%#3.0e", "1.e+03", new BigDecimal("1000.00")); + test("%3.0e", "1e+04", new BigDecimal("10000.00")); + test("%3.0e", "1e+05", new BigDecimal("100000.00")); + test("%3.0e", "1e+06", new BigDecimal("1000000.00")); + test("%3.0e", "1e+07", new BigDecimal("10000000.00")); + test("%3.0e", "1e+08", new BigDecimal("100000000.00")); + test("%10.3e", " 1.000e+00", one); + test("%+.3e", "+3.142e+00", pi); + test("%+.3e", "-3.142e+00", negate(pi)); + test("% .3e", " 3.142e+00", pi); + test("% .3e", "-3.142e+00", negate(pi)); + test("%#.0e", "3.e+00", create(3.0)); + test("%#.0e", "-3.e+00", create(-3.0)); + test("%.0e", "3e+00", create(3.0)); + test("%.0e", "-3e+00", create(-3.0)); + test("%(.4e", "3.1416e+06", mult(pi, 1000000.0)); + test("%(.4e", "(3.1416e+06)", mult(pi, -1000000.0)); + //--------------------------------------------------------------------- + // %e - boundary problems + //--------------------------------------------------------------------- + test("%3.0e", "1e-06", 0.000001); + test("%3.0e", "1e-05", 0.00001); + test("%3.0e", "1e-04", 0.0001); + test("%3.0e", "1e-03", 0.001); + test("%3.0e", "1e-02", 0.01); + test("%3.0e", "1e-01", 0.1); + test("%3.0e", "9e-01", 0.9); + test("%3.1e", "9.0e-01", 0.9); + test("%3.0e", "1e+00", 1.00); + test("%3.0e", "1e+01", 10.00); + test("%3.0e", "1e+02", 99.19); + test("%3.1e", "9.9e+01", 99.19); + test("%3.0e", "1e+02", 99.99); + test("%3.0e", "1e+02", 100.00); + test("%#3.0e", "1.e+03", 1000.00); + test("%3.0e", "1e+04", 10000.00); + test("%3.0e", "1e+05", 100000.00); + test("%3.0e", "1e+06", 1000000.00); + test("%3.0e", "1e+07", 10000000.00); + test("%3.0e", "1e+08", 100000000.00); + //--------------------------------------------------------------------- + // %f + // + // Floating-point conversions applicable to float, double, and + // BigDecimal. + //--------------------------------------------------------------------- + test("%f", "null", (Object)null); + test("%f", "3.141593", pi); + test(Locale.FRANCE, "%f", "3,141593", pi); + test("%10.3f", " 3.142", pi); + test("%10.3f", " -3.142", negate(pi)); + test("%010.3f", "000003.142", pi); + test("%010.3f", "-00003.142", negate(pi)); + test("%-10.3f", "3.142 ", pi); + test("%-10.3f", "-3.142 ", negate(pi)); + test("%.3f", "3.142", pi); + test("%.3f", "-3.142", negate(pi)); + test("%+.3f", "+3.142", pi); + test("%+.3f", "-3.142", negate(pi)); + test("% .3f", " 3.142", pi); + test("% .3f", "-3.142", negate(pi)); + test("%#.0f", "3.", create(3.0)); + test("%#.0f", "-3.", create(-3.0)); + test("%.0f", "3", create(3.0)); + test("%.0f", "-3", create(-3.0)); + test("%.3f", "10.000", ten); + test("%.3f", "1.000", one); + test("%10.3f", " 1.000", one); + //--------------------------------------------------------------------- + // %f - boundary problems + //--------------------------------------------------------------------- + test("%3.0f", " 0", 0.000001); + test("%3.0f", " 0", 0.00001); + test("%3.0f", " 0", 0.0001); + test("%3.0f", " 0", 0.001); + test("%3.0f", " 0", 0.01); + test("%3.0f", " 0", 0.1); + test("%3.0f", " 1", 0.9); + test("%3.1f", "0.9", 0.9); + test("%3.0f", " 1", 1.00); + test("%3.0f", " 10", 10.00); + test("%3.0f", " 99", 99.19); + test("%3.1f", "99.2", 99.19); + test("%3.0f", "100", 99.99); + test("%3.0f", "100", 100.00); + test("%#3.0f", "1000.", 1000.00); + test("%3.0f", "10000", 10000.00); + test("%3.0f", "100000", 100000.00); + test("%3.0f", "1000000", 1000000.00); + test("%3.0f", "10000000", 10000000.00); + test("%3.0f", "100000000", 100000000.00); + test("%10.0f", " 1000000", 1000000.00); + test("%,10.0f", " 1,000,000", 1000000.00); + test("%,10.1f", "1,000,000.0", 1000000.00); + test("%,3.0f", "1,000,000", 1000000.00); + test("%,3.0f", "10,000,000", 10000000.00); + test("%,3.0f", "100,000,000", 100000000.00); + test("%,3.0f", "10,000,000", 10000000.00); + test("%,3.0f", "100,000,000", 100000000.00); + //--------------------------------------------------------------------- + // %f - BigDecimal + //--------------------------------------------------------------------- + test("%4.0f", " 99", new BigDecimal("99.19")); + test("%4.1f", "99.2", new BigDecimal("99.19")); + BigDecimal val = new BigDecimal("99.95"); + test("%4.0f", " 100", val); + test("%#4.0f", "100.", val); + test("%4.1f", "100.0", val); + test("%4.2f", "99.95", val); + test("%4.3f", "99.950", val); + val = new BigDecimal(".99"); + test("%4.1f", " 1.0", val); + test("%4.2f", "0.99", val); + test("%4.3f", "0.990", val); + // #6476425 + val = new BigDecimal("0.00001"); + test("%.0f", "0", val); + test("%.1f", "0.0", val); + test("%.2f", "0.00", val); + test("%.3f", "0.000", val); + test("%.4f", "0.0000", val); + test("%.5f", "0.00001", val); + val = new BigDecimal("1.00001"); + test("%.0f", "1", val); + test("%.1f", "1.0", val); + test("%.2f", "1.00", val); + test("%.3f", "1.000", val); + test("%.4f", "1.0000", val); + test("%.5f", "1.00001", val); + val = new BigDecimal("1.23456"); + test("%.0f", "1", val); + test("%.1f", "1.2", val); + test("%.2f", "1.23", val); + test("%.3f", "1.235", val); + test("%.4f", "1.2346", val); + test("%.5f", "1.23456", val); + test("%.6f", "1.234560", val); + val = new BigDecimal("9.99999"); + test("%.0f", "10", val); + test("%.1f", "10.0", val); + test("%.2f", "10.00", val); + test("%.3f", "10.000", val); + test("%.4f", "10.0000", val); + test("%.5f", "9.99999", val); + test("%.6f", "9.999990", val); + val = new BigDecimal("1.99999"); + test("%.0f", "2", val); + test("%.1f", "2.0", val); + test("%.2f", "2.00", val); + test("%.3f", "2.000", val); + test("%.4f", "2.0000", val); + test("%.5f", "1.99999", val); + test("%.6f", "1.999990", val); + val = new BigDecimal(0.9996); + test("%.0f", "1", val); + test("%.1f", "1.0", val); + test("%.2f", "1.00", val); + test("%.3f", "1.000", val); + test("%.4f", "0.9996", val); + test("%.5f", "0.99960", val); + test("%.6f", "0.999600", val); + val = new BigDecimal(BigInteger.ZERO, 6); + test("%.4f", "0.0000", val); + val = new BigDecimal(BigInteger.ZERO, -6); + test("%.4f", "0.0000", val); + //--------------------------------------------------------------------- + // %f - float, double, Double, BigDecimal + //--------------------------------------------------------------------- + test("%.3f", "3141592.654", mult(pi, 1000000.0)); + test("%.3f", "-3141592.654", mult(pi, -1000000.0)); + test("%,.4f", "3,141,592.6536", mult(pi, 1000000.0)); + test(Locale.FRANCE, "%,.4f", "3\u202f141\u202f592,6536", mult(pi, 1000000.0)); + test("%,.4f", "-3,141,592.6536", mult(pi, -1000000.0)); + test("%(.4f", "3141592.6536", mult(pi, 1000000.0)); + test("%(.4f", "(3141592.6536)", mult(pi, -1000000.0)); + test("%(,.4f", "3,141,592.6536", mult(pi, 1000000.0)); + test("%(,.4f", "(3,141,592.6536)", mult(pi, -1000000.0)); + //--------------------------------------------------------------------- + // %g + // + // Floating-point conversions applicable to float, double, and + // BigDecimal. + //--------------------------------------------------------------------- + test("%g", "null", (Object)null); + test("%g", "3.14159", pi); + test(Locale.FRANCE, "%g", "3,14159", pi); + test("%.0g", "1e+01", ten); + test("%G", "3.14159", pi); + test("%10.3g", " 3.14", pi); + test("%10.3g", " -3.14", negate(pi)); + test("%010.3g", "0000003.14", pi); + test("%010.3g", "-000003.14", negate(pi)); + test("%-12.3g", "3.14 ", pi); + test("%-12.3g", "-3.14 ", negate(pi)); + test("%.3g", "3.14", pi); + test("%.3g", "-3.14", negate(pi)); + test("%.3g", "3.14e+08", mult(pi, 100000000.0)); + test("%.3g", "-3.14e+08", mult(pi, -100000000.0)); + test("%.3g", "1.00e-05", recip(create(100000.0))); + test("%.3g", "-1.00e-05", recip(create(-100000.0))); + test("%.0g", "-1e-05", recip(create(-100000.0))); + test("%.0g", "1e+05", create(100000.0)); + test("%.3G", "1.00E-05", recip(create(100000.0))); + test("%.3G", "-1.00E-05", recip(create(-100000.0))); + test("%.1g", "-0", -0.0); + test("%3.0g", " -0", -0.0); + test("%.1g", "0", 0.0); + test("%3.0g", " 0", 0.0); + test("%.1g", "0", +0.0); + test("%3.0g", " 0", +0.0); + test("%3.0g", "1e-06", 0.000001); + test("%3.0g", "1e-05", 0.00001); + test("%3.0g", "1e-05", 0.0000099); + test("%3.1g", "1e-05", 0.0000099); + test("%3.2g", "9.9e-06", 0.0000099); + test("%3.0g", "0.0001", 0.0001); + test("%3.0g", "9e-05", 0.00009); + test("%3.0g", "0.0001", 0.000099); + test("%3.1g", "0.0001", 0.000099); + test("%3.2g", "9.9e-05", 0.000099); + test("%3.0g", "0.001", 0.001); + test("%3.0g", "0.001", 0.00099); + test("%3.1g", "0.001", 0.00099); + test("%3.2g", "0.00099", 0.00099); + test("%3.3g", "0.00100", 0.001); + test("%3.4g", "0.001000", 0.001); + test("%3.0g", "0.01", 0.01); + test("%3.0g", "0.1", 0.1); + test("%3.0g", "0.9", 0.9); + test("%3.1g", "0.9", 0.9); + test("%3.0g", " 1", 1.00); + test("%3.2g", " 10", 10.00); + test("%3.0g", "1e+01", 10.00); + test("%3.0g", "1e+02", 99.19); + test("%3.1g", "1e+02", 99.19); + test("%3.2g", " 99", 99.19); + test("%3.0g", "1e+02", 99.9); + test("%3.1g", "1e+02", 99.9); + test("%3.2g", "1.0e+02", 99.9); + test("%3.0g", "1e+02", 99.99); + test("%3.0g", "1e+02", 100.00); + test("%3.0g", "1e+03", 999.9); + test("%3.1g", "1e+03", 999.9); + test("%3.2g", "1.0e+03", 999.9); + test("%3.3g", "1.00e+03", 999.9); + test("%3.4g", "999.9", 999.9); + test("%3.4g", "1000", 999.99); + test("%3.0g", "1e+03", 1000.00); + test("%3.0g", "1e+04", 10000.00); + test("%3.0g", "1e+05", 100000.00); + test("%3.0g", "1e+06", 1000000.00); + test("%3.0g", "1e+07", 10000000.00); + test("%3.9g", "100000000", 100000000.00); + test("%3.10g", "100000000.0", 100000000.00); + tryCatch("%#3.0g", FormatFlagsConversionMismatchException.class, 1000.00); + // double PI^300 + // = 13962455701329742638131355433930076081862072808 ... e+149 + //--------------------------------------------------------------------- + // %g - BigDecimal + //--------------------------------------------------------------------- + test("%.3g", "1.40e+149", piToThe300); + test("%.3g", "-1.40e+149", piToThe300.negate()); + test(Locale.FRANCE, "%.3g", "-1,40e+149", piToThe300.negate()); + test("%.3g", "1.00e-100", recip(ten.pow(100))); + test("%.3g", "-1.00e-100", negate(recip(ten.pow(100)))); + test("%3.0g", "1e-06", new BigDecimal("0.000001")); + test("%3.0g", "1e-05", new BigDecimal("0.00001")); + test("%3.0g", "0.0001", new BigDecimal("0.0001")); + test("%3.0g", "0.001", new BigDecimal("0.001")); + test("%3.3g", "0.00100", new BigDecimal("0.001")); + test("%3.4g", "0.001000", new BigDecimal("0.001")); + test("%3.0g", "0.01", new BigDecimal("0.01")); + test("%3.0g", "0.1", new BigDecimal("0.1")); + test("%3.0g", "0.9", new BigDecimal("0.9")); + test("%3.1g", "0.9", new BigDecimal("0.9")); + test("%3.0g", " 1", new BigDecimal("1.00")); + test("%3.2g", " 10", new BigDecimal("10.00")); + test("%3.0g", "1e+01", new BigDecimal("10.00")); + test("%3.0g", "1e+02", new BigDecimal("99.19")); + test("%3.1g", "1e+02", new BigDecimal("99.19")); + test("%3.2g", " 99", new BigDecimal("99.19")); + test("%3.0g", "1e+02", new BigDecimal("99.99")); + test("%3.0g", "1e+02", new BigDecimal("100.00")); + test("%3.0g", "1e+03", new BigDecimal("1000.00")); + test("%3.0g", "1e+04", new BigDecimal("10000.00")); + test("%3.0g", "1e+05", new BigDecimal("100000.00")); + test("%3.0g", "1e+06", new BigDecimal("1000000.00")); + test("%3.0g", "1e+07", new BigDecimal("10000000.00")); + test("%3.9g", "100000000", new BigDecimal("100000000.00")); + test("%3.10g", "100000000.0", new BigDecimal("100000000.00")); + test("%.3g", "10.0", ten); + test("%.3g", "1.00", one); + test("%10.3g", " 1.00", one); + test("%+10.3g", " +3.14", pi); + test("%+10.3g", " -3.14", negate(pi)); + test("% .3g", " 3.14", pi); + test("% .3g", "-3.14", negate(pi)); + test("%.0g", "3", create(3.0)); + test("%.0g", "-3", create(-3.0)); + test("%(.4g", "3.142e+08", mult(pi, 100000000.0)); + test("%(.4g", "(3.142e+08)", mult(pi, -100000000.0)); + test("%,.11g", "3,141,592.6536", mult(pi, 1000000.0)); + test("%(,.11g", "(3,141,592.6536)", mult(pi, -1000000.0)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %s - BigDecimal - //--------------------------------------------------------------------- - BigDecimal one = BigDecimal.ONE; - BigDecimal ten = BigDecimal.TEN; - BigDecimal pi = new BigDecimal(Math.PI); - BigDecimal piToThe300 = pi.pow(300); - - test("%s", "3.141592653589793115997963468544185161590576171875", pi); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // flag/conversion errors - //--------------------------------------------------------------------- - tryCatch("%d", IllegalFormatConversionException.class, one); - tryCatch("%,.4e", FormatFlagsConversionMismatchException.class, one); - - //--------------------------------------------------------------------- - // %e - // - // Floating-point conversions applicable to float, double, and - // BigDecimal. - //--------------------------------------------------------------------- - test("%e", "null", (Object)null); - - //--------------------------------------------------------------------- - // %e - float and double - //--------------------------------------------------------------------- - // double PI = 3.141 592 653 589 793 238 46; - test("%e", "3.141593e+00", pi); - test("%.0e", "1e+01", ten); - test("%#.0e", "1.e+01", ten); - test("%E", "3.141593E+00", pi); - test("%10.3e", " 3.142e+00", pi); - test("%10.3e", "-3.142e+00", negate(pi)); - test("%010.3e", "03.142e+00", pi); - test("%010.3e", "-3.142e+00", negate(pi)); - test("%-12.3e", "3.142e+00 ", pi); - test("%-12.3e", "-3.142e+00 ", negate(pi)); - test("%.3e", "3.142e+00", pi); - test("%.3e", "-3.142e+00", negate(pi)); - test("%.3e", "3.142e+06", mult(pi, 1000000.0)); - test("%.3e", "-3.142e+06", mult(pi, -1000000.0)); - - test(Locale.FRANCE, "%e", "3,141593e+00", pi); - - // double PI^300 - // = 13962455701329742638131355433930076081862072808 ... e+149 - - //--------------------------------------------------------------------- - // %e - BigDecimal - //--------------------------------------------------------------------- - test("%.3e", "1.396e+149", piToThe300); - test("%.3e", "-1.396e+149", piToThe300.negate()); - test("%.3e", "1.000e-100", recip(ten.pow(100))); - test("%.3e", "-1.000e-100", negate(recip(ten.pow(100)))); - - test("%3.0e", "1e-06", new BigDecimal("0.000001")); - test("%3.0e", "1e-05", new BigDecimal("0.00001")); - test("%3.0e", "1e-04", new BigDecimal("0.0001")); - test("%3.0e", "1e-03", new BigDecimal("0.001")); - test("%3.0e", "1e-02", new BigDecimal("0.01")); - test("%3.0e", "1e-01", new BigDecimal("0.1")); - test("%3.0e", "9e-01", new BigDecimal("0.9")); - test("%3.1e", "9.0e-01", new BigDecimal("0.9")); - test("%3.0e", "1e+00", new BigDecimal("1.00")); - test("%3.0e", "1e+01", new BigDecimal("10.00")); - test("%3.0e", "1e+02", new BigDecimal("99.19")); - test("%3.1e", "9.9e+01", new BigDecimal("99.19")); - test("%3.0e", "1e+02", new BigDecimal("99.99")); - test("%3.0e", "1e+02", new BigDecimal("100.00")); - test("%#3.0e", "1.e+03", new BigDecimal("1000.00")); - test("%3.0e", "1e+04", new BigDecimal("10000.00")); - test("%3.0e", "1e+05", new BigDecimal("100000.00")); - test("%3.0e", "1e+06", new BigDecimal("1000000.00")); - test("%3.0e", "1e+07", new BigDecimal("10000000.00")); - test("%3.0e", "1e+08", new BigDecimal("100000000.00")); - - - test("%10.3e", " 1.000e+00", one); - test("%+.3e", "+3.142e+00", pi); - test("%+.3e", "-3.142e+00", negate(pi)); - test("% .3e", " 3.142e+00", pi); - test("% .3e", "-3.142e+00", negate(pi)); - test("%#.0e", "3.e+00", create(3.0)); - test("%#.0e", "-3.e+00", create(-3.0)); - test("%.0e", "3e+00", create(3.0)); - test("%.0e", "-3e+00", create(-3.0)); - - test("%(.4e", "3.1416e+06", mult(pi, 1000000.0)); - test("%(.4e", "(3.1416e+06)", mult(pi, -1000000.0)); - - //--------------------------------------------------------------------- - // %e - boundary problems - //--------------------------------------------------------------------- - test("%3.0e", "1e-06", 0.000001); - test("%3.0e", "1e-05", 0.00001); - test("%3.0e", "1e-04", 0.0001); - test("%3.0e", "1e-03", 0.001); - test("%3.0e", "1e-02", 0.01); - test("%3.0e", "1e-01", 0.1); - test("%3.0e", "9e-01", 0.9); - test("%3.1e", "9.0e-01", 0.9); - test("%3.0e", "1e+00", 1.00); - test("%3.0e", "1e+01", 10.00); - test("%3.0e", "1e+02", 99.19); - test("%3.1e", "9.9e+01", 99.19); - test("%3.0e", "1e+02", 99.99); - test("%3.0e", "1e+02", 100.00); - test("%#3.0e", "1.e+03", 1000.00); - test("%3.0e", "1e+04", 10000.00); - test("%3.0e", "1e+05", 100000.00); - test("%3.0e", "1e+06", 1000000.00); - test("%3.0e", "1e+07", 10000000.00); - test("%3.0e", "1e+08", 100000000.00); - - //--------------------------------------------------------------------- - // %f - // - // Floating-point conversions applicable to float, double, and - // BigDecimal. - //--------------------------------------------------------------------- - test("%f", "null", (Object)null); - test("%f", "3.141593", pi); - test(Locale.FRANCE, "%f", "3,141593", pi); - test("%10.3f", " 3.142", pi); - test("%10.3f", " -3.142", negate(pi)); - test("%010.3f", "000003.142", pi); - test("%010.3f", "-00003.142", negate(pi)); - test("%-10.3f", "3.142 ", pi); - test("%-10.3f", "-3.142 ", negate(pi)); - test("%.3f", "3.142", pi); - test("%.3f", "-3.142", negate(pi)); - test("%+.3f", "+3.142", pi); - test("%+.3f", "-3.142", negate(pi)); - test("% .3f", " 3.142", pi); - test("% .3f", "-3.142", negate(pi)); - test("%#.0f", "3.", create(3.0)); - test("%#.0f", "-3.", create(-3.0)); - test("%.0f", "3", create(3.0)); - test("%.0f", "-3", create(-3.0)); - test("%.3f", "10.000", ten); - test("%.3f", "1.000", one); - test("%10.3f", " 1.000", one); - - //--------------------------------------------------------------------- - // %f - boundary problems - //--------------------------------------------------------------------- - test("%3.0f", " 0", 0.000001); - test("%3.0f", " 0", 0.00001); - test("%3.0f", " 0", 0.0001); - test("%3.0f", " 0", 0.001); - test("%3.0f", " 0", 0.01); - test("%3.0f", " 0", 0.1); - test("%3.0f", " 1", 0.9); - test("%3.1f", "0.9", 0.9); - test("%3.0f", " 1", 1.00); - test("%3.0f", " 10", 10.00); - test("%3.0f", " 99", 99.19); - test("%3.1f", "99.2", 99.19); - test("%3.0f", "100", 99.99); - test("%3.0f", "100", 100.00); - test("%#3.0f", "1000.", 1000.00); - test("%3.0f", "10000", 10000.00); - test("%3.0f", "100000", 100000.00); - test("%3.0f", "1000000", 1000000.00); - test("%3.0f", "10000000", 10000000.00); - test("%3.0f", "100000000", 100000000.00); - test("%10.0f", " 1000000", 1000000.00); - test("%,10.0f", " 1,000,000", 1000000.00); - test("%,10.1f", "1,000,000.0", 1000000.00); - test("%,3.0f", "1,000,000", 1000000.00); - test("%,3.0f", "10,000,000", 10000000.00); - test("%,3.0f", "100,000,000", 100000000.00); - test("%,3.0f", "10,000,000", 10000000.00); - test("%,3.0f", "100,000,000", 100000000.00); - - //--------------------------------------------------------------------- - // %f - BigDecimal - //--------------------------------------------------------------------- - test("%4.0f", " 99", new BigDecimal("99.19")); - test("%4.1f", "99.2", new BigDecimal("99.19")); - - BigDecimal val = new BigDecimal("99.95"); - test("%4.0f", " 100", val); - test("%#4.0f", "100.", val); - test("%4.1f", "100.0", val); - test("%4.2f", "99.95", val); - test("%4.3f", "99.950", val); - - val = new BigDecimal(".99"); - test("%4.1f", " 1.0", val); - test("%4.2f", "0.99", val); - test("%4.3f", "0.990", val); - - // #6476425 - val = new BigDecimal("0.00001"); - test("%.0f", "0", val); - test("%.1f", "0.0", val); - test("%.2f", "0.00", val); - test("%.3f", "0.000", val); - test("%.4f", "0.0000", val); - test("%.5f", "0.00001", val); - - val = new BigDecimal("1.00001"); - test("%.0f", "1", val); - test("%.1f", "1.0", val); - test("%.2f", "1.00", val); - test("%.3f", "1.000", val); - test("%.4f", "1.0000", val); - test("%.5f", "1.00001", val); - - val = new BigDecimal("1.23456"); - test("%.0f", "1", val); - test("%.1f", "1.2", val); - test("%.2f", "1.23", val); - test("%.3f", "1.235", val); - test("%.4f", "1.2346", val); - test("%.5f", "1.23456", val); - test("%.6f", "1.234560", val); - - val = new BigDecimal("9.99999"); - test("%.0f", "10", val); - test("%.1f", "10.0", val); - test("%.2f", "10.00", val); - test("%.3f", "10.000", val); - test("%.4f", "10.0000", val); - test("%.5f", "9.99999", val); - test("%.6f", "9.999990", val); - - - val = new BigDecimal("1.99999"); - test("%.0f", "2", val); - test("%.1f", "2.0", val); - test("%.2f", "2.00", val); - test("%.3f", "2.000", val); - test("%.4f", "2.0000", val); - test("%.5f", "1.99999", val); - test("%.6f", "1.999990", val); - - val = new BigDecimal(0.9996); - test("%.0f", "1", val); - test("%.1f", "1.0", val); - test("%.2f", "1.00", val); - test("%.3f", "1.000", val); - test("%.4f", "0.9996", val); - test("%.5f", "0.99960", val); - test("%.6f", "0.999600", val); - - val = new BigDecimal(BigInteger.ZERO, 6); - test("%.4f", "0.0000", val); - val = new BigDecimal(BigInteger.ZERO, -6); - test("%.4f", "0.0000", val); - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %f - float, double, Double, BigDecimal - //--------------------------------------------------------------------- - test("%.3f", "3141592.654", mult(pi, 1000000.0)); - test("%.3f", "-3141592.654", mult(pi, -1000000.0)); - test("%,.4f", "3,141,592.6536", mult(pi, 1000000.0)); - test(Locale.FRANCE, "%,.4f", "3\u202f141\u202f592,6536", mult(pi, 1000000.0)); - test("%,.4f", "-3,141,592.6536", mult(pi, -1000000.0)); - test("%(.4f", "3141592.6536", mult(pi, 1000000.0)); - test("%(.4f", "(3141592.6536)", mult(pi, -1000000.0)); - test("%(,.4f", "3,141,592.6536", mult(pi, 1000000.0)); - test("%(,.4f", "(3,141,592.6536)", mult(pi, -1000000.0)); - - - - - //--------------------------------------------------------------------- - // %g - // - // Floating-point conversions applicable to float, double, and - // BigDecimal. - //--------------------------------------------------------------------- - test("%g", "null", (Object)null); - test("%g", "3.14159", pi); - test(Locale.FRANCE, "%g", "3,14159", pi); - test("%.0g", "1e+01", ten); - test("%G", "3.14159", pi); - test("%10.3g", " 3.14", pi); - test("%10.3g", " -3.14", negate(pi)); - test("%010.3g", "0000003.14", pi); - test("%010.3g", "-000003.14", negate(pi)); - test("%-12.3g", "3.14 ", pi); - test("%-12.3g", "-3.14 ", negate(pi)); - test("%.3g", "3.14", pi); - test("%.3g", "-3.14", negate(pi)); - test("%.3g", "3.14e+08", mult(pi, 100000000.0)); - test("%.3g", "-3.14e+08", mult(pi, -100000000.0)); - - test("%.3g", "1.00e-05", recip(create(100000.0))); - test("%.3g", "-1.00e-05", recip(create(-100000.0))); - test("%.0g", "-1e-05", recip(create(-100000.0))); - test("%.0g", "1e+05", create(100000.0)); - test("%.3G", "1.00E-05", recip(create(100000.0))); - test("%.3G", "-1.00E-05", recip(create(-100000.0))); - - test("%.1g", "-0", -0.0); - test("%3.0g", " -0", -0.0); - test("%.1g", "0", 0.0); - test("%3.0g", " 0", 0.0); - test("%.1g", "0", +0.0); - test("%3.0g", " 0", +0.0); - - test("%3.0g", "1e-06", 0.000001); - test("%3.0g", "1e-05", 0.00001); - test("%3.0g", "1e-05", 0.0000099); - test("%3.1g", "1e-05", 0.0000099); - test("%3.2g", "9.9e-06", 0.0000099); - test("%3.0g", "0.0001", 0.0001); - test("%3.0g", "9e-05", 0.00009); - test("%3.0g", "0.0001", 0.000099); - test("%3.1g", "0.0001", 0.000099); - test("%3.2g", "9.9e-05", 0.000099); - test("%3.0g", "0.001", 0.001); - test("%3.0g", "0.001", 0.00099); - test("%3.1g", "0.001", 0.00099); - test("%3.2g", "0.00099", 0.00099); - test("%3.3g", "0.00100", 0.001); - test("%3.4g", "0.001000", 0.001); - test("%3.0g", "0.01", 0.01); - test("%3.0g", "0.1", 0.1); - test("%3.0g", "0.9", 0.9); - test("%3.1g", "0.9", 0.9); - test("%3.0g", " 1", 1.00); - test("%3.2g", " 10", 10.00); - test("%3.0g", "1e+01", 10.00); - test("%3.0g", "1e+02", 99.19); - test("%3.1g", "1e+02", 99.19); - test("%3.2g", " 99", 99.19); - test("%3.0g", "1e+02", 99.9); - test("%3.1g", "1e+02", 99.9); - test("%3.2g", "1.0e+02", 99.9); - test("%3.0g", "1e+02", 99.99); - test("%3.0g", "1e+02", 100.00); - test("%3.0g", "1e+03", 999.9); - test("%3.1g", "1e+03", 999.9); - test("%3.2g", "1.0e+03", 999.9); - test("%3.3g", "1.00e+03", 999.9); - test("%3.4g", "999.9", 999.9); - test("%3.4g", "1000", 999.99); - test("%3.0g", "1e+03", 1000.00); - test("%3.0g", "1e+04", 10000.00); - test("%3.0g", "1e+05", 100000.00); - test("%3.0g", "1e+06", 1000000.00); - test("%3.0g", "1e+07", 10000000.00); - test("%3.9g", "100000000", 100000000.00); - test("%3.10g", "100000000.0", 100000000.00); - - tryCatch("%#3.0g", FormatFlagsConversionMismatchException.class, 1000.00); - - // double PI^300 - // = 13962455701329742638131355433930076081862072808 ... e+149 - - //--------------------------------------------------------------------- - // %g - BigDecimal - //--------------------------------------------------------------------- - test("%.3g", "1.40e+149", piToThe300); - test("%.3g", "-1.40e+149", piToThe300.negate()); - test(Locale.FRANCE, "%.3g", "-1,40e+149", piToThe300.negate()); - test("%.3g", "1.00e-100", recip(ten.pow(100))); - test("%.3g", "-1.00e-100", negate(recip(ten.pow(100)))); - - test("%3.0g", "1e-06", new BigDecimal("0.000001")); - test("%3.0g", "1e-05", new BigDecimal("0.00001")); - test("%3.0g", "0.0001", new BigDecimal("0.0001")); - test("%3.0g", "0.001", new BigDecimal("0.001")); - test("%3.3g", "0.00100", new BigDecimal("0.001")); - test("%3.4g", "0.001000", new BigDecimal("0.001")); - test("%3.0g", "0.01", new BigDecimal("0.01")); - test("%3.0g", "0.1", new BigDecimal("0.1")); - test("%3.0g", "0.9", new BigDecimal("0.9")); - test("%3.1g", "0.9", new BigDecimal("0.9")); - test("%3.0g", " 1", new BigDecimal("1.00")); - test("%3.2g", " 10", new BigDecimal("10.00")); - test("%3.0g", "1e+01", new BigDecimal("10.00")); - test("%3.0g", "1e+02", new BigDecimal("99.19")); - test("%3.1g", "1e+02", new BigDecimal("99.19")); - test("%3.2g", " 99", new BigDecimal("99.19")); - test("%3.0g", "1e+02", new BigDecimal("99.99")); - test("%3.0g", "1e+02", new BigDecimal("100.00")); - test("%3.0g", "1e+03", new BigDecimal("1000.00")); - test("%3.0g", "1e+04", new BigDecimal("10000.00")); - test("%3.0g", "1e+05", new BigDecimal("100000.00")); - test("%3.0g", "1e+06", new BigDecimal("1000000.00")); - test("%3.0g", "1e+07", new BigDecimal("10000000.00")); - test("%3.9g", "100000000", new BigDecimal("100000000.00")); - test("%3.10g", "100000000.0", new BigDecimal("100000000.00")); - - - test("%.3g", "10.0", ten); - test("%.3g", "1.00", one); - test("%10.3g", " 1.00", one); - test("%+10.3g", " +3.14", pi); - test("%+10.3g", " -3.14", negate(pi)); - test("% .3g", " 3.14", pi); - test("% .3g", "-3.14", negate(pi)); - test("%.0g", "3", create(3.0)); - test("%.0g", "-3", create(-3.0)); - - test("%(.4g", "3.142e+08", mult(pi, 100000000.0)); - test("%(.4g", "(3.142e+08)", mult(pi, -100000000.0)); - - - - - - - - test("%,.11g", "3,141,592.6536", mult(pi, 1000000.0)); - test("%(,.11g", "(3,141,592.6536)", mult(pi, -1000000.0)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %f, %e, %g, %a - Boundaries - //--------------------------------------------------------------------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + //--------------------------------------------------------------------- + // %f, %e, %g, %a - Boundaries + //--------------------------------------------------------------------- @@ -1691,99 +671,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicBigInteger.java b/test/jdk/java/util/Formatter/BasicBigInteger.java index 18a069cee6d2c..cec882d6a0aea 100644 --- a/test/jdk/java/util/Formatter/BasicBigInteger.java +++ b/test/jdk/java/util/Formatter/BasicBigInteger.java @@ -38,300 +38,7 @@ import static java.util.Calendar.*; - - - - public class BasicBigInteger extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -521,1154 +228,87 @@ public static void test() { tryCatch("%#g", FormatFlagsConversionMismatchException.class); + //--------------------------------------------------------------------- + // BigInteger - errors + //--------------------------------------------------------------------- + tryCatch("%f", IllegalFormatConversionException.class, + new BigInteger("1")); + //--------------------------------------------------------------------- + // %d - BigInteger + //--------------------------------------------------------------------- + test("%d", "null", (Object)null); + test("%d", "1234567", new BigInteger("1234567", 10)); + test("%,d", "1,234,567", new BigInteger("1234567", 10)); + test(Locale.FRANCE, "%,d", "1\u202f234\u202f567", new BigInteger("1234567", 10)); + test("%,d", "-1,234,567", new BigInteger("-1234567", 10)); + test("%(d", "1234567", new BigInteger("1234567", 10)); + test("%(d", "(1234567)", new BigInteger("-1234567", 10)); + test("% d", " 1234567", new BigInteger("1234567", 10)); + test("% d", "-1234567", new BigInteger("-1234567", 10)); + test("%+d", "+1234567", new BigInteger("1234567", 10)); + test("%+d", "-1234567", new BigInteger("-1234567", 10)); + test("%010d", "0001234567", new BigInteger("1234567", 10)); + test("%010d", "-001234567", new BigInteger("-1234567", 10)); + test("%(10d", " (1234567)", new BigInteger("-1234567", 10)); + test("%+d", "+1234567", new BigInteger("1234567", 10)); + test("%+d", "-1234567", new BigInteger("-1234567", 10)); + test("%-10d", "1234567 ", new BigInteger("1234567", 10)); + test("%-10d", "-1234567 ", new BigInteger("-1234567", 10)); + // , variations: + test("%0,10d", "01,234,567", new BigInteger("1234567", 10)); + test("%0,10d", "-1,234,567", new BigInteger("-1234567", 10)); + test("%(,10d", "(1,234,567)", new BigInteger("-1234567", 10)); + test("%+,d", "+1,234,567", new BigInteger("1234567", 10)); + test("%+,d", "-1,234,567", new BigInteger("-1234567", 10)); + test("%-,10d", "1,234,567 ", new BigInteger("1234567", 10)); + test("%-,10d", "-1,234,567", new BigInteger("-1234567", 10)); + //--------------------------------------------------------------------- + // %o - BigInteger + //--------------------------------------------------------------------- + test("%o", "null", (Object)null); + test("%o", "1234567", new BigInteger("1234567", 8)); + test("%(o", "1234567", new BigInteger("1234567", 8)); + test("%(o", "(1234567)", new BigInteger("-1234567", 8)); + test("% o", " 1234567", new BigInteger("1234567", 8)); + test("% o", "-1234567", new BigInteger("-1234567", 8)); + test("%+o", "+1234567", new BigInteger("1234567", 8)); + test("%+o", "-1234567", new BigInteger("-1234567", 8)); + test("%010o", "0001234567", new BigInteger("1234567", 8)); + test("%010o", "-001234567", new BigInteger("-1234567", 8)); + test("%(10o", " (1234567)", new BigInteger("-1234567", 8)); + test("%+o", "+1234567", new BigInteger("1234567", 8)); + test("%+o", "-1234567", new BigInteger("-1234567", 8)); + test("%-10o", "1234567 ", new BigInteger("1234567", 8)); + test("%-10o", "-1234567 ", new BigInteger("-1234567", 8)); + test("%#10o", " 01234567", new BigInteger("1234567", 8)); + test("%#10o", " -01234567", new BigInteger("-1234567", 8)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // BigInteger - errors - //--------------------------------------------------------------------- - tryCatch("%f", IllegalFormatConversionException.class, - new BigInteger("1")); - - //--------------------------------------------------------------------- - // %d - BigInteger - //--------------------------------------------------------------------- - test("%d", "null", (Object)null); - test("%d", "1234567", new BigInteger("1234567", 10)); - test("%,d", "1,234,567", new BigInteger("1234567", 10)); - test(Locale.FRANCE, "%,d", "1\u202f234\u202f567", new BigInteger("1234567", 10)); - test("%,d", "-1,234,567", new BigInteger("-1234567", 10)); - test("%(d", "1234567", new BigInteger("1234567", 10)); - test("%(d", "(1234567)", new BigInteger("-1234567", 10)); - test("% d", " 1234567", new BigInteger("1234567", 10)); - test("% d", "-1234567", new BigInteger("-1234567", 10)); - test("%+d", "+1234567", new BigInteger("1234567", 10)); - test("%+d", "-1234567", new BigInteger("-1234567", 10)); - test("%010d", "0001234567", new BigInteger("1234567", 10)); - test("%010d", "-001234567", new BigInteger("-1234567", 10)); - test("%(10d", " (1234567)", new BigInteger("-1234567", 10)); - test("%+d", "+1234567", new BigInteger("1234567", 10)); - test("%+d", "-1234567", new BigInteger("-1234567", 10)); - test("%-10d", "1234567 ", new BigInteger("1234567", 10)); - test("%-10d", "-1234567 ", new BigInteger("-1234567", 10)); - // , variations: - test("%0,10d", "01,234,567", new BigInteger("1234567", 10)); - test("%0,10d", "-1,234,567", new BigInteger("-1234567", 10)); - test("%(,10d", "(1,234,567)", new BigInteger("-1234567", 10)); - test("%+,d", "+1,234,567", new BigInteger("1234567", 10)); - test("%+,d", "-1,234,567", new BigInteger("-1234567", 10)); - test("%-,10d", "1,234,567 ", new BigInteger("1234567", 10)); - test("%-,10d", "-1,234,567", new BigInteger("-1234567", 10)); - - //--------------------------------------------------------------------- - // %o - BigInteger - //--------------------------------------------------------------------- - test("%o", "null", (Object)null); - test("%o", "1234567", new BigInteger("1234567", 8)); - test("%(o", "1234567", new BigInteger("1234567", 8)); - test("%(o", "(1234567)", new BigInteger("-1234567", 8)); - test("% o", " 1234567", new BigInteger("1234567", 8)); - test("% o", "-1234567", new BigInteger("-1234567", 8)); - test("%+o", "+1234567", new BigInteger("1234567", 8)); - test("%+o", "-1234567", new BigInteger("-1234567", 8)); - test("%010o", "0001234567", new BigInteger("1234567", 8)); - test("%010o", "-001234567", new BigInteger("-1234567", 8)); - test("%(10o", " (1234567)", new BigInteger("-1234567", 8)); - test("%+o", "+1234567", new BigInteger("1234567", 8)); - test("%+o", "-1234567", new BigInteger("-1234567", 8)); - test("%-10o", "1234567 ", new BigInteger("1234567", 8)); - test("%-10o", "-1234567 ", new BigInteger("-1234567", 8)); - test("%#10o", " 01234567", new BigInteger("1234567", 8)); - test("%#10o", " -01234567", new BigInteger("-1234567", 8)); - - //--------------------------------------------------------------------- - // %x - BigInteger - //--------------------------------------------------------------------- - test("%x", "null", (Object)null); - test("%x", "1234567", new BigInteger("1234567", 16)); - test("%(x", "1234567", new BigInteger("1234567", 16)); - test("%(x", "(1234567)", new BigInteger("-1234567", 16)); - test("% x", " 1234567", new BigInteger("1234567", 16)); - test("% x", "-1234567", new BigInteger("-1234567", 16)); - test("%+x", "+1234567", new BigInteger("1234567", 16)); - test("%+x", "-1234567", new BigInteger("-1234567", 16)); - test("%010x", "0001234567", new BigInteger("1234567", 16)); - test("%010x", "-001234567", new BigInteger("-1234567", 16)); - test("%(10x", " (1234567)", new BigInteger("-1234567", 16)); - test("%+x", "+1234567", new BigInteger("1234567", 16)); - test("%+x", "-1234567", new BigInteger("-1234567", 16)); - test("%-10x", "1234567 ", new BigInteger("1234567", 16)); - test("%-10x", "-1234567 ", new BigInteger("-1234567", 16)); - test("%#10x", " 0x1234567", new BigInteger("1234567", 16)); - test("%#10x", "-0x1234567", new BigInteger("-1234567", 16)); - test("%#10X", " 0X1234567", new BigInteger("1234567", 16)); - test("%#10X", "-0X1234567", new BigInteger("-1234567", 16)); - test("%X", "1234567A", new BigInteger("1234567a", 16)); - test("%X", "-1234567A", new BigInteger("-1234567a", 16)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + //--------------------------------------------------------------------- + // %x - BigInteger + //--------------------------------------------------------------------- + test("%x", "null", (Object)null); + test("%x", "1234567", new BigInteger("1234567", 16)); + test("%(x", "1234567", new BigInteger("1234567", 16)); + test("%(x", "(1234567)", new BigInteger("-1234567", 16)); + test("% x", " 1234567", new BigInteger("1234567", 16)); + test("% x", "-1234567", new BigInteger("-1234567", 16)); + test("%+x", "+1234567", new BigInteger("1234567", 16)); + test("%+x", "-1234567", new BigInteger("-1234567", 16)); + test("%010x", "0001234567", new BigInteger("1234567", 16)); + test("%010x", "-001234567", new BigInteger("-1234567", 16)); + test("%(10x", " (1234567)", new BigInteger("-1234567", 16)); + test("%+x", "+1234567", new BigInteger("1234567", 16)); + test("%+x", "-1234567", new BigInteger("-1234567", 16)); + test("%-10x", "1234567 ", new BigInteger("1234567", 16)); + test("%-10x", "-1234567 ", new BigInteger("-1234567", 16)); + test("%#10x", " 0x1234567", new BigInteger("1234567", 16)); + test("%#10x", "-0x1234567", new BigInteger("-1234567", 16)); + test("%#10X", " 0X1234567", new BigInteger("1234567", 16)); + test("%#10X", "-0X1234567", new BigInteger("-1234567", 16)); + test("%X", "1234567A", new BigInteger("1234567a", 16)); + test("%X", "-1234567A", new BigInteger("-1234567a", 16)); //--------------------------------------------------------------------- @@ -1691,99 +331,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicBoolean.java b/test/jdk/java/util/Formatter/BasicBoolean.java index 7bc3ea6bb6a03..19ed3f372244c 100644 --- a/test/jdk/java/util/Formatter/BasicBoolean.java +++ b/test/jdk/java/util/Formatter/BasicBoolean.java @@ -38,300 +38,7 @@ import static java.util.Calendar.*; - - - - public class BasicBoolean extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -523,1161 +230,13 @@ public static void test() { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %t - // - // Date/Time conversions applicable to Calendar, Date, and long. - //--------------------------------------------------------------------- - test("%tA", "null", (Object)null); - test("%TA", "NULL", (Object)null); + //--------------------------------------------------------------------- + // %t + // + // Date/Time conversions applicable to Calendar, Date, and long. + //--------------------------------------------------------------------- + test("%tA", "null", (Object)null); + test("%TA", "NULL", (Object)null); //--------------------------------------------------------------------- // %t - errors @@ -1691,99 +250,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicBooleanObject.java b/test/jdk/java/util/Formatter/BasicBooleanObject.java index 28c3f0fe17343..a92643f45d787 100644 --- a/test/jdk/java/util/Formatter/BasicBooleanObject.java +++ b/test/jdk/java/util/Formatter/BasicBooleanObject.java @@ -38,300 +38,7 @@ import static java.util.Calendar.*; - - - - public class BasicBooleanObject extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -523,1161 +230,13 @@ public static void test() { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %t - // - // Date/Time conversions applicable to Calendar, Date, and long. - //--------------------------------------------------------------------- - test("%tA", "null", (Object)null); - test("%TA", "NULL", (Object)null); + //--------------------------------------------------------------------- + // %t + // + // Date/Time conversions applicable to Calendar, Date, and long. + //--------------------------------------------------------------------- + test("%tA", "null", (Object)null); + test("%TA", "NULL", (Object)null); //--------------------------------------------------------------------- // %t - errors @@ -1691,99 +250,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicByte.java b/test/jdk/java/util/Formatter/BasicByte.java index 7da7c8929c831..c90e03a47c35a 100644 --- a/test/jdk/java/util/Formatter/BasicByte.java +++ b/test/jdk/java/util/Formatter/BasicByte.java @@ -38,303 +38,13 @@ import static java.util.Calendar.*; - - - - public class BasicByte extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static byte negate(byte v) { return (byte) -v; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static void test() { TimeZone.setDefault(TimeZone.getTimeZone("GMT-0800")); @@ -520,24 +230,8 @@ public static void test() { tryCatch("%#g", FormatFlagsConversionMismatchException.class); - - byte minByte = Byte.MIN_VALUE; // -128 - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %d // @@ -546,8 +240,6 @@ public static void test() { //--------------------------------------------------------------------- test("%d", "null", (Object)null); - - //--------------------------------------------------------------------- // %d - byte //--------------------------------------------------------------------- @@ -566,132 +258,29 @@ public static void test() { test("%(10d", " (17)", negate(seventeen)); test("%-10d", "17 ", seventeen); test("%-10d", "-17 ", negate(seventeen)); + //--------------------------------------------------------------------- + // %d - errors + //--------------------------------------------------------------------- + tryCatch("%#d", FormatFlagsConversionMismatchException.class); + tryCatch("%D", UnknownFormatConversionException.class); + tryCatch("%0d", MissingFormatWidthException.class); + tryCatch("%-d", MissingFormatWidthException.class); + tryCatch("%7.3d", IllegalFormatPrecisionException.class); + //--------------------------------------------------------------------- + // %o + // + // Numeric conversion applicable to byte, short, int, long, and + // BigInteger. + //--------------------------------------------------------------------- + test("%o", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %d - errors - //--------------------------------------------------------------------- - tryCatch("%#d", FormatFlagsConversionMismatchException.class); - tryCatch("%D", UnknownFormatConversionException.class); - tryCatch("%0d", MissingFormatWidthException.class); - tryCatch("%-d", MissingFormatWidthException.class); - tryCatch("%7.3d", IllegalFormatPrecisionException.class); - - //--------------------------------------------------------------------- - // %o - // - // Numeric conversion applicable to byte, short, int, long, and - // BigInteger. - //--------------------------------------------------------------------- - test("%o", "null", (Object)null); - - - //--------------------------------------------------------------------- - // %o - byte - //--------------------------------------------------------------------- - test("%010o", "0000000200", minByte); - test("%-10o", "200 ", minByte); - test("%#10o", " 0200", minByte); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + //--------------------------------------------------------------------- + // %o - byte + //--------------------------------------------------------------------- + test("%010o", "0000000200", minByte); + test("%-10o", "200 ", minByte); + test("%#10o", " 0200", minByte); //--------------------------------------------------------------------- // %o - errors @@ -715,7 +304,6 @@ public static void test() { //--------------------------------------------------------------------- test("%x", "null", (Object)null); - //--------------------------------------------------------------------- // %x - byte //--------------------------------------------------------------------- @@ -725,58 +313,6 @@ public static void test() { test("%0#10x","0x00000080", minByte); test("%#10X", " 0X80", minByte); test("%X", "80", minByte); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %x - errors //--------------------------------------------------------------------- @@ -787,897 +323,13 @@ public static void test() { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %t - // - // Date/Time conversions applicable to Calendar, Date, and long. - //--------------------------------------------------------------------- - test("%tA", "null", (Object)null); - test("%TA", "NULL", (Object)null); + //--------------------------------------------------------------------- + // %t + // + // Date/Time conversions applicable to Calendar, Date, and long. + //--------------------------------------------------------------------- + test("%tA", "null", (Object)null); + test("%TA", "NULL", (Object)null); //--------------------------------------------------------------------- // %t - errors @@ -1691,99 +343,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicByteObject.java b/test/jdk/java/util/Formatter/BasicByteObject.java index cf28afc79d9b2..25e7524098759 100644 --- a/test/jdk/java/util/Formatter/BasicByteObject.java +++ b/test/jdk/java/util/Formatter/BasicByteObject.java @@ -38,303 +38,13 @@ import static java.util.Calendar.*; - - - - public class BasicByteObject extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static Byte negate(Byte v) { return (byte) -v.byteValue(); } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static void test() { TimeZone.setDefault(TimeZone.getTimeZone("GMT-0800")); @@ -520,24 +230,8 @@ public static void test() { tryCatch("%#g", FormatFlagsConversionMismatchException.class); - - - - - - - - Byte minByte = Byte.MIN_VALUE; - - - - - - - - //--------------------------------------------------------------------- // %d // @@ -546,1127 +240,52 @@ public static void test() { //--------------------------------------------------------------------- test("%d", "null", (Object)null); + //--------------------------------------------------------------------- + // %d - errors + //--------------------------------------------------------------------- + tryCatch("%#d", FormatFlagsConversionMismatchException.class); + tryCatch("%D", UnknownFormatConversionException.class); + tryCatch("%0d", MissingFormatWidthException.class); + tryCatch("%-d", MissingFormatWidthException.class); + tryCatch("%7.3d", IllegalFormatPrecisionException.class); + //--------------------------------------------------------------------- + // %o + // + // Numeric conversion applicable to byte, short, int, long, and + // BigInteger. + //--------------------------------------------------------------------- + test("%o", "null", (Object)null); + //--------------------------------------------------------------------- + // %o - errors + //--------------------------------------------------------------------- + tryCatch("%(o", FormatFlagsConversionMismatchException.class, + minByte); + tryCatch("%+o", FormatFlagsConversionMismatchException.class, + minByte); + tryCatch("% o", FormatFlagsConversionMismatchException.class, + minByte); + tryCatch("%0o", MissingFormatWidthException.class); + tryCatch("%-o", MissingFormatWidthException.class); + tryCatch("%,o", FormatFlagsConversionMismatchException.class); + tryCatch("%O", UnknownFormatConversionException.class); + //--------------------------------------------------------------------- + // %x + // + // Numeric conversion applicable to byte, short, int, long, and + // BigInteger. + //--------------------------------------------------------------------- + test("%x", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %d - errors - //--------------------------------------------------------------------- - tryCatch("%#d", FormatFlagsConversionMismatchException.class); - tryCatch("%D", UnknownFormatConversionException.class); - tryCatch("%0d", MissingFormatWidthException.class); - tryCatch("%-d", MissingFormatWidthException.class); - tryCatch("%7.3d", IllegalFormatPrecisionException.class); - - //--------------------------------------------------------------------- - // %o - // - // Numeric conversion applicable to byte, short, int, long, and - // BigInteger. - //--------------------------------------------------------------------- - test("%o", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %o - errors - //--------------------------------------------------------------------- - tryCatch("%(o", FormatFlagsConversionMismatchException.class, - minByte); - tryCatch("%+o", FormatFlagsConversionMismatchException.class, - minByte); - tryCatch("% o", FormatFlagsConversionMismatchException.class, - minByte); - tryCatch("%0o", MissingFormatWidthException.class); - tryCatch("%-o", MissingFormatWidthException.class); - tryCatch("%,o", FormatFlagsConversionMismatchException.class); - tryCatch("%O", UnknownFormatConversionException.class); - - //--------------------------------------------------------------------- - // %x - // - // Numeric conversion applicable to byte, short, int, long, and - // BigInteger. - //--------------------------------------------------------------------- - test("%x", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %x - errors - //--------------------------------------------------------------------- - tryCatch("%,x", FormatFlagsConversionMismatchException.class); - tryCatch("%0x", MissingFormatWidthException.class); - tryCatch("%-x", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + //--------------------------------------------------------------------- + // %x - errors + //--------------------------------------------------------------------- + tryCatch("%,x", FormatFlagsConversionMismatchException.class); + tryCatch("%0x", MissingFormatWidthException.class); + tryCatch("%-x", MissingFormatWidthException.class); @@ -1691,99 +310,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicChar.java b/test/jdk/java/util/Formatter/BasicChar.java index c17dfb7b9351d..da990f1c998b2 100644 --- a/test/jdk/java/util/Formatter/BasicChar.java +++ b/test/jdk/java/util/Formatter/BasicChar.java @@ -38,300 +38,7 @@ import static java.util.Calendar.*; - - - - public class BasicChar extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -523,1161 +230,13 @@ public static void test() { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %t - // - // Date/Time conversions applicable to Calendar, Date, and long. - //--------------------------------------------------------------------- - test("%tA", "null", (Object)null); - test("%TA", "NULL", (Object)null); + //--------------------------------------------------------------------- + // %t + // + // Date/Time conversions applicable to Calendar, Date, and long. + //--------------------------------------------------------------------- + test("%tA", "null", (Object)null); + test("%TA", "NULL", (Object)null); //--------------------------------------------------------------------- // %t - errors @@ -1691,99 +250,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicCharObject.java b/test/jdk/java/util/Formatter/BasicCharObject.java index 3b0c2b012df4c..44d16860da655 100644 --- a/test/jdk/java/util/Formatter/BasicCharObject.java +++ b/test/jdk/java/util/Formatter/BasicCharObject.java @@ -38,300 +38,7 @@ import static java.util.Calendar.*; - - - - public class BasicCharObject extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -523,1161 +230,13 @@ public static void test() { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %t - // - // Date/Time conversions applicable to Calendar, Date, and long. - //--------------------------------------------------------------------- - test("%tA", "null", (Object)null); - test("%TA", "NULL", (Object)null); + //--------------------------------------------------------------------- + // %t + // + // Date/Time conversions applicable to Calendar, Date, and long. + //--------------------------------------------------------------------- + test("%tA", "null", (Object)null); + test("%TA", "NULL", (Object)null); //--------------------------------------------------------------------- // %t - errors @@ -1691,99 +250,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicDateTime.java b/test/jdk/java/util/Formatter/BasicDateTime.java index 7fac4860692d2..4a65918b5b44f 100644 --- a/test/jdk/java/util/Formatter/BasicDateTime.java +++ b/test/jdk/java/util/Formatter/BasicDateTime.java @@ -37,110 +37,10 @@ import java.util.*; import static java.util.Calendar.*; - import static java.util.SimpleTimeZone.*; import java.util.regex.Pattern; - public class BasicDateTime extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void testDateTime(String fs, String exp, Calendar c) { testDateTime(fs, exp, c, true); } @@ -221,120 +121,6 @@ private static void testHours() { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static void test() { TimeZone.setDefault(TimeZone.getTimeZone("GMT-0800")); @@ -523,1264 +309,105 @@ public static void test() { + //--------------------------------------------------------------------- + // %t + // + // Date/Time conversions applicable to Calendar, Date, and long. + //--------------------------------------------------------------------- + test("%tA", "null", (Object)null); + test("%TA", "NULL", (Object)null); + //--------------------------------------------------------------------- + // %t - errors + //--------------------------------------------------------------------- + tryCatch("%t", UnknownFormatConversionException.class); + tryCatch("%T", UnknownFormatConversionException.class); + tryCatch("%tP", UnknownFormatConversionException.class); + tryCatch("%TP", UnknownFormatConversionException.class); + tryCatch("%.5tB", IllegalFormatPrecisionException.class); + tryCatch("%#tB", FormatFlagsConversionMismatchException.class); + tryCatch("%-tB", MissingFormatWidthException.class); + //--------------------------------------------------------------------- + // %t - create test Calendar + //--------------------------------------------------------------------- + // Get the supported ids for GMT-08:00 (Pacific Standard Time) + String[] ids = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000); + // Create a Pacific Standard Time time zone + SimpleTimeZone tz = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids[0]); + // public GregorianCalendar(TimeZone zone, Locale aLocale); + Calendar c0 = new GregorianCalendar(tz, Locale.US); + // public final void set(int year, int month, int date, + // int hourOfDay, int minute, int second); + c0.set(1995, MAY, 23, 19, 48, 34); + c0.set(Calendar.MILLISECOND, 584); + //--------------------------------------------------------------------- + // %t - Minutes, {nano,milli}*seconds + // + // testDateTime() verifies the expected output for all applicable types + // (Calendar, Date, and long). It also verifies output for "%t" and + // "%T". Thus it is sufficient to invoke that method once per + // conversion/expected output. + //--------------------------------------------------------------------- + testDateTime("%tM", "48", c0); + testDateTime("%tN", "584000000", c0); + testDateTime("%tL", "584", c0); +// testDateTime("%tQ", "801283714584", c0); + testDateTime("%ts", String.valueOf(c0.getTimeInMillis() / 1000), c0); + testDateTime("%tS", "34", c0); + testDateTime("%tT", "19:48:34", c0); + //--------------------------------------------------------------------- + // %t - Hours, morning/afternoon markers + // + // testHours() iterates through all twenty-four hours to verify + // numeric return value and morning/afternoon markers. + //--------------------------------------------------------------------- + testHours(); + //--------------------------------------------------------------------- + // %t - Portions of date [ day, month, dates, weeks ] + //--------------------------------------------------------------------- + testDateTime("%ta", "Tue", c0); + testDateTime("%tA", "Tuesday", c0); + testDateTime("%tb", "May", c0); + testDateTime("%tB", "May", c0); + testDateTime("%tC", "19", c0); + testDateTime("%td", "23", c0); + testDateTime("%te", "23", c0); + testDateTime("%th", "May", c0); + testDateTime("%tj", "143", c0); + testDateTime("%tm", "05", c0); + testDateTime("%ty", "95", c0); + testDateTime("%tY", "1995", c0); + //--------------------------------------------------------------------- + // %t - TimeZone + //--------------------------------------------------------------------- + testDateTime("%tz", "-0800", c0); + testDateTime("%tZ", "PST", c0); + //--------------------------------------------------------------------- + // %tz should always adjust for DST + //--------------------------------------------------------------------- + TimeZone dtz = TimeZone.getDefault(); + // Artificial TimeZone based on PST with 3:15 DST always in effect + TimeZone atz = new SimpleTimeZone(-8 * 60 * 60 * 1000, "AlwaysDST", + JANUARY, 1, 0, 0, STANDARD_TIME, + // 24hrs - 1m = 60 * 60 * 1000 * 24 - 1 + DECEMBER, 31, 0, 60 * 60 * 1000 * 24 - 1, STANDARD_TIME, + (int)(60 * 60 * 1000 * 3.25)); + TimeZone.setDefault(atz); + testDateTime("%tz", "-0445", Calendar.getInstance(atz)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %t - // - // Date/Time conversions applicable to Calendar, Date, and long. - //--------------------------------------------------------------------- - test("%tA", "null", (Object)null); - test("%TA", "NULL", (Object)null); - - //--------------------------------------------------------------------- - // %t - errors - //--------------------------------------------------------------------- - tryCatch("%t", UnknownFormatConversionException.class); - tryCatch("%T", UnknownFormatConversionException.class); - tryCatch("%tP", UnknownFormatConversionException.class); - tryCatch("%TP", UnknownFormatConversionException.class); - tryCatch("%.5tB", IllegalFormatPrecisionException.class); - tryCatch("%#tB", FormatFlagsConversionMismatchException.class); - tryCatch("%-tB", MissingFormatWidthException.class); - - - //--------------------------------------------------------------------- - // %t - create test Calendar - //--------------------------------------------------------------------- - - // Get the supported ids for GMT-08:00 (Pacific Standard Time) - String[] ids = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000); - // With tzdata2020b, the test fails for the mentioned zones expecting - // "PST" but JDK has Zone name "MST" for JRE locale provider. - // Therefore excluding them as the test is only looking for a GMT-08:00 - // time zone ID. See JDK-8254865. - final List list = new ArrayList(); - Collections.addAll(list, ids); - list.remove("America/Dawson"); - list.remove("America/WhiteHorse"); - list.remove("Canada/Yukon"); - ids = list.toArray(new String[list.size()]); - // Create a Pacific Standard Time time zone - SimpleTimeZone tz = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids[0]); - // public GregorianCalendar(TimeZone zone, Locale aLocale); - Calendar c0 = new GregorianCalendar(tz, Locale.US); - // public final void set(int year, int month, int date, - // int hourOfDay, int minute, int second); - c0.set(1995, MAY, 23, 19, 48, 34); - c0.set(Calendar.MILLISECOND, 584); - - //--------------------------------------------------------------------- - // %t - Minutes, {nano,milli}*seconds - // - // testDateTime() verifies the expected output for all applicable types - // (Calendar, Date, and long). It also verifies output for "%t" and - // "%T". Thus it is sufficient to invoke that method once per - // conversion/expected output. - //--------------------------------------------------------------------- - testDateTime("%tM", "48", c0); - testDateTime("%tN", "584000000", c0); - testDateTime("%tL", "584", c0); -// testDateTime("%tQ", "801283714584", c0); - - testDateTime("%ts", String.valueOf(c0.getTimeInMillis() / 1000), c0); - testDateTime("%tS", "34", c0); - testDateTime("%tT", "19:48:34", c0); - - //--------------------------------------------------------------------- - // %t - Hours, morning/afternoon markers - // - // testHours() iterates through all twenty-four hours to verify - // numeric return value and morning/afternoon markers. - //--------------------------------------------------------------------- - testHours(); - - //--------------------------------------------------------------------- - // %t - Portions of date [ day, month, dates, weeks ] - //--------------------------------------------------------------------- - testDateTime("%ta", "Tue", c0); - testDateTime("%tA", "Tuesday", c0); - testDateTime("%tb", "May", c0); - testDateTime("%tB", "May", c0); - testDateTime("%tC", "19", c0); - testDateTime("%td", "23", c0); - testDateTime("%te", "23", c0); - testDateTime("%th", "May", c0); - testDateTime("%tj", "143", c0); - testDateTime("%tm", "05", c0); - testDateTime("%ty", "95", c0); - testDateTime("%tY", "1995", c0); - - //--------------------------------------------------------------------- - // %t - TimeZone - //--------------------------------------------------------------------- - testDateTime("%tz", "-0800", c0); - testDateTime("%tZ", "PST", c0); - - //--------------------------------------------------------------------- - // %tz should always adjust for DST - //--------------------------------------------------------------------- - TimeZone dtz = TimeZone.getDefault(); - - // Artificial TimeZone based on PST with 3:15 DST always in effect - TimeZone atz = new SimpleTimeZone(-8 * 60 * 60 * 1000, "AlwaysDST", - JANUARY, 1, 0, 0, STANDARD_TIME, - // 24hrs - 1m = 60 * 60 * 1000 * 24 - 1 - DECEMBER, 31, 0, 60 * 60 * 1000 * 24 - 1, STANDARD_TIME, - (int)(60 * 60 * 1000 * 3.25)); - TimeZone.setDefault(atz); - testDateTime("%tz", "-0445", Calendar.getInstance(atz)); - - // Restore the TimeZone and verify - TimeZone.setDefault(dtz); - if (atz.hasSameRules(TimeZone.getDefault())) - throw new RuntimeException("Default TimeZone not restored"); + // Restore the TimeZone and verify + TimeZone.setDefault(dtz); + if (atz.hasSameRules(TimeZone.getDefault())) + throw new RuntimeException("Default TimeZone not restored"); //--------------------------------------------------------------------- // %t - Composites @@ -1793,7 +420,6 @@ public static void test() { testDateTime("%-12tF", "1995-05-23 ", c0); testDateTime("%12tF", " 1995-05-23", c0); - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicDouble.java b/test/jdk/java/util/Formatter/BasicDouble.java index 5637d10f21dc2..493840839c43d 100644 --- a/test/jdk/java/util/Formatter/BasicDouble.java +++ b/test/jdk/java/util/Formatter/BasicDouble.java @@ -38,266 +38,7 @@ import static java.util.Calendar.*; - - - - public class BasicDouble extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static double create(double v) { @@ -317,24 +58,6 @@ private static double recip(double v) { return 1.0 / v; } - - - - - - - - - - - - - - - - - - public static void test() { TimeZone.setDefault(TimeZone.getTimeZone("GMT-0800")); @@ -522,1088 +245,354 @@ public static void test() { + //--------------------------------------------------------------------- + // %s - double + //--------------------------------------------------------------------- + double one = 1.0; + double ten = 10.0; + double pi = Math.PI; + test("%s", "3.141592653589793", pi); + //--------------------------------------------------------------------- + // flag/conversion errors + //--------------------------------------------------------------------- + tryCatch("%d", IllegalFormatConversionException.class, one); + tryCatch("%,.4e", FormatFlagsConversionMismatchException.class, one); + //--------------------------------------------------------------------- + // %e + // + // Floating-point conversions applicable to float, double, and + // BigDecimal. + //--------------------------------------------------------------------- + test("%e", "null", (Object)null); + //--------------------------------------------------------------------- + // %e - float and double + //--------------------------------------------------------------------- + // double PI = 3.141 592 653 589 793 238 46; + test("%e", "3.141593e+00", pi); + test("%.0e", "1e+01", ten); + test("%#.0e", "1.e+01", ten); + test("%E", "3.141593E+00", pi); + test("%10.3e", " 3.142e+00", pi); + test("%10.3e", "-3.142e+00", negate(pi)); + test("%010.3e", "03.142e+00", pi); + test("%010.3e", "-3.142e+00", negate(pi)); + test("%-12.3e", "3.142e+00 ", pi); + test("%-12.3e", "-3.142e+00 ", negate(pi)); + test("%.3e", "3.142e+00", pi); + test("%.3e", "-3.142e+00", negate(pi)); + test("%.3e", "3.142e+06", mult(pi, 1000000.0)); + test("%.3e", "-3.142e+06", mult(pi, -1000000.0)); + test(Locale.FRANCE, "%e", "3,141593e+00", pi); + // double PI^300 + // = 13962455701329742638131355433930076081862072808 ... e+149 + test("%10.3e", " 1.000e+00", one); + test("%+.3e", "+3.142e+00", pi); + test("%+.3e", "-3.142e+00", negate(pi)); + test("% .3e", " 3.142e+00", pi); + test("% .3e", "-3.142e+00", negate(pi)); + test("%#.0e", "3.e+00", create(3.0)); + test("%#.0e", "-3.e+00", create(-3.0)); + test("%.0e", "3e+00", create(3.0)); + test("%.0e", "-3e+00", create(-3.0)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %s - double - //--------------------------------------------------------------------- - double one = 1.0; - double ten = 10.0; - double pi = Math.PI; - - test("%s", "3.141592653589793", pi); - - - - - - - - - - - - - //--------------------------------------------------------------------- - // flag/conversion errors - //--------------------------------------------------------------------- - tryCatch("%d", IllegalFormatConversionException.class, one); - tryCatch("%,.4e", FormatFlagsConversionMismatchException.class, one); - - //--------------------------------------------------------------------- - // %e - // - // Floating-point conversions applicable to float, double, and - // BigDecimal. - //--------------------------------------------------------------------- - test("%e", "null", (Object)null); - - //--------------------------------------------------------------------- - // %e - float and double - //--------------------------------------------------------------------- - // double PI = 3.141 592 653 589 793 238 46; - test("%e", "3.141593e+00", pi); - test("%.0e", "1e+01", ten); - test("%#.0e", "1.e+01", ten); - test("%E", "3.141593E+00", pi); - test("%10.3e", " 3.142e+00", pi); - test("%10.3e", "-3.142e+00", negate(pi)); - test("%010.3e", "03.142e+00", pi); - test("%010.3e", "-3.142e+00", negate(pi)); - test("%-12.3e", "3.142e+00 ", pi); - test("%-12.3e", "-3.142e+00 ", negate(pi)); - test("%.3e", "3.142e+00", pi); - test("%.3e", "-3.142e+00", negate(pi)); - test("%.3e", "3.142e+06", mult(pi, 1000000.0)); - test("%.3e", "-3.142e+06", mult(pi, -1000000.0)); - - test(Locale.FRANCE, "%e", "3,141593e+00", pi); - - // double PI^300 - // = 13962455701329742638131355433930076081862072808 ... e+149 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - test("%10.3e", " 1.000e+00", one); - test("%+.3e", "+3.142e+00", pi); - test("%+.3e", "-3.142e+00", negate(pi)); - test("% .3e", " 3.142e+00", pi); - test("% .3e", "-3.142e+00", negate(pi)); - test("%#.0e", "3.e+00", create(3.0)); - test("%#.0e", "-3.e+00", create(-3.0)); - test("%.0e", "3e+00", create(3.0)); - test("%.0e", "-3e+00", create(-3.0)); - - test("%(.4e", "3.1416e+06", mult(pi, 1000000.0)); - test("%(.4e", "(3.1416e+06)", mult(pi, -1000000.0)); - - //--------------------------------------------------------------------- - // %e - boundary problems - //--------------------------------------------------------------------- - test("%3.0e", "1e-06", 0.000001); - test("%3.0e", "1e-05", 0.00001); - test("%3.0e", "1e-04", 0.0001); - test("%3.0e", "1e-03", 0.001); - test("%3.0e", "1e-02", 0.01); - test("%3.0e", "1e-01", 0.1); - test("%3.0e", "9e-01", 0.9); - test("%3.1e", "9.0e-01", 0.9); - test("%3.0e", "1e+00", 1.00); - test("%3.0e", "1e+01", 10.00); - test("%3.0e", "1e+02", 99.19); - test("%3.1e", "9.9e+01", 99.19); - test("%3.0e", "1e+02", 99.99); - test("%3.0e", "1e+02", 100.00); - test("%#3.0e", "1.e+03", 1000.00); - test("%3.0e", "1e+04", 10000.00); - test("%3.0e", "1e+05", 100000.00); - test("%3.0e", "1e+06", 1000000.00); - test("%3.0e", "1e+07", 10000000.00); - test("%3.0e", "1e+08", 100000000.00); - - //--------------------------------------------------------------------- - // %f - // - // Floating-point conversions applicable to float, double, and - // BigDecimal. - //--------------------------------------------------------------------- - test("%f", "null", (Object)null); - test("%f", "3.141593", pi); - test(Locale.FRANCE, "%f", "3,141593", pi); - test("%10.3f", " 3.142", pi); - test("%10.3f", " -3.142", negate(pi)); - test("%010.3f", "000003.142", pi); - test("%010.3f", "-00003.142", negate(pi)); - test("%-10.3f", "3.142 ", pi); - test("%-10.3f", "-3.142 ", negate(pi)); - test("%.3f", "3.142", pi); - test("%.3f", "-3.142", negate(pi)); - test("%+.3f", "+3.142", pi); - test("%+.3f", "-3.142", negate(pi)); - test("% .3f", " 3.142", pi); - test("% .3f", "-3.142", negate(pi)); - test("%#.0f", "3.", create(3.0)); - test("%#.0f", "-3.", create(-3.0)); - test("%.0f", "3", create(3.0)); - test("%.0f", "-3", create(-3.0)); - test("%.3f", "10.000", ten); - test("%.3f", "1.000", one); - test("%10.3f", " 1.000", one); - - //--------------------------------------------------------------------- - // %f - boundary problems - //--------------------------------------------------------------------- - test("%3.0f", " 0", 0.000001); - test("%3.0f", " 0", 0.00001); - test("%3.0f", " 0", 0.0001); - test("%3.0f", " 0", 0.001); - test("%3.0f", " 0", 0.01); - test("%3.0f", " 0", 0.1); - test("%3.0f", " 1", 0.9); - test("%3.1f", "0.9", 0.9); - test("%3.0f", " 1", 1.00); - test("%3.0f", " 10", 10.00); - test("%3.0f", " 99", 99.19); - test("%3.1f", "99.2", 99.19); - test("%3.0f", "100", 99.99); - test("%3.0f", "100", 100.00); - test("%#3.0f", "1000.", 1000.00); - test("%3.0f", "10000", 10000.00); - test("%3.0f", "100000", 100000.00); - test("%3.0f", "1000000", 1000000.00); - test("%3.0f", "10000000", 10000000.00); - test("%3.0f", "100000000", 100000000.00); - test("%10.0f", " 1000000", 1000000.00); - test("%,10.0f", " 1,000,000", 1000000.00); - test("%,10.1f", "1,000,000.0", 1000000.00); - test("%,3.0f", "1,000,000", 1000000.00); - test("%,3.0f", "10,000,000", 10000000.00); - test("%,3.0f", "100,000,000", 100000000.00); - test("%,3.0f", "10,000,000", 10000000.00); - test("%,3.0f", "100,000,000", 100000000.00); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + test("%(.4e", "3.1416e+06", mult(pi, 1000000.0)); + test("%(.4e", "(3.1416e+06)", mult(pi, -1000000.0)); //--------------------------------------------------------------------- - // %f - float, double, Double, BigDecimal + // %e - boundary problems //--------------------------------------------------------------------- - test("%.3f", "3141592.654", mult(pi, 1000000.0)); - test("%.3f", "-3141592.654", mult(pi, -1000000.0)); - test("%,.4f", "3,141,592.6536", mult(pi, 1000000.0)); - test(Locale.FRANCE, "%,.4f", "3\u202f141\u202f592,6536", mult(pi, 1000000.0)); - test("%,.4f", "-3,141,592.6536", mult(pi, -1000000.0)); - test("%(.4f", "3141592.6536", mult(pi, 1000000.0)); - test("%(.4f", "(3141592.6536)", mult(pi, -1000000.0)); - test("%(,.4f", "3,141,592.6536", mult(pi, 1000000.0)); - test("%(,.4f", "(3,141,592.6536)", mult(pi, -1000000.0)); - - - + test("%3.0e", "1e-06", 0.000001); + test("%3.0e", "1e-05", 0.00001); + test("%3.0e", "1e-04", 0.0001); + test("%3.0e", "1e-03", 0.001); + test("%3.0e", "1e-02", 0.01); + test("%3.0e", "1e-01", 0.1); + test("%3.0e", "9e-01", 0.9); + test("%3.1e", "9.0e-01", 0.9); + test("%3.0e", "1e+00", 1.00); + test("%3.0e", "1e+01", 10.00); + test("%3.0e", "1e+02", 99.19); + test("%3.1e", "9.9e+01", 99.19); + test("%3.0e", "1e+02", 99.99); + test("%3.0e", "1e+02", 100.00); + test("%#3.0e", "1.e+03", 1000.00); + test("%3.0e", "1e+04", 10000.00); + test("%3.0e", "1e+05", 100000.00); + test("%3.0e", "1e+06", 1000000.00); + test("%3.0e", "1e+07", 10000000.00); + test("%3.0e", "1e+08", 100000000.00); //--------------------------------------------------------------------- - // %g + // %f // // Floating-point conversions applicable to float, double, and // BigDecimal. //--------------------------------------------------------------------- - test("%g", "null", (Object)null); - test("%g", "3.14159", pi); - test(Locale.FRANCE, "%g", "3,14159", pi); - test("%.0g", "1e+01", ten); - test("%G", "3.14159", pi); - test("%10.3g", " 3.14", pi); - test("%10.3g", " -3.14", negate(pi)); - test("%010.3g", "0000003.14", pi); - test("%010.3g", "-000003.14", negate(pi)); - test("%-12.3g", "3.14 ", pi); - test("%-12.3g", "-3.14 ", negate(pi)); - test("%.3g", "3.14", pi); - test("%.3g", "-3.14", negate(pi)); - test("%.3g", "3.14e+08", mult(pi, 100000000.0)); - test("%.3g", "-3.14e+08", mult(pi, -100000000.0)); - - test("%.3g", "1.00e-05", recip(create(100000.0))); - test("%.3g", "-1.00e-05", recip(create(-100000.0))); - test("%.0g", "-1e-05", recip(create(-100000.0))); - test("%.0g", "1e+05", create(100000.0)); - test("%.3G", "1.00E-05", recip(create(100000.0))); - test("%.3G", "-1.00E-05", recip(create(-100000.0))); - - test("%.1g", "-0", -0.0); - test("%3.0g", " -0", -0.0); - test("%.1g", "0", 0.0); - test("%3.0g", " 0", 0.0); - test("%.1g", "0", +0.0); - test("%3.0g", " 0", +0.0); - - test("%3.0g", "1e-06", 0.000001); - test("%3.0g", "1e-05", 0.00001); - test("%3.0g", "1e-05", 0.0000099); - test("%3.1g", "1e-05", 0.0000099); - test("%3.2g", "9.9e-06", 0.0000099); - test("%3.0g", "0.0001", 0.0001); - test("%3.0g", "9e-05", 0.00009); - test("%3.0g", "0.0001", 0.000099); - test("%3.1g", "0.0001", 0.000099); - test("%3.2g", "9.9e-05", 0.000099); - test("%3.0g", "0.001", 0.001); - test("%3.0g", "0.001", 0.00099); - test("%3.1g", "0.001", 0.00099); - test("%3.2g", "0.00099", 0.00099); - test("%3.3g", "0.00100", 0.001); - test("%3.4g", "0.001000", 0.001); - test("%3.0g", "0.01", 0.01); - test("%3.0g", "0.1", 0.1); - test("%3.0g", "0.9", 0.9); - test("%3.1g", "0.9", 0.9); - test("%3.0g", " 1", 1.00); - test("%3.2g", " 10", 10.00); - test("%3.0g", "1e+01", 10.00); - test("%3.0g", "1e+02", 99.19); - test("%3.1g", "1e+02", 99.19); - test("%3.2g", " 99", 99.19); - test("%3.0g", "1e+02", 99.9); - test("%3.1g", "1e+02", 99.9); - test("%3.2g", "1.0e+02", 99.9); - test("%3.0g", "1e+02", 99.99); - test("%3.0g", "1e+02", 100.00); - test("%3.0g", "1e+03", 999.9); - test("%3.1g", "1e+03", 999.9); - test("%3.2g", "1.0e+03", 999.9); - test("%3.3g", "1.00e+03", 999.9); - test("%3.4g", "999.9", 999.9); - test("%3.4g", "1000", 999.99); - test("%3.0g", "1e+03", 1000.00); - test("%3.0g", "1e+04", 10000.00); - test("%3.0g", "1e+05", 100000.00); - test("%3.0g", "1e+06", 1000000.00); - test("%3.0g", "1e+07", 10000000.00); - test("%3.9g", "100000000", 100000000.00); - test("%3.10g", "100000000.0", 100000000.00); - - tryCatch("%#3.0g", FormatFlagsConversionMismatchException.class, 1000.00); - - // double PI^300 - // = 13962455701329742638131355433930076081862072808 ... e+149 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - test("%.3g", "10.0", ten); - test("%.3g", "1.00", one); - test("%10.3g", " 1.00", one); - test("%+10.3g", " +3.14", pi); - test("%+10.3g", " -3.14", negate(pi)); - test("% .3g", " 3.14", pi); - test("% .3g", "-3.14", negate(pi)); - test("%.0g", "3", create(3.0)); - test("%.0g", "-3", create(-3.0)); - - test("%(.4g", "3.142e+08", mult(pi, 100000000.0)); - test("%(.4g", "(3.142e+08)", mult(pi, -100000000.0)); - - - - - - - - test("%,.11g", "3,141,592.6536", mult(pi, 1000000.0)); - test("%(,.11g", "(3,141,592.6536)", mult(pi, -1000000.0)); + test("%f", "null", (Object)null); + test("%f", "3.141593", pi); + test(Locale.FRANCE, "%f", "3,141593", pi); + test("%10.3f", " 3.142", pi); + test("%10.3f", " -3.142", negate(pi)); + test("%010.3f", "000003.142", pi); + test("%010.3f", "-00003.142", negate(pi)); + test("%-10.3f", "3.142 ", pi); + test("%-10.3f", "-3.142 ", negate(pi)); + test("%.3f", "3.142", pi); + test("%.3f", "-3.142", negate(pi)); + test("%+.3f", "+3.142", pi); + test("%+.3f", "-3.142", negate(pi)); + test("% .3f", " 3.142", pi); + test("% .3f", "-3.142", negate(pi)); + test("%#.0f", "3.", create(3.0)); + test("%#.0f", "-3.", create(-3.0)); + test("%.0f", "3", create(3.0)); + test("%.0f", "-3", create(-3.0)); + test("%.3f", "10.000", ten); + test("%.3f", "1.000", one); + test("%10.3f", " 1.000", one); + //--------------------------------------------------------------------- + // %f - boundary problems + //--------------------------------------------------------------------- + test("%3.0f", " 0", 0.000001); + test("%3.0f", " 0", 0.00001); + test("%3.0f", " 0", 0.0001); + test("%3.0f", " 0", 0.001); + test("%3.0f", " 0", 0.01); + test("%3.0f", " 0", 0.1); + test("%3.0f", " 1", 0.9); + test("%3.1f", "0.9", 0.9); + test("%3.0f", " 1", 1.00); + test("%3.0f", " 10", 10.00); + test("%3.0f", " 99", 99.19); + test("%3.1f", "99.2", 99.19); + test("%3.0f", "100", 99.99); + test("%3.0f", "100", 100.00); + test("%#3.0f", "1000.", 1000.00); + test("%3.0f", "10000", 10000.00); + test("%3.0f", "100000", 100000.00); + test("%3.0f", "1000000", 1000000.00); + test("%3.0f", "10000000", 10000000.00); + test("%3.0f", "100000000", 100000000.00); + test("%10.0f", " 1000000", 1000000.00); + test("%,10.0f", " 1,000,000", 1000000.00); + test("%,10.1f", "1,000,000.0", 1000000.00); + test("%,3.0f", "1,000,000", 1000000.00); + test("%,3.0f", "10,000,000", 10000000.00); + test("%,3.0f", "100,000,000", 100000000.00); + test("%,3.0f", "10,000,000", 10000000.00); + test("%,3.0f", "100,000,000", 100000000.00); + //--------------------------------------------------------------------- + // %f - float, double, Double, BigDecimal + //--------------------------------------------------------------------- + test("%.3f", "3141592.654", mult(pi, 1000000.0)); + test("%.3f", "-3141592.654", mult(pi, -1000000.0)); + test("%,.4f", "3,141,592.6536", mult(pi, 1000000.0)); + test(Locale.FRANCE, "%,.4f", "3\u202f141\u202f592,6536", mult(pi, 1000000.0)); + test("%,.4f", "-3,141,592.6536", mult(pi, -1000000.0)); + test("%(.4f", "3141592.6536", mult(pi, 1000000.0)); + test("%(.4f", "(3141592.6536)", mult(pi, -1000000.0)); + test("%(,.4f", "3,141,592.6536", mult(pi, 1000000.0)); + test("%(,.4f", "(3,141,592.6536)", mult(pi, -1000000.0)); //--------------------------------------------------------------------- - // %a + // %g // // Floating-point conversions applicable to float, double, and // BigDecimal. //--------------------------------------------------------------------- - test("%a", "null", (Object)null); - test("%.11a", "0x0.00000000000p0", 0.0); - test(Locale.FRANCE, "%.11a", "0x0.00000000000p0", 0.0); // no localization - test("%.1a", "0x0.0p0", 0.0); - test("%.11a", "-0x0.00000000000p0", -0.0); - test("%.1a", "-0x0.0p0", -0.0); - test("%.11a", "0x1.00000000000p0", 1.0); - test("%.1a", "0x1.0p0", 1.0); - test("%.11a", "-0x1.00000000000p0", -1.0); - test("%.1a", "-0x1.0p0", -1.0); - test("%.11a", "0x1.80000000000p1", 3.0); - test("%.1a", "0x1.8p1", 3.0); - test("%.11a", "0x1.00000000000p-1022", Double.MIN_NORMAL); - test("%.1a", "0x1.0p-1022", Double.MIN_NORMAL); - test("%.11a", "0x1.00000000000p-1022", - Math.nextDown(Double.MIN_NORMAL)); - test("%.1a", "0x1.0p-1022", - Math.nextDown(Double.MIN_NORMAL)); - test("%.11a", "0x1.ffffffffffep-1023", 0x0.fffffffffffp-1022); - test("%.1a", "0x1.0p-1022", 0x0.fffffffffffp-1022); - test("%.30a", "0x0.000000000000100000000000000000p-1022", Double.MIN_VALUE); - test("%.13a", "0x0.0000000000001p-1022", Double.MIN_VALUE); - test("%.11a", "0x1.00000000000p-1074", Double.MIN_VALUE); - test("%.1a", "0x1.0p-1074", Double.MIN_VALUE); - - test("%.11a", "0x1.08000000000p-1069", - Double.MIN_VALUE + Double.MIN_VALUE*32); - test("%.1a", "0x1.0p-1069", - Double.MIN_VALUE + Double.MIN_VALUE*32); - test("%.30a", "0x1.fffffffffffff00000000000000000p1023", Double.MAX_VALUE); - test("%.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); - test("%.11a", "0x1.00000000000p1024", Double.MAX_VALUE); - test("%.1a", "0x1.0p1024", Double.MAX_VALUE); - test("%.11a", "0x1.18000000000p0", 0x1.18p0); - test("%.1a", "0x1.2p0", 0x1.18p0); - - test("%.11a", "0x1.18000000000p0", 0x1.180000000001p0); - test("%.1a", "0x1.2p0", 0x1.180000000001p0); - test("%.11a", "0x1.28000000000p0", 0x1.28p0); - test("%.1a", "0x1.2p0", 0x1.28p0); - - test("%.11a", "0x1.28000000000p0", 0x1.280000000001p0); - test("%.1a", "0x1.3p0", 0x1.280000000001p0); - - test("%a", "0x0.123p-1022", 0x0.123p-1022); - test("%1.3a", "0x1.230p-1026", 0x0.123p-1022); - test("%1.12a", "0x1.230000000000p-1026", 0x0.123p-1022); - test("%1.15a", "0x0.123000000000000p-1022", 0x0.123p-1022); - test("%1.5a", "0x1.00000p-1074", 0x0.0000000000001p-1022); - test("%1.7a", "0x1.0000000p-1022", 0x0.fffffffffffffp-1022); - - test("%1.6a", "0x1.230000p-1026", 0x0.123000057p-1022); - test("%1.7a", "0x1.2300005p-1026", 0x0.123000057p-1022); - test("%1.8a", "0x1.23000057p-1026", 0x0.123000057p-1022); - test("%1.9a", "0x1.230000570p-1026", 0x0.123000057p-1022); - - test("%1.6a", "0x1.230000p-1026", 0x0.123000058p-1022); - test("%1.7a", "0x1.2300006p-1026", 0x0.123000058p-1022); - test("%1.8a", "0x1.23000058p-1026", 0x0.123000058p-1022); - test("%1.9a", "0x1.230000580p-1026", 0x0.123000058p-1022); - - test("%1.6a", "0x1.230000p-1026", 0x0.123000059p-1022); - test("%1.7a", "0x1.2300006p-1026", 0x0.123000059p-1022); - test("%1.8a", "0x1.23000059p-1026", 0x0.123000059p-1022); - test("%1.9a", "0x1.230000590p-1026", 0x0.123000059p-1022); - - test("%1.4a", "0x1.0000p-1022", Math.nextDown(Double.MIN_NORMAL)); - - test("%a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); - test("%1.1a", "0x1.0p1024", Double.MAX_VALUE); - test("%1.2a", "0x1.00p1024", Double.MAX_VALUE); - test("%1.6a", "0x1.000000p1024", Double.MAX_VALUE); - test("%1.9a", "0x1.000000000p1024", Double.MAX_VALUE); - test("%1.11a", "0x1.00000000000p1024", Double.MAX_VALUE); - test("%1.12a", "0x1.000000000000p1024", Double.MAX_VALUE); - test("%1.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); - - - - //--------------------------------------------------------------------- - // %f, %e, %g, %a - Boundaries - //--------------------------------------------------------------------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + test("%g", "null", (Object)null); + test("%g", "3.14159", pi); + test(Locale.FRANCE, "%g", "3,14159", pi); + test("%.0g", "1e+01", ten); + test("%G", "3.14159", pi); + test("%10.3g", " 3.14", pi); + test("%10.3g", " -3.14", negate(pi)); + test("%010.3g", "0000003.14", pi); + test("%010.3g", "-000003.14", negate(pi)); + test("%-12.3g", "3.14 ", pi); + test("%-12.3g", "-3.14 ", negate(pi)); + test("%.3g", "3.14", pi); + test("%.3g", "-3.14", negate(pi)); + test("%.3g", "3.14e+08", mult(pi, 100000000.0)); + test("%.3g", "-3.14e+08", mult(pi, -100000000.0)); + test("%.3g", "1.00e-05", recip(create(100000.0))); + test("%.3g", "-1.00e-05", recip(create(-100000.0))); + test("%.0g", "-1e-05", recip(create(-100000.0))); + test("%.0g", "1e+05", create(100000.0)); + test("%.3G", "1.00E-05", recip(create(100000.0))); + test("%.3G", "-1.00E-05", recip(create(-100000.0))); + test("%.1g", "-0", -0.0); + test("%3.0g", " -0", -0.0); + test("%.1g", "0", 0.0); + test("%3.0g", " 0", 0.0); + test("%.1g", "0", +0.0); + test("%3.0g", " 0", +0.0); + test("%3.0g", "1e-06", 0.000001); + test("%3.0g", "1e-05", 0.00001); + test("%3.0g", "1e-05", 0.0000099); + test("%3.1g", "1e-05", 0.0000099); + test("%3.2g", "9.9e-06", 0.0000099); + test("%3.0g", "0.0001", 0.0001); + test("%3.0g", "9e-05", 0.00009); + test("%3.0g", "0.0001", 0.000099); + test("%3.1g", "0.0001", 0.000099); + test("%3.2g", "9.9e-05", 0.000099); + test("%3.0g", "0.001", 0.001); + test("%3.0g", "0.001", 0.00099); + test("%3.1g", "0.001", 0.00099); + test("%3.2g", "0.00099", 0.00099); + test("%3.3g", "0.00100", 0.001); + test("%3.4g", "0.001000", 0.001); + test("%3.0g", "0.01", 0.01); + test("%3.0g", "0.1", 0.1); + test("%3.0g", "0.9", 0.9); + test("%3.1g", "0.9", 0.9); + test("%3.0g", " 1", 1.00); + test("%3.2g", " 10", 10.00); + test("%3.0g", "1e+01", 10.00); + test("%3.0g", "1e+02", 99.19); + test("%3.1g", "1e+02", 99.19); + test("%3.2g", " 99", 99.19); + test("%3.0g", "1e+02", 99.9); + test("%3.1g", "1e+02", 99.9); + test("%3.2g", "1.0e+02", 99.9); + test("%3.0g", "1e+02", 99.99); + test("%3.0g", "1e+02", 100.00); + test("%3.0g", "1e+03", 999.9); + test("%3.1g", "1e+03", 999.9); + test("%3.2g", "1.0e+03", 999.9); + test("%3.3g", "1.00e+03", 999.9); + test("%3.4g", "999.9", 999.9); + test("%3.4g", "1000", 999.99); + test("%3.0g", "1e+03", 1000.00); + test("%3.0g", "1e+04", 10000.00); + test("%3.0g", "1e+05", 100000.00); + test("%3.0g", "1e+06", 1000000.00); + test("%3.0g", "1e+07", 10000000.00); + test("%3.9g", "100000000", 100000000.00); + test("%3.10g", "100000000.0", 100000000.00); + tryCatch("%#3.0g", FormatFlagsConversionMismatchException.class, 1000.00); + // double PI^300 + // = 13962455701329742638131355433930076081862072808 ... e+149 + test("%.3g", "10.0", ten); + test("%.3g", "1.00", one); + test("%10.3g", " 1.00", one); + test("%+10.3g", " +3.14", pi); + test("%+10.3g", " -3.14", negate(pi)); + test("% .3g", " 3.14", pi); + test("% .3g", "-3.14", negate(pi)); + test("%.0g", "3", create(3.0)); + test("%.0g", "-3", create(-3.0)); + test("%(.4g", "3.142e+08", mult(pi, 100000000.0)); + test("%(.4g", "(3.142e+08)", mult(pi, -100000000.0)); + test("%,.11g", "3,141,592.6536", mult(pi, 1000000.0)); + test("%(,.11g", "(3,141,592.6536)", mult(pi, -1000000.0)); + //--------------------------------------------------------------------- + // %a + // + // Floating-point conversions applicable to float, double, and + // BigDecimal. + //--------------------------------------------------------------------- + test("%a", "null", (Object)null); + test("%.11a", "0x0.00000000000p0", 0.0); + test(Locale.FRANCE, "%.11a", "0x0.00000000000p0", 0.0); // no localization + test("%.1a", "0x0.0p0", 0.0); + test("%.11a", "-0x0.00000000000p0", -0.0); + test("%.1a", "-0x0.0p0", -0.0); + test("%.11a", "0x1.00000000000p0", 1.0); + test("%.1a", "0x1.0p0", 1.0); + test("%.11a", "-0x1.00000000000p0", -1.0); + test("%.1a", "-0x1.0p0", -1.0); + test("%.11a", "0x1.80000000000p1", 3.0); + test("%.1a", "0x1.8p1", 3.0); + test("%.11a", "0x1.00000000000p-1022", Double.MIN_NORMAL); + test("%.1a", "0x1.0p-1022", Double.MIN_NORMAL); + test("%.11a", "0x1.00000000000p-1022", + Math.nextDown(Double.MIN_NORMAL)); + test("%.1a", "0x1.0p-1022", + Math.nextDown(Double.MIN_NORMAL)); + test("%.11a", "0x1.ffffffffffep-1023", 0x0.fffffffffffp-1022); + test("%.1a", "0x1.0p-1022", 0x0.fffffffffffp-1022); + test("%.30a", "0x0.000000000000100000000000000000p-1022", Double.MIN_VALUE); + test("%.13a", "0x0.0000000000001p-1022", Double.MIN_VALUE); + test("%.11a", "0x1.00000000000p-1074", Double.MIN_VALUE); + test("%.1a", "0x1.0p-1074", Double.MIN_VALUE); + test("%.11a", "0x1.08000000000p-1069", + Double.MIN_VALUE + Double.MIN_VALUE*32); + test("%.1a", "0x1.0p-1069", + Double.MIN_VALUE + Double.MIN_VALUE*32); + test("%.30a", "0x1.fffffffffffff00000000000000000p1023", Double.MAX_VALUE); + test("%.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); + test("%.11a", "0x1.00000000000p1024", Double.MAX_VALUE); + test("%.1a", "0x1.0p1024", Double.MAX_VALUE); + test("%.11a", "0x1.18000000000p0", 0x1.18p0); + test("%.1a", "0x1.2p0", 0x1.18p0); + test("%.11a", "0x1.18000000000p0", 0x1.180000000001p0); + test("%.1a", "0x1.2p0", 0x1.180000000001p0); + test("%.11a", "0x1.28000000000p0", 0x1.28p0); + test("%.1a", "0x1.2p0", 0x1.28p0); + test("%.11a", "0x1.28000000000p0", 0x1.280000000001p0); + test("%.1a", "0x1.3p0", 0x1.280000000001p0); + test("%a", "0x0.123p-1022", 0x0.123p-1022); + test("%1.3a", "0x1.230p-1026", 0x0.123p-1022); + test("%1.12a", "0x1.230000000000p-1026", 0x0.123p-1022); + test("%1.15a", "0x0.123000000000000p-1022", 0x0.123p-1022); + test("%1.5a", "0x1.00000p-1074", 0x0.0000000000001p-1022); + test("%1.7a", "0x1.0000000p-1022", 0x0.fffffffffffffp-1022); + test("%1.6a", "0x1.230000p-1026", 0x0.123000057p-1022); + test("%1.7a", "0x1.2300005p-1026", 0x0.123000057p-1022); + test("%1.8a", "0x1.23000057p-1026", 0x0.123000057p-1022); + test("%1.9a", "0x1.230000570p-1026", 0x0.123000057p-1022); + test("%1.6a", "0x1.230000p-1026", 0x0.123000058p-1022); + test("%1.7a", "0x1.2300006p-1026", 0x0.123000058p-1022); + test("%1.8a", "0x1.23000058p-1026", 0x0.123000058p-1022); + test("%1.9a", "0x1.230000580p-1026", 0x0.123000058p-1022); + test("%1.6a", "0x1.230000p-1026", 0x0.123000059p-1022); + test("%1.7a", "0x1.2300006p-1026", 0x0.123000059p-1022); + test("%1.8a", "0x1.23000059p-1026", 0x0.123000059p-1022); + test("%1.9a", "0x1.230000590p-1026", 0x0.123000059p-1022); + test("%1.4a", "0x1.0000p-1022", Math.nextDown(Double.MIN_NORMAL)); + test("%a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); + test("%1.1a", "0x1.0p1024", Double.MAX_VALUE); + test("%1.2a", "0x1.00p1024", Double.MAX_VALUE); + test("%1.6a", "0x1.000000p1024", Double.MAX_VALUE); + test("%1.9a", "0x1.000000000p1024", Double.MAX_VALUE); + test("%1.11a", "0x1.00000000000p1024", Double.MAX_VALUE); + test("%1.12a", "0x1.000000000000p1024", Double.MAX_VALUE); + test("%1.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); + //--------------------------------------------------------------------- + // %f, %e, %g, %a - Boundaries + //--------------------------------------------------------------------- //--------------------------------------------------------------------- // %f, %e, %g, %a - Double.MIN_VALUE @@ -1669,8 +658,6 @@ public static void test() { test("%30a", " 0x1.fffffffffffffp1023", Double.MAX_VALUE); - - //--------------------------------------------------------------------- // %t // @@ -1691,99 +678,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicDoubleObject.java b/test/jdk/java/util/Formatter/BasicDoubleObject.java index dd88af2ee16f3..a62a10400db9a 100644 --- a/test/jdk/java/util/Formatter/BasicDoubleObject.java +++ b/test/jdk/java/util/Formatter/BasicDoubleObject.java @@ -38,284 +38,7 @@ import static java.util.Calendar.*; - - - - public class BasicDoubleObject extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static Double create(double v) { @@ -334,7 +57,6 @@ private static Double recip(Double v) { return 1.0 / v.doubleValue(); } - public static void test() { TimeZone.setDefault(TimeZone.getTimeZone("GMT-0800")); @@ -522,1152 +244,271 @@ public static void test() { + //--------------------------------------------------------------------- + // %s - Double + //--------------------------------------------------------------------- + Double one = 1.0d; + Double ten = 10.0d; + Double pi = (double) Math.PI; + test("%s", "3.141592653589793", pi); + //--------------------------------------------------------------------- + // flag/conversion errors + //--------------------------------------------------------------------- + tryCatch("%d", IllegalFormatConversionException.class, one); + tryCatch("%,.4e", FormatFlagsConversionMismatchException.class, one); + //--------------------------------------------------------------------- + // %e + // + // Floating-point conversions applicable to float, double, and + // BigDecimal. + //--------------------------------------------------------------------- + test("%e", "null", (Object)null); + //--------------------------------------------------------------------- + // %e - float and double + //--------------------------------------------------------------------- + // double PI = 3.141 592 653 589 793 238 46; + test("%e", "3.141593e+00", pi); + test("%.0e", "1e+01", ten); + test("%#.0e", "1.e+01", ten); + test("%E", "3.141593E+00", pi); + test("%10.3e", " 3.142e+00", pi); + test("%10.3e", "-3.142e+00", negate(pi)); + test("%010.3e", "03.142e+00", pi); + test("%010.3e", "-3.142e+00", negate(pi)); + test("%-12.3e", "3.142e+00 ", pi); + test("%-12.3e", "-3.142e+00 ", negate(pi)); + test("%.3e", "3.142e+00", pi); + test("%.3e", "-3.142e+00", negate(pi)); + test("%.3e", "3.142e+06", mult(pi, 1000000.0)); + test("%.3e", "-3.142e+06", mult(pi, -1000000.0)); + test(Locale.FRANCE, "%e", "3,141593e+00", pi); + // double PI^300 + // = 13962455701329742638131355433930076081862072808 ... e+149 + test("%10.3e", " 1.000e+00", one); + test("%+.3e", "+3.142e+00", pi); + test("%+.3e", "-3.142e+00", negate(pi)); + test("% .3e", " 3.142e+00", pi); + test("% .3e", "-3.142e+00", negate(pi)); + test("%#.0e", "3.e+00", create(3.0)); + test("%#.0e", "-3.e+00", create(-3.0)); + test("%.0e", "3e+00", create(3.0)); + test("%.0e", "-3e+00", create(-3.0)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %s - Double - //--------------------------------------------------------------------- - Double one = 1.0d; - Double ten = 10.0d; - Double pi = (double) Math.PI; - - test("%s", "3.141592653589793", pi); - - - //--------------------------------------------------------------------- - // flag/conversion errors - //--------------------------------------------------------------------- - tryCatch("%d", IllegalFormatConversionException.class, one); - tryCatch("%,.4e", FormatFlagsConversionMismatchException.class, one); - - //--------------------------------------------------------------------- - // %e - // - // Floating-point conversions applicable to float, double, and - // BigDecimal. - //--------------------------------------------------------------------- - test("%e", "null", (Object)null); - - //--------------------------------------------------------------------- - // %e - float and double - //--------------------------------------------------------------------- - // double PI = 3.141 592 653 589 793 238 46; - test("%e", "3.141593e+00", pi); - test("%.0e", "1e+01", ten); - test("%#.0e", "1.e+01", ten); - test("%E", "3.141593E+00", pi); - test("%10.3e", " 3.142e+00", pi); - test("%10.3e", "-3.142e+00", negate(pi)); - test("%010.3e", "03.142e+00", pi); - test("%010.3e", "-3.142e+00", negate(pi)); - test("%-12.3e", "3.142e+00 ", pi); - test("%-12.3e", "-3.142e+00 ", negate(pi)); - test("%.3e", "3.142e+00", pi); - test("%.3e", "-3.142e+00", negate(pi)); - test("%.3e", "3.142e+06", mult(pi, 1000000.0)); - test("%.3e", "-3.142e+06", mult(pi, -1000000.0)); - - test(Locale.FRANCE, "%e", "3,141593e+00", pi); - - // double PI^300 - // = 13962455701329742638131355433930076081862072808 ... e+149 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - test("%10.3e", " 1.000e+00", one); - test("%+.3e", "+3.142e+00", pi); - test("%+.3e", "-3.142e+00", negate(pi)); - test("% .3e", " 3.142e+00", pi); - test("% .3e", "-3.142e+00", negate(pi)); - test("%#.0e", "3.e+00", create(3.0)); - test("%#.0e", "-3.e+00", create(-3.0)); - test("%.0e", "3e+00", create(3.0)); - test("%.0e", "-3e+00", create(-3.0)); - - test("%(.4e", "3.1416e+06", mult(pi, 1000000.0)); - test("%(.4e", "(3.1416e+06)", mult(pi, -1000000.0)); - - //--------------------------------------------------------------------- - // %e - boundary problems - //--------------------------------------------------------------------- - test("%3.0e", "1e-06", 0.000001); - test("%3.0e", "1e-05", 0.00001); - test("%3.0e", "1e-04", 0.0001); - test("%3.0e", "1e-03", 0.001); - test("%3.0e", "1e-02", 0.01); - test("%3.0e", "1e-01", 0.1); - test("%3.0e", "9e-01", 0.9); - test("%3.1e", "9.0e-01", 0.9); - test("%3.0e", "1e+00", 1.00); - test("%3.0e", "1e+01", 10.00); - test("%3.0e", "1e+02", 99.19); - test("%3.1e", "9.9e+01", 99.19); - test("%3.0e", "1e+02", 99.99); - test("%3.0e", "1e+02", 100.00); - test("%#3.0e", "1.e+03", 1000.00); - test("%3.0e", "1e+04", 10000.00); - test("%3.0e", "1e+05", 100000.00); - test("%3.0e", "1e+06", 1000000.00); - test("%3.0e", "1e+07", 10000000.00); - test("%3.0e", "1e+08", 100000000.00); - - //--------------------------------------------------------------------- - // %f - // - // Floating-point conversions applicable to float, double, and - // BigDecimal. - //--------------------------------------------------------------------- - test("%f", "null", (Object)null); - test("%f", "3.141593", pi); - test(Locale.FRANCE, "%f", "3,141593", pi); - test("%10.3f", " 3.142", pi); - test("%10.3f", " -3.142", negate(pi)); - test("%010.3f", "000003.142", pi); - test("%010.3f", "-00003.142", negate(pi)); - test("%-10.3f", "3.142 ", pi); - test("%-10.3f", "-3.142 ", negate(pi)); - test("%.3f", "3.142", pi); - test("%.3f", "-3.142", negate(pi)); - test("%+.3f", "+3.142", pi); - test("%+.3f", "-3.142", negate(pi)); - test("% .3f", " 3.142", pi); - test("% .3f", "-3.142", negate(pi)); - test("%#.0f", "3.", create(3.0)); - test("%#.0f", "-3.", create(-3.0)); - test("%.0f", "3", create(3.0)); - test("%.0f", "-3", create(-3.0)); - test("%.3f", "10.000", ten); - test("%.3f", "1.000", one); - test("%10.3f", " 1.000", one); - - //--------------------------------------------------------------------- - // %f - boundary problems - //--------------------------------------------------------------------- - test("%3.0f", " 0", 0.000001); - test("%3.0f", " 0", 0.00001); - test("%3.0f", " 0", 0.0001); - test("%3.0f", " 0", 0.001); - test("%3.0f", " 0", 0.01); - test("%3.0f", " 0", 0.1); - test("%3.0f", " 1", 0.9); - test("%3.1f", "0.9", 0.9); - test("%3.0f", " 1", 1.00); - test("%3.0f", " 10", 10.00); - test("%3.0f", " 99", 99.19); - test("%3.1f", "99.2", 99.19); - test("%3.0f", "100", 99.99); - test("%3.0f", "100", 100.00); - test("%#3.0f", "1000.", 1000.00); - test("%3.0f", "10000", 10000.00); - test("%3.0f", "100000", 100000.00); - test("%3.0f", "1000000", 1000000.00); - test("%3.0f", "10000000", 10000000.00); - test("%3.0f", "100000000", 100000000.00); - test("%10.0f", " 1000000", 1000000.00); - test("%,10.0f", " 1,000,000", 1000000.00); - test("%,10.1f", "1,000,000.0", 1000000.00); - test("%,3.0f", "1,000,000", 1000000.00); - test("%,3.0f", "10,000,000", 10000000.00); - test("%,3.0f", "100,000,000", 100000000.00); - test("%,3.0f", "10,000,000", 10000000.00); - test("%,3.0f", "100,000,000", 100000000.00); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %f - float, double, Double, BigDecimal - //--------------------------------------------------------------------- - test("%.3f", "3141592.654", mult(pi, 1000000.0)); - test("%.3f", "-3141592.654", mult(pi, -1000000.0)); - test("%,.4f", "3,141,592.6536", mult(pi, 1000000.0)); - test(Locale.FRANCE, "%,.4f", "3\u202f141\u202f592,6536", mult(pi, 1000000.0)); - test("%,.4f", "-3,141,592.6536", mult(pi, -1000000.0)); - test("%(.4f", "3141592.6536", mult(pi, 1000000.0)); - test("%(.4f", "(3141592.6536)", mult(pi, -1000000.0)); - test("%(,.4f", "3,141,592.6536", mult(pi, 1000000.0)); - test("%(,.4f", "(3,141,592.6536)", mult(pi, -1000000.0)); - - - - - //--------------------------------------------------------------------- - // %g - // - // Floating-point conversions applicable to float, double, and - // BigDecimal. - //--------------------------------------------------------------------- - test("%g", "null", (Object)null); - test("%g", "3.14159", pi); - test(Locale.FRANCE, "%g", "3,14159", pi); - test("%.0g", "1e+01", ten); - test("%G", "3.14159", pi); - test("%10.3g", " 3.14", pi); - test("%10.3g", " -3.14", negate(pi)); - test("%010.3g", "0000003.14", pi); - test("%010.3g", "-000003.14", negate(pi)); - test("%-12.3g", "3.14 ", pi); - test("%-12.3g", "-3.14 ", negate(pi)); - test("%.3g", "3.14", pi); - test("%.3g", "-3.14", negate(pi)); - test("%.3g", "3.14e+08", mult(pi, 100000000.0)); - test("%.3g", "-3.14e+08", mult(pi, -100000000.0)); - - test("%.3g", "1.00e-05", recip(create(100000.0))); - test("%.3g", "-1.00e-05", recip(create(-100000.0))); - test("%.0g", "-1e-05", recip(create(-100000.0))); - test("%.0g", "1e+05", create(100000.0)); - test("%.3G", "1.00E-05", recip(create(100000.0))); - test("%.3G", "-1.00E-05", recip(create(-100000.0))); - - test("%.1g", "-0", -0.0); - test("%3.0g", " -0", -0.0); - test("%.1g", "0", 0.0); - test("%3.0g", " 0", 0.0); - test("%.1g", "0", +0.0); - test("%3.0g", " 0", +0.0); - - test("%3.0g", "1e-06", 0.000001); - test("%3.0g", "1e-05", 0.00001); - test("%3.0g", "1e-05", 0.0000099); - test("%3.1g", "1e-05", 0.0000099); - test("%3.2g", "9.9e-06", 0.0000099); - test("%3.0g", "0.0001", 0.0001); - test("%3.0g", "9e-05", 0.00009); - test("%3.0g", "0.0001", 0.000099); - test("%3.1g", "0.0001", 0.000099); - test("%3.2g", "9.9e-05", 0.000099); - test("%3.0g", "0.001", 0.001); - test("%3.0g", "0.001", 0.00099); - test("%3.1g", "0.001", 0.00099); - test("%3.2g", "0.00099", 0.00099); - test("%3.3g", "0.00100", 0.001); - test("%3.4g", "0.001000", 0.001); - test("%3.0g", "0.01", 0.01); - test("%3.0g", "0.1", 0.1); - test("%3.0g", "0.9", 0.9); - test("%3.1g", "0.9", 0.9); - test("%3.0g", " 1", 1.00); - test("%3.2g", " 10", 10.00); - test("%3.0g", "1e+01", 10.00); - test("%3.0g", "1e+02", 99.19); - test("%3.1g", "1e+02", 99.19); - test("%3.2g", " 99", 99.19); - test("%3.0g", "1e+02", 99.9); - test("%3.1g", "1e+02", 99.9); - test("%3.2g", "1.0e+02", 99.9); - test("%3.0g", "1e+02", 99.99); - test("%3.0g", "1e+02", 100.00); - test("%3.0g", "1e+03", 999.9); - test("%3.1g", "1e+03", 999.9); - test("%3.2g", "1.0e+03", 999.9); - test("%3.3g", "1.00e+03", 999.9); - test("%3.4g", "999.9", 999.9); - test("%3.4g", "1000", 999.99); - test("%3.0g", "1e+03", 1000.00); - test("%3.0g", "1e+04", 10000.00); - test("%3.0g", "1e+05", 100000.00); - test("%3.0g", "1e+06", 1000000.00); - test("%3.0g", "1e+07", 10000000.00); - test("%3.9g", "100000000", 100000000.00); - test("%3.10g", "100000000.0", 100000000.00); - - tryCatch("%#3.0g", FormatFlagsConversionMismatchException.class, 1000.00); - - // double PI^300 - // = 13962455701329742638131355433930076081862072808 ... e+149 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - test("%.3g", "10.0", ten); - test("%.3g", "1.00", one); - test("%10.3g", " 1.00", one); - test("%+10.3g", " +3.14", pi); - test("%+10.3g", " -3.14", negate(pi)); - test("% .3g", " 3.14", pi); - test("% .3g", "-3.14", negate(pi)); - test("%.0g", "3", create(3.0)); - test("%.0g", "-3", create(-3.0)); - - test("%(.4g", "3.142e+08", mult(pi, 100000000.0)); - test("%(.4g", "(3.142e+08)", mult(pi, -100000000.0)); - - - - - - - - test("%,.11g", "3,141,592.6536", mult(pi, 1000000.0)); - test("%(,.11g", "(3,141,592.6536)", mult(pi, -1000000.0)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + test("%(.4e", "3.1416e+06", mult(pi, 1000000.0)); + test("%(.4e", "(3.1416e+06)", mult(pi, -1000000.0)); //--------------------------------------------------------------------- - // %f, %e, %g, %a - Boundaries + // %e - boundary problems //--------------------------------------------------------------------- + test("%3.0e", "1e-06", 0.000001); + test("%3.0e", "1e-05", 0.00001); + test("%3.0e", "1e-04", 0.0001); + test("%3.0e", "1e-03", 0.001); + test("%3.0e", "1e-02", 0.01); + test("%3.0e", "1e-01", 0.1); + test("%3.0e", "9e-01", 0.9); + test("%3.1e", "9.0e-01", 0.9); + test("%3.0e", "1e+00", 1.00); + test("%3.0e", "1e+01", 10.00); + test("%3.0e", "1e+02", 99.19); + test("%3.1e", "9.9e+01", 99.19); + test("%3.0e", "1e+02", 99.99); + test("%3.0e", "1e+02", 100.00); + test("%#3.0e", "1.e+03", 1000.00); + test("%3.0e", "1e+04", 10000.00); + test("%3.0e", "1e+05", 100000.00); + test("%3.0e", "1e+06", 1000000.00); + test("%3.0e", "1e+07", 10000000.00); + test("%3.0e", "1e+08", 100000000.00); + //--------------------------------------------------------------------- + // %f + // + // Floating-point conversions applicable to float, double, and + // BigDecimal. + //--------------------------------------------------------------------- + test("%f", "null", (Object)null); + test("%f", "3.141593", pi); + test(Locale.FRANCE, "%f", "3,141593", pi); + test("%10.3f", " 3.142", pi); + test("%10.3f", " -3.142", negate(pi)); + test("%010.3f", "000003.142", pi); + test("%010.3f", "-00003.142", negate(pi)); + test("%-10.3f", "3.142 ", pi); + test("%-10.3f", "-3.142 ", negate(pi)); + test("%.3f", "3.142", pi); + test("%.3f", "-3.142", negate(pi)); + test("%+.3f", "+3.142", pi); + test("%+.3f", "-3.142", negate(pi)); + test("% .3f", " 3.142", pi); + test("% .3f", "-3.142", negate(pi)); + test("%#.0f", "3.", create(3.0)); + test("%#.0f", "-3.", create(-3.0)); + test("%.0f", "3", create(3.0)); + test("%.0f", "-3", create(-3.0)); + test("%.3f", "10.000", ten); + test("%.3f", "1.000", one); + test("%10.3f", " 1.000", one); + //--------------------------------------------------------------------- + // %f - boundary problems + //--------------------------------------------------------------------- + test("%3.0f", " 0", 0.000001); + test("%3.0f", " 0", 0.00001); + test("%3.0f", " 0", 0.0001); + test("%3.0f", " 0", 0.001); + test("%3.0f", " 0", 0.01); + test("%3.0f", " 0", 0.1); + test("%3.0f", " 1", 0.9); + test("%3.1f", "0.9", 0.9); + test("%3.0f", " 1", 1.00); + test("%3.0f", " 10", 10.00); + test("%3.0f", " 99", 99.19); + test("%3.1f", "99.2", 99.19); + test("%3.0f", "100", 99.99); + test("%3.0f", "100", 100.00); + test("%#3.0f", "1000.", 1000.00); + test("%3.0f", "10000", 10000.00); + test("%3.0f", "100000", 100000.00); + test("%3.0f", "1000000", 1000000.00); + test("%3.0f", "10000000", 10000000.00); + test("%3.0f", "100000000", 100000000.00); + test("%10.0f", " 1000000", 1000000.00); + test("%,10.0f", " 1,000,000", 1000000.00); + test("%,10.1f", "1,000,000.0", 1000000.00); + test("%,3.0f", "1,000,000", 1000000.00); + test("%,3.0f", "10,000,000", 10000000.00); + test("%,3.0f", "100,000,000", 100000000.00); + test("%,3.0f", "10,000,000", 10000000.00); + test("%,3.0f", "100,000,000", 100000000.00); + //--------------------------------------------------------------------- + // %f - float, double, Double, BigDecimal + //--------------------------------------------------------------------- + test("%.3f", "3141592.654", mult(pi, 1000000.0)); + test("%.3f", "-3141592.654", mult(pi, -1000000.0)); + test("%,.4f", "3,141,592.6536", mult(pi, 1000000.0)); + test(Locale.FRANCE, "%,.4f", "3\u202f141\u202f592,6536", mult(pi, 1000000.0)); + test("%,.4f", "-3,141,592.6536", mult(pi, -1000000.0)); + test("%(.4f", "3141592.6536", mult(pi, 1000000.0)); + test("%(.4f", "(3141592.6536)", mult(pi, -1000000.0)); + test("%(,.4f", "3,141,592.6536", mult(pi, 1000000.0)); + test("%(,.4f", "(3,141,592.6536)", mult(pi, -1000000.0)); + //--------------------------------------------------------------------- + // %g + // + // Floating-point conversions applicable to float, double, and + // BigDecimal. + //--------------------------------------------------------------------- + test("%g", "null", (Object)null); + test("%g", "3.14159", pi); + test(Locale.FRANCE, "%g", "3,14159", pi); + test("%.0g", "1e+01", ten); + test("%G", "3.14159", pi); + test("%10.3g", " 3.14", pi); + test("%10.3g", " -3.14", negate(pi)); + test("%010.3g", "0000003.14", pi); + test("%010.3g", "-000003.14", negate(pi)); + test("%-12.3g", "3.14 ", pi); + test("%-12.3g", "-3.14 ", negate(pi)); + test("%.3g", "3.14", pi); + test("%.3g", "-3.14", negate(pi)); + test("%.3g", "3.14e+08", mult(pi, 100000000.0)); + test("%.3g", "-3.14e+08", mult(pi, -100000000.0)); + test("%.3g", "1.00e-05", recip(create(100000.0))); + test("%.3g", "-1.00e-05", recip(create(-100000.0))); + test("%.0g", "-1e-05", recip(create(-100000.0))); + test("%.0g", "1e+05", create(100000.0)); + test("%.3G", "1.00E-05", recip(create(100000.0))); + test("%.3G", "-1.00E-05", recip(create(-100000.0))); + test("%.1g", "-0", -0.0); + test("%3.0g", " -0", -0.0); + test("%.1g", "0", 0.0); + test("%3.0g", " 0", 0.0); + test("%.1g", "0", +0.0); + test("%3.0g", " 0", +0.0); + test("%3.0g", "1e-06", 0.000001); + test("%3.0g", "1e-05", 0.00001); + test("%3.0g", "1e-05", 0.0000099); + test("%3.1g", "1e-05", 0.0000099); + test("%3.2g", "9.9e-06", 0.0000099); + test("%3.0g", "0.0001", 0.0001); + test("%3.0g", "9e-05", 0.00009); + test("%3.0g", "0.0001", 0.000099); + test("%3.1g", "0.0001", 0.000099); + test("%3.2g", "9.9e-05", 0.000099); + test("%3.0g", "0.001", 0.001); + test("%3.0g", "0.001", 0.00099); + test("%3.1g", "0.001", 0.00099); + test("%3.2g", "0.00099", 0.00099); + test("%3.3g", "0.00100", 0.001); + test("%3.4g", "0.001000", 0.001); + test("%3.0g", "0.01", 0.01); + test("%3.0g", "0.1", 0.1); + test("%3.0g", "0.9", 0.9); + test("%3.1g", "0.9", 0.9); + test("%3.0g", " 1", 1.00); + test("%3.2g", " 10", 10.00); + test("%3.0g", "1e+01", 10.00); + test("%3.0g", "1e+02", 99.19); + test("%3.1g", "1e+02", 99.19); + test("%3.2g", " 99", 99.19); + test("%3.0g", "1e+02", 99.9); + test("%3.1g", "1e+02", 99.9); + test("%3.2g", "1.0e+02", 99.9); + test("%3.0g", "1e+02", 99.99); + test("%3.0g", "1e+02", 100.00); + test("%3.0g", "1e+03", 999.9); + test("%3.1g", "1e+03", 999.9); + test("%3.2g", "1.0e+03", 999.9); + test("%3.3g", "1.00e+03", 999.9); + test("%3.4g", "999.9", 999.9); + test("%3.4g", "1000", 999.99); + test("%3.0g", "1e+03", 1000.00); + test("%3.0g", "1e+04", 10000.00); + test("%3.0g", "1e+05", 100000.00); + test("%3.0g", "1e+06", 1000000.00); + test("%3.0g", "1e+07", 10000000.00); + test("%3.9g", "100000000", 100000000.00); + test("%3.10g", "100000000.0", 100000000.00); + tryCatch("%#3.0g", FormatFlagsConversionMismatchException.class, 1000.00); + // double PI^300 + // = 13962455701329742638131355433930076081862072808 ... e+149 + test("%.3g", "10.0", ten); + test("%.3g", "1.00", one); + test("%10.3g", " 1.00", one); + test("%+10.3g", " +3.14", pi); + test("%+10.3g", " -3.14", negate(pi)); + test("% .3g", " 3.14", pi); + test("% .3g", "-3.14", negate(pi)); + test("%.0g", "3", create(3.0)); + test("%.0g", "-3", create(-3.0)); + test("%(.4g", "3.142e+08", mult(pi, 100000000.0)); + test("%(.4g", "(3.142e+08)", mult(pi, -100000000.0)); + test("%,.11g", "3,141,592.6536", mult(pi, 1000000.0)); + test("%(,.11g", "(3,141,592.6536)", mult(pi, -1000000.0)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + //--------------------------------------------------------------------- + // %f, %e, %g, %a - Boundaries + //--------------------------------------------------------------------- @@ -1691,99 +532,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicFloat.java b/test/jdk/java/util/Formatter/BasicFloat.java index 3f5aa78f226c8..ba61b3f52d04b 100644 --- a/test/jdk/java/util/Formatter/BasicFloat.java +++ b/test/jdk/java/util/Formatter/BasicFloat.java @@ -38,232 +38,7 @@ import static java.util.Calendar.*; - - - - public class BasicFloat extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static float create(double v) { @@ -282,59 +57,6 @@ private static float recip(float v) { return 1.0f / v; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static void test() { TimeZone.setDefault(TimeZone.getTimeZone("GMT-0800")); @@ -522,487 +244,65 @@ public static void test() { + //--------------------------------------------------------------------- + // %s - float + //--------------------------------------------------------------------- + float one = 1.0f; + float ten = 10.0f; + float pi = (float) Math.PI; + test("%s", "3.1415927", pi); + //--------------------------------------------------------------------- + // flag/conversion errors + //--------------------------------------------------------------------- + tryCatch("%d", IllegalFormatConversionException.class, one); + tryCatch("%,.4e", FormatFlagsConversionMismatchException.class, one); + //--------------------------------------------------------------------- + // %e + // + // Floating-point conversions applicable to float, double, and + // BigDecimal. + //--------------------------------------------------------------------- + test("%e", "null", (Object)null); + //--------------------------------------------------------------------- + // %e - float and double + //--------------------------------------------------------------------- + // double PI = 3.141 592 653 589 793 238 46; + test("%e", "3.141593e+00", pi); + test("%.0e", "1e+01", ten); + test("%#.0e", "1.e+01", ten); + test("%E", "3.141593E+00", pi); + test("%10.3e", " 3.142e+00", pi); + test("%10.3e", "-3.142e+00", negate(pi)); + test("%010.3e", "03.142e+00", pi); + test("%010.3e", "-3.142e+00", negate(pi)); + test("%-12.3e", "3.142e+00 ", pi); + test("%-12.3e", "-3.142e+00 ", negate(pi)); + test("%.3e", "3.142e+00", pi); + test("%.3e", "-3.142e+00", negate(pi)); + test("%.3e", "3.142e+06", mult(pi, 1000000.0)); + test("%.3e", "-3.142e+06", mult(pi, -1000000.0)); + test(Locale.FRANCE, "%e", "3,141593e+00", pi); + // double PI^300 + // = 13962455701329742638131355433930076081862072808 ... e+149 + test("%10.3e", " 1.000e+00", one); + test("%+.3e", "+3.142e+00", pi); + test("%+.3e", "-3.142e+00", negate(pi)); + test("% .3e", " 3.142e+00", pi); + test("% .3e", "-3.142e+00", negate(pi)); + test("%#.0e", "3.e+00", create(3.0)); + test("%#.0e", "-3.e+00", create(-3.0)); + test("%.0e", "3e+00", create(3.0)); + test("%.0e", "-3e+00", create(-3.0)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %s - float - //--------------------------------------------------------------------- - float one = 1.0f; - float ten = 10.0f; - float pi = (float) Math.PI; - - test("%s", "3.1415927", pi); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // flag/conversion errors - //--------------------------------------------------------------------- - tryCatch("%d", IllegalFormatConversionException.class, one); - tryCatch("%,.4e", FormatFlagsConversionMismatchException.class, one); - - //--------------------------------------------------------------------- - // %e - // - // Floating-point conversions applicable to float, double, and - // BigDecimal. - //--------------------------------------------------------------------- - test("%e", "null", (Object)null); - - //--------------------------------------------------------------------- - // %e - float and double - //--------------------------------------------------------------------- - // double PI = 3.141 592 653 589 793 238 46; - test("%e", "3.141593e+00", pi); - test("%.0e", "1e+01", ten); - test("%#.0e", "1.e+01", ten); - test("%E", "3.141593E+00", pi); - test("%10.3e", " 3.142e+00", pi); - test("%10.3e", "-3.142e+00", negate(pi)); - test("%010.3e", "03.142e+00", pi); - test("%010.3e", "-3.142e+00", negate(pi)); - test("%-12.3e", "3.142e+00 ", pi); - test("%-12.3e", "-3.142e+00 ", negate(pi)); - test("%.3e", "3.142e+00", pi); - test("%.3e", "-3.142e+00", negate(pi)); - test("%.3e", "3.142e+06", mult(pi, 1000000.0)); - test("%.3e", "-3.142e+06", mult(pi, -1000000.0)); - - test(Locale.FRANCE, "%e", "3,141593e+00", pi); - - // double PI^300 - // = 13962455701329742638131355433930076081862072808 ... e+149 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - test("%10.3e", " 1.000e+00", one); - test("%+.3e", "+3.142e+00", pi); - test("%+.3e", "-3.142e+00", negate(pi)); - test("% .3e", " 3.142e+00", pi); - test("% .3e", "-3.142e+00", negate(pi)); - test("%#.0e", "3.e+00", create(3.0)); - test("%#.0e", "-3.e+00", create(-3.0)); - test("%.0e", "3e+00", create(3.0)); - test("%.0e", "-3e+00", create(-3.0)); - - test("%(.4e", "3.1416e+06", mult(pi, 1000000.0)); - test("%(.4e", "(3.1416e+06)", mult(pi, -1000000.0)); + test("%(.4e", "3.1416e+06", mult(pi, 1000000.0)); + test("%(.4e", "(3.1416e+06)", mult(pi, -1000000.0)); //--------------------------------------------------------------------- // %e - boundary problems @@ -1089,85 +389,6 @@ public static void test() { test("%,3.0f", "10,000,000", 10000000.00); test("%,3.0f", "100,000,000", 100000000.00); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %f - float //--------------------------------------------------------------------- @@ -1185,22 +406,6 @@ public static void test() { - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %g // @@ -1280,48 +485,12 @@ public static void test() { test("%3.0g", "1e+06", 1000000.00); test("%3.0g", "1e+07", 10000000.00); test("%3.9g", "100000000", 100000000.00); - test("%3.10g", "100000000.0", 100000000.00); - - tryCatch("%#3.0g", FormatFlagsConversionMismatchException.class, 1000.00); - - // double PI^300 - // = 13962455701329742638131355433930076081862072808 ... e+149 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + test("%3.10g", "100000000.0", 100000000.00); + tryCatch("%#3.0g", FormatFlagsConversionMismatchException.class, 1000.00); + // double PI^300 + // = 13962455701329742638131355433930076081862072808 ... e+149 test("%.3g", "10.0", ten); test("%.3g", "1.00", one); @@ -1336,107 +505,14 @@ public static void test() { test("%(.4g", "3.142e+08", mult(pi, 100000000.0)); test("%(.4g", "(3.142e+08)", mult(pi, -100000000.0)); - // Float can not accurately store 1e6 * PI. test("%,.6g", "3,141.59", mult(pi, 1000.0)); test("%(,.6g", "(3,141.59)", mult(pi, -1000.0)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %f, %e, %g, %a - Boundaries //--------------------------------------------------------------------- - //--------------------------------------------------------------------- // %f, %e, %g, %a - NaN //--------------------------------------------------------------------- @@ -1605,72 +681,6 @@ public static void test() { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %t // @@ -1691,99 +701,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicFloatObject.java b/test/jdk/java/util/Formatter/BasicFloatObject.java index ac08d0eab4fd7..9bfe1dcc036c8 100644 --- a/test/jdk/java/util/Formatter/BasicFloatObject.java +++ b/test/jdk/java/util/Formatter/BasicFloatObject.java @@ -38,249 +38,7 @@ import static java.util.Calendar.*; - - - - public class BasicFloatObject extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static Float create(double v) { @@ -299,42 +57,6 @@ private static Float recip(Float v) { return 1.0f / v.floatValue(); } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static void test() { TimeZone.setDefault(TimeZone.getTimeZone("GMT-0800")); @@ -522,1152 +244,257 @@ public static void test() { + //--------------------------------------------------------------------- + // %s - Float + //--------------------------------------------------------------------- + Float one = 1.0f; + Float ten = 10.0f; + Float pi = (float) Math.PI; + test("%s", "3.1415927", pi); + //--------------------------------------------------------------------- + // flag/conversion errors + //--------------------------------------------------------------------- + tryCatch("%d", IllegalFormatConversionException.class, one); + tryCatch("%,.4e", FormatFlagsConversionMismatchException.class, one); + //--------------------------------------------------------------------- + // %e + // + // Floating-point conversions applicable to float, double, and + // BigDecimal. + //--------------------------------------------------------------------- + test("%e", "null", (Object)null); + //--------------------------------------------------------------------- + // %e - float and double + //--------------------------------------------------------------------- + // double PI = 3.141 592 653 589 793 238 46; + test("%e", "3.141593e+00", pi); + test("%.0e", "1e+01", ten); + test("%#.0e", "1.e+01", ten); + test("%E", "3.141593E+00", pi); + test("%10.3e", " 3.142e+00", pi); + test("%10.3e", "-3.142e+00", negate(pi)); + test("%010.3e", "03.142e+00", pi); + test("%010.3e", "-3.142e+00", negate(pi)); + test("%-12.3e", "3.142e+00 ", pi); + test("%-12.3e", "-3.142e+00 ", negate(pi)); + test("%.3e", "3.142e+00", pi); + test("%.3e", "-3.142e+00", negate(pi)); + test("%.3e", "3.142e+06", mult(pi, 1000000.0)); + test("%.3e", "-3.142e+06", mult(pi, -1000000.0)); + test(Locale.FRANCE, "%e", "3,141593e+00", pi); + // double PI^300 + // = 13962455701329742638131355433930076081862072808 ... e+149 + test("%10.3e", " 1.000e+00", one); + test("%+.3e", "+3.142e+00", pi); + test("%+.3e", "-3.142e+00", negate(pi)); + test("% .3e", " 3.142e+00", pi); + test("% .3e", "-3.142e+00", negate(pi)); + test("%#.0e", "3.e+00", create(3.0)); + test("%#.0e", "-3.e+00", create(-3.0)); + test("%.0e", "3e+00", create(3.0)); + test("%.0e", "-3e+00", create(-3.0)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %s - Float - //--------------------------------------------------------------------- - Float one = 1.0f; - Float ten = 10.0f; - Float pi = (float) Math.PI; - - test("%s", "3.1415927", pi); - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // flag/conversion errors - //--------------------------------------------------------------------- - tryCatch("%d", IllegalFormatConversionException.class, one); - tryCatch("%,.4e", FormatFlagsConversionMismatchException.class, one); - - //--------------------------------------------------------------------- - // %e - // - // Floating-point conversions applicable to float, double, and - // BigDecimal. - //--------------------------------------------------------------------- - test("%e", "null", (Object)null); - - //--------------------------------------------------------------------- - // %e - float and double - //--------------------------------------------------------------------- - // double PI = 3.141 592 653 589 793 238 46; - test("%e", "3.141593e+00", pi); - test("%.0e", "1e+01", ten); - test("%#.0e", "1.e+01", ten); - test("%E", "3.141593E+00", pi); - test("%10.3e", " 3.142e+00", pi); - test("%10.3e", "-3.142e+00", negate(pi)); - test("%010.3e", "03.142e+00", pi); - test("%010.3e", "-3.142e+00", negate(pi)); - test("%-12.3e", "3.142e+00 ", pi); - test("%-12.3e", "-3.142e+00 ", negate(pi)); - test("%.3e", "3.142e+00", pi); - test("%.3e", "-3.142e+00", negate(pi)); - test("%.3e", "3.142e+06", mult(pi, 1000000.0)); - test("%.3e", "-3.142e+06", mult(pi, -1000000.0)); - - test(Locale.FRANCE, "%e", "3,141593e+00", pi); - - // double PI^300 - // = 13962455701329742638131355433930076081862072808 ... e+149 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - test("%10.3e", " 1.000e+00", one); - test("%+.3e", "+3.142e+00", pi); - test("%+.3e", "-3.142e+00", negate(pi)); - test("% .3e", " 3.142e+00", pi); - test("% .3e", "-3.142e+00", negate(pi)); - test("%#.0e", "3.e+00", create(3.0)); - test("%#.0e", "-3.e+00", create(-3.0)); - test("%.0e", "3e+00", create(3.0)); - test("%.0e", "-3e+00", create(-3.0)); - - test("%(.4e", "3.1416e+06", mult(pi, 1000000.0)); - test("%(.4e", "(3.1416e+06)", mult(pi, -1000000.0)); - - //--------------------------------------------------------------------- - // %e - boundary problems - //--------------------------------------------------------------------- - test("%3.0e", "1e-06", 0.000001); - test("%3.0e", "1e-05", 0.00001); - test("%3.0e", "1e-04", 0.0001); - test("%3.0e", "1e-03", 0.001); - test("%3.0e", "1e-02", 0.01); - test("%3.0e", "1e-01", 0.1); - test("%3.0e", "9e-01", 0.9); - test("%3.1e", "9.0e-01", 0.9); - test("%3.0e", "1e+00", 1.00); - test("%3.0e", "1e+01", 10.00); - test("%3.0e", "1e+02", 99.19); - test("%3.1e", "9.9e+01", 99.19); - test("%3.0e", "1e+02", 99.99); - test("%3.0e", "1e+02", 100.00); - test("%#3.0e", "1.e+03", 1000.00); - test("%3.0e", "1e+04", 10000.00); - test("%3.0e", "1e+05", 100000.00); - test("%3.0e", "1e+06", 1000000.00); - test("%3.0e", "1e+07", 10000000.00); - test("%3.0e", "1e+08", 100000000.00); - - //--------------------------------------------------------------------- - // %f - // - // Floating-point conversions applicable to float, double, and - // BigDecimal. - //--------------------------------------------------------------------- - test("%f", "null", (Object)null); - test("%f", "3.141593", pi); - test(Locale.FRANCE, "%f", "3,141593", pi); - test("%10.3f", " 3.142", pi); - test("%10.3f", " -3.142", negate(pi)); - test("%010.3f", "000003.142", pi); - test("%010.3f", "-00003.142", negate(pi)); - test("%-10.3f", "3.142 ", pi); - test("%-10.3f", "-3.142 ", negate(pi)); - test("%.3f", "3.142", pi); - test("%.3f", "-3.142", negate(pi)); - test("%+.3f", "+3.142", pi); - test("%+.3f", "-3.142", negate(pi)); - test("% .3f", " 3.142", pi); - test("% .3f", "-3.142", negate(pi)); - test("%#.0f", "3.", create(3.0)); - test("%#.0f", "-3.", create(-3.0)); - test("%.0f", "3", create(3.0)); - test("%.0f", "-3", create(-3.0)); - test("%.3f", "10.000", ten); - test("%.3f", "1.000", one); - test("%10.3f", " 1.000", one); - - //--------------------------------------------------------------------- - // %f - boundary problems - //--------------------------------------------------------------------- - test("%3.0f", " 0", 0.000001); - test("%3.0f", " 0", 0.00001); - test("%3.0f", " 0", 0.0001); - test("%3.0f", " 0", 0.001); - test("%3.0f", " 0", 0.01); - test("%3.0f", " 0", 0.1); - test("%3.0f", " 1", 0.9); - test("%3.1f", "0.9", 0.9); - test("%3.0f", " 1", 1.00); - test("%3.0f", " 10", 10.00); - test("%3.0f", " 99", 99.19); - test("%3.1f", "99.2", 99.19); - test("%3.0f", "100", 99.99); - test("%3.0f", "100", 100.00); - test("%#3.0f", "1000.", 1000.00); - test("%3.0f", "10000", 10000.00); - test("%3.0f", "100000", 100000.00); - test("%3.0f", "1000000", 1000000.00); - test("%3.0f", "10000000", 10000000.00); - test("%3.0f", "100000000", 100000000.00); - test("%10.0f", " 1000000", 1000000.00); - test("%,10.0f", " 1,000,000", 1000000.00); - test("%,10.1f", "1,000,000.0", 1000000.00); - test("%,3.0f", "1,000,000", 1000000.00); - test("%,3.0f", "10,000,000", 10000000.00); - test("%,3.0f", "100,000,000", 100000000.00); - test("%,3.0f", "10,000,000", 10000000.00); - test("%,3.0f", "100,000,000", 100000000.00); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %g - // - // Floating-point conversions applicable to float, double, and - // BigDecimal. - //--------------------------------------------------------------------- - test("%g", "null", (Object)null); - test("%g", "3.14159", pi); - test(Locale.FRANCE, "%g", "3,14159", pi); - test("%.0g", "1e+01", ten); - test("%G", "3.14159", pi); - test("%10.3g", " 3.14", pi); - test("%10.3g", " -3.14", negate(pi)); - test("%010.3g", "0000003.14", pi); - test("%010.3g", "-000003.14", negate(pi)); - test("%-12.3g", "3.14 ", pi); - test("%-12.3g", "-3.14 ", negate(pi)); - test("%.3g", "3.14", pi); - test("%.3g", "-3.14", negate(pi)); - test("%.3g", "3.14e+08", mult(pi, 100000000.0)); - test("%.3g", "-3.14e+08", mult(pi, -100000000.0)); - - test("%.3g", "1.00e-05", recip(create(100000.0))); - test("%.3g", "-1.00e-05", recip(create(-100000.0))); - test("%.0g", "-1e-05", recip(create(-100000.0))); - test("%.0g", "1e+05", create(100000.0)); - test("%.3G", "1.00E-05", recip(create(100000.0))); - test("%.3G", "-1.00E-05", recip(create(-100000.0))); - - test("%.1g", "-0", -0.0); - test("%3.0g", " -0", -0.0); - test("%.1g", "0", 0.0); - test("%3.0g", " 0", 0.0); - test("%.1g", "0", +0.0); - test("%3.0g", " 0", +0.0); - - test("%3.0g", "1e-06", 0.000001); - test("%3.0g", "1e-05", 0.00001); - test("%3.0g", "1e-05", 0.0000099); - test("%3.1g", "1e-05", 0.0000099); - test("%3.2g", "9.9e-06", 0.0000099); - test("%3.0g", "0.0001", 0.0001); - test("%3.0g", "9e-05", 0.00009); - test("%3.0g", "0.0001", 0.000099); - test("%3.1g", "0.0001", 0.000099); - test("%3.2g", "9.9e-05", 0.000099); - test("%3.0g", "0.001", 0.001); - test("%3.0g", "0.001", 0.00099); - test("%3.1g", "0.001", 0.00099); - test("%3.2g", "0.00099", 0.00099); - test("%3.3g", "0.00100", 0.001); - test("%3.4g", "0.001000", 0.001); - test("%3.0g", "0.01", 0.01); - test("%3.0g", "0.1", 0.1); - test("%3.0g", "0.9", 0.9); - test("%3.1g", "0.9", 0.9); - test("%3.0g", " 1", 1.00); - test("%3.2g", " 10", 10.00); - test("%3.0g", "1e+01", 10.00); - test("%3.0g", "1e+02", 99.19); - test("%3.1g", "1e+02", 99.19); - test("%3.2g", " 99", 99.19); - test("%3.0g", "1e+02", 99.9); - test("%3.1g", "1e+02", 99.9); - test("%3.2g", "1.0e+02", 99.9); - test("%3.0g", "1e+02", 99.99); - test("%3.0g", "1e+02", 100.00); - test("%3.0g", "1e+03", 999.9); - test("%3.1g", "1e+03", 999.9); - test("%3.2g", "1.0e+03", 999.9); - test("%3.3g", "1.00e+03", 999.9); - test("%3.4g", "999.9", 999.9); - test("%3.4g", "1000", 999.99); - test("%3.0g", "1e+03", 1000.00); - test("%3.0g", "1e+04", 10000.00); - test("%3.0g", "1e+05", 100000.00); - test("%3.0g", "1e+06", 1000000.00); - test("%3.0g", "1e+07", 10000000.00); - test("%3.9g", "100000000", 100000000.00); - test("%3.10g", "100000000.0", 100000000.00); - - tryCatch("%#3.0g", FormatFlagsConversionMismatchException.class, 1000.00); - - // double PI^300 - // = 13962455701329742638131355433930076081862072808 ... e+149 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - test("%.3g", "10.0", ten); - test("%.3g", "1.00", one); - test("%10.3g", " 1.00", one); - test("%+10.3g", " +3.14", pi); - test("%+10.3g", " -3.14", negate(pi)); - test("% .3g", " 3.14", pi); - test("% .3g", "-3.14", negate(pi)); - test("%.0g", "3", create(3.0)); - test("%.0g", "-3", create(-3.0)); - - test("%(.4g", "3.142e+08", mult(pi, 100000000.0)); - test("%(.4g", "(3.142e+08)", mult(pi, -100000000.0)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + test("%(.4e", "3.1416e+06", mult(pi, 1000000.0)); + test("%(.4e", "(3.1416e+06)", mult(pi, -1000000.0)); //--------------------------------------------------------------------- - // %f, %e, %g, %a - Boundaries + // %e - boundary problems //--------------------------------------------------------------------- + test("%3.0e", "1e-06", 0.000001); + test("%3.0e", "1e-05", 0.00001); + test("%3.0e", "1e-04", 0.0001); + test("%3.0e", "1e-03", 0.001); + test("%3.0e", "1e-02", 0.01); + test("%3.0e", "1e-01", 0.1); + test("%3.0e", "9e-01", 0.9); + test("%3.1e", "9.0e-01", 0.9); + test("%3.0e", "1e+00", 1.00); + test("%3.0e", "1e+01", 10.00); + test("%3.0e", "1e+02", 99.19); + test("%3.1e", "9.9e+01", 99.19); + test("%3.0e", "1e+02", 99.99); + test("%3.0e", "1e+02", 100.00); + test("%#3.0e", "1.e+03", 1000.00); + test("%3.0e", "1e+04", 10000.00); + test("%3.0e", "1e+05", 100000.00); + test("%3.0e", "1e+06", 1000000.00); + test("%3.0e", "1e+07", 10000000.00); + test("%3.0e", "1e+08", 100000000.00); + //--------------------------------------------------------------------- + // %f + // + // Floating-point conversions applicable to float, double, and + // BigDecimal. + //--------------------------------------------------------------------- + test("%f", "null", (Object)null); + test("%f", "3.141593", pi); + test(Locale.FRANCE, "%f", "3,141593", pi); + test("%10.3f", " 3.142", pi); + test("%10.3f", " -3.142", negate(pi)); + test("%010.3f", "000003.142", pi); + test("%010.3f", "-00003.142", negate(pi)); + test("%-10.3f", "3.142 ", pi); + test("%-10.3f", "-3.142 ", negate(pi)); + test("%.3f", "3.142", pi); + test("%.3f", "-3.142", negate(pi)); + test("%+.3f", "+3.142", pi); + test("%+.3f", "-3.142", negate(pi)); + test("% .3f", " 3.142", pi); + test("% .3f", "-3.142", negate(pi)); + test("%#.0f", "3.", create(3.0)); + test("%#.0f", "-3.", create(-3.0)); + test("%.0f", "3", create(3.0)); + test("%.0f", "-3", create(-3.0)); + test("%.3f", "10.000", ten); + test("%.3f", "1.000", one); + test("%10.3f", " 1.000", one); + //--------------------------------------------------------------------- + // %f - boundary problems + //--------------------------------------------------------------------- + test("%3.0f", " 0", 0.000001); + test("%3.0f", " 0", 0.00001); + test("%3.0f", " 0", 0.0001); + test("%3.0f", " 0", 0.001); + test("%3.0f", " 0", 0.01); + test("%3.0f", " 0", 0.1); + test("%3.0f", " 1", 0.9); + test("%3.1f", "0.9", 0.9); + test("%3.0f", " 1", 1.00); + test("%3.0f", " 10", 10.00); + test("%3.0f", " 99", 99.19); + test("%3.1f", "99.2", 99.19); + test("%3.0f", "100", 99.99); + test("%3.0f", "100", 100.00); + test("%#3.0f", "1000.", 1000.00); + test("%3.0f", "10000", 10000.00); + test("%3.0f", "100000", 100000.00); + test("%3.0f", "1000000", 1000000.00); + test("%3.0f", "10000000", 10000000.00); + test("%3.0f", "100000000", 100000000.00); + test("%10.0f", " 1000000", 1000000.00); + test("%,10.0f", " 1,000,000", 1000000.00); + test("%,10.1f", "1,000,000.0", 1000000.00); + test("%,3.0f", "1,000,000", 1000000.00); + test("%,3.0f", "10,000,000", 10000000.00); + test("%,3.0f", "100,000,000", 100000000.00); + test("%,3.0f", "10,000,000", 10000000.00); + test("%,3.0f", "100,000,000", 100000000.00); + //--------------------------------------------------------------------- + // %g + // + // Floating-point conversions applicable to float, double, and + // BigDecimal. + //--------------------------------------------------------------------- + test("%g", "null", (Object)null); + test("%g", "3.14159", pi); + test(Locale.FRANCE, "%g", "3,14159", pi); + test("%.0g", "1e+01", ten); + test("%G", "3.14159", pi); + test("%10.3g", " 3.14", pi); + test("%10.3g", " -3.14", negate(pi)); + test("%010.3g", "0000003.14", pi); + test("%010.3g", "-000003.14", negate(pi)); + test("%-12.3g", "3.14 ", pi); + test("%-12.3g", "-3.14 ", negate(pi)); + test("%.3g", "3.14", pi); + test("%.3g", "-3.14", negate(pi)); + test("%.3g", "3.14e+08", mult(pi, 100000000.0)); + test("%.3g", "-3.14e+08", mult(pi, -100000000.0)); + test("%.3g", "1.00e-05", recip(create(100000.0))); + test("%.3g", "-1.00e-05", recip(create(-100000.0))); + test("%.0g", "-1e-05", recip(create(-100000.0))); + test("%.0g", "1e+05", create(100000.0)); + test("%.3G", "1.00E-05", recip(create(100000.0))); + test("%.3G", "-1.00E-05", recip(create(-100000.0))); + test("%.1g", "-0", -0.0); + test("%3.0g", " -0", -0.0); + test("%.1g", "0", 0.0); + test("%3.0g", " 0", 0.0); + test("%.1g", "0", +0.0); + test("%3.0g", " 0", +0.0); + test("%3.0g", "1e-06", 0.000001); + test("%3.0g", "1e-05", 0.00001); + test("%3.0g", "1e-05", 0.0000099); + test("%3.1g", "1e-05", 0.0000099); + test("%3.2g", "9.9e-06", 0.0000099); + test("%3.0g", "0.0001", 0.0001); + test("%3.0g", "9e-05", 0.00009); + test("%3.0g", "0.0001", 0.000099); + test("%3.1g", "0.0001", 0.000099); + test("%3.2g", "9.9e-05", 0.000099); + test("%3.0g", "0.001", 0.001); + test("%3.0g", "0.001", 0.00099); + test("%3.1g", "0.001", 0.00099); + test("%3.2g", "0.00099", 0.00099); + test("%3.3g", "0.00100", 0.001); + test("%3.4g", "0.001000", 0.001); + test("%3.0g", "0.01", 0.01); + test("%3.0g", "0.1", 0.1); + test("%3.0g", "0.9", 0.9); + test("%3.1g", "0.9", 0.9); + test("%3.0g", " 1", 1.00); + test("%3.2g", " 10", 10.00); + test("%3.0g", "1e+01", 10.00); + test("%3.0g", "1e+02", 99.19); + test("%3.1g", "1e+02", 99.19); + test("%3.2g", " 99", 99.19); + test("%3.0g", "1e+02", 99.9); + test("%3.1g", "1e+02", 99.9); + test("%3.2g", "1.0e+02", 99.9); + test("%3.0g", "1e+02", 99.99); + test("%3.0g", "1e+02", 100.00); + test("%3.0g", "1e+03", 999.9); + test("%3.1g", "1e+03", 999.9); + test("%3.2g", "1.0e+03", 999.9); + test("%3.3g", "1.00e+03", 999.9); + test("%3.4g", "999.9", 999.9); + test("%3.4g", "1000", 999.99); + test("%3.0g", "1e+03", 1000.00); + test("%3.0g", "1e+04", 10000.00); + test("%3.0g", "1e+05", 100000.00); + test("%3.0g", "1e+06", 1000000.00); + test("%3.0g", "1e+07", 10000000.00); + test("%3.9g", "100000000", 100000000.00); + test("%3.10g", "100000000.0", 100000000.00); + tryCatch("%#3.0g", FormatFlagsConversionMismatchException.class, 1000.00); + // double PI^300 + // = 13962455701329742638131355433930076081862072808 ... e+149 + test("%.3g", "10.0", ten); + test("%.3g", "1.00", one); + test("%10.3g", " 1.00", one); + test("%+10.3g", " +3.14", pi); + test("%+10.3g", " -3.14", negate(pi)); + test("% .3g", " 3.14", pi); + test("% .3g", "-3.14", negate(pi)); + test("%.0g", "3", create(3.0)); + test("%.0g", "-3", create(-3.0)); + test("%(.4g", "3.142e+08", mult(pi, 100000000.0)); + test("%(.4g", "(3.142e+08)", mult(pi, -100000000.0)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + //--------------------------------------------------------------------- + // %f, %e, %g, %a - Boundaries + //--------------------------------------------------------------------- @@ -1691,99 +518,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicInt.java b/test/jdk/java/util/Formatter/BasicInt.java index 4cab1f29b6a7c..4d849534293c5 100644 --- a/test/jdk/java/util/Formatter/BasicInt.java +++ b/test/jdk/java/util/Formatter/BasicInt.java @@ -38,303 +38,13 @@ import static java.util.Calendar.*; - - - - public class BasicInt extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static int negate(int v) { return (int) -v; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static void test() { TimeZone.setDefault(TimeZone.getTimeZone("GMT-0800")); @@ -520,24 +230,8 @@ public static void test() { tryCatch("%#g", FormatFlagsConversionMismatchException.class); - - int minByte = Byte.MIN_VALUE; // -128 - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %d // @@ -546,89 +240,34 @@ public static void test() { //--------------------------------------------------------------------- test("%d", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %d - int and long - //--------------------------------------------------------------------- - int oneToSeven = (int) 1234567; - test("%d", "1234567", oneToSeven); - test("%,d", "1,234,567", oneToSeven); - test(Locale.FRANCE, "%,d", "1\u202f234\u202f567", oneToSeven); - test("%,d", "-1,234,567", negate(oneToSeven)); - test("%(d", "1234567", oneToSeven); - test("%(d", "(1234567)", negate(oneToSeven)); - test("% d", " 1234567", oneToSeven); - test("% d", "-1234567", negate(oneToSeven)); - test("%+d", "+1234567", oneToSeven); - test("%+d", "-1234567", negate(oneToSeven)); - test("%010d", "0001234567", oneToSeven); - test("%010d", "-001234567", negate(oneToSeven)); - test("%(10d", " (1234567)", negate(oneToSeven)); - test("%-10d", "1234567 ", oneToSeven); - test("%-10d", "-1234567 ", negate(oneToSeven)); - // , variations: - test("% ,d", " 1,234,567", oneToSeven); - test("% ,d", "-1,234,567", negate(oneToSeven)); - test("%+,10d", "+1,234,567", oneToSeven); - test("%0,10d", "01,234,567", oneToSeven); - test("%0,10d", "-1,234,567", negate(oneToSeven)); - test("%(,10d", "(1,234,567)", negate(oneToSeven)); - test("%-,10d", "1,234,567 ", oneToSeven); - test("%-,10d", "-1,234,567", negate(oneToSeven)); - - - + //--------------------------------------------------------------------- + // %d - int and long + //--------------------------------------------------------------------- + int oneToSeven = (int) 1234567; + test("%d", "1234567", oneToSeven); + test("%,d", "1,234,567", oneToSeven); + test(Locale.FRANCE, "%,d", "1\u202f234\u202f567", oneToSeven); + test("%,d", "-1,234,567", negate(oneToSeven)); + test("%(d", "1234567", oneToSeven); + test("%(d", "(1234567)", negate(oneToSeven)); + test("% d", " 1234567", oneToSeven); + test("% d", "-1234567", negate(oneToSeven)); + test("%+d", "+1234567", oneToSeven); + test("%+d", "-1234567", negate(oneToSeven)); + test("%010d", "0001234567", oneToSeven); + test("%010d", "-001234567", negate(oneToSeven)); + test("%(10d", " (1234567)", negate(oneToSeven)); + test("%-10d", "1234567 ", oneToSeven); + test("%-10d", "-1234567 ", negate(oneToSeven)); + // , variations: + test("% ,d", " 1,234,567", oneToSeven); + test("% ,d", "-1,234,567", negate(oneToSeven)); + test("%+,10d", "+1,234,567", oneToSeven); + test("%0,10d", "01,234,567", oneToSeven); + test("%0,10d", "-1,234,567", negate(oneToSeven)); + test("%(,10d", "(1,234,567)", negate(oneToSeven)); + test("%-,10d", "1,234,567 ", oneToSeven); + test("%-,10d", "-1,234,567", negate(oneToSeven)); //--------------------------------------------------------------------- // %d - errors @@ -647,24 +286,6 @@ public static void test() { //--------------------------------------------------------------------- test("%o", "null", (Object)null); - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %o - int //--------------------------------------------------------------------- @@ -678,21 +299,6 @@ public static void test() { test("%-10o", "4553207 ", oneToSevenOct); test("%#10o", " 04553207", oneToSevenOct); - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %o - errors //--------------------------------------------------------------------- @@ -715,29 +321,6 @@ public static void test() { //--------------------------------------------------------------------- test("%x", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %x - int //--------------------------------------------------------------------- @@ -756,27 +339,6 @@ public static void test() { test("%0#12x","0x00ffffff80", minByte); test("%#12X", " 0XFFFFFF80", minByte); test("%X", "FFFFFF80", minByte); - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %x - errors //--------------------------------------------------------------------- @@ -787,897 +349,13 @@ public static void test() { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %t - // - // Date/Time conversions applicable to Calendar, Date, and long. - //--------------------------------------------------------------------- - test("%tA", "null", (Object)null); - test("%TA", "NULL", (Object)null); + //--------------------------------------------------------------------- + // %t + // + // Date/Time conversions applicable to Calendar, Date, and long. + //--------------------------------------------------------------------- + test("%tA", "null", (Object)null); + test("%TA", "NULL", (Object)null); //--------------------------------------------------------------------- // %t - errors @@ -1691,99 +369,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicIntObject.java b/test/jdk/java/util/Formatter/BasicIntObject.java index 3e22d7973824a..b07eef69c214b 100644 --- a/test/jdk/java/util/Formatter/BasicIntObject.java +++ b/test/jdk/java/util/Formatter/BasicIntObject.java @@ -38,303 +38,13 @@ import static java.util.Calendar.*; - - - - public class BasicIntObject extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static Integer negate(Integer v) { return -v.intValue(); } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static void test() { TimeZone.setDefault(TimeZone.getTimeZone("GMT-0800")); @@ -520,24 +230,8 @@ public static void test() { tryCatch("%#g", FormatFlagsConversionMismatchException.class); - - - - - - - - - - - Integer minByte = (int) Byte.MIN_VALUE; - - - - - //--------------------------------------------------------------------- // %d // @@ -546,1127 +240,52 @@ public static void test() { //--------------------------------------------------------------------- test("%d", "null", (Object)null); + //--------------------------------------------------------------------- + // %d - errors + //--------------------------------------------------------------------- + tryCatch("%#d", FormatFlagsConversionMismatchException.class); + tryCatch("%D", UnknownFormatConversionException.class); + tryCatch("%0d", MissingFormatWidthException.class); + tryCatch("%-d", MissingFormatWidthException.class); + tryCatch("%7.3d", IllegalFormatPrecisionException.class); + //--------------------------------------------------------------------- + // %o + // + // Numeric conversion applicable to byte, short, int, long, and + // BigInteger. + //--------------------------------------------------------------------- + test("%o", "null", (Object)null); + //--------------------------------------------------------------------- + // %o - errors + //--------------------------------------------------------------------- + tryCatch("%(o", FormatFlagsConversionMismatchException.class, + minByte); + tryCatch("%+o", FormatFlagsConversionMismatchException.class, + minByte); + tryCatch("% o", FormatFlagsConversionMismatchException.class, + minByte); + tryCatch("%0o", MissingFormatWidthException.class); + tryCatch("%-o", MissingFormatWidthException.class); + tryCatch("%,o", FormatFlagsConversionMismatchException.class); + tryCatch("%O", UnknownFormatConversionException.class); + //--------------------------------------------------------------------- + // %x + // + // Numeric conversion applicable to byte, short, int, long, and + // BigInteger. + //--------------------------------------------------------------------- + test("%x", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %d - errors - //--------------------------------------------------------------------- - tryCatch("%#d", FormatFlagsConversionMismatchException.class); - tryCatch("%D", UnknownFormatConversionException.class); - tryCatch("%0d", MissingFormatWidthException.class); - tryCatch("%-d", MissingFormatWidthException.class); - tryCatch("%7.3d", IllegalFormatPrecisionException.class); - - //--------------------------------------------------------------------- - // %o - // - // Numeric conversion applicable to byte, short, int, long, and - // BigInteger. - //--------------------------------------------------------------------- - test("%o", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %o - errors - //--------------------------------------------------------------------- - tryCatch("%(o", FormatFlagsConversionMismatchException.class, - minByte); - tryCatch("%+o", FormatFlagsConversionMismatchException.class, - minByte); - tryCatch("% o", FormatFlagsConversionMismatchException.class, - minByte); - tryCatch("%0o", MissingFormatWidthException.class); - tryCatch("%-o", MissingFormatWidthException.class); - tryCatch("%,o", FormatFlagsConversionMismatchException.class); - tryCatch("%O", UnknownFormatConversionException.class); - - //--------------------------------------------------------------------- - // %x - // - // Numeric conversion applicable to byte, short, int, long, and - // BigInteger. - //--------------------------------------------------------------------- - test("%x", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %x - errors - //--------------------------------------------------------------------- - tryCatch("%,x", FormatFlagsConversionMismatchException.class); - tryCatch("%0x", MissingFormatWidthException.class); - tryCatch("%-x", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + //--------------------------------------------------------------------- + // %x - errors + //--------------------------------------------------------------------- + tryCatch("%,x", FormatFlagsConversionMismatchException.class); + tryCatch("%0x", MissingFormatWidthException.class); + tryCatch("%-x", MissingFormatWidthException.class); @@ -1691,99 +310,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicLong.java b/test/jdk/java/util/Formatter/BasicLong.java index 32b25b3462134..750b07f1d1207 100644 --- a/test/jdk/java/util/Formatter/BasicLong.java +++ b/test/jdk/java/util/Formatter/BasicLong.java @@ -38,303 +38,13 @@ import static java.util.Calendar.*; - - - - public class BasicLong extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static long negate(long v) { return (long) -v; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static void test() { TimeZone.setDefault(TimeZone.getTimeZone("GMT-0800")); @@ -520,24 +230,8 @@ public static void test() { tryCatch("%#g", FormatFlagsConversionMismatchException.class); - - long minByte = Byte.MIN_VALUE; // -128 - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %d // @@ -546,89 +240,34 @@ public static void test() { //--------------------------------------------------------------------- test("%d", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %d - int and long - //--------------------------------------------------------------------- - long oneToSeven = (long) 1234567; - test("%d", "1234567", oneToSeven); - test("%,d", "1,234,567", oneToSeven); - test(Locale.FRANCE, "%,d", "1\u202f234\u202f567", oneToSeven); - test("%,d", "-1,234,567", negate(oneToSeven)); - test("%(d", "1234567", oneToSeven); - test("%(d", "(1234567)", negate(oneToSeven)); - test("% d", " 1234567", oneToSeven); - test("% d", "-1234567", negate(oneToSeven)); - test("%+d", "+1234567", oneToSeven); - test("%+d", "-1234567", negate(oneToSeven)); - test("%010d", "0001234567", oneToSeven); - test("%010d", "-001234567", negate(oneToSeven)); - test("%(10d", " (1234567)", negate(oneToSeven)); - test("%-10d", "1234567 ", oneToSeven); - test("%-10d", "-1234567 ", negate(oneToSeven)); - // , variations: - test("% ,d", " 1,234,567", oneToSeven); - test("% ,d", "-1,234,567", negate(oneToSeven)); - test("%+,10d", "+1,234,567", oneToSeven); - test("%0,10d", "01,234,567", oneToSeven); - test("%0,10d", "-1,234,567", negate(oneToSeven)); - test("%(,10d", "(1,234,567)", negate(oneToSeven)); - test("%-,10d", "1,234,567 ", oneToSeven); - test("%-,10d", "-1,234,567", negate(oneToSeven)); - - - + //--------------------------------------------------------------------- + // %d - int and long + //--------------------------------------------------------------------- + long oneToSeven = (long) 1234567; + test("%d", "1234567", oneToSeven); + test("%,d", "1,234,567", oneToSeven); + test(Locale.FRANCE, "%,d", "1\u202f234\u202f567", oneToSeven); + test("%,d", "-1,234,567", negate(oneToSeven)); + test("%(d", "1234567", oneToSeven); + test("%(d", "(1234567)", negate(oneToSeven)); + test("% d", " 1234567", oneToSeven); + test("% d", "-1234567", negate(oneToSeven)); + test("%+d", "+1234567", oneToSeven); + test("%+d", "-1234567", negate(oneToSeven)); + test("%010d", "0001234567", oneToSeven); + test("%010d", "-001234567", negate(oneToSeven)); + test("%(10d", " (1234567)", negate(oneToSeven)); + test("%-10d", "1234567 ", oneToSeven); + test("%-10d", "-1234567 ", negate(oneToSeven)); + // , variations: + test("% ,d", " 1,234,567", oneToSeven); + test("% ,d", "-1,234,567", negate(oneToSeven)); + test("%+,10d", "+1,234,567", oneToSeven); + test("%0,10d", "01,234,567", oneToSeven); + test("%0,10d", "-1,234,567", negate(oneToSeven)); + test("%(,10d", "(1,234,567)", negate(oneToSeven)); + test("%-,10d", "1,234,567 ", oneToSeven); + test("%-,10d", "-1,234,567", negate(oneToSeven)); //--------------------------------------------------------------------- // %d - errors @@ -647,38 +286,6 @@ public static void test() { //--------------------------------------------------------------------- test("%o", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %o - long //--------------------------------------------------------------------- @@ -692,7 +299,6 @@ public static void test() { test("%-10o", "4553207 ", oneToSevenOct); test("%#10o", " 04553207", oneToSevenOct); - //--------------------------------------------------------------------- // %o - errors //--------------------------------------------------------------------- @@ -715,49 +321,6 @@ public static void test() { //--------------------------------------------------------------------- test("%x", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %x - long //--------------------------------------------------------------------- @@ -776,7 +339,6 @@ public static void test() { test("%0#20x", "0x00ffffffffffffff80", minByte); test("%#20X", " 0XFFFFFFFFFFFFFF80", minByte); test("%X", "FFFFFFFFFFFFFF80", minByte); - //--------------------------------------------------------------------- // %x - errors //--------------------------------------------------------------------- @@ -787,897 +349,13 @@ public static void test() { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %t - // - // Date/Time conversions applicable to Calendar, Date, and long. - //--------------------------------------------------------------------- - test("%tA", "null", (Object)null); - test("%TA", "NULL", (Object)null); + //--------------------------------------------------------------------- + // %t + // + // Date/Time conversions applicable to Calendar, Date, and long. + //--------------------------------------------------------------------- + test("%tA", "null", (Object)null); + test("%TA", "NULL", (Object)null); //--------------------------------------------------------------------- // %t - errors @@ -1691,99 +369,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicLongObject.java b/test/jdk/java/util/Formatter/BasicLongObject.java index a7f382d9846eb..b8e1a787b366f 100644 --- a/test/jdk/java/util/Formatter/BasicLongObject.java +++ b/test/jdk/java/util/Formatter/BasicLongObject.java @@ -38,303 +38,13 @@ import static java.util.Calendar.*; - - - - public class BasicLongObject extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static Long negate(Long v) { return -v.longValue(); } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static void test() { TimeZone.setDefault(TimeZone.getTimeZone("GMT-0800")); @@ -520,24 +230,8 @@ public static void test() { tryCatch("%#g", FormatFlagsConversionMismatchException.class); - - - - - - - - - - - - - - Long minByte = (long) Byte.MIN_VALUE; - - //--------------------------------------------------------------------- // %d // @@ -546,1127 +240,52 @@ public static void test() { //--------------------------------------------------------------------- test("%d", "null", (Object)null); + //--------------------------------------------------------------------- + // %d - errors + //--------------------------------------------------------------------- + tryCatch("%#d", FormatFlagsConversionMismatchException.class); + tryCatch("%D", UnknownFormatConversionException.class); + tryCatch("%0d", MissingFormatWidthException.class); + tryCatch("%-d", MissingFormatWidthException.class); + tryCatch("%7.3d", IllegalFormatPrecisionException.class); + //--------------------------------------------------------------------- + // %o + // + // Numeric conversion applicable to byte, short, int, long, and + // BigInteger. + //--------------------------------------------------------------------- + test("%o", "null", (Object)null); + //--------------------------------------------------------------------- + // %o - errors + //--------------------------------------------------------------------- + tryCatch("%(o", FormatFlagsConversionMismatchException.class, + minByte); + tryCatch("%+o", FormatFlagsConversionMismatchException.class, + minByte); + tryCatch("% o", FormatFlagsConversionMismatchException.class, + minByte); + tryCatch("%0o", MissingFormatWidthException.class); + tryCatch("%-o", MissingFormatWidthException.class); + tryCatch("%,o", FormatFlagsConversionMismatchException.class); + tryCatch("%O", UnknownFormatConversionException.class); + //--------------------------------------------------------------------- + // %x + // + // Numeric conversion applicable to byte, short, int, long, and + // BigInteger. + //--------------------------------------------------------------------- + test("%x", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %d - errors - //--------------------------------------------------------------------- - tryCatch("%#d", FormatFlagsConversionMismatchException.class); - tryCatch("%D", UnknownFormatConversionException.class); - tryCatch("%0d", MissingFormatWidthException.class); - tryCatch("%-d", MissingFormatWidthException.class); - tryCatch("%7.3d", IllegalFormatPrecisionException.class); - - //--------------------------------------------------------------------- - // %o - // - // Numeric conversion applicable to byte, short, int, long, and - // BigInteger. - //--------------------------------------------------------------------- - test("%o", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %o - errors - //--------------------------------------------------------------------- - tryCatch("%(o", FormatFlagsConversionMismatchException.class, - minByte); - tryCatch("%+o", FormatFlagsConversionMismatchException.class, - minByte); - tryCatch("% o", FormatFlagsConversionMismatchException.class, - minByte); - tryCatch("%0o", MissingFormatWidthException.class); - tryCatch("%-o", MissingFormatWidthException.class); - tryCatch("%,o", FormatFlagsConversionMismatchException.class); - tryCatch("%O", UnknownFormatConversionException.class); - - //--------------------------------------------------------------------- - // %x - // - // Numeric conversion applicable to byte, short, int, long, and - // BigInteger. - //--------------------------------------------------------------------- - test("%x", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %x - errors - //--------------------------------------------------------------------- - tryCatch("%,x", FormatFlagsConversionMismatchException.class); - tryCatch("%0x", MissingFormatWidthException.class); - tryCatch("%-x", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + //--------------------------------------------------------------------- + // %x - errors + //--------------------------------------------------------------------- + tryCatch("%,x", FormatFlagsConversionMismatchException.class); + tryCatch("%0x", MissingFormatWidthException.class); + tryCatch("%-x", MissingFormatWidthException.class); @@ -1691,99 +310,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicShort.java b/test/jdk/java/util/Formatter/BasicShort.java index 21fe93f3339a7..771120e2183bf 100644 --- a/test/jdk/java/util/Formatter/BasicShort.java +++ b/test/jdk/java/util/Formatter/BasicShort.java @@ -38,303 +38,13 @@ import static java.util.Calendar.*; - - - - public class BasicShort extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static short negate(short v) { return (short) -v; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static void test() { TimeZone.setDefault(TimeZone.getTimeZone("GMT-0800")); @@ -520,24 +230,8 @@ public static void test() { tryCatch("%#g", FormatFlagsConversionMismatchException.class); - - short minByte = Byte.MIN_VALUE; // -128 - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %d // @@ -546,29 +240,6 @@ public static void test() { //--------------------------------------------------------------------- test("%d", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %d - short //--------------------------------------------------------------------- @@ -596,40 +267,6 @@ public static void test() { test("%-,10d", "12,345 ", oneToFive); test("%-,10d", "-12,345 ", negate(oneToFive)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %d - errors //--------------------------------------------------------------------- @@ -647,15 +284,6 @@ public static void test() { //--------------------------------------------------------------------- test("%o", "null", (Object)null); - - - - - - - - - //--------------------------------------------------------------------- // %o - short //--------------------------------------------------------------------- @@ -664,35 +292,6 @@ public static void test() { test("%-10o", "177600 ", minByte); test("%#10o", " 0177600", minByte); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %o - errors //--------------------------------------------------------------------- @@ -715,18 +314,6 @@ public static void test() { //--------------------------------------------------------------------- test("%x", "null", (Object)null); - - - - - - - - - - - - //--------------------------------------------------------------------- // %x - short //--------------------------------------------------------------------- @@ -736,47 +323,6 @@ public static void test() { test("%0#10x","0x0000ff80", minByte); test("%#10X", " 0XFF80", minByte); test("%X", "FF80", minByte); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %x - errors //--------------------------------------------------------------------- @@ -787,897 +333,13 @@ public static void test() { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %t - // - // Date/Time conversions applicable to Calendar, Date, and long. - //--------------------------------------------------------------------- - test("%tA", "null", (Object)null); - test("%TA", "NULL", (Object)null); + //--------------------------------------------------------------------- + // %t + // + // Date/Time conversions applicable to Calendar, Date, and long. + //--------------------------------------------------------------------- + test("%tA", "null", (Object)null); + test("%TA", "NULL", (Object)null); //--------------------------------------------------------------------- // %t - errors @@ -1691,99 +353,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/BasicShortObject.java b/test/jdk/java/util/Formatter/BasicShortObject.java index 6d2fe4a792ea9..b73e3d84e646c 100644 --- a/test/jdk/java/util/Formatter/BasicShortObject.java +++ b/test/jdk/java/util/Formatter/BasicShortObject.java @@ -38,303 +38,13 @@ import static java.util.Calendar.*; - - - - public class BasicShortObject extends Basic { - - private static void test(String fs, String exp, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), Locale.US); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(Locale l, String fs, String exp, Object ... args) - { - Formatter f = new Formatter(new StringBuilder(), l); - f.format(fs, args); - ck(fs, exp, f.toString()); - - f = new Formatter(new StringBuilder(), l); - f.format("foo " + fs + " bar", args); - ck(fs, "foo " + exp + " bar", f.toString()); - } - - private static void test(String fs, Object ... args) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, args); - ck(fs, "fail", f.toString()); - } - - private static void test(String fs) { - Formatter f = new Formatter(new StringBuilder(), Locale.US); - f.format(fs, "fail"); - ck(fs, "fail", f.toString()); - } - - private static void testSysOut(String fs, String exp, Object ... args) { - FileOutputStream fos = null; - FileInputStream fis = null; - try { - PrintStream saveOut = System.out; - fos = new FileOutputStream("testSysOut"); - System.setOut(new PrintStream(fos)); - System.out.format(Locale.US, fs, args); - fos.close(); - - fis = new FileInputStream("testSysOut"); - byte [] ba = new byte[exp.length()]; - int len = fis.read(ba); - String got = new String(ba); - if (len != ba.length) - fail(fs, exp, got); - ck(fs, exp, got); - - System.setOut(saveOut); - } catch (FileNotFoundException ex) { - fail(fs, ex.getClass()); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } finally { - try { - if (fos != null) - fos.close(); - if (fis != null) - fis.close(); - } catch (IOException ex) { - fail(fs, ex.getClass()); - } - } - } - - private static void tryCatch(String fs, Class ex) { - boolean caught = false; - try { - test(fs); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - private static void tryCatch(String fs, Class ex, Object ... args) { - boolean caught = false; - try { - test(fs, args); - } catch (Throwable x) { - if (ex.isAssignableFrom(x.getClass())) - caught = true; - } - if (!caught) - fail(fs, ex); - else - pass(); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static Short negate(Short v) { return (short) -v.shortValue(); } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static void test() { TimeZone.setDefault(TimeZone.getTimeZone("GMT-0800")); @@ -520,24 +230,8 @@ public static void test() { tryCatch("%#g", FormatFlagsConversionMismatchException.class); - - - - - Short minByte = (short) Byte.MIN_VALUE; - - - - - - - - - - - //--------------------------------------------------------------------- // %d // @@ -546,1127 +240,52 @@ public static void test() { //--------------------------------------------------------------------- test("%d", "null", (Object)null); + //--------------------------------------------------------------------- + // %d - errors + //--------------------------------------------------------------------- + tryCatch("%#d", FormatFlagsConversionMismatchException.class); + tryCatch("%D", UnknownFormatConversionException.class); + tryCatch("%0d", MissingFormatWidthException.class); + tryCatch("%-d", MissingFormatWidthException.class); + tryCatch("%7.3d", IllegalFormatPrecisionException.class); + //--------------------------------------------------------------------- + // %o + // + // Numeric conversion applicable to byte, short, int, long, and + // BigInteger. + //--------------------------------------------------------------------- + test("%o", "null", (Object)null); + //--------------------------------------------------------------------- + // %o - errors + //--------------------------------------------------------------------- + tryCatch("%(o", FormatFlagsConversionMismatchException.class, + minByte); + tryCatch("%+o", FormatFlagsConversionMismatchException.class, + minByte); + tryCatch("% o", FormatFlagsConversionMismatchException.class, + minByte); + tryCatch("%0o", MissingFormatWidthException.class); + tryCatch("%-o", MissingFormatWidthException.class); + tryCatch("%,o", FormatFlagsConversionMismatchException.class); + tryCatch("%O", UnknownFormatConversionException.class); + //--------------------------------------------------------------------- + // %x + // + // Numeric conversion applicable to byte, short, int, long, and + // BigInteger. + //--------------------------------------------------------------------- + test("%x", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %d - errors - //--------------------------------------------------------------------- - tryCatch("%#d", FormatFlagsConversionMismatchException.class); - tryCatch("%D", UnknownFormatConversionException.class); - tryCatch("%0d", MissingFormatWidthException.class); - tryCatch("%-d", MissingFormatWidthException.class); - tryCatch("%7.3d", IllegalFormatPrecisionException.class); - - //--------------------------------------------------------------------- - // %o - // - // Numeric conversion applicable to byte, short, int, long, and - // BigInteger. - //--------------------------------------------------------------------- - test("%o", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %o - errors - //--------------------------------------------------------------------- - tryCatch("%(o", FormatFlagsConversionMismatchException.class, - minByte); - tryCatch("%+o", FormatFlagsConversionMismatchException.class, - minByte); - tryCatch("% o", FormatFlagsConversionMismatchException.class, - minByte); - tryCatch("%0o", MissingFormatWidthException.class); - tryCatch("%-o", MissingFormatWidthException.class); - tryCatch("%,o", FormatFlagsConversionMismatchException.class); - tryCatch("%O", UnknownFormatConversionException.class); - - //--------------------------------------------------------------------- - // %x - // - // Numeric conversion applicable to byte, short, int, long, and - // BigInteger. - //--------------------------------------------------------------------- - test("%x", "null", (Object)null); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- - // %x - errors - //--------------------------------------------------------------------- - tryCatch("%,x", FormatFlagsConversionMismatchException.class); - tryCatch("%0x", MissingFormatWidthException.class); - tryCatch("%-x", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + //--------------------------------------------------------------------- + // %x - errors + //--------------------------------------------------------------------- + tryCatch("%,x", FormatFlagsConversionMismatchException.class); + tryCatch("%0x", MissingFormatWidthException.class); + tryCatch("%-x", MissingFormatWidthException.class); @@ -1691,99 +310,6 @@ public static void test() { tryCatch("%-tB", MissingFormatWidthException.class); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //--------------------------------------------------------------------- // %n //--------------------------------------------------------------------- diff --git a/test/jdk/java/util/Formatter/genBasic.sh b/test/jdk/java/util/Formatter/genBasic.sh index 809873fbfd431..247f42a4edeae 100644 --- a/test/jdk/java/util/Formatter/genBasic.sh +++ b/test/jdk/java/util/Formatter/genBasic.sh @@ -32,7 +32,7 @@ gen() { # fi out=Basic$2.java rm -f $out - java build.tools.spp.Spp -K$1 -Dtype=$1 -DType=$2 -K$3 -K$4 -K$5 -K$6 -iBasic-X.java.template -o$out + java build.tools.spp.Spp -K$1 -Dtype=$1 -DType=$2 -K$3 -K$4 -K$5 -K$6 -iBasic-X.java.template -nel -o$out } gen boolean Boolean prim "" "" "" From 9abc9cefaf22110899a87b80f254fc9d0b10606e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 07:26:58 +0000 Subject: [PATCH 238/846] 8303549: [AIX] TestNativeStack.java is failing with exit value 1 Backport-of: 5ff42d14294199eb3bf10b66530f9249fb68810d --- .../runtime/jni/getCreatedJavaVMs/exeGetCreatedJavaVMs.c | 7 ++++++- .../jtreg/runtime/jni/nativeStack/libnativeStack.c | 9 ++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/runtime/jni/getCreatedJavaVMs/exeGetCreatedJavaVMs.c b/test/hotspot/jtreg/runtime/jni/getCreatedJavaVMs/exeGetCreatedJavaVMs.c index a6fe23851f427..6c2b1ec5d9116 100644 --- a/test/hotspot/jtreg/runtime/jni/getCreatedJavaVMs/exeGetCreatedJavaVMs.c +++ b/test/hotspot/jtreg/runtime/jni/getCreatedJavaVMs/exeGetCreatedJavaVMs.c @@ -89,14 +89,19 @@ void *thread_runner(void *threadid) { int main (int argc, char* argv[]) { pthread_t threads[NUM_THREADS]; + pthread_attr_t attr; + pthread_attr_init(&attr); + size_t stack_size = 0x100000; + pthread_attr_setstacksize(&attr, stack_size); for (int i = 0; i < NUM_THREADS; i++ ) { printf("[*] Creating thread %d\n", i); - int status = pthread_create(&threads[i], NULL, thread_runner, (void *)(intptr_t)i); + int status = pthread_create(&threads[i], &attr, thread_runner, (void *)(intptr_t)i); if (status != 0) { printf("[*] Error creating thread %d - %d\n", i, status); exit(-1); } } + pthread_attr_destroy(&attr); for (int i = 0; i < NUM_THREADS; i++ ) { pthread_join(threads[i], NULL); } diff --git a/test/hotspot/jtreg/runtime/jni/nativeStack/libnativeStack.c b/test/hotspot/jtreg/runtime/jni/nativeStack/libnativeStack.c index 4087e874c93d6..1da49f586d3f4 100644 --- a/test/hotspot/jtreg/runtime/jni/nativeStack/libnativeStack.c +++ b/test/hotspot/jtreg/runtime/jni/nativeStack/libnativeStack.c @@ -109,11 +109,18 @@ Java_TestNativeStack_triggerJNIStackTrace warning = warn; - if ((res = pthread_create(&thread, NULL, thread_start, NULL)) != 0) { + pthread_attr_t attr; + pthread_attr_init(&attr); + size_t stack_size = 0x100000; + pthread_attr_setstacksize(&attr, stack_size); + + if ((res = pthread_create(&thread, &attr, thread_start, NULL)) != 0) { fprintf(stderr, "TEST ERROR: pthread_create failed: %s (%d)\n", strerror(res), res); exit(1); } + pthread_attr_destroy(&attr); + if ((res = pthread_join(thread, NULL)) != 0) { fprintf(stderr, "TEST ERROR: pthread_join failed: %s (%d)\n", strerror(res), res); exit(1); From e5599624c23c0f8c8d5ceff5eb9fd79ad0f302a5 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 07:34:17 +0000 Subject: [PATCH 239/846] 8349501: Relocate supporting classes in security/testlibrary to test/lib/jdk tree Reviewed-by: rschmelter Backport-of: fdd0cb550e4345d93c5436404e0a798563d623f1 --- .../auth/callback/TextCallbackHandler/Default.java | 5 +++-- test/jdk/java/security/KeyFactory/Failover.java | 6 +++--- .../jdk/java/security/KeyPairGenerator/Failover.java | 6 +++--- test/jdk/java/security/Provider/ChangeProviders.java | 7 +++---- test/jdk/java/security/Provider/GetInstance.java | 5 +++-- test/jdk/java/security/Provider/GetServiceRace.java | 3 +-- test/jdk/java/security/Provider/RemoveProvider.java | 5 +++-- .../java/security/Security/NoInstalledProviders.java | 5 +++-- .../java/security/Security/SynchronizedAccess.java | 5 +++-- .../security/Security/removing/RemoveProviders.java | 5 +++-- .../cert/CertPathValidator/OCSP/GetAndPostTests.java | 7 +++---- .../cert/CertPathValidator/OCSP/OCSPTimeout.java | 12 +++++------- .../trustAnchor/ValWithAnchorByName.java | 4 ++-- .../EncryptedPrivateKeyInfo/GetKeySpecException.java | 7 ++++--- .../crypto/JceSecurity/SunJCE_BC_LoadOrdering.java | 6 +++--- .../javax/net/ssl/Stapling/HttpsUrlConnClient.java | 9 ++++----- .../net/ssl/Stapling/SSLEngineWithStapling.java | 9 ++++----- .../net/ssl/Stapling/SSLSocketWithStapling.java | 9 ++++----- .../javax/net/ssl/Stapling/StapleEnableProps.java | 7 +++---- test/jdk/sun/security/ec/TestEC.java | 4 ++-- .../jdk/sun/security/pkcs11/ec/ReadCertificates.java | 4 ++-- test/jdk/sun/security/pkcs11/ec/ReadPKCS12.java | 4 ++-- test/jdk/sun/security/pkcs11/ec/TestECDH.java | 5 +++-- test/jdk/sun/security/pkcs11/ec/TestECDH2.java | 3 +-- test/jdk/sun/security/pkcs11/ec/TestECDSA.java | 4 ++-- test/jdk/sun/security/pkcs11/ec/TestECDSA2.java | 3 +-- test/jdk/sun/security/pkcs11/rsa/TestCACerts.java | 4 ++-- .../security/pkcs11/sslecc/ClientJSSEServerJSSE.java | 4 ++-- .../provider/certpath/OCSP/OCSPNoContentLength.java | 9 ++++----- .../security/ssl/Stapling/StatusResponseManager.java | 8 +++++--- .../sun/security/ssl/StatusResponseManagerTests.java | 6 +++--- test/jdk/sun/security/tools/keytool/KeyToolTest.java | 6 +++--- test/jdk/sun/security/tools/keytool/NssTest.java | 4 ++-- .../security/x509/URICertStore/AIACertTimeout.java | 10 +++------- .../jdk/test/lib/security}/CertificateBuilder.java | 4 ++-- .../jdk/test/lib/security}/HumanInputStream.java | 5 ++++- .../jdk/test/lib/security}/Providers.java | 4 +++- .../jdk/test/lib/security}/ProvidersSnapshot.java | 4 +++- .../jdk/test/lib/security}/SimpleOCSPServer.java | 4 ++-- 39 files changed, 111 insertions(+), 110 deletions(-) rename test/{jdk/java/security/testlibrary => lib/jdk/test/lib/security}/CertificateBuilder.java (99%) rename test/{jdk/java/security/testlibrary => lib/jdk/test/lib/security}/HumanInputStream.java (98%) rename test/{jdk/java/security/testlibrary => lib/jdk/test/lib/security}/Providers.java (92%) rename test/{jdk/java/security/testlibrary => lib/jdk/test/lib/security}/ProvidersSnapshot.java (93%) rename test/{jdk/java/security/testlibrary => lib/jdk/test/lib/security}/SimpleOCSPServer.java (99%) diff --git a/test/jdk/com/sun/security/auth/callback/TextCallbackHandler/Default.java b/test/jdk/com/sun/security/auth/callback/TextCallbackHandler/Default.java index 1fb3350c8f7ea..5b7b075250e79 100644 --- a/test/jdk/com/sun/security/auth/callback/TextCallbackHandler/Default.java +++ b/test/jdk/com/sun/security/auth/callback/TextCallbackHandler/Default.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @library /test/lib /java/security/testlibrary + * @library /test/lib * @bug 4470717 * @summary fix default handling and other misc * @run main/othervm Default @@ -34,6 +34,7 @@ import javax.security.auth.callback.*; import java.io.*; +import jdk.test.lib.security.HumanInputStream; public class Default { public static void main(String args[]) throws Exception { diff --git a/test/jdk/java/security/KeyFactory/Failover.java b/test/jdk/java/security/KeyFactory/Failover.java index 7107ef1ad0281..3fd69a3cbc323 100644 --- a/test/jdk/java/security/KeyFactory/Failover.java +++ b/test/jdk/java/security/KeyFactory/Failover.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -24,7 +24,7 @@ /** * @test * @bug 4894125 7054918 8130181 - * @library ../testlibrary /test/lib + * @library /test/lib * @summary test that failover for KeyFactory works * @author Andreas Sterbenz */ @@ -32,8 +32,8 @@ import java.util.*; import java.security.*; -import java.security.interfaces.*; import java.security.spec.*; +import jdk.test.lib.security.ProvidersSnapshot; import jdk.test.lib.security.SecurityUtils; public class Failover { diff --git a/test/jdk/java/security/KeyPairGenerator/Failover.java b/test/jdk/java/security/KeyPairGenerator/Failover.java index 7fc8da8ccfc34..1bc2bfee2c8de 100644 --- a/test/jdk/java/security/KeyPairGenerator/Failover.java +++ b/test/jdk/java/security/KeyPairGenerator/Failover.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -24,7 +24,7 @@ /** * @test * @bug 4894125 7054918 8130181 - * @library ../testlibrary + * @library /test/lib * @summary test that failover for KeyPairGenerator works * @author Andreas Sterbenz */ @@ -32,8 +32,8 @@ import java.util.*; import java.security.*; -import java.security.interfaces.*; import java.security.spec.*; +import jdk.test.lib.security.ProvidersSnapshot; public class Failover { diff --git a/test/jdk/java/security/Provider/ChangeProviders.java b/test/jdk/java/security/Provider/ChangeProviders.java index 2c699cd70b1a0..7c408d70fb62c 100644 --- a/test/jdk/java/security/Provider/ChangeProviders.java +++ b/test/jdk/java/security/Provider/ChangeProviders.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -24,14 +24,13 @@ /* * @test * @bug 4856968 7054918 8130181 - * @library ../testlibrary + * @library /test/lib * @summary make sure add/insert/removeProvider() work correctly * @author Andreas Sterbenz */ -import java.util.*; - import java.security.*; +import jdk.test.lib.security.ProvidersSnapshot; public class ChangeProviders extends Provider { diff --git a/test/jdk/java/security/Provider/GetInstance.java b/test/jdk/java/security/Provider/GetInstance.java index d0d6417f02b08..f0e1a149f5cb6 100644 --- a/test/jdk/java/security/Provider/GetInstance.java +++ b/test/jdk/java/security/Provider/GetInstance.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -24,7 +24,7 @@ /* * @test * @bug 4856968 7054918 8130181 - * @library ../testlibrary + * @library /test/lib * @summary make sure getInstance() works correctly, including failover * and delayed provider selection for Signatures * @author Andreas Sterbenz @@ -34,6 +34,7 @@ import java.security.*; import java.security.cert.*; +import jdk.test.lib.security.ProvidersSnapshot; public class GetInstance { diff --git a/test/jdk/java/security/Provider/GetServiceRace.java b/test/jdk/java/security/Provider/GetServiceRace.java index 7f3f6b56ff722..427d555d37567 100644 --- a/test/jdk/java/security/Provider/GetServiceRace.java +++ b/test/jdk/java/security/Provider/GetServiceRace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -24,7 +24,6 @@ /* * @test * @bug 8231387 - * @library ../testlibrary * @summary make sure getService() avoids a race * @author Tianmin Shi */ diff --git a/test/jdk/java/security/Provider/RemoveProvider.java b/test/jdk/java/security/Provider/RemoveProvider.java index 05ab5eb0549c1..9983aa59b2a8f 100644 --- a/test/jdk/java/security/Provider/RemoveProvider.java +++ b/test/jdk/java/security/Provider/RemoveProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, 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 @@ -24,13 +24,14 @@ /* * @test * @bug 4190873 7054918 8130181 - * @library ../testlibrary + * @library /test/lib * @summary Make sure provider instance can be removed from list of registered * providers, and "entrySet", "keySet", and "values" methods don't loop * indefinitely. */ import java.security.*; import java.util.*; +import jdk.test.lib.security.ProvidersSnapshot; public class RemoveProvider { diff --git a/test/jdk/java/security/Security/NoInstalledProviders.java b/test/jdk/java/security/Security/NoInstalledProviders.java index 551f1896ecbe5..1e701f9a6e1f6 100644 --- a/test/jdk/java/security/Security/NoInstalledProviders.java +++ b/test/jdk/java/security/Security/NoInstalledProviders.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -24,12 +24,13 @@ /* * @test * @bug 4273454 7054918 7052537 - * @library ../testlibrary + * @library /test/lib * @summary Make sure getProviders(filter) doesn't throw NPE * @run main/othervm NoInstalledProviders */ import java.security.*; +import jdk.test.lib.security.ProvidersSnapshot; public class NoInstalledProviders { diff --git a/test/jdk/java/security/Security/SynchronizedAccess.java b/test/jdk/java/security/Security/SynchronizedAccess.java index 28019213b3c24..c1443529fe79c 100644 --- a/test/jdk/java/security/Security/SynchronizedAccess.java +++ b/test/jdk/java/security/Security/SynchronizedAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -24,13 +24,14 @@ /* * @test * @bug 4162583 7054918 8130181 8028127 - * @library /test/lib ../testlibrary + * @library /test/lib * @summary Make sure Provider api implementations are synchronized properly */ import java.security.*; import jdk.test.lib.Asserts; +import jdk.test.lib.security.ProvidersSnapshot; public class SynchronizedAccess { diff --git a/test/jdk/java/security/Security/removing/RemoveProviders.java b/test/jdk/java/security/Security/removing/RemoveProviders.java index 0d9f6b207c595..38edf983fb020 100644 --- a/test/jdk/java/security/Security/removing/RemoveProviders.java +++ b/test/jdk/java/security/Security/removing/RemoveProviders.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -24,7 +24,7 @@ /** * @test * @bug 4963416 7054918 - * @library ../../testlibrary + * @library /test/lib * @summary make sure removeProvider() always works correctly * @author Andreas Sterbenz */ @@ -32,6 +32,7 @@ import java.util.*; import java.security.*; +import jdk.test.lib.security.ProvidersSnapshot; public class RemoveProviders { diff --git a/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java b/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java index 478e94572bc73..d29ca878cd34d 100644 --- a/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java +++ b/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, 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 @@ -25,8 +25,7 @@ * @test * @bug 8179503 8328638 * @summary Java should support GET OCSP calls - * @library /javax/net/ssl/templates /java/security/testlibrary - * @build SimpleOCSPServer + * @library /javax/net/ssl/templates /test/lib * @modules java.base/sun.security.util * java.base/sun.security.provider.certpath * java.base/sun.security.x509 @@ -64,7 +63,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; +import jdk.test.lib.security.SimpleOCSPServer; import sun.security.util.DerOutputStream; import sun.security.util.DerValue; import sun.security.util.ObjectIdentifier; diff --git a/test/jdk/java/security/cert/CertPathValidator/OCSP/OCSPTimeout.java b/test/jdk/java/security/cert/CertPathValidator/OCSP/OCSPTimeout.java index dfd7dcdc81efe..342617a5fa93d 100644 --- a/test/jdk/java/security/cert/CertPathValidator/OCSP/OCSPTimeout.java +++ b/test/jdk/java/security/cert/CertPathValidator/OCSP/OCSPTimeout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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,8 +34,7 @@ * @modules java.base/sun.security.x509 * java.base/sun.security.provider.certpath * java.base/sun.security.util - * @library ../../../../../java/security/testlibrary - * @build CertificateBuilder SimpleOCSPServer + * @library /test/lib * @run main/othervm -Djava.security.debug=certpath OCSPTimeout 1000 true * @run main/othervm -Djava.security.debug=certpath * -Dcom.sun.security.ocsp.readtimeout=5 OCSPTimeout 1000 true @@ -59,8 +58,8 @@ import java.security.cert.*; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; import static java.security.cert.PKIXRevocationChecker.Option.*; @@ -84,7 +83,7 @@ public class OCSPTimeout { public static void main(String[] args) throws Exception { int ocspTimeout = 15000; - boolean expected = false; + boolean expected; createPKI(); @@ -195,7 +194,6 @@ private static void createPKI() throws Exception { rootOcsp = new SimpleOCSPServer(rootKeystore, passwd, ROOT_ALIAS, null); rootOcsp.enableLog(debug); rootOcsp.setNextUpdateInterval(3600); - rootOcsp.setDisableContentLength(true); rootOcsp.start(); // Wait 60 seconds for server ready diff --git a/test/jdk/java/security/cert/CertPathValidator/trustAnchor/ValWithAnchorByName.java b/test/jdk/java/security/cert/CertPathValidator/trustAnchor/ValWithAnchorByName.java index 29abfb9f551d4..c57abdf243d31 100644 --- a/test/jdk/java/security/cert/CertPathValidator/trustAnchor/ValWithAnchorByName.java +++ b/test/jdk/java/security/cert/CertPathValidator/trustAnchor/ValWithAnchorByName.java @@ -52,8 +52,8 @@ public class ValWithAnchorByName { // The following certificates and OCSP responses were captured from // a test run that used certificates and responses generated by - // sun.security.testlibrary.CertificateBuilder and - // sun.security.testlibrary.SimpleOCSPServer. + // jdk.test.lib.security.CertificateBuilder and + // jdk.test.lib.security.SimpleOCSPServer. // Subject: CN=SSLCertificate, O=SomeCompany // Issuer: CN=Intermediate CA Cert, O=SomeCompany diff --git a/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKeySpecException.java b/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKeySpecException.java index f55f1eea42ce6..5385beb9999fd 100644 --- a/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKeySpecException.java +++ b/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKeySpecException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -24,19 +24,20 @@ /** * @test * @bug 4508341 7055362 - * @library ../../../java/security/testlibrary + * @library /test/lib * @summary Test the error conditions of * EncryptedPrivateKeyInfo.getKeySpec(...) methods. * @author Valerie Peng * @run main/othervm -DcipherAlg=PBEWithMD5AndDES GetKeySpecException * @run main/othervm -DcipherAlg=PBEWithSHA1AndDESede GetKeySpecException */ + import java.security.*; -import java.util.Arrays; import java.util.Vector; import java.security.spec.*; import javax.crypto.*; import javax.crypto.spec.*; +import jdk.test.lib.security.ProvidersSnapshot; public class GetKeySpecException { private static String cipherAlg; diff --git a/test/jdk/javax/crypto/JceSecurity/SunJCE_BC_LoadOrdering.java b/test/jdk/javax/crypto/JceSecurity/SunJCE_BC_LoadOrdering.java index 50a1c188d0fa5..82ac4e70899f7 100644 --- a/test/jdk/javax/crypto/JceSecurity/SunJCE_BC_LoadOrdering.java +++ b/test/jdk/javax/crypto/JceSecurity/SunJCE_BC_LoadOrdering.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, 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 @@ -24,7 +24,7 @@ /* * @test * @bug 6377058 7055362 - * @library ../../../java/security/testlibrary + * @library /test/lib * @summary SunJCE depends on sun.security.provider.SignatureImpl * behaviour, BC can't load into 1st slot. * @author Brad R. Wetmore @@ -33,7 +33,7 @@ import java.security.*; import javax.crypto.*; -import java.io.*; +import jdk.test.lib.security.ProvidersSnapshot; public class SunJCE_BC_LoadOrdering { diff --git a/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java b/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java index 72a68cdddb06d..b9829621d686b 100644 --- a/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java +++ b/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -28,8 +28,7 @@ * @test * @bug 8046321 8153829 * @summary OCSP Stapling for TLS - * @library ../../../../java/security/testlibrary - * @build CertificateBuilder SimpleOCSPServer + * @library /test/lib * @run main/othervm HttpsUrlConnClient RSA SHA256withRSA * @run main/othervm HttpsUrlConnClient RSASSA-PSS RSASSA-PSS */ @@ -59,8 +58,8 @@ import java.util.*; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; public class HttpsUrlConnClient { diff --git a/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java b/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java index ec869f8343118..506e7b00e6d28 100644 --- a/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java +++ b/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -28,8 +28,7 @@ * @test * @bug 8046321 8153829 * @summary OCSP Stapling for TLS - * @library ../../../../java/security/testlibrary - * @build CertificateBuilder SimpleOCSPServer + * @library /test/lib * @run main/othervm SSLEngineWithStapling */ @@ -87,8 +86,8 @@ import java.util.Map; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; public class SSLEngineWithStapling { diff --git a/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java b/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java index 7e1473c2828ad..30f5e5898899e 100644 --- a/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java +++ b/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -28,8 +28,7 @@ * @test * @bug 8046321 8153829 * @summary OCSP Stapling for TLS - * @library ../../../../java/security/testlibrary - * @build CertificateBuilder SimpleOCSPServer + * @library /test/lib * @run main/othervm SSLSocketWithStapling */ @@ -63,8 +62,8 @@ import java.util.HashMap; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; public class SSLSocketWithStapling { diff --git a/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java b/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java index 14651cf3db926..90b01d19c03b6 100644 --- a/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java +++ b/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java @@ -28,8 +28,7 @@ * @test * @bug 8145854 8153829 * @summary SSLContextImpl.statusResponseManager should be generated if required - * @library ../../../../java/security/testlibrary - * @build CertificateBuilder SimpleOCSPServer + * @library /test/lib * @run main/othervm StapleEnableProps */ @@ -49,8 +48,8 @@ import java.util.Objects; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; public class StapleEnableProps { diff --git a/test/jdk/sun/security/ec/TestEC.java b/test/jdk/sun/security/ec/TestEC.java index dacb67ce892fc..3720df03e1fdf 100644 --- a/test/jdk/sun/security/ec/TestEC.java +++ b/test/jdk/sun/security/ec/TestEC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2025, 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,7 +34,6 @@ * @library ../pkcs11 * @library ../pkcs11/ec * @library ../pkcs11/sslecc - * @library ../../../java/security/testlibrary * @library ../../../javax/net/ssl/TLSCommon * @modules jdk.crypto.cryptoki/sun.security.pkcs11.wrapper * @run main/othervm -Djdk.tls.namedGroups="secp256r1" TestEC @@ -45,6 +44,7 @@ import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; +import jdk.test.lib.security.ProvidersSnapshot; /* * Leverage the collection of EC tests used by PKCS11 diff --git a/test/jdk/sun/security/pkcs11/ec/ReadCertificates.java b/test/jdk/sun/security/pkcs11/ec/ReadCertificates.java index 4b4a6a20a4a38..e0700a45553a6 100644 --- a/test/jdk/sun/security/pkcs11/ec/ReadCertificates.java +++ b/test/jdk/sun/security/pkcs11/ec/ReadCertificates.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, 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 @@ -28,7 +28,6 @@ * and verify their signatures * @author Andreas Sterbenz * @library /test/lib .. - * @library ../../../../java/security/testlibrary * @modules jdk.crypto.cryptoki * @run main/othervm ReadCertificates * @run main/othervm -Djava.security.manager=allow ReadCertificates sm policy @@ -56,6 +55,7 @@ import java.util.List; import java.util.Map; import javax.security.auth.x500.X500Principal; +import jdk.test.lib.security.Providers; public class ReadCertificates extends PKCS11Test { diff --git a/test/jdk/sun/security/pkcs11/ec/ReadPKCS12.java b/test/jdk/sun/security/pkcs11/ec/ReadPKCS12.java index 6005d88aec4db..7acd4c2dc691c 100644 --- a/test/jdk/sun/security/pkcs11/ec/ReadPKCS12.java +++ b/test/jdk/sun/security/pkcs11/ec/ReadPKCS12.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, 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 @@ -27,7 +27,6 @@ * @summary Verify that we can parse ECPrivateKeys from PKCS#12 and use them * @author Andreas Sterbenz * @library /test/lib .. - * @library ../../../../java/security/testlibrary * @key randomness * @modules jdk.crypto.cryptoki jdk.crypto.ec/sun.security.ec * @run main/othervm ReadPKCS12 @@ -55,6 +54,7 @@ import java.util.List; import java.util.Map; import java.util.Random; +import jdk.test.lib.security.Providers; public class ReadPKCS12 extends PKCS11Test { diff --git a/test/jdk/sun/security/pkcs11/ec/TestECDH.java b/test/jdk/sun/security/pkcs11/ec/TestECDH.java index 49061f1288dcc..d2a45f3842db0 100644 --- a/test/jdk/sun/security/pkcs11/ec/TestECDH.java +++ b/test/jdk/sun/security/pkcs11/ec/TestECDH.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, 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 @@ -27,7 +27,6 @@ * @summary Basic known answer test for ECDH * @author Andreas Sterbenz * @library /test/lib .. - * @library ../../../../java/security/testlibrary * @modules jdk.crypto.cryptoki * @run main/othervm TestECDH * @run main/othervm -Djava.security.manager=allow TestECDH sm policy @@ -44,6 +43,8 @@ import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import javax.crypto.KeyAgreement; +import jdk.test.lib.security.Providers; + public class TestECDH extends PKCS11Test { diff --git a/test/jdk/sun/security/pkcs11/ec/TestECDH2.java b/test/jdk/sun/security/pkcs11/ec/TestECDH2.java index 69ea7275193a2..1e4de55da0283 100644 --- a/test/jdk/sun/security/pkcs11/ec/TestECDH2.java +++ b/test/jdk/sun/security/pkcs11/ec/TestECDH2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -27,7 +27,6 @@ * @summary basic test of ECDSA signatures for P-256 and P-384 from the * example data in "Suite B Implementer's Guide to FIPS 186-3". * @library /test/lib .. - * @library ../../../../java/security/testlibrary * @modules java.base/sun.security.util * jdk.crypto.cryptoki * @compile -XDignore.symbol.file TestECDH2.java diff --git a/test/jdk/sun/security/pkcs11/ec/TestECDSA.java b/test/jdk/sun/security/pkcs11/ec/TestECDSA.java index 59db0a3ed0138..8ce69c61667ef 100644 --- a/test/jdk/sun/security/pkcs11/ec/TestECDSA.java +++ b/test/jdk/sun/security/pkcs11/ec/TestECDSA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, 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 @@ -27,7 +27,6 @@ * @summary basic test of SHA1withECDSA and NONEwithECDSA signing/verifying * @author Andreas Sterbenz * @library /test/lib .. - * @library ../../../../java/security/testlibrary * @key randomness * @modules jdk.crypto.cryptoki * @run main/othervm TestECDSA @@ -46,6 +45,7 @@ import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Random; +import jdk.test.lib.security.Providers; public class TestECDSA extends PKCS11Test { diff --git a/test/jdk/sun/security/pkcs11/ec/TestECDSA2.java b/test/jdk/sun/security/pkcs11/ec/TestECDSA2.java index 4b6cb6f14ed09..88edb93668e6d 100644 --- a/test/jdk/sun/security/pkcs11/ec/TestECDSA2.java +++ b/test/jdk/sun/security/pkcs11/ec/TestECDSA2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -27,7 +27,6 @@ * @summary basic test of ECDSA signatures for P-256 and P-384 from the * example data in "Suite B Implementer's Guide to FIPS 186-3". * @library /test/lib .. - * @library ../../../../java/security/testlibrary * @modules java.base/sun.security.util * jdk.crypto.cryptoki * @compile -XDignore.symbol.file TestECDSA2.java diff --git a/test/jdk/sun/security/pkcs11/rsa/TestCACerts.java b/test/jdk/sun/security/pkcs11/rsa/TestCACerts.java index c95d27bc3d8cf..a6844d28f782e 100644 --- a/test/jdk/sun/security/pkcs11/rsa/TestCACerts.java +++ b/test/jdk/sun/security/pkcs11/rsa/TestCACerts.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -27,7 +27,6 @@ * @summary Test the new RSA provider can verify all the RSA certs in the cacerts file * @author Andreas Sterbenz * @library /test/lib .. - * @library ../../../../java/security/testlibrary * @modules jdk.crypto.cryptoki * @run main/othervm TestCACerts * @run main/othervm -Djava.security.manager=allow TestCACerts sm TestCACerts.policy @@ -43,6 +42,7 @@ import java.security.Security; import java.security.cert.X509Certificate; import java.util.Enumeration; +import jdk.test.lib.security.Providers; public class TestCACerts extends PKCS11Test { diff --git a/test/jdk/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java b/test/jdk/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java index 08b29fe6df189..e57ba07741c90 100644 --- a/test/jdk/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java +++ b/test/jdk/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, 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 @@ -32,7 +32,6 @@ * @summary Verify that all ciphersuites work (incl. ECC using NSS crypto) * @author Andreas Sterbenz * @library /test/lib .. ../../../../javax/net/ssl/TLSCommon - * @library ../../../../java/security/testlibrary * @modules jdk.crypto.cryptoki * @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" * ClientJSSEServerJSSE @@ -42,6 +41,7 @@ import java.security.Provider; import java.security.Security; +import jdk.test.lib.security.Providers; public class ClientJSSEServerJSSE extends PKCS11Test { diff --git a/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java b/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java index 8be1b05cd85af..979d270d8a5a0 100644 --- a/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java +++ b/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -28,8 +28,7 @@ * @modules java.base/sun.security.x509 * java.base/sun.security.provider.certpath * java.base/sun.security.util - * @library ../../../../../java/security/testlibrary - * @build CertificateBuilder SimpleOCSPServer + * @library /test/lib * @run main/othervm OCSPNoContentLength */ @@ -46,8 +45,8 @@ import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; public class OCSPNoContentLength { diff --git a/test/jdk/sun/security/ssl/Stapling/StatusResponseManager.java b/test/jdk/sun/security/ssl/Stapling/StatusResponseManager.java index 58ebb5b876af8..0f66db4064cf2 100644 --- a/test/jdk/sun/security/ssl/Stapling/StatusResponseManager.java +++ b/test/jdk/sun/security/ssl/Stapling/StatusResponseManager.java @@ -23,10 +23,12 @@ /* * @test + * @library /test/lib + * @build jdk.test.lib.security.SimpleOCSPServer + * jdk.test.lib.security.CertificateBuilder * @bug 8046321 - * @library ../../../../java/security/testlibrary - * @build CertificateBuilder SimpleOCSPServer - * @run main/othervm -Djavax.net.debug=ssl:respmgr java.base/sun.security.ssl.StatusResponseManagerTests * @summary OCSP Stapling for TLS + * @run main/othervm -Djavax.net.debug=ssl:respmgr + * java.base/sun.security.ssl.StatusResponseManagerTests */ diff --git a/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java b/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java index 07058a29c2525..63910c67e2d9d 100644 --- a/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java +++ b/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -33,8 +33,8 @@ import java.security.PublicKey; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; import static sun.security.ssl.CertStatusExtension.*; diff --git a/test/jdk/sun/security/tools/keytool/KeyToolTest.java b/test/jdk/sun/security/tools/keytool/KeyToolTest.java index 4d3563978fe18..4e03e73629ee9 100644 --- a/test/jdk/sun/security/tools/keytool/KeyToolTest.java +++ b/test/jdk/sun/security/tools/keytool/KeyToolTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @library /java/security/testlibrary + * @library /test/lib * @bug 6251120 8231950 8242151 * @summary Testing keytool * @@ -68,10 +68,10 @@ import java.util.*; import java.security.cert.X509Certificate; import jdk.test.lib.util.FileUtils; +import jdk.test.lib.security.HumanInputStream; import jdk.test.lib.security.SecurityUtils; import sun.security.util.ObjectIdentifier; - public class KeyToolTest { // The stdout and stderr outputs after a keytool run diff --git a/test/jdk/sun/security/tools/keytool/NssTest.java b/test/jdk/sun/security/tools/keytool/NssTest.java index 1ed2d4c3f391c..6f82da4b4c8a4 100644 --- a/test/jdk/sun/security/tools/keytool/NssTest.java +++ b/test/jdk/sun/security/tools/keytool/NssTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, 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 @@ -29,7 +29,7 @@ /* * @test * @summary It tests (almost) all keytool behaviors with NSS. - * @library /test/lib /test/jdk/sun/security/pkcs11 /java/security/testlibrary + * @library /test/lib /test/jdk/sun/security/pkcs11 * @modules java.base/sun.security.tools.keytool * java.base/sun.security.util * java.base/sun.security.x509 diff --git a/test/jdk/sun/security/x509/URICertStore/AIACertTimeout.java b/test/jdk/sun/security/x509/URICertStore/AIACertTimeout.java index 487f5e2471ce4..cabb225bf1cc6 100644 --- a/test/jdk/sun/security/x509/URICertStore/AIACertTimeout.java +++ b/test/jdk/sun/security/x509/URICertStore/AIACertTimeout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -27,8 +27,7 @@ * @summary Enhance OCSP, CRL and Certificate Fetch Timeouts * @modules java.base/sun.security.x509 * java.base/sun.security.util - * @library /test/lib ../../../../java/security/testlibrary - * @build CertificateBuilder + * @library /test/lib * @run main/othervm -Dcom.sun.security.enableAIAcaIssuers=true * -Dcom.sun.security.cert.readtimeout=1 AIACertTimeout 5000 false * @run main/othervm -Dcom.sun.security.enableAIAcaIssuers=true @@ -55,10 +54,7 @@ import java.util.*; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.CertificateBuilder; - -import sun.security.x509.*; -import sun.security.util.*; +import jdk.test.lib.security.CertificateBuilder; public class AIACertTimeout { diff --git a/test/jdk/java/security/testlibrary/CertificateBuilder.java b/test/lib/jdk/test/lib/security/CertificateBuilder.java similarity index 99% rename from test/jdk/java/security/testlibrary/CertificateBuilder.java rename to test/lib/jdk/test/lib/security/CertificateBuilder.java index 53c36531da18d..e9de3799259b9 100644 --- a/test/jdk/java/security/testlibrary/CertificateBuilder.java +++ b/test/lib/jdk/test/lib/security/CertificateBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ * questions. */ -package sun.security.testlibrary; +package jdk.test.lib.security; import java.io.*; import java.util.*; diff --git a/test/jdk/java/security/testlibrary/HumanInputStream.java b/test/lib/jdk/test/lib/security/HumanInputStream.java similarity index 98% rename from test/jdk/java/security/testlibrary/HumanInputStream.java rename to test/lib/jdk/test/lib/security/HumanInputStream.java index 50e5dd0bcc8c4..c68f515881e05 100644 --- a/test/jdk/java/security/testlibrary/HumanInputStream.java +++ b/test/lib/jdk/test/lib/security/HumanInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, 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 @@ -21,6 +21,7 @@ * questions. */ +package jdk.test.lib.security; import java.io.BufferedReader; import java.io.IOException; @@ -82,6 +83,7 @@ public HumanInputStream(String input) { } return re; } + @Override public int read(byte[] buffer, int offset, int len) { inLine = true; try { @@ -92,6 +94,7 @@ public HumanInputStream(String input) { inLine = false; } } + @Override public int available() { if (pos < length) return 1; return 0; diff --git a/test/jdk/java/security/testlibrary/Providers.java b/test/lib/jdk/test/lib/security/Providers.java similarity index 92% rename from test/jdk/java/security/testlibrary/Providers.java rename to test/lib/jdk/test/lib/security/Providers.java index b3e9f3e96b645..42dd698403649 100644 --- a/test/jdk/java/security/testlibrary/Providers.java +++ b/test/lib/jdk/test/lib/security/Providers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.test.lib.security; + import java.security.Provider; import java.security.Security; diff --git a/test/jdk/java/security/testlibrary/ProvidersSnapshot.java b/test/lib/jdk/test/lib/security/ProvidersSnapshot.java similarity index 93% rename from test/jdk/java/security/testlibrary/ProvidersSnapshot.java rename to test/lib/jdk/test/lib/security/ProvidersSnapshot.java index 33c45329e3f48..cef02f814befb 100644 --- a/test/jdk/java/security/testlibrary/ProvidersSnapshot.java +++ b/test/lib/jdk/test/lib/security/ProvidersSnapshot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.test.lib.security; + import java.security.Provider; import java.security.Security; diff --git a/test/jdk/java/security/testlibrary/SimpleOCSPServer.java b/test/lib/jdk/test/lib/security/SimpleOCSPServer.java similarity index 99% rename from test/jdk/java/security/testlibrary/SimpleOCSPServer.java rename to test/lib/jdk/test/lib/security/SimpleOCSPServer.java index b2a7d1ca80fd7..ded4f6cf5e766 100644 --- a/test/jdk/java/security/testlibrary/SimpleOCSPServer.java +++ b/test/lib/jdk/test/lib/security/SimpleOCSPServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ * questions. */ -package sun.security.testlibrary; +package jdk.test.lib.security; import java.io.*; import java.net.*; From 75fa2e7c44d52874fa0054889f1240e0c58fcfd1 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Thu, 8 May 2025 08:34:16 +0000 Subject: [PATCH 240/846] 8350540: [17u,11u] B8312065.java fails Network is unreachable Reviewed-by: phh --- test/jdk/java/net/Socket/B8312065.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/jdk/java/net/Socket/B8312065.java b/test/jdk/java/net/Socket/B8312065.java index 118792eada3e9..69194ddfa0147 100644 --- a/test/jdk/java/net/Socket/B8312065.java +++ b/test/jdk/java/net/Socket/B8312065.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Alibaba Group Holding Limited. All Rights Reserved. + * Copyright (c) 2023, 2025, Alibaba Group Holding Limited. 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 @@ -26,6 +26,8 @@ * @bug 8312065 * @summary Socket.connect does not timeout as expected when profiling (i.e. keep receiving signal) * @requires (os.family != "windows") + * @library /test/lib + * @build jtreg.SkippedException * @compile NativeThread.java * @run main/othervm/native/timeout=120 -Djdk.net.usePlainSocketImpl B8312065 */ @@ -37,6 +39,8 @@ import java.net.SocketTimeoutException; import java.util.concurrent.TimeUnit; +import jtreg.SkippedException; + public class B8312065 { public static void main(String[] args) throws Exception { System.loadLibrary("NativeThread"); @@ -83,6 +87,8 @@ public static void main(String[] args) throws Exception { System.out.println("Test FAILED: duration " + duration + " ms, expected >= " + timeoutMillis + " ms"); System.exit(1); } + } catch (java.net.ConnectException e) { + throw new SkippedException("Network setup issue, skip this test", e); } } } From e0c70dae5e2f70995ca4cd7b105ea18a11c9f5e2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 09:10:30 +0000 Subject: [PATCH 241/846] 8286789: Test forceEarlyReturn002.java timed out Reviewed-by: mbaesken Backport-of: c90cd2c0608d250434bff7013360b8388d9854b3 --- .../forceEarlyReturn002.java | 7 +++-- .../forceEarlyReturn002a.java | 10 +++++- .../libforceEarlyReturn002a.cpp | 31 ++++++++++++++++--- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002.java index 3d1fb85f0758f..e66da8076692a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -55,7 +55,7 @@ * When test thread has finish execution debugger suspends thread and call command for this thread, INVALID_THREAD * error is expected, then, debugger resumes test thread and call command again, INVALID_THREAD error should * be returned in reply. - * - debuggee starts test thread which executes infinite loop in native method, debugger calls command for + * - debuggee starts test thread which executes loop in native method, debugger calls command for * this thread(without suspending) and expects THREAD_NOT_SUSPENDED error. Then, debugger suspends this thread * and calls command again, OPAQUE_FRAME error is expected. * - debugger creates ThreadStartEventRequest with suspend policy 'JDWP.SuspendPolicy.ALL' and forces debuggee start new thread. @@ -248,6 +248,9 @@ public void doTest() { // suspended thread in native, expect OPAQUE_FRAME error sendCommand(threadID, value, true, JDWP.Error.OPAQUE_FRAME); + // signal native method to exit; the thread will be actually suspended + pipe.println(forceEarlyReturn002a.COMMAND_EXIT_THREAD_IN_NATIVE); + // create request for ThreadStart event int requestID = createThreadStartEventRequest(); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002a.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002a.java index f5a740ec2f172..dc09ffdb7c9e1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002a.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002a.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -40,6 +40,8 @@ public class forceEarlyReturn002a extends AbstractJDWPDebuggee { public final static String COMMAND_STOP_THREAD_IN_NATIVE = "stopInNative"; + public final static String COMMAND_EXIT_THREAD_IN_NATIVE = "exitInNative"; + public final static String COMMAND_START_NEW_THREAD = "startNewThread"; public boolean parseCommand(String command) { @@ -49,6 +51,10 @@ public boolean parseCommand(String command) { if (command.equals(COMMAND_STOP_THREAD_IN_NATIVE)) { stopThreadInNative(); + return true; + } else if (command.equals(COMMAND_EXIT_THREAD_IN_NATIVE)) { + exitThreadInNative(); + return true; } else if (command.equals(COMMAND_START_NEW_THREAD)) { testNewThread.start(); @@ -95,6 +101,8 @@ public void run() { private static native int nativeMethod(Object object); + private static native void exitThreadInNative(); + public static void main(String args[]) { new forceEarlyReturn002a().doTest(args); } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/libforceEarlyReturn002a.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/libforceEarlyReturn002a.cpp index 79d46c3095edb..c287de9056b1f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/libforceEarlyReturn002a.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/libforceEarlyReturn002a.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -23,23 +23,46 @@ #include "jni.h" +#if defined(_WIN32) +#include +#else +#include +#endif + +#include + extern "C" { +static std::atomic wait_in_native(true); + +static void delay(int seconds) { +#if defined(_WIN32) + Sleep(1000L * seconds); +#else + sleep(seconds); +#endif +} JNIEXPORT jint JNICALL Java_nsk_jdwp_ThreadReference_ForceEarlyReturn_forceEarlyReturn002_forceEarlyReturn002a_nativeMethod(JNIEnv *env, jobject classObject, jobject object) { - static volatile int dummy_counter = 0; // notify another thread that thread in native method jclass klass = env->GetObjectClass(object); jfieldID field = env->GetFieldID(klass, "threadInNative", "Z"); env->SetBooleanField(object, field, 1); // execute infinite loop to be sure that thread in native method - while (dummy_counter == 0) {} + while (wait_in_native) { + delay(1); + } - // Should not reach here return 0; } +JNIEXPORT void JNICALL +Java_nsk_jdwp_ThreadReference_ForceEarlyReturn_forceEarlyReturn002_forceEarlyReturn002a_exitThreadInNative(JNIEnv *env, jobject classObject) +{ + wait_in_native = false; +} + } From ce8287725b63cd114cc4a6ea9fee58bbe5fb9d90 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 09:12:10 +0000 Subject: [PATCH 242/846] 8325682: Rename nsk_strace.h Backport-of: 22e81810ddb293ceb45d577b2b0ab43ab3f154b2 --- .../strace/{nsk_strace.h => nsk_strace.hpp} | 16 ++++++++-------- .../vmTestbase/nsk/stress/strace/strace003.cpp | 4 ++-- .../vmTestbase/nsk/stress/strace/strace004.cpp | 4 ++-- .../vmTestbase/nsk/stress/strace/strace005.cpp | 2 +- .../vmTestbase/nsk/stress/strace/strace006.cpp | 2 +- .../vmTestbase/nsk/stress/strace/strace008.cpp | 4 ++-- .../vmTestbase/nsk/stress/strace/strace009.cpp | 4 ++-- .../vmTestbase/nsk/stress/strace/strace011.cpp | 4 ++-- .../vmTestbase/nsk/stress/strace/strace012.cpp | 4 ++-- .../vmTestbase/nsk/stress/strace/strace014.cpp | 4 ++-- .../vmTestbase/nsk/stress/strace/strace015.cpp | 4 ++-- 11 files changed, 26 insertions(+), 26 deletions(-) rename test/hotspot/jtreg/vmTestbase/nsk/stress/strace/{nsk_strace.h => nsk_strace.hpp} (92%) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/nsk_strace.h b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/nsk_strace.hpp similarity index 92% rename from test/hotspot/jtreg/vmTestbase/nsk/stress/strace/nsk_strace.h rename to test/hotspot/jtreg/vmTestbase/nsk/stress/strace/nsk_strace.hpp index eb787baddac1d..9a03b990df79f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/nsk_strace.h +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/nsk_strace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ // Check for pending exception of the specified type // If it's present, then clear it #define EXCEPTION_CHECK(exceptionClass, recurDepth) \ - if (EXCEPTION_OCCURRED != NULL) { \ + if (EXCEPTION_OCCURRED != nullptr) { \ jobject exception = EXCEPTION_OCCURRED; \ if (env->IsInstanceOf(exception, exceptionClass) == JNI_TRUE) { \ EXCEPTION_CLEAR; \ @@ -45,22 +45,22 @@ #define FIND_CLASS(_class, _className)\ if (!NSK_JNI_VERIFY(env, (_class = \ - env->FindClass(_className)) != NULL))\ + env->FindClass(_className)) != nullptr))\ exit(1) #define GET_OBJECT_CLASS(_class, _obj)\ if (!NSK_JNI_VERIFY(env, (_class = \ - env->GetObjectClass(_obj)) != NULL))\ + env->GetObjectClass(_obj)) != nullptr))\ exit(1) #define GET_FIELD_ID(_fieldID, _class, _fieldName, _fieldSig)\ if (!NSK_JNI_VERIFY(env, (_fieldID = \ - env->GetFieldID(_class, _fieldName, _fieldSig)) != NULL))\ + env->GetFieldID(_class, _fieldName, _fieldSig)) != nullptr))\ exit(1) #define GET_STATIC_FIELD_ID(_fieldID, _class, _fieldName, _fieldSig)\ if (!NSK_JNI_VERIFY(env, (_fieldID = \ - env->GetStaticFieldID(_class, _fieldName, _fieldSig)) != NULL))\ + env->GetStaticFieldID(_class, _fieldName, _fieldSig)) != nullptr))\ exit(1) #define GET_STATIC_BOOL_FIELD(_value, _class, _fieldName)\ @@ -93,12 +93,12 @@ #define GET_STATIC_METHOD_ID(_methodID, _class, _methodName, _sig)\ if (!NSK_JNI_VERIFY(env, (_methodID = \ - env->GetStaticMethodID(_class, _methodName, _sig)) != NULL))\ + env->GetStaticMethodID(_class, _methodName, _sig)) != nullptr))\ exit(1) #define GET_METHOD_ID(_methodID, _class, _methodName, _sig)\ if (!NSK_JNI_VERIFY(env, (_methodID = \ - env->GetMethodID(_class, _methodName, _sig)) != NULL))\ + env->GetMethodID(_class, _methodName, _sig)) != nullptr))\ exit(1) #define CALL_STATIC_VOID_NOPARAM(_class, _methodName)\ diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace003.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace003.cpp index 727da0f532465..1c1c91d242bcd 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace003.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace003.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ */ #include -#include "nsk_strace.h" +#include "nsk_strace.hpp" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace004.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace004.cpp index ee278b054be29..031397841ac4d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace004.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace004.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ */ #include -#include "nsk_strace.h" +#include "nsk_strace.hpp" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace005.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace005.cpp index 4cc89978fd1d7..c16fe6ea13cf8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace005.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace005.cpp @@ -22,7 +22,7 @@ */ #include -#include "nsk_strace.h" +#include "nsk_strace.hpp" #include "nsk_tools.h" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace006.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace006.cpp index 9b5329f2cb9bd..138a1e07ac20e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace006.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace006.cpp @@ -22,7 +22,7 @@ */ #include -#include "nsk_strace.h" +#include "nsk_strace.hpp" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace008.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace008.cpp index cca0c1c2d8a4e..18c8d76e18834 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace008.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace008.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ */ #include -#include "nsk_strace.h" +#include "nsk_strace.hpp" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace009.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace009.cpp index 995e06ad1abe7..8ff02942b1a63 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace009.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace009.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ */ #include -#include "nsk_strace.h" +#include "nsk_strace.hpp" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace011.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace011.cpp index c9e699f7bb5b9..462d187970978 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace011.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace011.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ */ #include -#include "nsk_strace.h" +#include "nsk_strace.hpp" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace012.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace012.cpp index 3c58b84eff0d2..d58e0eacbf3d2 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace012.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace012.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ */ #include -#include "nsk_strace.h" +#include "nsk_strace.hpp" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace014.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace014.cpp index 4f58b8a590373..2b535c60f483c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace014.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace014.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ */ #include -#include "nsk_strace.h" +#include "nsk_strace.hpp" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace015.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace015.cpp index e0fd29fbebb85..658561bcc3fd3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace015.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace015.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ */ #include -#include "nsk_strace.h" +#include "nsk_strace.hpp" extern "C" { From bdc6ab594975420b165ef1e126bfab2084954966 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 10:57:41 +0000 Subject: [PATCH 243/846] 8330534: Update nsk/jdwp tests to use driver instead of othervm Backport-of: 56e8e60792b23bc101f46b497dcc9d3c76855384 --- .../jdwp/ArrayReference/GetValues/getvalues001.java | 7 +++++-- .../GetValues/getvalues001/TestDescription.java | 4 ++-- .../jdwp/ArrayReference/GetValues/getvalues002.java | 7 +++++-- .../GetValues/getvalues002/TestDescription.java | 4 ++-- .../nsk/jdwp/ArrayReference/Length/length001.java | 7 +++++-- .../Length/length001/TestDescription.java | 4 ++-- .../jdwp/ArrayReference/SetValues/setvalues001.java | 7 +++++-- .../SetValues/setvalues001/TestDescription.java | 4 ++-- .../jdwp/ArrayType/NewInstance/newinstance001.java | 7 +++++-- .../NewInstance/newinstance001/TestDescription.java | 4 ++-- .../VisibleClasses/visibclasses001.java | 7 +++++-- .../visibclasses001/TestDescription.java | 4 ++-- .../ReflectedType/reflectype001.java | 7 +++++-- .../ReflectedType/reflectype001/TestDescription.java | 4 ++-- .../jdwp/ClassType/InvokeMethod/invokemeth001.java | 7 +++++-- .../InvokeMethod/invokemeth001/TestDescription.java | 4 ++-- .../nsk/jdwp/ClassType/NewInstance/newinst001.java | 9 ++++++--- .../NewInstance/newinst001/TestDescription.java | 4 ++-- .../nsk/jdwp/ClassType/SetValues/setvalues001.java | 7 +++++-- .../SetValues/setvalues001/TestDescription.java | 4 ++-- .../nsk/jdwp/ClassType/Superclass/superclass001.java | 7 +++++-- .../Superclass/superclass001/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/BREAKPOINT/breakpoint001.java | 9 ++++++--- .../BREAKPOINT/breakpoint001/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/CLASS_PREPARE/clsprepare001.java | 9 ++++++--- .../CLASS_PREPARE/clsprepare001/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/CLASS_UNLOAD/clsunload001.java | 9 ++++++--- .../CLASS_UNLOAD/clsunload001/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/Composite/composite001.java | 9 ++++++--- .../Event/Composite/composite001/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/EXCEPTION/exception001.java | 9 ++++++--- .../Event/EXCEPTION/exception001/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/FIELD_ACCESS/fldaccess001.java | 9 ++++++--- .../FIELD_ACCESS/fldaccess001/TestDescription.java | 4 ++-- .../Event/FIELD_MODIFICATION/fldmodification001.java | 9 ++++++--- .../fldmodification001/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/METHOD_ENTRY/methentry001.java | 9 ++++++--- .../METHOD_ENTRY/methentry001/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/METHOD_EXIT/methexit001.java | 9 ++++++--- .../METHOD_EXIT/methexit001/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/SINGLE_STEP/singlestep001.java | 9 ++++++--- .../SINGLE_STEP/singlestep001/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/SINGLE_STEP/singlestep002.java | 9 ++++++--- .../SINGLE_STEP/singlestep002/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/SINGLE_STEP/singlestep003.java | 9 ++++++--- .../SINGLE_STEP/singlestep003/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/THREAD_DEATH/thrdeath001.java | 9 ++++++--- .../THREAD_DEATH/thrdeath001/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/THREAD_START/thrstart001.java | 9 ++++++--- .../THREAD_START/thrstart001/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/VM_DEATH/vmdeath001.java | 9 ++++++--- .../Event/VM_DEATH/vmdeath001/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/VM_DEATH/vmdeath002.java | 9 ++++++--- .../Event/VM_DEATH/vmdeath002/TestDescription.java | 4 ++-- .../nsk/jdwp/Event/VM_START/vmstart001.java | 9 ++++++--- .../Event/VM_START/vmstart001/TestDescription.java | 4 ++-- .../nsk/jdwp/EventRequest/Clear/clear001.java | 9 ++++++--- .../EventRequest/Clear/clear001/TestDescription.java | 4 ++-- .../ClearAllBreakpoints/clrallbreakp001.java | 9 ++++++--- .../clrallbreakp001/TestDescription.java | 4 ++-- .../ClearAllBreakpoints/clrallbreakp002.java | 9 ++++++--- .../clrallbreakp002/TestDescription.java | 4 ++-- .../ClearAllBreakpoints/clrallbreakp003.java | 9 ++++++--- .../clrallbreakp003/TestDescription.java | 4 ++-- .../vmTestbase/nsk/jdwp/EventRequest/Set/set001.java | 9 ++++++--- .../jdwp/EventRequest/Set/set001/TestDescription.java | 4 ++-- .../vmTestbase/nsk/jdwp/EventRequest/Set/set002.java | 9 ++++++--- .../jdwp/EventRequest/Set/set002/TestDescription.java | 4 ++-- .../nsk/jdwp/Method/Bytecodes/bytecodes001.java | 7 +++++-- .../Bytecodes/bytecodes001/TestDescription.java | 4 ++-- .../nsk/jdwp/Method/IsObsolete/isobsolete001.java | 7 +++++-- .../IsObsolete/isobsolete001/TestDescription.java | 4 ++-- .../nsk/jdwp/Method/IsObsolete/isobsolete002.java | 7 +++++-- .../IsObsolete/isobsolete002/TestDescription.java | 4 ++-- .../nsk/jdwp/Method/LineTable/linetable001.java | 7 +++++-- .../LineTable/linetable001/TestDescription.java | 4 ++-- .../nsk/jdwp/Method/VariableTable/vartable001.java | 7 +++++-- .../VariableTable/vartable001/TestDescription.java | 4 ++-- .../VariableTableWithGeneric/vartblwithgen001.java | 7 +++++-- .../vartblwithgen001/TestDescription.java | 4 ++-- .../DisableCollection/disablecol001.java | 7 +++++-- .../disablecol001/TestDescription.java | 4 ++-- .../EnableCollection/enablecol001.java | 7 +++++-- .../enablecol001/TestDescription.java | 4 ++-- .../jdwp/ObjectReference/GetValues/getvalues001.java | 7 +++++-- .../GetValues/getvalues001/TestDescription.java | 4 ++-- .../ObjectReference/InvokeMethod/invokemeth001.java | 7 +++++-- .../InvokeMethod/invokemeth001/TestDescription.java | 4 ++-- .../ObjectReference/IsCollected/iscollected001.java | 7 +++++-- .../IsCollected/iscollected001/TestDescription.java | 4 ++-- .../ObjectReference/MonitorInfo/monitorinfo001.java | 7 +++++-- .../MonitorInfo/monitorinfo001/TestDescription.java | 4 ++-- .../ReferenceType/referencetype001.java | 7 +++++-- .../referencetype001/TestDescription.java | 4 ++-- .../referringObjects001/referringObjects001.java | 9 ++++++--- .../referringObjects002/referringObjects002.java | 9 ++++++--- .../jdwp/ObjectReference/SetValues/setvalues001.java | 7 +++++-- .../SetValues/setvalues001/TestDescription.java | 4 ++-- .../ReferenceType/ClassLoader/classloader001.java | 7 +++++-- .../ClassLoader/classloader001/TestDescription.java | 4 ++-- .../jdwp/ReferenceType/ClassObject/classobj001.java | 7 +++++-- .../ClassObject/classobj001/TestDescription.java | 4 ++-- .../nsk/jdwp/ReferenceType/Fields/fields001.java | 7 +++++-- .../Fields/fields001/TestDescription.java | 4 ++-- .../FieldsWithGeneric/fldwithgeneric001.java | 9 ++++++--- .../fldwithgeneric001/TestDescription.java | 4 ++-- .../jdwp/ReferenceType/GetValues/getvalues001.java | 7 +++++-- .../GetValues/getvalues001/TestDescription.java | 4 ++-- .../Instances/instances001/instances001.java | 9 ++++++--- .../Instances/instances002/instances002.java | 11 +++++++---- .../jdwp/ReferenceType/Interfaces/interfaces001.java | 7 +++++-- .../Interfaces/interfaces001/TestDescription.java | 4 ++-- .../nsk/jdwp/ReferenceType/Methods/methods001.java | 7 +++++-- .../Methods/methods001/TestDescription.java | 4 ++-- .../MethodsWithGeneric/methwithgeneric001.java | 9 ++++++--- .../methwithgeneric001/TestDescription.java | 4 ++-- .../jdwp/ReferenceType/Modifiers/modifiers001.java | 7 +++++-- .../Modifiers/modifiers001/TestDescription.java | 4 ++-- .../ReferenceType/NestedTypes/nestedtypes001.java | 7 +++++-- .../NestedTypes/nestedtypes001/TestDescription.java | 4 ++-- .../jdwp/ReferenceType/Signature/signature001.java | 7 +++++-- .../Signature/signature001/TestDescription.java | 4 ++-- .../SignatureWithGeneric/sigwithgeneric001.java | 9 ++++++--- .../sigwithgeneric001/TestDescription.java | 4 ++-- .../SourceDebugExtension/srcdebugext001.java | 7 +++++-- .../srcdebugext001/TestDescription.java | 4 ++-- .../nsk/jdwp/ReferenceType/SourceFile/srcfile001.java | 7 +++++-- .../SourceFile/srcfile001/TestDescription.java | 4 ++-- .../nsk/jdwp/ReferenceType/Status/status001.java | 7 +++++-- .../Status/status001/TestDescription.java | 4 ++-- .../nsk/jdwp/StackFrame/GetValues/getvalues001.java | 7 +++++-- .../GetValues/getvalues001/TestDescription.java | 4 ++-- .../nsk/jdwp/StackFrame/PopFrames/popframes001.java | 7 +++++-- .../PopFrames/popframes001/TestDescription.java | 4 ++-- .../nsk/jdwp/StackFrame/SetValues/setvalues001.java | 7 +++++-- .../SetValues/setvalues001/TestDescription.java | 4 ++-- .../nsk/jdwp/StackFrame/ThisObject/thisobject001.java | 7 +++++-- .../ThisObject/thisobject001/TestDescription.java | 4 ++-- .../nsk/jdwp/StringReference/Value/value001.java | 7 +++++-- .../Value/value001/TestDescription.java | 4 ++-- .../ThreadGroupReference/Children/children001.java | 7 +++++-- .../Children/children001/TestDescription.java | 4 ++-- .../nsk/jdwp/ThreadGroupReference/Name/name001.java | 7 +++++-- .../Name/name001/TestDescription.java | 4 ++-- .../jdwp/ThreadGroupReference/Parent/parent001.java | 7 +++++-- .../Parent/parent001/TestDescription.java | 4 ++-- .../CurrentContendedMonitor/curcontmonitor001.java | 7 +++++-- .../curcontmonitor001/TestDescription.java | 4 ++-- .../forceEarlyReturn001/forceEarlyReturn001.java | 11 +++++++---- .../forceEarlyReturn002/forceEarlyReturn002.java | 9 ++++++--- .../jdwp/ThreadReference/FrameCount/framecnt001.java | 7 +++++-- .../FrameCount/framecnt001/TestDescription.java | 4 ++-- .../nsk/jdwp/ThreadReference/Frames/frames001.java | 7 +++++-- .../Frames/frames001/TestDescription.java | 4 ++-- .../jdwp/ThreadReference/Interrupt/interrupt001.java | 7 +++++-- .../Interrupt/interrupt001/TestDescription.java | 4 ++-- .../nsk/jdwp/ThreadReference/Name/name001.java | 7 +++++-- .../ThreadReference/Name/name001/TestDescription.java | 4 ++-- .../ThreadReference/OwnedMonitors/ownmonitors001.java | 7 +++++-- .../OwnedMonitors/ownmonitors001/TestDescription.java | 4 ++-- .../ownedMonitorsStackDepthInfo001.java | 9 ++++++--- .../ownedMonitorsStackDepthInfo002.java | 11 +++++++---- .../nsk/jdwp/ThreadReference/Resume/resume001.java | 7 +++++-- .../Resume/resume001/TestDescription.java | 4 ++-- .../nsk/jdwp/ThreadReference/Status/status001.java | 7 +++++-- .../Status/status001/TestDescription.java | 4 ++-- .../nsk/jdwp/ThreadReference/Stop/stop001.java | 7 +++++-- .../ThreadReference/Stop/stop001/TestDescription.java | 4 ++-- .../nsk/jdwp/ThreadReference/Suspend/suspend001.java | 7 +++++-- .../Suspend/suspend001/TestDescription.java | 4 ++-- .../ThreadReference/SuspendCount/suspendcnt001.java | 7 +++++-- .../SuspendCount/suspendcnt001/TestDescription.java | 4 ++-- .../ThreadReference/ThreadGroup/threadgroup001.java | 7 +++++-- .../ThreadGroup/threadgroup001/TestDescription.java | 4 ++-- .../jdwp/VirtualMachine/AllClasses/allclasses001.java | 7 +++++-- .../AllClasses/allclasses001/TestDescription.java | 4 ++-- .../AllClassesWithGeneric/allclswithgeneric001.java | 9 ++++++--- .../allclswithgeneric001/TestDescription.java | 4 ++-- .../jdwp/VirtualMachine/AllThreads/allthreads001.java | 7 +++++-- .../AllThreads/allthreads001/TestDescription.java | 4 ++-- .../VirtualMachine/Capabilities/capabilities001.java | 7 +++++-- .../Capabilities/capabilities001/TestDescription.java | 4 ++-- .../CapabilitiesNew/capabilitiesnew001.java | 7 +++++-- .../capabilitiesnew001/TestDescription.java | 4 ++-- .../jdwp/VirtualMachine/ClassPaths/classpaths001.java | 7 +++++-- .../ClassPaths/classpaths001/TestDescription.java | 4 ++-- .../ClassesBySignature/classbysig001.java | 7 +++++-- .../classbysig001/TestDescription.java | 4 ++-- .../VirtualMachine/CreateString/createstr001.java | 7 +++++-- .../CreateString/createstr001/TestDescription.java | 4 ++-- .../nsk/jdwp/VirtualMachine/Dispose/dispose001.java | 7 +++++-- .../Dispose/dispose001/TestDescription.java | 4 ++-- .../VirtualMachine/DisposeObjects/disposeobj001.java | 7 +++++-- .../DisposeObjects/disposeobj001/TestDescription.java | 4 ++-- .../nsk/jdwp/VirtualMachine/Exit/exit001.java | 7 +++++-- .../VirtualMachine/Exit/exit001/TestDescription.java | 4 ++-- .../jdwp/VirtualMachine/HoldEvents/holdevents001.java | 7 +++++-- .../HoldEvents/holdevents001/TestDescription.java | 4 ++-- .../jdwp/VirtualMachine/HoldEvents/holdevents002.java | 9 ++++++--- .../nsk/jdwp/VirtualMachine/IDSizes/idsizes001.java | 7 +++++-- .../IDSizes/idsizes001/TestDescription.java | 4 ++-- .../instanceCounts001/instanceCounts001.java | 9 ++++++--- .../RedefineClasses/redefinecls001.java | 7 +++++-- .../redefinecls001/TestDescription.java | 4 ++-- .../ReleaseEvents/releaseevents001.java | 7 +++++-- .../releaseevents001/TestDescription.java | 4 ++-- .../ReleaseEvents/releaseevents002.java | 9 ++++++--- .../releaseevents002/TestDescription.java | 4 ++-- .../nsk/jdwp/VirtualMachine/Resume/resume001.java | 7 +++++-- .../Resume/resume001/TestDescription.java | 4 ++-- .../SetDefaultStratum/setdefstrat001.java | 7 +++++-- .../setdefstrat001/TestDescription.java | 4 ++-- .../TopLevelThreadGroups/threadgroups001.java | 7 +++++-- .../threadgroups001/TestDescription.java | 4 ++-- .../nsk/jdwp/VirtualMachine/Version/version001.java | 7 +++++-- .../Version/version001/TestDescription.java | 4 ++-- .../nsk/jdwp/VirtualMachine/Version/version002.java | 7 +++++-- .../Version/version002/TestDescription.java | 4 ++-- .../vmTestbase/nsk/share/jpda/DebugeeBinder.java | 8 ++++---- 219 files changed, 824 insertions(+), 482 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues001.java index 60ae805703b18..5af71d569f162 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -89,7 +89,10 @@ public class getvalues001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues001/TestDescription.java index 4fc9630df3c87..04ddee420613c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ArrayReference.GetValues.getvalues001a - * @run main/othervm + * @run driver * nsk.jdwp.ArrayReference.GetValues.getvalues001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues002.java index 47f4097dae680..d5d44faef48a3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -116,7 +116,10 @@ public class getvalues002 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues002/TestDescription.java index 92b567dccf276..5e1e30ae541ca 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues002/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues002/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ArrayReference.GetValues.getvalues002a - * @run main/othervm + * @run driver * nsk.jdwp.ArrayReference.GetValues.getvalues002 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/Length/length001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/Length/length001.java index 36324982533e8..45acc929bfa2a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/Length/length001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/Length/length001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,7 +85,10 @@ public class length001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/Length/length001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/Length/length001/TestDescription.java index 164d8c8ecab8d..2f96d7c3a0792 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/Length/length001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/Length/length001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ArrayReference.Length.length001a - * @run main/othervm + * @run driver * nsk.jdwp.ArrayReference.Length.length001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/SetValues/setvalues001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/SetValues/setvalues001.java index 117d66fe24c48..12c06d8735df6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/SetValues/setvalues001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/SetValues/setvalues001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,7 +92,10 @@ public class setvalues001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/SetValues/setvalues001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/SetValues/setvalues001/TestDescription.java index 380ba4549ef48..bf252a44d43ce 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/SetValues/setvalues001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/SetValues/setvalues001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ArrayReference.SetValues.setvalues001a - * @run main/othervm + * @run driver * nsk.jdwp.ArrayReference.SetValues.setvalues001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayType/NewInstance/newinstance001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayType/NewInstance/newinstance001.java index c56ccde4c2f60..b29a39fb4c5ef 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayType/NewInstance/newinstance001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayType/NewInstance/newinstance001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,7 +84,10 @@ public class newinstance001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayType/NewInstance/newinstance001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayType/NewInstance/newinstance001/TestDescription.java index 7376e32c3cc3b..66b15f2166586 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayType/NewInstance/newinstance001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayType/NewInstance/newinstance001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ArrayType.NewInstance.newinstance001a - * @run main/othervm + * @run driver * nsk.jdwp.ArrayType.NewInstance.newinstance001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassLoaderReference/VisibleClasses/visibclasses001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassLoaderReference/VisibleClasses/visibclasses001.java index ba21914994d1e..1c02b225e0b36 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassLoaderReference/VisibleClasses/visibclasses001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassLoaderReference/VisibleClasses/visibclasses001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,7 +81,10 @@ public class visibclasses001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassLoaderReference/VisibleClasses/visibclasses001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassLoaderReference/VisibleClasses/visibclasses001/TestDescription.java index b298e05d72175..379091615fec6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassLoaderReference/VisibleClasses/visibclasses001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassLoaderReference/VisibleClasses/visibclasses001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ClassLoaderReference.VisibleClasses.visibclasses001a - * @run main/othervm + * @run driver * nsk.jdwp.ClassLoaderReference.VisibleClasses.visibclasses001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassObjectReference/ReflectedType/reflectype001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassObjectReference/ReflectedType/reflectype001.java index b894d10c1b098..a23144b50e6d6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassObjectReference/ReflectedType/reflectype001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassObjectReference/ReflectedType/reflectype001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,10 @@ public class reflectype001 { static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";"; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassObjectReference/ReflectedType/reflectype001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassObjectReference/ReflectedType/reflectype001/TestDescription.java index f476b8df0c807..ea86ce80bcbee 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassObjectReference/ReflectedType/reflectype001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassObjectReference/ReflectedType/reflectype001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ClassObjectReference.ReflectedType.reflectype001a - * @run main/othervm + * @run driver * nsk.jdwp.ClassObjectReference.ReflectedType.reflectype001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/InvokeMethod/invokemeth001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/InvokeMethod/invokemeth001.java index d9f5e31b65318..c5ab5ed56c837 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/InvokeMethod/invokemeth001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/InvokeMethod/invokemeth001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -97,7 +97,10 @@ public class invokemeth001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/InvokeMethod/invokemeth001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/InvokeMethod/invokemeth001/TestDescription.java index 9b97c95b32f1d..c393e091c56a5 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/InvokeMethod/invokemeth001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/InvokeMethod/invokemeth001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ClassType.InvokeMethod.invokemeth001a - * @run main/othervm + * @run driver * nsk.jdwp.ClassType.InvokeMethod.invokemeth001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/NewInstance/newinst001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/NewInstance/newinst001.java index ff23a6420e643..a2323daaf749c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/NewInstance/newinst001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/NewInstance/newinst001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -96,8 +96,11 @@ public class newinst001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/NewInstance/newinst001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/NewInstance/newinst001/TestDescription.java index 6132dbc6a4d32..2d9abe94b73b8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/NewInstance/newinst001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/NewInstance/newinst001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ClassType.NewInstance.newinst001a - * @run main/othervm + * @run driver * nsk.jdwp.ClassType.NewInstance.newinst001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/SetValues/setvalues001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/SetValues/setvalues001.java index 7931560a853e7..e40906c299ae9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/SetValues/setvalues001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/SetValues/setvalues001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,7 +88,10 @@ public class setvalues001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/SetValues/setvalues001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/SetValues/setvalues001/TestDescription.java index 0f5a71aefda4b..dee1aa7f03c2e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/SetValues/setvalues001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/SetValues/setvalues001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,7 +66,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ClassType.SetValues.setvalues001a - * @run main/othervm + * @run driver * nsk.jdwp.ClassType.SetValues.setvalues001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/Superclass/superclass001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/Superclass/superclass001.java index 1e46507079e91..4aed67d1f7e31 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/Superclass/superclass001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/Superclass/superclass001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,7 +85,10 @@ public class superclass001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/Superclass/superclass001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/Superclass/superclass001/TestDescription.java index 02082032398f5..6cd1cd9404297 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/Superclass/superclass001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/Superclass/superclass001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ClassType.Superclass.superclass001a - * @run main/othervm + * @run driver * nsk.jdwp.ClassType.Superclass.superclass001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/BREAKPOINT/breakpoint001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/BREAKPOINT/breakpoint001.java index 60b926256adaf..6518ff5bb06dc 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/BREAKPOINT/breakpoint001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/BREAKPOINT/breakpoint001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,8 +90,11 @@ public class breakpoint001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/BREAKPOINT/breakpoint001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/BREAKPOINT/breakpoint001/TestDescription.java index f4583fc101552..72c5a23c94f35 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/BREAKPOINT/breakpoint001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/BREAKPOINT/breakpoint001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.BREAKPOINT.breakpoint001a - * @run main/othervm + * @run driver * nsk.jdwp.Event.BREAKPOINT.breakpoint001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_PREPARE/clsprepare001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_PREPARE/clsprepare001.java index 4bb0add7c6508..3edb73a609c9d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_PREPARE/clsprepare001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_PREPARE/clsprepare001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,8 +80,11 @@ public class clsprepare001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_PREPARE/clsprepare001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_PREPARE/clsprepare001/TestDescription.java index 8690a9d6125f4..563db72242479 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_PREPARE/clsprepare001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_PREPARE/clsprepare001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.CLASS_PREPARE.clsprepare001a - * @run main/othervm + * @run driver * nsk.jdwp.Event.CLASS_PREPARE.clsprepare001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_UNLOAD/clsunload001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_UNLOAD/clsunload001.java index ba6905a68bded..ccfec8efeb9e7 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_UNLOAD/clsunload001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_UNLOAD/clsunload001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,8 +80,11 @@ public class clsunload001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_UNLOAD/clsunload001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_UNLOAD/clsunload001/TestDescription.java index 2d323c7193143..354b71a085ed0 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_UNLOAD/clsunload001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_UNLOAD/clsunload001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,7 +62,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.CLASS_UNLOAD.clsunload001a - * @run main/othervm + * @run driver * nsk.jdwp.Event.CLASS_UNLOAD.clsunload001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/Composite/composite001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/Composite/composite001.java index 0d6c11c40c81f..789402dd37a08 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/Composite/composite001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/Composite/composite001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,8 +75,11 @@ public class composite001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/Composite/composite001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/Composite/composite001/TestDescription.java index 5cf8976cb8806..ad91d73534c0b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/Composite/composite001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/Composite/composite001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.Composite.composite001a - * @run main/othervm + * @run driver * nsk.jdwp.Event.Composite.composite001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/EXCEPTION/exception001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/EXCEPTION/exception001.java index 4a482ab2164a3..aca9989608e6e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/EXCEPTION/exception001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/EXCEPTION/exception001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -97,8 +97,11 @@ public class exception001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/EXCEPTION/exception001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/EXCEPTION/exception001/TestDescription.java index 9524d171c4bc2..7307c026cf51e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/EXCEPTION/exception001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/EXCEPTION/exception001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,7 +64,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.EXCEPTION.exception001a - * @run main/othervm + * @run driver * nsk.jdwp.Event.EXCEPTION.exception001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_ACCESS/fldaccess001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_ACCESS/fldaccess001.java index c81d901115cd2..1c6b5f4a931a1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_ACCESS/fldaccess001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_ACCESS/fldaccess001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,8 +99,11 @@ public class fldaccess001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_ACCESS/fldaccess001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_ACCESS/fldaccess001/TestDescription.java index d0c835009d60c..ff74b0849ee20 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_ACCESS/fldaccess001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_ACCESS/fldaccess001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.FIELD_ACCESS.fldaccess001a - * @run main/othervm + * @run driver * nsk.jdwp.Event.FIELD_ACCESS.fldaccess001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_MODIFICATION/fldmodification001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_MODIFICATION/fldmodification001.java index 7bcf14c87c3a2..840b48428e51a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_MODIFICATION/fldmodification001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_MODIFICATION/fldmodification001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,8 +100,11 @@ public class fldmodification001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_MODIFICATION/fldmodification001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_MODIFICATION/fldmodification001/TestDescription.java index 5055936173d11..3901a6eaf8c77 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_MODIFICATION/fldmodification001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_MODIFICATION/fldmodification001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,7 +64,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.FIELD_MODIFICATION.fldmodification001a - * @run main/othervm + * @run driver * nsk.jdwp.Event.FIELD_MODIFICATION.fldmodification001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_ENTRY/methentry001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_ENTRY/methentry001.java index 6d75896e2dfcd..b8834e94bcfde 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_ENTRY/methentry001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_ENTRY/methentry001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,8 +92,11 @@ public class methentry001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_ENTRY/methentry001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_ENTRY/methentry001/TestDescription.java index e41084de6281f..106002fdf9d67 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_ENTRY/methentry001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_ENTRY/methentry001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.METHOD_ENTRY.methentry001a - * @run main/othervm + * @run driver * nsk.jdwp.Event.METHOD_ENTRY.methentry001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_EXIT/methexit001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_EXIT/methexit001.java index a113161ca3241..6da08d6b85815 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_EXIT/methexit001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_EXIT/methexit001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,8 +92,11 @@ public class methexit001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_EXIT/methexit001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_EXIT/methexit001/TestDescription.java index bd765e2ea8846..e6a74885a13b9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_EXIT/methexit001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_EXIT/methexit001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.METHOD_EXIT.methexit001a - * @run main/othervm + * @run driver * nsk.jdwp.Event.METHOD_EXIT.methexit001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep001.java index 25003f018a0ab..fef8a0959082e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,8 +93,11 @@ public class singlestep001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep001/TestDescription.java index 7d7afefd44603..661189bcf310f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.SINGLE_STEP.singlestep001a - * @run main/othervm + * @run driver * nsk.jdwp.Event.SINGLE_STEP.singlestep001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep002.java index 50e55925d0d4f..66c9e65df56e0 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,8 +95,11 @@ public class singlestep002 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep002/TestDescription.java index ac11ead1f0925..4fe15d10884e0 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep002/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep002/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.SINGLE_STEP.singlestep002a - * @run main/othervm + * @run driver * nsk.jdwp.Event.SINGLE_STEP.singlestep002 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep003.java index ae98242c0eeb9..47ef6474536ba 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,8 +95,11 @@ public class singlestep003 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep003/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep003/TestDescription.java index 00cf70a223d8f..d3c38bcbeb8b3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep003/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep003/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.SINGLE_STEP.singlestep003a - * @run main/othervm + * @run driver * nsk.jdwp.Event.SINGLE_STEP.singlestep003 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_DEATH/thrdeath001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_DEATH/thrdeath001.java index f5aae7067db5a..753e5b4948051 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_DEATH/thrdeath001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_DEATH/thrdeath001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,8 +88,11 @@ public class thrdeath001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_DEATH/thrdeath001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_DEATH/thrdeath001/TestDescription.java index 85dd77be7e9ca..8cd28cb2381db 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_DEATH/thrdeath001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_DEATH/thrdeath001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.THREAD_DEATH.thrdeath001a - * @run main/othervm + * @run driver * nsk.jdwp.Event.THREAD_DEATH.thrdeath001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_START/thrstart001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_START/thrstart001.java index f525d7d550faf..7936fcbf5cb45 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_START/thrstart001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_START/thrstart001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,8 +88,11 @@ public class thrstart001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_START/thrstart001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_START/thrstart001/TestDescription.java index a43503248490b..7345debf5252c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_START/thrstart001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_START/thrstart001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.THREAD_START.thrstart001a - * @run main/othervm + * @run driver * nsk.jdwp.Event.THREAD_START.thrstart001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath001.java index 771e121d8cecb..8a8526bbeb2e6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,8 +74,11 @@ public class vmdeath001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath001/TestDescription.java index e1f3b1053b489..f40ecc66655de 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.VM_DEATH.vmdeath001a - * @run main/othervm + * @run driver * nsk.jdwp.Event.VM_DEATH.vmdeath001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath002.java index 20f96d064d1e0..6bfb79d2575a3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,8 +81,11 @@ public class vmdeath002 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath002/TestDescription.java index f0dbd749a3271..cee21042bf57d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath002/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath002/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.VM_DEATH.vmdeath002a - * @run main/othervm + * @run driver * nsk.jdwp.Event.VM_DEATH.vmdeath002 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_START/vmstart001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_START/vmstart001.java index 58d77cd8901a5..eac5ee3efb660 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_START/vmstart001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_START/vmstart001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,8 +74,11 @@ public class vmstart001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_START/vmstart001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_START/vmstart001/TestDescription.java index 139db45bef5b5..b0d6abd6928f2 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_START/vmstart001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_START/vmstart001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Event.VM_START.vmstart001a - * @run main/othervm + * @run driver * nsk.jdwp.Event.VM_START.vmstart001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Clear/clear001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Clear/clear001.java index 4973cac34a7ae..dccddcf806650 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Clear/clear001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Clear/clear001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,8 +88,11 @@ public class clear001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Clear/clear001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Clear/clear001/TestDescription.java index acc4090eb10e6..cc544397bf2c3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Clear/clear001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Clear/clear001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.EventRequest.Clear.clear001a - * @run main/othervm + * @run driver * nsk.jdwp.EventRequest.Clear.clear001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp001.java index b4cbd4f207228..166334be16a5a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,8 +88,11 @@ public class clrallbreakp001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp001/TestDescription.java index 49c6d12afa525..bd251fe9c91aa 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp001a - * @run main/othervm + * @run driver * nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp002.java index c106daa64ff2f..1a881b075f12d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,8 +82,11 @@ public class clrallbreakp002 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp002/TestDescription.java index 981b8fccb5efc..53fa51809db39 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp002/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp002/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp002a - * @run main/othervm + * @run driver * nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp002 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp003.java index 34a69758774ba..ce7c1f6609f95 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,8 +88,11 @@ public class clrallbreakp003 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp003/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp003/TestDescription.java index 15acb91350c34..61c2355c1cb77 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp003/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp003/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp003a - * @run main/othervm + * @run driver * nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp003 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set001.java index 522c6096cdfb2..55b5d12ee13a1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,8 +90,11 @@ public class set001 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set001/TestDescription.java index d04dc2f9328d8..d982e35850d68 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.EventRequest.Set.set001a - * @run main/othervm + * @run driver * nsk.jdwp.EventRequest.Set.set001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set002.java index ae25ddc2fe265..86256e706fc8b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,8 +77,11 @@ public class set002 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set002/TestDescription.java index efd3b66692425..38df090783b55 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set002/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set002/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.EventRequest.Set.set002a - * @run main/othervm + * @run driver * nsk.jdwp.EventRequest.Set.set002 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/Bytecodes/bytecodes001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/Bytecodes/bytecodes001.java index 29a06be58fc46..7a5972860344d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/Bytecodes/bytecodes001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/Bytecodes/bytecodes001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,7 +93,10 @@ public class bytecodes001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/Bytecodes/bytecodes001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/Bytecodes/bytecodes001/TestDescription.java index b522bbedaa4bb..46efecf437e0e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/Bytecodes/bytecodes001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/Bytecodes/bytecodes001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Method.Bytecodes.bytecodes001a - * @run main/othervm + * @run driver * nsk.jdwp.Method.Bytecodes.bytecodes001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete001.java index c9e558363a282..b01e814af1e0a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -89,7 +89,10 @@ public class isobsolete001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete001/TestDescription.java index c3b3b3c049d11..270f5744bac06 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Method.IsObsolete.isobsolete001a - * @run main/othervm + * @run driver * nsk.jdwp.Method.IsObsolete.isobsolete001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002.java index c3266489f9289..c06e62be3164b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -96,7 +96,10 @@ public class isobsolete002 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002/TestDescription.java index ce9fc223daefe..e5b41793291c1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,7 +72,7 @@ * nsk.jdwp.Method.IsObsolete.isobsolete002b * @run driver nsk.share.ExtraClassesBuilder * newclass - * @run main/othervm + * @run driver * nsk.jdwp.Method.IsObsolete.isobsolete002 * . * -arch=${os.family}-${os.simpleArch} diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/LineTable/linetable001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/LineTable/linetable001.java index ebb3063893851..cf1bd6eb79a61 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/LineTable/linetable001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/LineTable/linetable001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -89,7 +89,10 @@ public class linetable001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/LineTable/linetable001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/LineTable/linetable001/TestDescription.java index d5dad5cc97926..7a53a1b3816eb 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/LineTable/linetable001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/LineTable/linetable001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,7 +68,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.Method.LineTable.linetable001a - * @run main/othervm + * @run driver * nsk.jdwp.Method.LineTable.linetable001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTable/vartable001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTable/vartable001.java index 9953dc9c94f55..d6a2dcee264b8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTable/vartable001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTable/vartable001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,7 +119,10 @@ public class vartable001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTable/vartable001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTable/vartable001/TestDescription.java index f5633b360f332..f08b09e5079f9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTable/vartable001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTable/vartable001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ * @comment debuggee should be compiled w/ debug info * @clean nsk.jdwp.Method.VariableTable.vartable001a * @compile -g:lines,source,vars ../vartable001a.java - * @run main/othervm + * @run driver * nsk.jdwp.Method.VariableTable.vartable001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTableWithGeneric/vartblwithgen001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTableWithGeneric/vartblwithgen001.java index a2e18c4f75997..39890990b8dcf 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTableWithGeneric/vartblwithgen001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTableWithGeneric/vartblwithgen001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -136,7 +136,10 @@ public class vartblwithgen001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTableWithGeneric/vartblwithgen001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTableWithGeneric/vartblwithgen001/TestDescription.java index 7741b0226187b..0227cae87ea74 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTableWithGeneric/vartblwithgen001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTableWithGeneric/vartblwithgen001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ * @comment debuggee should be compiled w/ debug info * @clean nsk.jdwp.Method.VariableTableWithGeneric.vartblwithgen001a * @compile -g:lines,source,vars ../vartblwithgen001a.java - * @run main/othervm + * @run driver * nsk.jdwp.Method.VariableTableWithGeneric.vartblwithgen001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/DisableCollection/disablecol001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/DisableCollection/disablecol001.java index 419d944398af5..6f11394db53ea 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/DisableCollection/disablecol001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/DisableCollection/disablecol001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,7 +86,10 @@ public class disablecol001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/DisableCollection/disablecol001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/DisableCollection/disablecol001/TestDescription.java index 9e50200593e7e..fdcc258523e67 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/DisableCollection/disablecol001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/DisableCollection/disablecol001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ObjectReference.DisableCollection.disablecol001a - * @run main/othervm + * @run driver * nsk.jdwp.ObjectReference.DisableCollection.disablecol001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/EnableCollection/enablecol001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/EnableCollection/enablecol001.java index 2ab8c28e1c4c1..9172b4413d700 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/EnableCollection/enablecol001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/EnableCollection/enablecol001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,7 +86,10 @@ public class enablecol001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/EnableCollection/enablecol001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/EnableCollection/enablecol001/TestDescription.java index d2dd41472e9f7..71a849b0c2a5e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/EnableCollection/enablecol001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/EnableCollection/enablecol001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ObjectReference.EnableCollection.enablecol001a - * @run main/othervm + * @run driver * nsk.jdwp.ObjectReference.EnableCollection.enablecol001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/GetValues/getvalues001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/GetValues/getvalues001.java index 08668e91afabd..9702cb7f9e621 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/GetValues/getvalues001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/GetValues/getvalues001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,7 +99,10 @@ public class getvalues001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/GetValues/getvalues001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/GetValues/getvalues001/TestDescription.java index 7ecb552e6c9d8..8bfbca6d44890 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/GetValues/getvalues001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/GetValues/getvalues001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ObjectReference.GetValues.getvalues001a - * @run main/othervm + * @run driver * nsk.jdwp.ObjectReference.GetValues.getvalues001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/InvokeMethod/invokemeth001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/InvokeMethod/invokemeth001.java index 761a5bf19a48a..ffc2cc151a99e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/InvokeMethod/invokemeth001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/InvokeMethod/invokemeth001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,7 +99,10 @@ public class invokemeth001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/InvokeMethod/invokemeth001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/InvokeMethod/invokemeth001/TestDescription.java index 71bfafa7718f6..3ad6bbf79db18 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/InvokeMethod/invokemeth001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/InvokeMethod/invokemeth001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ObjectReference.InvokeMethod.invokemeth001a - * @run main/othervm + * @run driver * nsk.jdwp.ObjectReference.InvokeMethod.invokemeth001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/IsCollected/iscollected001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/IsCollected/iscollected001.java index 284765bd25af4..a8d61451f9a97 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/IsCollected/iscollected001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/IsCollected/iscollected001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,7 +86,10 @@ public class iscollected001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/IsCollected/iscollected001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/IsCollected/iscollected001/TestDescription.java index fda668d8b3201..f6facbb76092a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/IsCollected/iscollected001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/IsCollected/iscollected001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ObjectReference.IsCollected.iscollected001a - * @run main/othervm + * @run driver * nsk.jdwp.ObjectReference.IsCollected.iscollected001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/MonitorInfo/monitorinfo001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/MonitorInfo/monitorinfo001.java index 8834b30e21b50..e50dc29b151b4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/MonitorInfo/monitorinfo001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/MonitorInfo/monitorinfo001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -101,7 +101,10 @@ public class monitorinfo001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/MonitorInfo/monitorinfo001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/MonitorInfo/monitorinfo001/TestDescription.java index cf58779b87dd3..40be209f16f5b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/MonitorInfo/monitorinfo001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/MonitorInfo/monitorinfo001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,7 +69,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ObjectReference.MonitorInfo.monitorinfo001a - * @run main/othervm + * @run driver * nsk.jdwp.ObjectReference.MonitorInfo.monitorinfo001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferenceType/referencetype001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferenceType/referencetype001.java index cc5530cf82a65..4066c90576893 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferenceType/referencetype001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferenceType/referencetype001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,7 +86,10 @@ public class referencetype001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferenceType/referencetype001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferenceType/referencetype001/TestDescription.java index 0e7e8b9bb6b2e..e5b1413f1479a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferenceType/referencetype001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferenceType/referencetype001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ObjectReference.ReferenceType.referencetype001a - * @run main/othervm + * @run driver * nsk.jdwp.ObjectReference.ReferenceType.referencetype001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferringObjects/referringObjects001/referringObjects001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferringObjects/referringObjects001/referringObjects001.java index c9ee73fa67c96..f578d3be7d436 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferringObjects/referringObjects001/referringObjects001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferringObjects/referringObjects001/referringObjects001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,8 +95,11 @@ protected String getDebugeeClassName() { return nsk.jdwp.ObjectReference.ReferringObjects.referringObjects001.referringObjects001a.class.getName(); } - public static void main(String[] argv) { - System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String[] argv, PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferringObjects/referringObjects002/referringObjects002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferringObjects/referringObjects002/referringObjects002.java index 4ad6b6ae32881..4591bf093eaab 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferringObjects/referringObjects002/referringObjects002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferringObjects/referringObjects002/referringObjects002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,8 +83,11 @@ protected String getDebugeeClassName() { return nsk.jdwp.ObjectReference.ReferringObjects.referringObjects002.referringObjects002a.class.getName(); } - public static void main(String[] argv) { - System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String[] argv, PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/SetValues/setvalues001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/SetValues/setvalues001.java index 3d20db7fa7ebe..d9a7622ea042d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/SetValues/setvalues001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/SetValues/setvalues001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,7 +95,10 @@ public class setvalues001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/SetValues/setvalues001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/SetValues/setvalues001/TestDescription.java index 9fc3f9949cfe2..461daf145c0cf 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/SetValues/setvalues001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/SetValues/setvalues001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,7 +68,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ObjectReference.SetValues.setvalues001a - * @run main/othervm + * @run driver * nsk.jdwp.ObjectReference.SetValues.setvalues001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassLoader/classloader001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassLoader/classloader001.java index 23b1c3de7eec1..0d7961924f9cf 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassLoader/classloader001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassLoader/classloader001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,10 @@ public class classloader001 { static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";"; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassLoader/classloader001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassLoader/classloader001/TestDescription.java index be36b5eccee5b..6b818c0a408e5 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassLoader/classloader001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassLoader/classloader001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.ClassLoader.classloader001a - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.ClassLoader.classloader001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassObject/classobj001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassObject/classobj001.java index b86d17d752fa6..5d74b011111da 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassObject/classobj001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassObject/classobj001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,10 @@ public class classobj001 { static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";"; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassObject/classobj001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassObject/classobj001/TestDescription.java index 12baa51bca2cc..ffa15c1a66d81 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassObject/classobj001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassObject/classobj001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.ClassObject.classobj001a - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.ClassObject.classobj001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Fields/fields001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Fields/fields001.java index b6f559a5ae031..a4cfd9d9eba35 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Fields/fields001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Fields/fields001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,10 @@ public class fields001 { static final int FIELD_MODIFIER_FLAGS = JDWP.ModifierFlag.PUBLIC; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Fields/fields001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Fields/fields001/TestDescription.java index a337e6b7fb5a6..7d6b41cc75014 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Fields/fields001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Fields/fields001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.Fields.fields001a - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.Fields.fields001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001.java index 24ac7321b9fdf..5feafc3c2b3c2 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -101,8 +101,11 @@ public class fldwithgeneric001 { static final int FLDS_NUM = fields.length; - public static void main(String argv[]) { - System.exit(run(argv,System.out) + Consts.JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001/TestDescription.java index c410dabad0893..7e9679e10eb4e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.FieldsWithGeneric.fldwithgeneric001t - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.FieldsWithGeneric.fldwithgeneric001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/GetValues/getvalues001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/GetValues/getvalues001.java index cafe1ba1d1aef..72c0c679bb80c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/GetValues/getvalues001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/GetValues/getvalues001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,7 +99,10 @@ public class getvalues001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/GetValues/getvalues001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/GetValues/getvalues001/TestDescription.java index 6a0ceb754d8c6..e4c850e28a4ef 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/GetValues/getvalues001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/GetValues/getvalues001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.GetValues.getvalues001a - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.GetValues.getvalues001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Instances/instances001/instances001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Instances/instances001/instances001.java index 2312f571822d4..5a83ed4435b93 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Instances/instances001/instances001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Instances/instances001/instances001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -89,8 +89,11 @@ protected String getDebugeeClassName() { return nsk.jdwp.ReferenceType.Instances.instances001.instances001a.class.getName(); } - public static void main(String[] argv) { - System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String[] argv, PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Instances/instances002/instances002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Instances/instances002/instances002.java index cd90392f3d939..378104a1b746d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Instances/instances002/instances002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Instances/instances002/instances002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ * * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.Instances.instances002.instances002 * -arch=${os.family}-${os.simpleArch} * -verbose @@ -82,8 +82,11 @@ protected String getDebugeeClassName() { return nsk.jdwp.ReferenceType.Instances.instances002.instances002a.class.getName(); } - public static void main(String[] argv) { - System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String[] argv, PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Interfaces/interfaces001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Interfaces/interfaces001.java index e7e06473d7b12..d30d63b272bf3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Interfaces/interfaces001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Interfaces/interfaces001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,10 @@ public class interfaces001 { static final long interfaceIDs[] = new long[DECLARED_INTERFACES]; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Interfaces/interfaces001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Interfaces/interfaces001/TestDescription.java index b67ad06b1c333..bfa503d42b3e3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Interfaces/interfaces001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Interfaces/interfaces001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.Interfaces.interfaces001a - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.Interfaces.interfaces001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Methods/methods001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Methods/methods001.java index 22e656e1f4148..247ed13f6686d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Methods/methods001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Methods/methods001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,10 @@ public class methods001 { static final int METHOD_MODIFIER_FLAGS = JDWP.ModifierFlag.PUBLIC; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Methods/methods001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Methods/methods001/TestDescription.java index f24bcd39b8453..28a7ad43a60e5 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Methods/methods001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Methods/methods001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.Methods.methods001a - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.Methods.methods001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001.java index e2e633222b3fc..d153603562529 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -110,8 +110,11 @@ public class methwithgeneric001 { static final int CLS_NUM = classes.length; - public static void main(String argv[]) { - System.exit(run(argv,System.out) + Consts.JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001/TestDescription.java index 648349f887e56..475b7eedb0595 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.MethodsWithGeneric.methwithgeneric001t - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.MethodsWithGeneric.methwithgeneric001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Modifiers/modifiers001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Modifiers/modifiers001.java index 92e4f6f6b7cb0..7695861df3a2f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Modifiers/modifiers001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Modifiers/modifiers001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,10 @@ public class modifiers001 { | JDWP.ModifierFlag.FINAL; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Modifiers/modifiers001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Modifiers/modifiers001/TestDescription.java index fa26934f1497a..907993049a4c3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Modifiers/modifiers001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Modifiers/modifiers001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.Modifiers.modifiers001a - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.Modifiers.modifiers001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/NestedTypes/nestedtypes001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/NestedTypes/nestedtypes001.java index 33e4727bfe8a1..6b4e82dd6b607 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/NestedTypes/nestedtypes001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/NestedTypes/nestedtypes001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,7 +92,10 @@ public class nestedtypes001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/NestedTypes/nestedtypes001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/NestedTypes/nestedtypes001/TestDescription.java index 4436bcccbb607..5da686e4a434b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/NestedTypes/nestedtypes001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/NestedTypes/nestedtypes001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.NestedTypes.nestedtypes001a - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.NestedTypes.nestedtypes001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Signature/signature001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Signature/signature001.java index 641079ba7fa3f..ddba04e292ab6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Signature/signature001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Signature/signature001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,10 @@ public class signature001 { static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";"; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Signature/signature001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Signature/signature001/TestDescription.java index 27628d13e610a..49ac330b51879 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Signature/signature001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Signature/signature001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.Signature.signature001a - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.Signature.signature001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001.java index c6bbcd437f8a6..8f819a050b9d1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,8 +81,11 @@ public class sigwithgeneric001 { static final int CLS_NUM = classes.length; - public static void main(String argv[]) { - System.exit(run(argv,System.out) + Consts.JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001/TestDescription.java index 9dc7275de7d13..9928a55505ea8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.SignatureWithGeneric.sigwithgeneric001t - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.SignatureWithGeneric.sigwithgeneric001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceDebugExtension/srcdebugext001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceDebugExtension/srcdebugext001.java index af9d7a26021ad..0735246d2395b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceDebugExtension/srcdebugext001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceDebugExtension/srcdebugext001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,10 @@ public class srcdebugext001 { private Transport transport; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceDebugExtension/srcdebugext001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceDebugExtension/srcdebugext001/TestDescription.java index c614604e55d71..f3fbe8830c430 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceDebugExtension/srcdebugext001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceDebugExtension/srcdebugext001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.SourceDebugExtension.srcdebugext001t - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.SourceDebugExtension.srcdebugext001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceFile/srcfile001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceFile/srcfile001.java index fb9d8948ef5dc..6ca69c009b22f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceFile/srcfile001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceFile/srcfile001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,10 @@ public class srcfile001 { static final String TESTED_CLASS_SRCFILENAME = "srcfile001a.java"; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceFile/srcfile001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceFile/srcfile001/TestDescription.java index 09608b3757d74..ff56e5c99ccd1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceFile/srcfile001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceFile/srcfile001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.SourceFile.srcfile001a - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.SourceFile.srcfile001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Status/status001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Status/status001.java index f0e357b48403b..2aa64d3ed4b4a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Status/status001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Status/status001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,10 @@ public class status001 { | JDWP.ClassStatus.INITIALIZED; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Status/status001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Status/status001/TestDescription.java index aefbb989bf98e..5efd81a389627 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Status/status001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Status/status001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ReferenceType.Status.status001a - * @run main/othervm + * @run driver * nsk.jdwp.ReferenceType.Status.status001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/GetValues/getvalues001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/GetValues/getvalues001.java index 656ba90a25039..b9f7a1f0ef32e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/GetValues/getvalues001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/GetValues/getvalues001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,7 +102,10 @@ public class getvalues001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/GetValues/getvalues001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/GetValues/getvalues001/TestDescription.java index 09ee0ba021a9b..5d862a12ec3cd 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/GetValues/getvalues001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/GetValues/getvalues001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,7 +64,7 @@ * @comment debuggee should be compiled w/ debug info * @clean nsk.jdwp.StackFrame.GetValues.getvalues001a * @compile -g:lines,source,vars ../getvalues001a.java - * @run main/othervm + * @run driver * nsk.jdwp.StackFrame.GetValues.getvalues001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/PopFrames/popframes001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/PopFrames/popframes001.java index a896d567eb524..b4ad931f04438 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/PopFrames/popframes001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/PopFrames/popframes001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,7 +93,10 @@ public class popframes001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/PopFrames/popframes001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/PopFrames/popframes001/TestDescription.java index 2fd126b9fbb2a..902cdda31dcec 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/PopFrames/popframes001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/PopFrames/popframes001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.StackFrame.PopFrames.popframes001a - * @run main/othervm + * @run driver * nsk.jdwp.StackFrame.PopFrames.popframes001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/SetValues/setvalues001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/SetValues/setvalues001.java index 58b9c26fae368..7e7d44ff9682d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/SetValues/setvalues001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/SetValues/setvalues001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -109,7 +109,10 @@ public class setvalues001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/SetValues/setvalues001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/SetValues/setvalues001/TestDescription.java index 96302cd95925f..fec909b409230 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/SetValues/setvalues001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/SetValues/setvalues001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,7 +75,7 @@ * @comment debuggee should be compiled w/ debug info * @clean nsk.jdwp.StackFrame.SetValues.setvalues001a * @compile -g:lines,source,vars ../setvalues001a.java - * @run main/othervm + * @run driver * nsk.jdwp.StackFrame.SetValues.setvalues001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/ThisObject/thisobject001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/ThisObject/thisobject001.java index 90ab9f6e06bf6..d8302f07c7d80 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/ThisObject/thisobject001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/ThisObject/thisobject001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,7 +87,10 @@ public class thisobject001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/ThisObject/thisobject001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/ThisObject/thisobject001/TestDescription.java index 9216e598b04c6..7d00be7f30711 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/ThisObject/thisobject001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/ThisObject/thisobject001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.StackFrame.ThisObject.thisobject001a - * @run main/othervm + * @run driver * nsk.jdwp.StackFrame.ThisObject.thisobject001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StringReference/Value/value001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StringReference/Value/value001.java index 6a218281473a1..b07413fae93bc 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StringReference/Value/value001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StringReference/Value/value001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class value001 { static final int JDWP_COMMAND_ID = JDWP.Command.StringReference.Value; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StringReference/Value/value001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StringReference/Value/value001/TestDescription.java index ff107802db07b..7380eed448ded 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StringReference/Value/value001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StringReference/Value/value001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.StringReference.Value.value001a - * @run main/othervm + * @run driver * nsk.jdwp.StringReference.Value.value001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Children/children001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Children/children001.java index 5bcf5132863c7..24e5d1a48d6a3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Children/children001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Children/children001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class children001 { static final int JDWP_COMMAND_ID = JDWP.Command.ThreadGroupReference.Children; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Children/children001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Children/children001/TestDescription.java index 679af7f78c7a5..b77233495fd17 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Children/children001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Children/children001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadGroupReference.Children.children001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadGroupReference.Children.children001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Name/name001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Name/name001.java index abb7ed4a59e94..c33780bfba0eb 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Name/name001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Name/name001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class name001 { static final int JDWP_COMMAND_ID = JDWP.Command.ThreadGroupReference.Name; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Name/name001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Name/name001/TestDescription.java index 14218e86942b3..00304ac2b1df7 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Name/name001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Name/name001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadGroupReference.Name.name001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadGroupReference.Name.name001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Parent/parent001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Parent/parent001.java index bdcdbc1dd2dbe..8ebb47b1aea95 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Parent/parent001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Parent/parent001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class parent001 { static final int JDWP_COMMAND_ID = JDWP.Command.ThreadGroupReference.Parent; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Parent/parent001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Parent/parent001/TestDescription.java index 4a2ff8684acbf..48aeb6e47d28a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Parent/parent001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Parent/parent001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadGroupReference.Parent.parent001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadGroupReference.Parent.parent001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/CurrentContendedMonitor/curcontmonitor001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/CurrentContendedMonitor/curcontmonitor001.java index 3b8219e63b76c..9d74ebcc0819e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/CurrentContendedMonitor/curcontmonitor001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/CurrentContendedMonitor/curcontmonitor001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,7 +92,10 @@ public class curcontmonitor001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/CurrentContendedMonitor/curcontmonitor001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/CurrentContendedMonitor/curcontmonitor001/TestDescription.java index c1310a9c3fbf8..fb64f7b22e616 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/CurrentContendedMonitor/curcontmonitor001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/CurrentContendedMonitor/curcontmonitor001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,7 +62,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadReference.CurrentContendedMonitor.curcontmonitor001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadReference.CurrentContendedMonitor.curcontmonitor001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001/forceEarlyReturn001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001/forceEarlyReturn001.java index 8453e54e2c105..e7dce1525a045 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001/forceEarlyReturn001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001/forceEarlyReturn001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,7 +74,7 @@ * * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib - * @run main/othervm + * @run driver * nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn001.forceEarlyReturn001 * -arch=${os.family}-${os.simpleArch} * -verbose @@ -123,8 +123,11 @@ protected String getDebugeeClassName() { return "nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn001.forceEarlyReturn001a"; } - public static void main(String[] argv) { - System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String[] argv, PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002.java index e66da8076692a..2cb8de8cfa7e6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,8 +95,11 @@ protected String getDebugeeClassName() { return "nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn002.forceEarlyReturn002a"; } - public static void main(String[] argv) { - System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String[] argv, PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/FrameCount/framecnt001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/FrameCount/framecnt001.java index 0a6770fe338ef..5bab037024d76 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/FrameCount/framecnt001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/FrameCount/framecnt001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,7 +90,10 @@ public class framecnt001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/FrameCount/framecnt001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/FrameCount/framecnt001/TestDescription.java index 16adec92f82e4..77063a5ce2f2a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/FrameCount/framecnt001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/FrameCount/framecnt001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadReference.FrameCount.framecnt001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadReference.FrameCount.framecnt001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Frames/frames001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Frames/frames001.java index 42ab3aa776e3d..0a5028c4a65da 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Frames/frames001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Frames/frames001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,7 +95,10 @@ public class frames001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Frames/frames001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Frames/frames001/TestDescription.java index d742fb39d0ebb..b8dad9a09d7ed 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Frames/frames001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Frames/frames001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,7 +62,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadReference.Frames.frames001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadReference.Frames.frames001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Interrupt/interrupt001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Interrupt/interrupt001.java index 722543cf8e100..f0c2914dffcac 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Interrupt/interrupt001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Interrupt/interrupt001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,7 +90,10 @@ public class interrupt001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Interrupt/interrupt001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Interrupt/interrupt001/TestDescription.java index 236ff3140d583..b6284ec0a505c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Interrupt/interrupt001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Interrupt/interrupt001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,7 +66,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadReference.Interrupt.interrupt001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadReference.Interrupt.interrupt001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Name/name001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Name/name001.java index 5793eb8dc67fa..4633c6f118539 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Name/name001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Name/name001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,7 +87,10 @@ public class name001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Name/name001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Name/name001/TestDescription.java index afc50298c1c8d..ab49aa26e14e1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Name/name001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Name/name001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadReference.Name.name001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadReference.Name.name001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitors/ownmonitors001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitors/ownmonitors001.java index 75f1dc408e6b5..c9ba5bcc9554d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitors/ownmonitors001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitors/ownmonitors001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -98,7 +98,10 @@ public class ownmonitors001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitors/ownmonitors001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitors/ownmonitors001/TestDescription.java index 84c7f627e6d9f..a929ce527f586 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitors/ownmonitors001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitors/ownmonitors001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,7 +62,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadReference.OwnedMonitors.ownmonitors001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadReference.OwnedMonitors.ownmonitors001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo001/ownedMonitorsStackDepthInfo001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo001/ownedMonitorsStackDepthInfo001.java index f178c88ae1474..3b250989a43eb 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo001/ownedMonitorsStackDepthInfo001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo001/ownedMonitorsStackDepthInfo001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,8 +87,11 @@ protected String getDebugeeClassName() { return nsk.jdwp.ThreadReference.OwnedMonitorsStackDepthInfo.ownedMonitorsStackDepthInfo001.ownedMonitorsStackDepthInfo001a.class.getName(); } - public static void main(String[] argv) { - System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String[] argv, PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo002/ownedMonitorsStackDepthInfo002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo002/ownedMonitorsStackDepthInfo002.java index cbc5fb63a235b..140b249de9cb1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo002/ownedMonitorsStackDepthInfo002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo002/ownedMonitorsStackDepthInfo002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ * * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib - * @run main/othervm + * @run driver * nsk.jdwp.ThreadReference.OwnedMonitorsStackDepthInfo.ownedMonitorsStackDepthInfo002.ownedMonitorsStackDepthInfo002 * -arch=${os.family}-${os.simpleArch} * -verbose @@ -77,8 +77,11 @@ protected String getDebugeeClassName() { return AbstractJDWPDebuggee.class.getName(); } - public static void main(String[] argv) { - System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String[] argv, PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Resume/resume001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Resume/resume001.java index 946974522006c..97e270b32ecc0 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Resume/resume001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Resume/resume001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,7 +87,10 @@ public class resume001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Resume/resume001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Resume/resume001/TestDescription.java index e5eb1c510f1a1..12af9f769393c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Resume/resume001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Resume/resume001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadReference.Resume.resume001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadReference.Resume.resume001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Status/status001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Status/status001.java index b7c708570f56f..f41e3e919a52d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Status/status001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Status/status001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,7 +87,10 @@ public class status001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Status/status001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Status/status001/TestDescription.java index 14ff024714377..5ae025526ac87 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Status/status001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Status/status001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadReference.Status.status001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadReference.Status.status001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Stop/stop001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Stop/stop001.java index f89d64ae747aa..416b3254e0ecc 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Stop/stop001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Stop/stop001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -91,7 +91,10 @@ public class stop001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Stop/stop001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Stop/stop001/TestDescription.java index 9229392142b77..a9bcab6ef3e2d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Stop/stop001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Stop/stop001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadReference.Stop.stop001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadReference.Stop.stop001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Suspend/suspend001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Suspend/suspend001.java index 9f6ed3db961b4..0418fe080d6aa 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Suspend/suspend001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Suspend/suspend001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,7 +87,10 @@ public class suspend001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Suspend/suspend001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Suspend/suspend001/TestDescription.java index d1477e4774933..1c4bcf62e5223 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Suspend/suspend001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Suspend/suspend001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadReference.Suspend.suspend001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadReference.Suspend.suspend001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/SuspendCount/suspendcnt001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/SuspendCount/suspendcnt001.java index cbfe330774e61..cbdff74e9ccc8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/SuspendCount/suspendcnt001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/SuspendCount/suspendcnt001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,7 +90,10 @@ public class suspendcnt001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/SuspendCount/suspendcnt001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/SuspendCount/suspendcnt001/TestDescription.java index 39e5469173a30..188b5c01ec178 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/SuspendCount/suspendcnt001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/SuspendCount/suspendcnt001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadReference.SuspendCount.suspendcnt001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadReference.SuspendCount.suspendcnt001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ThreadGroup/threadgroup001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ThreadGroup/threadgroup001.java index c58491cb3d4d0..eb66314ebdaa1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ThreadGroup/threadgroup001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ThreadGroup/threadgroup001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class threadgroup001 { static final int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.ThreadGroup; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ThreadGroup/threadgroup001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ThreadGroup/threadgroup001/TestDescription.java index f9b503a82fe1d..0aa449e923904 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ThreadGroup/threadgroup001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ThreadGroup/threadgroup001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.ThreadReference.ThreadGroup.threadgroup001a - * @run main/othervm + * @run driver * nsk.jdwp.ThreadReference.ThreadGroup.threadgroup001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClasses/allclasses001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClasses/allclasses001.java index 687a56e69fbb0..292b2d8eb53e8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClasses/allclasses001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClasses/allclasses001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,10 @@ public class allclasses001 { static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClasses/allclasses001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClasses/allclasses001/TestDescription.java index 4f11e1d91bde0..85a45c798e631 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClasses/allclasses001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClasses/allclasses001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.AllClasses.allclasses001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.AllClasses.allclasses001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001.java index c5806ce7b5402..aee8b353368f7 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,8 +87,11 @@ public class allclswithgeneric001 { private Log log; - public static void main(String argv[]) { - System.exit(run(argv,System.out) + Consts.JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001/TestDescription.java index 980bdb98c8939..8c251a0ca4b8b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.AllClassesWithGeneric.allclswithgeneric001t - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.AllClassesWithGeneric.allclswithgeneric001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllThreads/allthreads001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllThreads/allthreads001.java index e3e291fcdcdd3..5fa23569fc48c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllThreads/allthreads001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllThreads/allthreads001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,10 @@ public class allthreads001 { static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllThreads/allthreads001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllThreads/allthreads001/TestDescription.java index 782045881ac51..6822e5e7b327c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllThreads/allthreads001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllThreads/allthreads001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.AllThreads.allthreads001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.AllThreads.allthreads001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Capabilities/capabilities001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Capabilities/capabilities001.java index 5e05f6406f6f6..e5b11b3be969e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Capabilities/capabilities001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Capabilities/capabilities001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class capabilities001 { static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.Capabilities; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Capabilities/capabilities001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Capabilities/capabilities001/TestDescription.java index bba5b1c30153e..30ed332c53ec8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Capabilities/capabilities001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Capabilities/capabilities001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.Capabilities.capabilities001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.Capabilities.capabilities001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CapabilitiesNew/capabilitiesnew001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CapabilitiesNew/capabilitiesnew001.java index 00ffc50503480..1fe5df86db8f0 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CapabilitiesNew/capabilitiesnew001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CapabilitiesNew/capabilitiesnew001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class capabilitiesnew001 { static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.CapabilitiesNew; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CapabilitiesNew/capabilitiesnew001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CapabilitiesNew/capabilitiesnew001/TestDescription.java index 4d4c69cde636d..aa0479c819bc3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CapabilitiesNew/capabilitiesnew001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CapabilitiesNew/capabilitiesnew001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.CapabilitiesNew.capabilitiesnew001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.CapabilitiesNew.capabilitiesnew001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassPaths/classpaths001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassPaths/classpaths001.java index da06f738f93e6..1882ce8141561 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassPaths/classpaths001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassPaths/classpaths001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class classpaths001 { static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.ClassPaths; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassPaths/classpaths001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassPaths/classpaths001/TestDescription.java index 4f7d685117c9d..41e53912f2081 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassPaths/classpaths001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassPaths/classpaths001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.ClassPaths.classpaths001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.ClassPaths.classpaths001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassesBySignature/classbysig001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassesBySignature/classbysig001.java index 03fc0c49dca77..c319372fc90a5 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassesBySignature/classbysig001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassesBySignature/classbysig001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,10 @@ public class classbysig001 { // static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME + ";"; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassesBySignature/classbysig001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassesBySignature/classbysig001/TestDescription.java index 14f40d16e78f8..2127c0d3d876f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassesBySignature/classbysig001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassesBySignature/classbysig001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.ClassesBySignature.classbysig001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.ClassesBySignature.classbysig001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CreateString/createstr001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CreateString/createstr001.java index 5e0a4b8427e0d..aaa964b4fa399 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CreateString/createstr001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CreateString/createstr001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class createstr001 { static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.CreateString; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CreateString/createstr001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CreateString/createstr001/TestDescription.java index 54789071b5132..27bab252c0238 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CreateString/createstr001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CreateString/createstr001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.CreateString.createstr001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.CreateString.createstr001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Dispose/dispose001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Dispose/dispose001.java index e115fa9e6487e..89b0f608ff730 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Dispose/dispose001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Dispose/dispose001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class dispose001 { static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.Dispose; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Dispose/dispose001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Dispose/dispose001/TestDescription.java index 44b64f614f31e..2e3e7d2afcda0 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Dispose/dispose001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Dispose/dispose001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.Dispose.dispose001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.Dispose.dispose001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/DisposeObjects/disposeobj001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/DisposeObjects/disposeobj001.java index 901b69de37ae3..9c2a0e5347858 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/DisposeObjects/disposeobj001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/DisposeObjects/disposeobj001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,7 +93,10 @@ public class disposeobj001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/DisposeObjects/disposeobj001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/DisposeObjects/disposeobj001/TestDescription.java index 3782fc59b3fbd..5fc151bf339a4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/DisposeObjects/disposeobj001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/DisposeObjects/disposeobj001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.DisposeObjects.disposeobj001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.DisposeObjects.disposeobj001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Exit/exit001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Exit/exit001.java index b9313fc838f05..f7fd27b03d533 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Exit/exit001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Exit/exit001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class exit001 { static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.Exit; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Exit/exit001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Exit/exit001/TestDescription.java index c1fb69e22281a..772184d294ee6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Exit/exit001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Exit/exit001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.Exit.exit001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.Exit.exit001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents001.java index c0b28b905ccce..890b1be77bc0b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,7 +78,10 @@ public class holdevents001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents001/TestDescription.java index c562dc2e2a66b..4f096ee2f4915 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.HoldEvents.holdevents001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.HoldEvents.holdevents001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents002.java index 2995beb7979b1..c6e0cc4b014bd 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,8 +87,11 @@ public class holdevents002 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/IDSizes/idsizes001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/IDSizes/idsizes001.java index 49dbbcd170546..863160e6a1fda 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/IDSizes/idsizes001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/IDSizes/idsizes001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class idsizes001 { static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.IDSizes; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/IDSizes/idsizes001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/IDSizes/idsizes001/TestDescription.java index 0dcb07c803b40..bf0d6db0f880d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/IDSizes/idsizes001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/IDSizes/idsizes001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.IDSizes.idsizes001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.IDSizes.idsizes001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/InstanceCounts/instanceCounts001/instanceCounts001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/InstanceCounts/instanceCounts001/instanceCounts001.java index e25d2cc3189f8..dc21d1bc9d380 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/InstanceCounts/instanceCounts001/instanceCounts001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/InstanceCounts/instanceCounts001/instanceCounts001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -91,8 +91,11 @@ protected String getDebugeeClassName() { return "nsk.jdwp.VirtualMachine.InstanceCounts.instanceCounts001.instanceCounts001a"; } - public static void main(String[] argv) { - System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String[] argv, PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001.java index 37cc65ff94eb9..bc620c8b59c6f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,7 +102,10 @@ public class redefinecls001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001/TestDescription.java index 5ea557b5164f5..7707821bc7936 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,7 +74,7 @@ * nsk.jdwp.VirtualMachine.RedefineClasses.redefinecls001b * @run driver nsk.share.ExtraClassesBuilder * newclass - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.RedefineClasses.redefinecls001 * . * -arch=${os.family}-${os.simpleArch} diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents001.java index 95bafeb1aff07..ddca99b03d314 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,7 +78,10 @@ public class releaseevents001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents001/TestDescription.java index 589d061373d49..8cbb7a6e15fce 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.ReleaseEvents.releaseevents001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.ReleaseEvents.releaseevents001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents002.java index 64b6ce1547b57..ff278aabcf354 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,8 +87,11 @@ public class releaseevents002 { /** * Start test from command line. */ - public static void main(String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + public static void main (String argv[]) { + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents002/TestDescription.java index cb6760f97876b..1c94d9d75876e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents002/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents002/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.ReleaseEvents.releaseevents002a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.ReleaseEvents.releaseevents002 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Resume/resume001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Resume/resume001.java index ed427439edc72..cb602d17ba037 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Resume/resume001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Resume/resume001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class resume001 { static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.Resume; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Resume/resume001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Resume/resume001/TestDescription.java index 14fcd815f2897..90b6db41be0e4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Resume/resume001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Resume/resume001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.Resume.resume001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.Resume.resume001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/SetDefaultStratum/setdefstrat001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/SetDefaultStratum/setdefstrat001.java index 51e8a03487bc8..b90423e62190d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/SetDefaultStratum/setdefstrat001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/SetDefaultStratum/setdefstrat001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,7 +85,10 @@ public class setdefstrat001 { * Start test from command line. */ public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } /** diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/SetDefaultStratum/setdefstrat001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/SetDefaultStratum/setdefstrat001/TestDescription.java index 94828c43d800b..43f0a40379870 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/SetDefaultStratum/setdefstrat001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/SetDefaultStratum/setdefstrat001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.SetDefaultStratum.setdefstrat001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.SetDefaultStratum.setdefstrat001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/TopLevelThreadGroups/threadgroups001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/TopLevelThreadGroups/threadgroups001.java index e04cb45580c61..daaf39cc5fa2d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/TopLevelThreadGroups/threadgroups001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/TopLevelThreadGroups/threadgroups001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class threadgroups001 { static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.TopLevelThreadGroups; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/TopLevelThreadGroups/threadgroups001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/TopLevelThreadGroups/threadgroups001/TestDescription.java index ecd37d43e848f..ac51bc95011ad 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/TopLevelThreadGroups/threadgroups001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/TopLevelThreadGroups/threadgroups001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.TopLevelThreadGroups.threadgroups001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.TopLevelThreadGroups.threadgroups001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version001.java index b89aa3e0ec0b7..66575fee4f8e1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class version001 { static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.Version; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version001/TestDescription.java index c26171f0dec23..cd1d7123a34af 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.Version.version001a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.Version.version001 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version002.java index 5907a8159ffe5..8060922340ce5 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class version002 { static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.Version; public static void main (String argv[]) { - System.exit(run(argv,System.out) + JCK_STATUS_BASE); + int result = run(argv, System.out); + if (result != 0) { + throw new RuntimeException("Test failed"); + } } public static int run(String argv[], PrintStream out) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version002/TestDescription.java index cfc6ed266c173..d09e4f5176d0c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version002/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version002/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase * /test/lib * @build nsk.jdwp.VirtualMachine.Version.version002a - * @run main/othervm + * @run driver * nsk.jdwp.VirtualMachine.Version.version002 * -arch=${os.family}-${os.simpleArch} * -verbose diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java index ab8b8f7b2b9e7..2500dfeb8ebc0 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java @@ -322,11 +322,11 @@ public String[] makeCommandLineArgs(String classToExecute, String transportAddre } } -/* - String classPath = System.getProperty("java.class.path"); - args.add("-classpath") + + String classPath = System.getProperty("test.class.path"); + args.add("-classpath"); args.add(classPath); - */ + String server; if (argumentHandler.isAttachingConnector()) { From e869bfde1f25787278c3fe935ba75b6fbcc037ce Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 10:59:15 +0000 Subject: [PATCH 244/846] 8335836: serviceability/jvmti/StartPhase/AllowedFunctions/AllowedFunctions.java fails with unexpected exit code: 112 Backport-of: 965d6b9cbe2dd882fe3c3c955dfa08685af7d6c2 --- .../AllowedFunctions/libAllowedFunctions.c | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/jvmti/StartPhase/AllowedFunctions/libAllowedFunctions.c b/test/hotspot/jtreg/serviceability/jvmti/StartPhase/AllowedFunctions/libAllowedFunctions.c index 4299a98d7e63b..97b5cab341eb2 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/StartPhase/AllowedFunctions/libAllowedFunctions.c +++ b/test/hotspot/jtreg/serviceability/jvmti/StartPhase/AllowedFunctions/libAllowedFunctions.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,8 @@ extern "C" { #define FAILED 2 static jint result = PASSED; +static jrawMonitorID event_mon = NULL; +static jboolean is_vm_dead = JNI_FALSE; static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved); @@ -68,7 +70,7 @@ jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { static void check_jvmti_error(jvmtiEnv *jvmti, char* fname, jvmtiError err) { if (err != JVMTI_ERROR_NONE) { printf(" ## %s error: %d\n", fname, err); - exit(err); + abort(); } } @@ -317,7 +319,7 @@ VMStart(jvmtiEnv *jvmti, JNIEnv* jni) { } static void JNICALL -VMInit(jvmtiEnv *jvmti, JNIEnv* jnii, jthread thread) { +VMInit(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) { jvmtiPhase phase; printf("VMInit event\n"); @@ -329,22 +331,52 @@ VMInit(jvmtiEnv *jvmti, JNIEnv* jnii, jthread thread) { } } +static void JNICALL +VMDeath(jvmtiEnv *jvmti, JNIEnv* jni) { + jvmtiError err; + + // Block ClassPrepare events while this callback is executed. + err = (*jvmti)->RawMonitorEnter(jvmti, event_mon); + check_jvmti_error(jvmti, "VMDeath event: Failed in RawMonitorEnter", err); + + is_vm_dead = JNI_TRUE; + printf("VMDeath event\n"); + + err = (*jvmti)->RawMonitorExit(jvmti, event_mon); + check_jvmti_error(jvmti, "VMDeath event: Failed in RawMonitorExit", err); +} + static void JNICALL ClassPrepare(jvmtiEnv *jvmti, JNIEnv *env, jthread thread, jclass klass) { static const jint EVENTS_LIMIT = 2; static jint event_no = 0; - jthread cur_thread = get_cur_thread(jvmti); jvmtiPhase phase; intptr_t exp_val = 777; intptr_t act_val; + jvmtiError err; + + // Block VMDeath event and other ClassPrepare events while this callback is executed. + // Sync with VMDeath event and check for is_vm_dead guard against JVMTI_ERROR WRONG_PHASE. + err = (*jvmti)->RawMonitorEnter(jvmti, event_mon); + check_jvmti_error(jvmti, "ClassPrepare event: Failed in RawMonitorEnter", err); + if (is_vm_dead) { + printf("\nIgnoring ClassPrepare event during the dead phase\n"); + err = (*jvmti)->RawMonitorExit(jvmti, event_mon); + check_jvmti_error(jvmti, "ClassPrepare event: Failed in RawMonitorExit", err); + return; + } get_phase(jvmti, &phase); if (phase != JVMTI_PHASE_START && phase != JVMTI_PHASE_LIVE) { printf(" ## Error: unexpected phase: %d, expected: %d or %d\n", phase, JVMTI_PHASE_START, JVMTI_PHASE_LIVE); + result = FAILED; + err = (*jvmti)->RawMonitorExit(jvmti, event_mon); + check_jvmti_error(jvmti, "ClassPrepare event: Failed in RawMonitorExit", err); return; } if (phase == JVMTI_PHASE_START && event_no < EVENTS_LIMIT) { + jthread cur_thread = get_cur_thread(jvmti); printf("\nClassPrepare event during the start phase: #%d\n", event_no); // Test the JVMTI class functions during the start phase test_class_functions(jvmti, env, thread, klass); @@ -360,6 +392,8 @@ ClassPrepare(jvmtiEnv *jvmti, JNIEnv *env, jthread thread, jclass klass) { } event_no++; } + err = (*jvmti)->RawMonitorExit(jvmti, event_mon); + check_jvmti_error(jvmti, "ClassPrepare event: Failed in RawMonitorExit", err); } static @@ -400,6 +434,9 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { callbacks.VMInit = VMInit; callbacks.ClassPrepare = ClassPrepare; + err = (*jvmti)->CreateRawMonitor(jvmti, "Events Monitor", &event_mon); + check_jvmti_error(jvmti, "## Agent_Initialize: CreateRawMonitor", err); + err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, size); check_jvmti_error(jvmti, "## Agent_Initialize: SetEventCallbacks", err); From 8c2fdd00593a382980ab89780a96297c5421dd78 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 11:00:53 +0000 Subject: [PATCH 245/846] 8338154: Fix -Wzero-as-null-pointer-constant warnings in gtest framework Backport-of: d77e6fe45c7b834db457a772ce0bea514d2e44f3 --- make/hotspot/lib/CompileGtest.gmk | 3 ++- test/hotspot/gtest/gtestMain.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/make/hotspot/lib/CompileGtest.gmk b/make/hotspot/lib/CompileGtest.gmk index f16b9a747bcc4..71fbf7c3dda2c 100644 --- a/make/hotspot/lib/CompileGtest.gmk +++ b/make/hotspot/lib/CompileGtest.gmk @@ -49,7 +49,8 @@ $(eval $(call SetupJdkLibrary, BUILD_GTEST_LIBGTEST, \ $(GTEST_FRAMEWORK_SRC)/googletest/src \ $(GTEST_FRAMEWORK_SRC)/googlemock/src, \ INCLUDE_FILES := gtest-all.cc gmock-all.cc, \ - DISABLED_WARNINGS_gcc := undef unused-result format-nonliteral maybe-uninitialized, \ + DISABLED_WARNINGS_gcc := undef unused-result format-nonliteral \ + maybe-uninitialized zero-as-null-pointer-constant, \ DISABLED_WARNINGS_clang := undef unused-result format-nonliteral, \ CFLAGS := $(JVM_CFLAGS) \ -I$(GTEST_FRAMEWORK_SRC)/googletest \ diff --git a/test/hotspot/gtest/gtestMain.cpp b/test/hotspot/gtest/gtestMain.cpp index 9f0d395c87bf8..9e2c1209b8910 100644 --- a/test/hotspot/gtest/gtestMain.cpp +++ b/test/hotspot/gtest/gtestMain.cpp @@ -334,7 +334,7 @@ static void run_in_new_thread(const args_t* args) { extern "C" void* thread_wrapper(void* p) { const args_t* const p_args = (const args_t*) p; runUnitTestsInner(p_args->argc, p_args->argv); - return 0; + return nullptr; } static void run_in_new_thread(const args_t* args) { From 741f7173d3b37a190694409c8fcffc7d60eb5164 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 11:02:35 +0000 Subject: [PATCH 246/846] 8340407: Open source a few more Component related tests Backport-of: a32c3b43aaefdebf5be229f90d9cd26db1859b95 --- .../ComponentLeakTest/ComponentLeakTest.java | 769 ++++++++++++++++++ .../ComponentSerializationTest.java | 354 ++++++++ .../MinMaxSizeDefensive/GetSizesTest.java | 113 +++ .../awt/Component/ZOrderTest/ZOrderTest.java | 159 ++++ 4 files changed, 1395 insertions(+) create mode 100644 test/jdk/java/awt/Component/ComponentLeakTest/ComponentLeakTest.java create mode 100644 test/jdk/java/awt/Component/ComponentSerializationTest/ComponentSerializationTest.java create mode 100644 test/jdk/java/awt/Component/MinMaxSizeDefensive/GetSizesTest.java create mode 100644 test/jdk/java/awt/Component/ZOrderTest/ZOrderTest.java diff --git a/test/jdk/java/awt/Component/ComponentLeakTest/ComponentLeakTest.java b/test/jdk/java/awt/Component/ComponentLeakTest/ComponentLeakTest.java new file mode 100644 index 0000000000000..2936880dde6c6 --- /dev/null +++ b/test/jdk/java/awt/Component/ComponentLeakTest/ComponentLeakTest.java @@ -0,0 +1,769 @@ +/* + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 + * @key headful + * @requires (os.family != "linux") + * @bug 4119609 4149812 4136116 4171960 4170095 4294016 4343272 + * @summary This test verifies that java.awt objects are being garbage + * collected correctly. That is, it ensures that unneeded + * references (such as JNI global refs or refs in static arrays) + * do not remain after the object is disposed. + * @run main/othervm ComponentLeakTest + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Canvas; +import java.awt.CardLayout; +import java.awt.Checkbox; +import java.awt.CheckboxGroup; +import java.awt.CheckboxMenuItem; +import java.awt.Choice; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.FileDialog; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Label; +import java.awt.LayoutManager; +import java.awt.List; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.MenuShortcut; +import java.awt.Panel; +import java.awt.PopupMenu; +import java.awt.ScrollPane; +import java.awt.Scrollbar; +import java.awt.TextArea; +import java.awt.TextField; +import java.awt.Window; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.lang.ref.PhantomReference; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.util.Map; +import java.util.HashMap; + +public class ComponentLeakTest { + + public static void main(String[] args) { + final int iter = 5; + + for(int count = 0; count < iter; count++) { + MainFrame f = new MainFrame(); + MainWindow w = new MainWindow(f); + MainDialog d = new MainDialog(f); + TestFileDialog fd = new TestFileDialog(f, "TestFileDialog"); + fd.addNotify(); // fd.show() hangs + + fd.dispose(); + d.dispose(); + w.dispose(); + f.dispose(); + } + + // Test layout managers + Frame border = new Frame(); + border.setLayout(new BorderLayout()); + Frame card = new Frame(); + card.setLayout(new CardLayout()); + Frame flow = new Frame(); + flow.setLayout(new FlowLayout()); + Frame gridBag = new Frame(); + gridBag.setLayout(new GridBagLayout()); + Frame grid = new Frame(); + grid.setLayout(new GridLayout(1, 2)); + + for (int count = 0; count < iter; count++) { + border.add(new BorderTestButton("BorderTest"), + BorderLayout.WEST); + border.add(new BorderTestButton("BorderTest"), + BorderLayout.EAST); + card.add(new CardTestButton("CardTest"), "card0"); + card.add(new CardTestButton("CardTest"), "card1"); + flow.add(new FlowTestButton()); + flow.add(new FlowTestButton()); + gridBag.add(new GridBagTestButton(), new GridBagConstraints()); + gridBag.add(new GridBagTestButton(), new GridBagConstraints()); + grid.add(new GridTestButton()); + grid.add(new GridTestButton()); + + border.removeAll(); + card.removeAll(); + flow.removeAll(); + gridBag.removeAll(); + grid.removeAll(); + } + + gc(5); + try { + Thread.sleep(1000); + } catch (InterruptedException ie) { + } + + freeReferences(); + reportLeaks(); + System.err.println("Test passed."); + } + + public static void initWindow(Window w) { + w.setSize(600, 400); + w.setLayout(new FlowLayout()); + + // peered components + w.add(new TestButton("Button")); + w.add(new TestCanvas()); + w.add(new TestCheckbox("Checkbox", true)); + TestChoice choice = new TestChoice(); + choice.add("Choice 1"); + choice.add("Choice Two"); + w.add(choice); + w.add(new TestLabel("Label")); + TestList list = new TestList(); + list.add("List 1"); + list.add("List Two"); + w.add(list); + w.add(new TestScrollbar(Scrollbar.VERTICAL)); + w.add(new TestScrollbar(Scrollbar.HORIZONTAL)); + TestScrollPane scrollpane = new TestScrollPane(); + scrollpane.add(new TestButton("Button in a scrollpane")); + w.add(scrollpane); + w.add(new TestTextArea("TextArea", 3, 30)); + w.add(new TestTextField("TextField")); + + // nested components + TestPanel panel1 = new TestPanel(); + panel1.setLayout(new FlowLayout()); + panel1.setBackground(Color.red); + w.add(panel1); + + panel1.add(new TestButton("level 2")); + + Panel panel2 = new Panel(); + panel2.setLayout(new FlowLayout()); + panel2.setBackground(Color.green); + panel1.add(panel2); + + panel2.add(new TestButton("level 3")); + + w.add(new TestLightweight("Lightweight")); + } + + private static ReferenceQueue queue = new ReferenceQueue(); + private static Map refs = new HashMap(); + + public static void register(Object obj) { + PhantomReference ref = new PhantomReference(obj, queue); + refs.put(ref, obj.getClass().getName()); + } + + private static void gc() { + System.gc(); + try { + Thread.sleep(100); + } catch (InterruptedException ie) { + throw new RuntimeException("Test was interrupted"); + } + } + + private static void gc(int num) { + for (; num > 0; num--) { + gc(); + } + } + + public static void freeReferences() { + System.err.println("Total references: " + refs.size()); + boolean wasFreed = false; + do { + Object[] arr = new Object[2000]; + gc(5); + Reference ref = null; + wasFreed = false; + while ((ref = queue.poll()) != null) { + refs.remove(ref); + wasFreed = true; + gc(); + } + } while (wasFreed); + } + + public static void reportLeaks() { + for (Reference ref : refs.keySet()) { + System.err.println("Leaked " + refs.get(ref)); + } + + if (refs.size() > 0) { + throw new RuntimeException("Some references remained: " + refs.size()); + } + } +} + +class TestFrame extends Frame { + public TestFrame() { + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestFrame(String title) { + super(title); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } +} + +class TestWindow extends Window { + public TestWindow(Frame owner) { + super(owner); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestWindow(Window owner) { + super(owner); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } +} + +class TestDialogL extends Dialog { + public TestDialogL(Frame owner) { + super(owner); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestDialogL(Frame owner, boolean modal) { + super(owner, modal); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestDialogL(Frame owner, String title) { + super(owner, title); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestDialogL(Frame owner, String title, boolean modal) { + super(owner, title, modal); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestDialogL(Dialog owner) { + super(owner); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestDialogL(Dialog owner, String title) { + super(owner, title); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestDialogL(Dialog owner, String title, boolean modal) { + super(owner, title, modal); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } +} + +class TestFileDialog extends FileDialog { + public TestFileDialog(Frame parent) { + super(parent); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestFileDialog(Frame parent, String title) { + super(parent, title); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestFileDialog(Frame parent, String title, int mode) { + super(parent, title, mode); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } +} + +class TestButton extends Button { + public TestButton() { + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestButton(String title) { + super(title); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } +} + +class TestCanvas extends Canvas { + int width = 100; + int height = 100; + + public TestCanvas() { + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestCanvas(GraphicsConfiguration config) { + super(config); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public void paint(Graphics g) { + g.setColor(Color.blue); + g.fillRoundRect(10, 10, 50, 50, 15, 30); + g.setColor(Color.red); + g.fillOval(70, 70, 25, 25); + } + + public Dimension getPreferredSize() { + return new Dimension(width, height); + } +} + +class TestCheckbox extends Checkbox { + public TestCheckbox() { + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestCheckbox(String label) { + super(label); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestCheckbox(String label, boolean state) { + super(label, state); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestCheckbox(String label, boolean state, CheckboxGroup group) { + super(label, state, group); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestCheckbox(String label, CheckboxGroup group, boolean state) { + super(label, group, state); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } +} + +class TestChoice extends Choice { + public TestChoice() { + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } +} + +class TestLabel extends Label { + public TestLabel() { + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestLabel(String text) { + super(text); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestLabel(String text, int align) { + super(text, align); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } +} + +class TestList extends List { + public TestList() { + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestList(int rows) { + super(rows); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestList(int rows, boolean multipleMode) { + super(rows, multipleMode); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } +} + +class TestScrollbar extends Scrollbar { + public TestScrollbar() { + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestScrollbar(int orientation) { + super(orientation); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestScrollbar(int orient, int val, int visible, int min, int max) { + super(orient, val, visible, min, max); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } +} + +class TestScrollPane extends ScrollPane { + public TestScrollPane() { + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestScrollPane(int policy) { + super(policy); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } +} + +class TestTextField extends TextField { + public TestTextField() { + ComponentLeakTest.register(this); + requestFocus(); + setDropTarget(new TestDropTarget(this)); + } + + public TestTextField(String text) { + super(text); + ComponentLeakTest.register(this); + requestFocus(); + setDropTarget(new TestDropTarget(this)); + } + + public TestTextField(int columns) { + super(columns); + ComponentLeakTest.register(this); + requestFocus(); + setDropTarget(new TestDropTarget(this)); + } + + public TestTextField(String text, int columns) { + super(text, columns); + ComponentLeakTest.register(this); + requestFocus(); + setDropTarget(new TestDropTarget(this)); + } +} + +class TestTextArea extends TextArea { + public TestTextArea() { + ComponentLeakTest.register(this); + requestFocus(); + setDropTarget(new TestDropTarget(this)); + } + + public TestTextArea(String text) { + super(text); + ComponentLeakTest.register(this); + requestFocus(); + setDropTarget(new TestDropTarget(this)); + } + + public TestTextArea(int rows, int columns) { + super(rows, columns); + ComponentLeakTest.register(this); + requestFocus(); + setDropTarget(new TestDropTarget(this)); + } + + public TestTextArea(String text, int rows, int columns) { + super(text, rows, columns); + ComponentLeakTest.register(this); + requestFocus(); + setDropTarget(new TestDropTarget(this)); + } + + public TestTextArea(String text, int rows, int columns, int bars) { + super(text, rows, columns, bars); + ComponentLeakTest.register(this); + requestFocus(); + setDropTarget(new TestDropTarget(this)); + } +} + +class TestPanel extends Panel { + public TestPanel() { + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } + + public TestPanel(LayoutManager layout) { + super(layout); + ComponentLeakTest.register(this); + setDropTarget(new TestDropTarget(this)); + } +} +class TestMenu extends Menu { + public TestMenu() { + ComponentLeakTest.register(this); + } + + public TestMenu(String label) { + super(label); + ComponentLeakTest.register(this); + } + + public TestMenu(String label, boolean tearOff) { + super(label, tearOff); + ComponentLeakTest.register(this); + } +} + +class TestMenuItem extends MenuItem { + public TestMenuItem() { + ComponentLeakTest.register(this); + } + public TestMenuItem(String label) { + super(label); + ComponentLeakTest.register(this); + } + + public TestMenuItem(String label, MenuShortcut s) { + super(label, s); + ComponentLeakTest.register(this); + } +} + +class TestMenuBar extends MenuBar { + public TestMenuBar() { + ComponentLeakTest.register(this); + } +} + +class TestPopupMenu extends PopupMenu { + public TestPopupMenu() { + ComponentLeakTest.register(this); + } + + public TestPopupMenu(String label) { + super(label); + ComponentLeakTest.register(this); + } +} + +class TestCheckboxMenuItem extends CheckboxMenuItem { + public TestCheckboxMenuItem() { + ComponentLeakTest.register(this); + } + + public TestCheckboxMenuItem(String label) { + super(label); + ComponentLeakTest.register(this); + } + + public TestCheckboxMenuItem(String label, boolean state) { + super(label, state); + ComponentLeakTest.register(this); + } +} + +class BorderTestButton extends Button { + public BorderTestButton() { + ComponentLeakTest.register(this); + } + + public BorderTestButton(String title) { + super(title); + ComponentLeakTest.register(this); + } +} + +class CardTestButton extends Button { + public CardTestButton() { + ComponentLeakTest.register(this); + } + + public CardTestButton(String title) { + super(title); + ComponentLeakTest.register(this); + } +} + +class FlowTestButton extends Button { + public FlowTestButton() { + ComponentLeakTest.register(this); + } + + public FlowTestButton(String title) { + super(title); + ComponentLeakTest.register(this); + } +} + +class GridBagTestButton extends Button { + public GridBagTestButton() { + ComponentLeakTest.register(this); + } + + public GridBagTestButton(String title) { + super(title); + ComponentLeakTest.register(this); + } +} + +class GridTestButton extends Button { + public GridTestButton() { + ComponentLeakTest.register(this); + } + + public GridTestButton(String title) { + super(title); + ComponentLeakTest.register(this); + } +} + +class TestLightweight extends Component { + String label; + int width = 100; + int height = 30; + + public TestLightweight(String label) { + this.label = label; + ComponentLeakTest.register(this); + } + + public void paint(Graphics g) { + Dimension d = getSize(); + g.setColor(Color.orange); + g.fillRect(0, 0, d.width, d.height); + g.setColor(Color.black); + int x = 5; + int y = (d.height - 5); + g.drawString(label, x, y); + } + + public Dimension getPreferredSize() { + return new Dimension(width,height); + } +} + +class TestDropTarget extends DropTarget { + public TestDropTarget(Component comp) { + super(comp, new DropTargetListener() { + public void dragEnter(DropTargetDragEvent dtde) {} + public void dragOver(DropTargetDragEvent dtde) {} + public void dropActionChanged(DropTargetDragEvent dtde) {} + public void dragExit(DropTargetEvent dte) {} + public void drop(DropTargetDropEvent dtde) {} + }); + ComponentLeakTest.register(this); + } +} + +class MainWindow extends TestWindow { + public MainWindow(Frame f) { + super(f); + ComponentLeakTest.initWindow(this); + setVisible(true); + + TestPopupMenu popup = new TestPopupMenu("hi"); + add(popup); + popup.show(this, 5, 5); + } +} + +class MainDialog extends TestDialogL { + public MainDialog(Frame f) { + super(f, "MainDialog", false); + ComponentLeakTest.initWindow(this); + setVisible(true); + + TestPopupMenu popup = new TestPopupMenu("hi"); + add(popup); + popup.show(this, 5, 5); + } +} + +class MainFrame extends TestFrame { + public MainFrame(){ + super("Component Leak Test MainFrame"); + + ComponentLeakTest.initWindow(this); + + TestMenu menu = new TestMenu("Print"); + TestMenu menu2 = new TestMenu("File"); + TestMenu menu3 = new TestMenu("Edit"); + TestMenu menu4 = new TestMenu("ReallyReallyReallyReallyReallyReallyReallyReally" + + "ReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyLong"); + menu2.setFont(new Font("SansSerif", Font.BOLD, 20)); + menu2.setEnabled(false); + menu3.setFont(new Font("Monospaced", Font.ITALIC, 18)); + menu3.setEnabled(false); + menu4.setEnabled(false); + TestMenuItem itemPrinter = new TestMenuItem("foobar"); + TestMenuItem itemScreen = new TestMenuItem("baz"); + TestCheckboxMenuItem itemCheck = new TestCheckboxMenuItem("yep"); + menu.add(itemPrinter); + menu.add(itemScreen); + menu.add(itemCheck); + TestMenuBar menuBar = new TestMenuBar(); + menuBar.add( menu ); + menuBar.add( menu2 ); + menuBar.add( menu3 ); + menuBar.add( menu4 ); + setMenuBar(menuBar); + + setVisible(true); + + TestPopupMenu popup = new TestPopupMenu("hi"); + add(popup); + popup.show(this, 5, 5); + } +} diff --git a/test/jdk/java/awt/Component/ComponentSerializationTest/ComponentSerializationTest.java b/test/jdk/java/awt/Component/ComponentSerializationTest/ComponentSerializationTest.java new file mode 100644 index 0000000000000..ddf7efffdbdfc --- /dev/null +++ b/test/jdk/java/awt/Component/ComponentSerializationTest/ComponentSerializationTest.java @@ -0,0 +1,354 @@ +/* + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4146452 + * @summary Tests serialization of peered and lightweight Components. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ComponentSerializationTest + */ + +import java.awt.Button; +import java.awt.Canvas; +import java.awt.Checkbox; +import java.awt.CheckboxMenuItem; +import java.awt.Choice; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FileDialog; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Label; +import java.awt.List; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.ScrollPane; +import java.awt.Scrollbar; +import java.awt.TextArea; +import java.awt.TextField; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import javax.swing.JPanel; + +public class ComponentSerializationTest extends JPanel { + private MainFrame mf; + private MainWindow mw; + private MainDialog md; + private MainFileDialog mfd; + private static final String INSTRUCTIONS = """ + A Frame, a Window, and a Dialog should appear. From the Frame's + "Serialize" menu, select "Serialize!". Another Frame, Window, and + Dialog should appear exactly on top of the existing ones. The state + and functionality of the two sets of Windows should be identical. If + any errors or exceptions appear in the log area, or if the second set of + Windows is different from the first, the test fails. Otherwise, the + test passes. + """; + + private static final ArrayList toDispose = new ArrayList<>(); + + public ComponentSerializationTest() { + mf = new MainFrame(); + toDispose.add(mf); + mw = new MainWindow(mf); + toDispose.add(mw); + md = new MainDialog(mf); + toDispose.add(md); + mfd = new MainFileDialog(mf); + toDispose.add(mfd); + } + + public static void main(String[] argc) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Component Serialization Test") + .splitUI(ComponentSerializationTest::new) + .instructions(INSTRUCTIONS) + .columns(40) + .logArea() + .build() + .awaitAndCheck(); + for (Window w : toDispose) { + if (w != null) { + EventQueue.invokeAndWait(w::dispose); + } + } + } + + private void initWindow(Window w) { + w.setSize(600, 400); + w.setLayout(new FlowLayout()); + + // peered components + w.add(new Button("Button")); + w.add(new TestCanvas()); + w.add(new Checkbox("Checkbox", true)); + Choice choice = new Choice(); + choice.add("Choice 1"); + choice.add("Choice Two"); + w.add(choice); + w.add(new Label("Label")); + List list = new List(); + list.add("List 1"); + list.add("List Two"); + w.add(list); + w.add(new Scrollbar(Scrollbar.VERTICAL)); + w.add(new Scrollbar(Scrollbar.HORIZONTAL)); + ScrollPane scrollpane = new ScrollPane(); + scrollpane.add(new Button("Button in a scrollpane")); + w.add(scrollpane); + w.add(new TextArea("TextArea", 3, 30)); + w.add(new TextField("TextField")); + + // nested components + Panel panel1 = new Panel(); + panel1.setLayout(new FlowLayout()); + panel1.setBackground(Color.red); + w.add(panel1); + + panel1.add(new Button("level 2")); + + Panel panel2 = new Panel(); + panel2.setLayout(new FlowLayout()); + panel2.setBackground(Color.green); + panel1.add(panel2); + + panel2.add(new Button("level 3")); + + // lightweight components + w.add(new LWButton("LWbutton") ); + + // overlapping components + w.add(new ZOrderPanel()); + } + + class MainWindow extends Window { + public MainWindow(Frame f) { + super(f); + initWindow(this); + setLocation(650, 0); + setVisible(true); + } + } + + class MainDialog extends Dialog { + public MainDialog(Frame f) { + super(f, "MainDialog", false); + initWindow(this); + setLocation(0, 450); + setVisible(true); + } + } + + class MainFileDialog extends FileDialog { + public MainFileDialog(Frame f) { + super(f, "MainFileDialog", FileDialog.SAVE); + setLocation(650, 450); + addNotify(); + } + } + + class MainFrame extends Frame { + public MainFrame() { + super("ComponentSerializationTest"); + initWindow(this); + + Menu menu = new Menu("Serialize"); + Menu menu2 = new Menu("File"); + Menu menu3 = new Menu("Edit"); + Menu menu4 = new Menu("ReallyReallyReallyReallyReallyReallyReallyReally" + + "ReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyLong"); + menu2.setFont(new Font("SansSerif", Font.BOLD, 20)); + menu2.setEnabled(false); + menu3.setFont(new Font("Monospaced", Font.ITALIC, 18)); + menu3.setEnabled(false); + menu4.setEnabled(false); + MenuItem itemSerialize = new MenuItem("Serialize!"); + CheckboxMenuItem itemCheck = new CheckboxMenuItem("Check me"); + menu.add(itemSerialize); + menu.add(itemCheck); + MenuBar menuBar = new MenuBar(); + menuBar.add(menu); + menuBar.add(menu2); + menuBar.add(menu3); + menuBar.add(menu4); + setMenuBar(menuBar); + + itemSerialize.addActionListener(new ActionSerialize()); + + setLocation(0, 0); + setVisible(true); + } + } + + class ActionSerialize implements ActionListener { + public void actionPerformed(ActionEvent ev) { + Frame f2 = null; + Window w2 = null; + Dialog d2 = null; + FileDialog fd2 = null; + + try { + FileOutputStream fos = new FileOutputStream("tmp"); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(mf); + oos.writeObject(mw); + oos.writeObject(md); + oos.writeObject(mfd); + oos.flush(); + + FileInputStream fis = new FileInputStream("tmp"); + ObjectInputStream ois = new ObjectInputStream(fis); + f2 = (Frame)ois.readObject(); + w2 = (Window)ois.readObject(); + d2 = (Dialog)ois.readObject(); + fd2= (FileDialog)ois.readObject(); + } catch (Exception e) { + PassFailJFrame.log(e.getMessage()); + } + + if (f2 == null || w2 == null || d2 == null || fd2 == null) { + PassFailJFrame.log("ERROR: one of the components was not deserialized."); + PassFailJFrame.log("frame = " + f2); + PassFailJFrame.log("window = " + w2); + PassFailJFrame.log("dialog = " + d2); + PassFailJFrame.log("file dalog = " + fd2); + } + + if (f2 != null) { + toDispose.add(f2); + f2.setVisible(true); + } + if (w2 != null) { + toDispose.add(w2); + w2.setVisible(true); + } + if (d2 != null) { + toDispose.add(d2); + d2.setVisible(true); + } + if (fd2 != null) { + toDispose.add(fd2); + fd2.addNotify(); + } + } + } + + class LWButton extends Component { + String label; + int width = 100; + int height = 30; + + public LWButton(String label) { + super(); + this.label = label; + } + + public void paint(Graphics g) { + Dimension d = getSize(); + g.setColor(Color.orange); + g.fillRect(0, 0, d.width, d.height); + g.setColor(Color.black); + int x = 5; + int y = (d.height - 5); + g.drawString(label, x, y); + } + + public Dimension getPreferredSize() { + return new Dimension(width, height); + } + } + + class TestCanvas extends Canvas { + int width = 100; + int height = 100; + + public void paint(Graphics g) { + g.setColor(Color.blue); + g.fillRoundRect(10, 10, 50, 50, 15, 30); + g.setColor(Color.red); + g.fillOval(70, 70, 25, 25); + } + public Dimension getPreferredSize() { + return new Dimension(width, height); + } + } + + class ZOrderPanel extends Panel { + public ZOrderPanel() { + setLayout(null); + + Component first, second, third, fourth; + + show(); + first = makeBox("Second", Color.blue, -1); + second = makeBox("First", Color.yellow, 0); + fourth = makeBox("Fourth", Color.red, 2); + third = makeBox("Third", Color.green, 3); + remove(third); + add(third, 2); + validate(); + add(new LWButton("LWButton"), 0); + } + + public Dimension preferredSize() { + return new Dimension(260, 80); + } + + public void layout() { + int i, n; + Insets ins = insets(); + n = countComponents(); + for (i = n - 1; i >= 0; i--) { + Component p = getComponent(i); + p.reshape(ins.left + 40 * i, ins.top + 5 * i, 60, 60); + } + } + + public Component makeBox(String s, Color c, int index) { + Label l = new Label(s); + l.setBackground(c); + l.setAlignment(Label.RIGHT); + add(l, index); + validate(); + return l; + } + } +} diff --git a/test/jdk/java/awt/Component/MinMaxSizeDefensive/GetSizesTest.java b/test/jdk/java/awt/Component/MinMaxSizeDefensive/GetSizesTest.java new file mode 100644 index 0000000000000..2b4954879380a --- /dev/null +++ b/test/jdk/java/awt/Component/MinMaxSizeDefensive/GetSizesTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4783989 + @summary get(Preferred|Minimum|Maximum)Size() must not return a reference. + The object copy of Dimension class needed. + @key headful + @run main GetSizesTest +*/ + +import java.awt.Button; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.lang.reflect.InvocationTargetException; + +public class GetSizesTest extends Frame { + Button b; + + public static void main(final String[] args) throws InterruptedException, + InvocationTargetException { + GetSizesTest app = new GetSizesTest(); + EventQueue.invokeAndWait(() -> { + try { + app.init(); + app.start(); + } finally { + app.dispose(); + } + }); + } + + public void init() { + b = new Button("button"); + add(b); + } + + public void start () { + setSize(200, 200); + setLocationRelativeTo(null); + setVisible(true); + validate(); + + System.out.println("Test set for Container (Frame)."); + + Dimension dimPref = getPreferredSize(); + dimPref.setSize(101, 101); + if (getPreferredSize().equals(new Dimension(101, 101))) { + throw new RuntimeException("Test Failed for: " + dimPref); + } + System.out.println("getPreferredSize() Passed."); + + Dimension dimMin = getMinimumSize(); + dimMin.setSize(101, 101); + if (getMinimumSize().equals(new Dimension(101, 101))) { + throw new RuntimeException("Test Failed for: " + dimMin); + } + System.out.println("getMinimumSize() Passed."); + + Dimension dimMax = getMaximumSize(); + dimMax.setSize(101, 101); + if (getMaximumSize().equals(new Dimension(101, 101))) { + throw new RuntimeException("Test Failed for: " + dimMax); + } + System.out.println("getMaximumSize() Passed."); + + System.out.println("Test set for Component (Button)."); + + dimPref = b.getPreferredSize(); + dimPref.setSize(33, 33); + if (b.getPreferredSize().equals(new Dimension(33, 33))) { + throw new RuntimeException("Test Failed for: " + dimPref); + } + System.out.println("getPreferredSize() Passed."); + + dimMin = b.getMinimumSize(); + dimMin.setSize(33, 33); + if (b.getMinimumSize().equals(new Dimension(33, 33))) { + throw new RuntimeException("Test Failed for: " + dimMin); + } + System.out.println("getMinimumSize() Passed."); + + dimMax = b.getMaximumSize(); + dimMax.setSize(33, 33); + if (b.getMaximumSize().equals(new Dimension(33, 33))) { + throw new RuntimeException("Test Failed for: " + dimMax); + } + System.out.println("getMaximumSize() Passed."); + System.out.println("GetSizesTest Succeeded."); + } +} diff --git a/test/jdk/java/awt/Component/ZOrderTest/ZOrderTest.java b/test/jdk/java/awt/Component/ZOrderTest/ZOrderTest.java new file mode 100644 index 0000000000000..15003f753a6fe --- /dev/null +++ b/test/jdk/java/awt/Component/ZOrderTest/ZOrderTest.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4059430 + * @summary Test for component z-ordering consistency + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ZOrderTest + */ + +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Insets; +import java.awt.Label; +import java.awt.Panel; +import java.lang.reflect.InvocationTargetException; +import java.util.List; + +public class ZOrderTest { + public final static String INSTRUCTIONS = """ + The ZOrderTest creates two frames. + - Frame 1 has components added to an intermediate panel + - Frame 2 has components added directly to the frame itself + Verify that the components are in the correct z-order. Lower numbered + components should overlap higher numbered ones (e.g. component zero should + appear on top of component one). + Both frames should have the same component ordering, and this ordering should + be the same on all supported operating systems. + """; + + public static void main(String [] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Component ZOrder Test") + .testUI(ZOrderTest::makeFrames) + .instructions(INSTRUCTIONS) + .columns(40) + .logArea() + .build() + .awaitAndCheck(); + } + + private static List makeFrames() { + Frame frame, frame2; + + // test adding components to panel on a frame + frame = new Frame("ZOrderTest(1) for 4059430"); + frame.pack(); + frame.show(); + Panel panel = new ZOrderPanel(); + frame.setBounds(0, 0, 500, 350); + frame.setLayout(new GridLayout()); + frame.add(panel); + doTest(panel); + + // test adding components directly to frame + frame2 = new ZOrderTestFrame("ZOrderTest(2) for 4059430"); + frame2.pack(); + frame2.show(); + frame2.setBounds(80, 80, 500, 350); + doTest(frame2); + + return List.of(frame, frame2); + } + + /* + * This tests various boundary conditions with z-ordering + * - inserting at the top of the z-order + * - inserting at the bottom of the z-order + * - inserting in the middle of the z-order + */ + private static void doTest(Container cont) { + Component compZero, compOne, compTwo, compThree, compFour; + + compZero = makeBox(cont, "Comp One", Color.blue, -1); + // insert on top + compOne = makeBox(cont, "Comp Zero", Color.yellow, 0); + // put at the back + compThree = makeBox(cont, "Comp Three", Color.red, 2); + // insert in last position + compTwo = makeBox(cont, "Comp Two", Color.green, 3); + // swap compTwo and compThree to correct positions + cont.remove(compTwo); + cont.add(compTwo, 2); + // one more test of adding to the end + compFour = makeBox(cont, "Comp Four", Color.magenta, -1); + // re-validate so components cascade into proper place + cont.validate(); + } + + private static Component makeBox(Container cont, String s, Color c, int index) { + Label l = new Label(s); + l.setBackground(c); + l.setAlignment(Label.RIGHT); + if (index == -1) { + cont.add(l); // semantically equivalent to -1, but why not test this too + } else { + cont.add(l, index); + } + cont.validate(); + return l; + } + + /** + * Cascades components across the container so + * that they overlap, demonstrating their z-ordering + */ + static void doCascadeLayout(Container cont) { + int i, n; + Insets ins = cont.insets(); + n = cont.countComponents(); + for (i = n - 1; i >= 0; i--) { + Component comp = cont.getComponent(i); + comp.reshape(ins.left + 75 * i, ins.top + 30 * i, 100, 100); + } + } +} + +class ZOrderPanel extends Panel { + public void layout() { + ZOrderTest.doCascadeLayout(this); + } +} + +class ZOrderTestFrame extends Frame +{ + public ZOrderTestFrame(String title) { + super(title); + } + + public void layout() { + ZOrderTest.doCascadeLayout(this); + } +} From 8eecdea3570f73e3a8fc62a55ede08cfba46f483 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 11:04:09 +0000 Subject: [PATCH 247/846] 8341177: Opensource few List and a Window test Backport-of: 602408e4f3848b30299ea94264e88ead5361a310 --- .../awt/List/ActionEventWhenHitEnterTest.java | 126 ++++++++++++++++++ test/jdk/java/awt/List/ListAddPerfTest.java | 99 ++++++++++++++ ...MouseDraggedOriginatedByScrollBarTest.java | 103 ++++++++++++++ test/jdk/java/awt/Window/bug4189244.java | 120 +++++++++++++++++ 4 files changed, 448 insertions(+) create mode 100644 test/jdk/java/awt/List/ActionEventWhenHitEnterTest.java create mode 100644 test/jdk/java/awt/List/ListAddPerfTest.java create mode 100644 test/jdk/java/awt/List/MouseDraggedOriginatedByScrollBarTest.java create mode 100644 test/jdk/java/awt/Window/bug4189244.java diff --git a/test/jdk/java/awt/List/ActionEventWhenHitEnterTest.java b/test/jdk/java/awt/List/ActionEventWhenHitEnterTest.java new file mode 100644 index 0000000000000..232189ef53bbb --- /dev/null +++ b/test/jdk/java/awt/List/ActionEventWhenHitEnterTest.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4234245 + * @summary the actionEvent is not invoked when hit enter on list. + * @key headful + * @run main ActionEventWhenHitEnterTest + */ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.IllegalComponentStateException; +import java.awt.List; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyEvent; + +public class ActionEventWhenHitEnterTest + implements ActionListener, ItemListener { + + volatile boolean passed1; + volatile boolean passed2; + volatile Point pt; + List list; + Frame frame; + + public static void main(final String[] args) throws Exception { + ActionEventWhenHitEnterTest app = new ActionEventWhenHitEnterTest(); + app.doTest(); + } + + public ActionEventWhenHitEnterTest() { + list = new List(7); + for (int i = 0; i < 10; i++) { + list.add("Item " + i); + } + list.addItemListener(this); + list.addActionListener(this); + } + + public void actionPerformed(ActionEvent ae) { + passed1 = true; + System.out.println("--> Action event invoked: " + ae.getSource()); + } + + public void itemStateChanged(ItemEvent ie) { + passed2 = true; + System.out.println("--> Item state changed:" + ie.getSource()); + } + + public void doTest() throws Exception { + EventQueue.invokeAndWait(() -> { + frame = new Frame("ActionEventWhenHitEnterTest"); + frame.add(list); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + try { + Robot robot = new Robot(); + robot.setAutoDelay(100); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + pt = list.getLocationOnScreen(); + }); + + if (pt.x != 0 || pt.y != 0) { + robot.mouseMove(pt.x + list.getWidth() / 2, + pt.y + list.getHeight() / 2); + robot.waitForIdle(); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + } + + robot.waitForIdle(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + + if (!passed1 || !passed2) { + throw new RuntimeException("ActionEventWhenHitEnterTest FAILED"); + } + System.out.println("Test PASSED"); + + } + +} diff --git a/test/jdk/java/awt/List/ListAddPerfTest.java b/test/jdk/java/awt/List/ListAddPerfTest.java new file mode 100644 index 0000000000000..7ff3eaf882c62 --- /dev/null +++ b/test/jdk/java/awt/List/ListAddPerfTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4117288 + * @summary JDKversion1.2beta3-J List's add() method is much slower. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ListAddPerfTest + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Frame; +import java.awt.List; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class ListAddPerfTest { + + static Button button; + static List list; + + private static final String INSTRUCTIONS = """ + It is used to check the performance of List add operation. + + Instructions: + Click on the Remove All button. + The list should be cleared. + The button is now named "Add Items". + Click on the "Add Items" button. + 800 items should be added to the list. + Notice not only how fast or slow this is, but also how + 'smooth' it goes as well i.e. without any flashing. + + Press pass if the list performance is acceptable."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("ListAddPerfTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int)INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(ListAddPerfTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Frame frame = new Frame("ListAddPerfTest"); + frame.setLayout(new BorderLayout()); + + button = new Button("Remove All"); + button.addActionListener((ActionEvent e) -> { + if (list.getItemCount() > 0) { + list.removeAll(); + list.invalidate(); + button.setLabel("Add Items"); + } else { + for (int i = 0; i < 800; i ++) { + list.add("My number is " + i); + } + button.setLabel("Remove All"); + } + }); + + list = new List(15); + for (int i = 0; i < 800; i ++) { + list.add("My number is " + i); + } + + frame.add("North", button); + frame.add("South", list); + + frame.pack(); + return frame; + } +} diff --git a/test/jdk/java/awt/List/MouseDraggedOriginatedByScrollBarTest.java b/test/jdk/java/awt/List/MouseDraggedOriginatedByScrollBarTest.java new file mode 100644 index 0000000000000..600d38fe39380 --- /dev/null +++ b/test/jdk/java/awt/List/MouseDraggedOriginatedByScrollBarTest.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6240151 + * @summary XToolkit: Dragging the List scrollbar initiates DnD + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MouseDraggedOriginatedByScrollBarTest +*/ + +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.List; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class MouseDraggedOriginatedByScrollBarTest { + + private static final String INSTRUCTIONS = """ + 1) Click and drag the scrollbar of the list. + 2) Keep dragging till the mouse pointer goes out the scrollbar. + 3) The test failed if you see messages about events. The test passed if you don't."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("MouseDraggedOriginatedByScrollBarTest Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(MouseDraggedOriginatedByScrollBarTest::createTestUI) + .logArea() + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Frame frame = new Frame(); + List list = new List(4, false); + + list.add("000"); + list.add("111"); + list.add("222"); + list.add("333"); + list.add("444"); + list.add("555"); + list.add("666"); + list.add("777"); + list.add("888"); + list.add("999"); + + frame.add(list); + + list.addMouseMotionListener( + new MouseMotionAdapter(){ + @Override + public void mouseDragged(MouseEvent me){ + PassFailJFrame.log(me.toString()); + } + }); + + list.addMouseListener( + new MouseAdapter() { + public void mousePressed(MouseEvent me) { + PassFailJFrame.log(me.toString()); + } + + public void mouseReleased(MouseEvent me) { + PassFailJFrame.log(me.toString()); + } + + public void mouseClicked(MouseEvent me){ + PassFailJFrame.log(me.toString()); + } + }); + + frame.setLayout(new FlowLayout()); + frame.pack(); + return frame; + } +} diff --git a/test/jdk/java/awt/Window/bug4189244.java b/test/jdk/java/awt/Window/bug4189244.java new file mode 100644 index 0000000000000..df37d2fce0e2b --- /dev/null +++ b/test/jdk/java/awt/Window/bug4189244.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4189244 + * @summary Swing Popup menu is not being refreshed (cleared) under a Dialog + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @requires (os.family == "windows") + * @run main/manual bug4189244 +*/ + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; + +public class bug4189244 { + + private static final String INSTRUCTIONS = """ + This is Windows only test! + + Click right button on frame to show popup menu. + (menu should be placed inside frame otherwise bug is not reproducible) + click on any menu item (dialog will be shown). + close dialog. + if you see part of popupmenu, under dialog, before it is closed, + then test failed, else passed."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("bug4189244 Instructions") + .instructions(INSTRUCTIONS) + .rows((int)INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(bug4189244::createTestUI) + .build() + .awaitAndCheck(); + } + + + private static JFrame createTestUI() { + RefreshBug panel = new RefreshBug(); + JFrame frame = new JFrame("Popup refresh bug"); + + frame.add(panel, BorderLayout.CENTER); + panel.init(); + frame.setSize(400, 400); + return frame; + } +} + +class RefreshBug extends JPanel implements ActionListener { + JPopupMenu _jPopupMenu = new JPopupMenu(); + + public void init() { + JMenuItem menuItem; + JButton jb = new JButton("Bring the popup here and select an item"); + + this.add(jb, BorderLayout.CENTER); + + for(int i = 1; i < 10; i++) { + menuItem = new JMenuItem("Item " + i); + menuItem.addActionListener(this); + _jPopupMenu.add(menuItem); + } + + MouseListener ml = new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + if (e.isPopupTrigger()) { + _jPopupMenu.show(e.getComponent(), + e.getX(), e.getY()); + } + } + }; + this.addMouseListener(ml); + + jb.addMouseListener(ml); + + } + + // An action is requested by the user + public void actionPerformed(java.awt.event.ActionEvent e) { + JOptionPane.showMessageDialog(this, + "Check if there is some popup left under me\n"+ + "if not, retry and let the popup appear where i am", + "WARNING", + JOptionPane.WARNING_MESSAGE); + + } +} From 7b61a783e9177cf67126ac5e08c6b621f410d911 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 11:05:49 +0000 Subject: [PATCH 248/846] 8347019: Test javax/swing/JRadioButton/8033699/bug8033699.java still fails: Focus is not on Radio Button Single as Expected Backport-of: 342dec93f22193309aa8865df95eb19d659b082c --- test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java b/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java index 699338c4b30f5..30d83a0538eb7 100644 --- a/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java +++ b/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, 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 @@ -63,7 +63,6 @@ public static void main(String[] args) throws Throwable { }); robot = new Robot(); - robot.setAutoDelay(100); robot.waitForIdle(); robot.delay(1000); From 3aeaf86b00aaa6685f3ddd312ceaa74036c53d21 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 11:07:29 +0000 Subject: [PATCH 249/846] 8249831: Test sun/security/mscapi/nonUniqueAliases/NonUniqueAliases.java is marked with @ignore Backport-of: c5ac3c4f11e777b24d597deec522c9df09750f59 --- .../nonUniqueAliases/NonUniqueAliases.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/test/jdk/sun/security/mscapi/nonUniqueAliases/NonUniqueAliases.java b/test/jdk/sun/security/mscapi/nonUniqueAliases/NonUniqueAliases.java index b78ade34eae3d..9384ac4b1311b 100644 --- a/test/jdk/sun/security/mscapi/nonUniqueAliases/NonUniqueAliases.java +++ b/test/jdk/sun/security/mscapi/nonUniqueAliases/NonUniqueAliases.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, 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 @@ -27,20 +27,32 @@ * @requires os.family == "windows" * @library /test/lib * @summary Test "keytool -list" displays correctly same named certificates - * @ignore Uses certutil.exe that isn't guaranteed to be installed */ import jdk.test.lib.process.ProcessTools; +import java.io.IOException; import java.security.KeyStore; import java.util.Collections; +import jtreg.SkippedException; public class NonUniqueAliases { public static void main(String[] args) throws Throwable { - try { - String testSrc = System.getProperty("test.src", "."); + runTest(); + } catch (IOException ex) { + // It uses certutil.exe that isn't guaranteed to be installed + String certutilMsg = "Cannot run program \"certutil\""; + if (ex.getMessage().contains(certutilMsg)) { + throw new SkippedException("certutil is not installed"); + } + throw ex; + } + } + private static void runTest() throws Exception { + String testSrc = System.getProperty("test.src", "."); + try { // removing the alias NonUniqueName if it already exists ProcessTools.executeCommand("certutil", "-user", "-delstore", "MY", "NonUniqueName"); From 4c50e1758f78f3fcca0f8e15f4efe36c7d268574 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 11:08:44 +0000 Subject: [PATCH 250/846] 8348865: JButton/bug4796987.java never runs because Windows XP is unavailable Backport-of: 650d0d954ea8e20e31f17d459993d5edecf08a4c --- .../swing/JButton/4796987/bug4796987.java | 104 +++++++++++------- 1 file changed, 67 insertions(+), 37 deletions(-) diff --git a/test/jdk/javax/swing/JButton/4796987/bug4796987.java b/test/jdk/javax/swing/JButton/4796987/bug4796987.java index 62d11fc18c08b..bfa6ef8d129ef 100644 --- a/test/jdk/javax/swing/JButton/4796987/bug4796987.java +++ b/test/jdk/javax/swing/JButton/4796987/bug4796987.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 @@ -26,67 +26,91 @@ * @bug 4796987 * @key headful * @requires (os.family == "windows") - * @summary XP Only: JButton.setBorderPainted() does not work with XP L&F - * @author Alexander Scherbatiy + * @summary Verify JButton.setBorderPainted(false) removes border + * for Windows visual styles (Windows XP and later) * @library ../../regtesthelpers - * @library /test/lib - * @modules java.desktop/com.sun.java.swing.plaf.windows - * java.desktop/sun.awt - * @build jdk.test.lib.OSVersion jdk.test.lib.Platform * @build Util * @run main bug4796987 */ -import jdk.test.lib.Platform; -import jdk.test.lib.OSVersion; -import java.awt.*; -import javax.swing.*; -import com.sun.java.swing.plaf.windows.WindowsLookAndFeel; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; public class bug4796987 { private static JButton button1; private static JButton button2; private static JFrame frame; + private static JPanel panel; public static void main(String[] args) throws Exception { try { - if (Platform.isWindows() - && OSVersion.current().equals(OSVersion.WINDOWS_XP)) { - UIManager.setLookAndFeel(new WindowsLookAndFeel()); - testButtonBorder(); - } + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + testButtonBorder(); } finally { - if (frame != null) SwingUtilities.invokeAndWait(() -> frame.dispose()); + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); } } private static void testButtonBorder() throws Exception { Robot robot = new Robot(); - robot.setAutoDelay(50); - SwingUtilities.invokeAndWait(new Runnable() { - - public void run() { - createAndShowGUI(); - } - }); + SwingUtilities.invokeAndWait(bug4796987::createAndShowGUI); + robot.waitForIdle(); + robot.delay(500); + // Hover over button1 + Point b1Center = Util.getCenterPoint(button1); + robot.mouseMove(b1Center.x, b1Center.y); robot.waitForIdle(); - Thread.sleep(500); - Point p1 = Util.getCenterPoint(button1); - Point p2 = Util.getCenterPoint(button2); + Rectangle panelBounds = Util.invokeOnEDT(() -> + new Rectangle(panel.getLocationOnScreen(), + panel.getSize())); + BufferedImage image = robot.createScreenCapture(panelBounds); + + final Point p1 = Util.invokeOnEDT(() -> getCenterPoint(button1)); + final Point p2 = Util.invokeOnEDT(() -> getCenterPoint(button2)); - Color color = robot.getPixelColor(p1.x, p2.x); - for (int dx = p1.x; dx < p2.x - p1.x; dx++) { - robot.mouseMove(p1.x + dx, p1.y); - if (!color.equals(robot.getPixelColor(p1.x + dx, p1.y))) { + final int color = image.getRGB(p1.x, p1.y); + for (int dx = 0; p1.x + dx < p2.x; dx++) { + if (color != image.getRGB(p1.x + dx, p1.y)) { + System.err.println("Wrong color at " + (p1.x + dx) + ", " + p1.y + + " - expected " + Integer.toHexString(color)); + saveImage(image); throw new RuntimeException("Button has border and background!"); } } } + /** + * {@return the center point of a button relative to its parent} + * @param button the button to calculate the center point + */ + private static Point getCenterPoint(JButton button) { + Point location = button.getLocation(); + Dimension size = button.getSize(); + location.translate(size.width / 2, size.height / 2); + return location; + } + private static JButton getButton() { JButton button = new JButton(); button.setBorderPainted(false); @@ -95,18 +119,24 @@ private static JButton getButton() { } private static void createAndShowGUI() { - frame = new JFrame("Test"); + frame = new JFrame("bug4796987"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(200, 200); - JButton button = new JButton(); - button.setBorder(null); - - JPanel panel = new JPanel(new BorderLayout(50, 50)); + panel = new JPanel(new BorderLayout(50, 50)); panel.add(getButton(), BorderLayout.CENTER); panel.add(button1 = getButton(), BorderLayout.WEST); panel.add(button2 = getButton(), BorderLayout.EAST); frame.getContentPane().add(panel); + frame.setLocationRelativeTo(null); frame.setVisible(true); } + + private static void saveImage(BufferedImage image) { + try { + ImageIO.write(image, "png", + new File("frame.png")); + } catch (IOException ignored) { + } + } } From 4e011ef165025c3369e4654a9ace503a4e1e1b87 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 8 May 2025 11:11:23 +0000 Subject: [PATCH 251/846] 8350498: Remove two Camerfirma root CA certificates Reviewed-by: mbaesken Backport-of: 1313349a2efd42ab84a543dfee11e3547f6ef4a3 --- .../data/cacerts/camerfirmachamberscommerceca | 35 ----------- make/data/cacerts/camerfirmachambersignca | 48 -------------- .../validator/CamerfirmaTLSPolicy.java | 30 +++------ .../security/lib/cacerts/VerifyCACerts.java | 10 +-- .../distrust/Camerfirma.java | 24 +++---- .../camerfirmachamberscommerceca-chain.pem | 48 -------------- .../camerfirmachambersignca-chain.pem | 62 ------------------- 7 files changed, 24 insertions(+), 233 deletions(-) delete mode 100644 make/data/cacerts/camerfirmachamberscommerceca delete mode 100644 make/data/cacerts/camerfirmachambersignca delete mode 100644 test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachamberscommerceca-chain.pem delete mode 100644 test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachambersignca-chain.pem diff --git a/make/data/cacerts/camerfirmachamberscommerceca b/make/data/cacerts/camerfirmachamberscommerceca deleted file mode 100644 index b92255f770cdf..0000000000000 --- a/make/data/cacerts/camerfirmachamberscommerceca +++ /dev/null @@ -1,35 +0,0 @@ -Owner: CN=Chambers of Commerce Root, OU=http://www.chambersign.org, O=AC Camerfirma SA CIF A82743287, C=EU -Issuer: CN=Chambers of Commerce Root, OU=http://www.chambersign.org, O=AC Camerfirma SA CIF A82743287, C=EU -Serial number: 0 -Valid from: Tue Sep 30 16:13:43 GMT 2003 until: Wed Sep 30 16:13:44 GMT 2037 -Signature algorithm name: SHA1withRSA -Subject Public Key Algorithm: 2048-bit RSA key -Version: 3 ------BEGIN CERTIFICATE----- -MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn -MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL -ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg -b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa -MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB -ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw -IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B -AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb -unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d -BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq -7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3 -0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX -roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG -A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j -aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p -26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA -BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud -EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN -BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz -aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB -AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd -p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi -1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc -XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0 -eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu -tGWaIZDgqtCYvDi1czyL+Nw= ------END CERTIFICATE----- diff --git a/make/data/cacerts/camerfirmachambersignca b/make/data/cacerts/camerfirmachambersignca deleted file mode 100644 index 935eea9c2121e..0000000000000 --- a/make/data/cacerts/camerfirmachambersignca +++ /dev/null @@ -1,48 +0,0 @@ -Owner: CN=Global Chambersign Root - 2008, O=AC Camerfirma S.A., SERIALNUMBER=A82743287, L=Madrid (see current address at www.camerfirma.com/address), C=EU -Issuer: CN=Global Chambersign Root - 2008, O=AC Camerfirma S.A., SERIALNUMBER=A82743287, L=Madrid (see current address at www.camerfirma.com/address), C=EU -Serial number: c9cdd3e9d57d23ce -Valid from: Fri Aug 01 12:31:40 GMT 2008 until: Sat Jul 31 12:31:40 GMT 2038 -Signature algorithm name: SHA1withRSA -Subject Public Key Algorithm: 4096-bit RSA key -Version: 3 ------BEGIN CERTIFICATE----- -MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD -VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 -IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 -MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD -aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx -MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy -cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG -A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl -BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI -hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed -KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 -G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 -zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 -ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG -HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 -Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V -yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e -beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r -6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh -wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog -zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW -BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr -ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp -ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk -cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt -YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC -CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow -KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI -hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ -UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz -X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x -fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz -a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd -Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd -SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O -AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso -M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge -v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z -09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B ------END CERTIFICATE----- diff --git a/src/java.base/share/classes/sun/security/validator/CamerfirmaTLSPolicy.java b/src/java.base/share/classes/sun/security/validator/CamerfirmaTLSPolicy.java index 591a7a26c6893..984f5a0ab47f9 100644 --- a/src/java.base/share/classes/sun/security/validator/CamerfirmaTLSPolicy.java +++ b/src/java.base/share/classes/sun/security/validator/CamerfirmaTLSPolicy.java @@ -43,26 +43,14 @@ final class CamerfirmaTLSPolicy { private static final Debug debug = Debug.getInstance("certpath"); - // SHA-256 certificate fingerprints of distrusted roots - private static final Set FINGERPRINTS = Set.of( - // cacerts alias: camerfirmachamberscommerceca - // DN: CN=Chambers of Commerce Root, - // OU=http://www.chambersign.org, - // O=AC Camerfirma SA CIF A82743287, C=EU - "0C258A12A5674AEF25F28BA7DCFAECEEA348E541E6F5CC4EE63B71B361606AC3", - // cacerts alias: camerfirmachambersca - // DN: CN=Chambers of Commerce Root - 2008, - // O=AC Camerfirma S.A., SERIALNUMBER=A82743287, - // L=Madrid (see current address at www.camerfirma.com/address), - // C=EU - "063E4AFAC491DFD332F3089B8542E94617D893D7FE944E10A7937EE29D9693C0", - // cacerts alias: camerfirmachambersignca - // DN: CN=Global Chambersign Root - 2008, - // O=AC Camerfirma S.A., SERIALNUMBER=A82743287, - // L=Madrid (see current address at www.camerfirma.com/address), - // C=EU - "136335439334A7698016A0D324DE72284E079D7B5220BB8FBD747816EEBEBACA" - ); + // SHA-256 certificate fingerprint of distrusted root for TLS + // cacerts alias: camerfirmachambersca + // DN: CN=Chambers of Commerce Root - 2008, + // O=AC Camerfirma S.A., SERIALNUMBER=A82743287, + // L=Madrid (see current address at www.camerfirma.com/address), + // C=EU + private static final String FINGERPRINT = + "063E4AFAC491DFD332F3089B8542E94617D893D7FE944E10A7937EE29D9693C0"; // Any TLS Server certificate that is anchored by one of the Camerfirma // roots above and is issued after this date will be distrusted. @@ -85,7 +73,7 @@ static void checkDistrust(X509Certificate[] chain) throw new ValidatorException("Cannot generate fingerprint for " + "trust anchor of TLS server certificate"); } - if (FINGERPRINTS.contains(fp)) { + if (FINGERPRINT.equalsIgnoreCase(fp)) { Date notBefore = chain[0].getNotBefore(); LocalDate ldNotBefore = LocalDate.ofInstant(notBefore.toInstant(), ZoneOffset.UTC); diff --git a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java index 0ebb8248b0308..434df6e013e35 100644 --- a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java +++ b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java @@ -28,7 +28,7 @@ * 8223499 8225392 8232019 8234245 8233223 8225068 8225069 8243321 8243320 * 8243559 8225072 8258630 8259312 8256421 8225081 8225082 8225083 8245654 * 8305975 8304760 8307134 8295894 8314960 8317373 8317374 8318759 8319187 - * 8321408 8316138 8341057 8303770 + * 8321408 8316138 8341057 8303770 8350498 * @summary Check root CA entries in cacerts file */ import java.io.ByteArrayInputStream; @@ -47,12 +47,12 @@ public class VerifyCACerts { + File.separator + "security" + File.separator + "cacerts"; // The numbers of certs now. - private static final int COUNT = 111; + private static final int COUNT = 109; // SHA-256 of cacerts, can be generated with // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95 private static final String CHECKSUM - = "B7:60:5A:7A:01:0A:9F:47:E3:46:B9:30:E1:FC:A2:71:69:58:76:CB:8C:85:2B:FF:1A:D5:92:71:AF:F5:60:8F"; + = "07:21:E0:F8:EA:55:CC:93:24:2E:74:07:4B:6B:CE:F3:81:C3:BB:47:5B:85:A2:F1:9E:44:CD:C0:99:55:D7:5F"; // Hex formatter to upper case with ":" delimiter private static final HexFormat HEX = HexFormat.ofDelimiter(":").withUpperCase(); @@ -69,10 +69,6 @@ public class VerifyCACerts { "ED:F7:EB:BC:A2:7A:2A:38:4D:38:7B:7D:40:10:C6:66:E2:ED:B4:84:3E:4C:29:B4:AE:1D:5B:93:32:E6:B2:4D"); put("camerfirmachambersca [jdk]", "06:3E:4A:FA:C4:91:DF:D3:32:F3:08:9B:85:42:E9:46:17:D8:93:D7:FE:94:4E:10:A7:93:7E:E2:9D:96:93:C0"); - put("camerfirmachambersignca [jdk]", - "13:63:35:43:93:34:A7:69:80:16:A0:D3:24:DE:72:28:4E:07:9D:7B:52:20:BB:8F:BD:74:78:16:EE:BE:BA:CA"); - put("camerfirmachamberscommerceca [jdk]", - "0C:25:8A:12:A5:67:4A:EF:25:F2:8B:A7:DC:FA:EC:EE:A3:48:E5:41:E6:F5:CC:4E:E6:3B:71:B3:61:60:6A:C3"); put("certumca [jdk]", "D8:E0:FE:BC:1D:B2:E3:8D:00:94:0F:37:D2:7D:41:34:4D:99:3E:73:4B:99:D5:65:6D:97:78:D4:D8:14:36:24"); put("certumtrustednetworkca [jdk]", diff --git a/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/Camerfirma.java b/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/Camerfirma.java index 50a723441a519..8d9dfe1ef18f5 100644 --- a/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/Camerfirma.java +++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/Camerfirma.java @@ -21,17 +21,19 @@ * questions. */ +import javax.net.ssl.X509TrustManager; import java.io.File; import java.security.Security; -import java.time.*; -import java.util.*; -import javax.net.ssl.*; +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.Date; -/** +/* * @test - * @bug 8346587 + * @bug 8346587 8350498 * @summary Check that TLS Server certificates chaining back to distrusted - * Camerfirma roots are invalid + * Camerfirma root are invalid * @library /test/lib * @modules java.base/sun.security.validator * @run main/othervm Camerfirma after policyOn invalid @@ -42,13 +44,11 @@ public class Camerfirma { - private static final String certPath = "chains" + File.separator + "camerfirma"; + private static final String CERT_PATH = "chains" + File.separator + "camerfirma"; // Each of the roots have a test certificate chain stored in a file // named "-chain.pem". - private static String[] rootsToTest = new String[] { - "camerfirmachamberscommerceca", "camerfirmachambersca", - "camerfirmachambersignca"}; + private static final String ROOT_TO_TEST = "camerfirmachambersca"; // Date after the restrictions take effect private static final ZonedDateTime DISTRUST_DATE = @@ -56,7 +56,7 @@ public class Camerfirma { public static void main(String[] args) throws Exception { - // All of the test certificates are signed with SHA-1 so we need + // All the test certificates are signed with SHA-1, so we need // to remove the constraint that disallows SHA-1 certificates. String prop = Security.getProperty("jdk.certpath.disabledAlgorithms"); String newProp = prop.replace(", SHA1 jdkCA & usage TLSServer", ""); @@ -70,6 +70,6 @@ public static void main(String[] args) throws Exception { }; Date notBefore = distrust.getNotBefore(DISTRUST_DATE); - distrust.testCertificateChain(certPath, notBefore, tms, rootsToTest); + distrust.testCertificateChain(CERT_PATH, notBefore, tms, ROOT_TO_TEST); } } diff --git a/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachamberscommerceca-chain.pem b/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachamberscommerceca-chain.pem deleted file mode 100644 index b27d46c17c8cf..0000000000000 --- a/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachamberscommerceca-chain.pem +++ /dev/null @@ -1,48 +0,0 @@ -Owner: CN=AC Camerfirma Certificados Camerales, - O=AC Camerfirma SA, SERIALNUMBER=A82743287, - L=Madrid (see current address at www.camerfirma.com/address), - EMAILADDRESS=ac_camerfirma_cc@camerfirma.com, C=ES -Issuer: CN=Chambers of Commerce Root, OU=http://www.chambersign.org, - O=AC Camerfirma SA CIF A82743287, C=EU -Serial number: 5 -Valid from: Mon Feb 09 07:42:47 PST 2004 until: Thu Feb 09 07:42:47 PST 2034 -Certificate fingerprints: - SHA1: 9F:36:B4:BE:9D:AF:1C:91:01:B2:D7:61:58:FB:95:CB:53:82:01:10 - SHA256: C7:D8:43:81:E1:1F:7C:57:46:77:1A:F5:B0:50:DC:51:FC:6F:DA:D6:F6:F3:5B:B5:3A:3D:E9:13:82:2E:A0:9E -Signature algorithm name: SHA1withRSA (weak) -Subject Public Key Algorithm: 2048-bit RSA key -Version: 3 - ------BEGIN CERTIFICATE----- -MIIFwDCCBKigAwIBAgIBBTANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn -MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL -ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg -b2YgQ29tbWVyY2UgUm9vdDAeFw0wNDAyMDkxNTQyNDdaFw0zNDAyMDkxNTQyNDda -MIHgMQswCQYDVQQGEwJFUzEuMCwGCSqGSIb3DQEJARYfYWNfY2FtZXJmaXJtYV9j -Y0BjYW1lcmZpcm1hLmNvbTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBh -ZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ -QTgyNzQzMjg3MRkwFwYDVQQKExBBQyBDYW1lcmZpcm1hIFNBMS0wKwYDVQQDEyRB -QyBDYW1lcmZpcm1hIENlcnRpZmljYWRvcyBDYW1lcmFsZXMwggEgMA0GCSqGSIb3 -DQEBAQUAA4IBDQAwggEIAoIBAQCjxnvvj01f36lgGhihRYVf1fAPEXsTJKrY4aLQ -cEUSh5szZE7VTtGiyMTMc2uCmnaXafjYHK8Lgmy6T9xxGEZ5OS4x6rgtuPyy13AP -tu3X3Y2kPVLu7ZMw5HoQC64wBj6YcnxTnBwmVW05DjzRXp6OyBIEKEaAB9vv2qEl -fh/Y234FG6Wd/ut1s0ScRZAo+6CSMNQxaY+ryXKD11uWkzWXJa9UZOasG7z4uPqc -Gr4/Hz2/CTLDTgp0xkMJYuzOztpUvOACrxlkS2utKUwVlAikJnboNwf/en94RbHN -zkKc5t0SAbzCf57ueawbzxSdPa+SAC25FNur64FKkfdq5PPjAgEDo4IB5TCCAeEw -EgYDVR0TAQH/BAgwBgEB/wIBCzA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vY3Js -LmNoYW1iZXJzaWduLm9yZy9jaGFtYmVyc3Jvb3QuY3JsMB0GA1UdDgQWBBS2H06d -HGiRLjdyYOFGj1qlKjExuTCBqwYDVR0jBIGjMIGggBTjlPWxTenboSlbV4tNdgZ2 -4dGiiqGBhKSBgTB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt -YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJz -aWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdIIBADAO -BgNVHQ8BAf8EBAMCAYYwKgYDVR0RBCMwIYEfYWNfY2FtZXJmaXJtYV9jY0BjYW1l -cmZpcm1hLmNvbTAnBgNVHRIEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24u -b3JnMFsGA1UdIARUMFIwUAYLKwYBBAGBhy4KCQEwQTA/BggrBgEFBQcCARYzaHR0 -cDovL2Nwcy5jYW1lcmZpcm1hLmNvbS9jcHMvYWNfY2FtZXJmaXJtYV9jYy5odG1s -MA0GCSqGSIb3DQEBBQUAA4IBAQBl8KoPBYL//EBonqQWS0N+hLfxImP1eQ6nac+v -R5QfF/0w+VCTkShfKwHaa6V/W1dPlVwXSECuvXHkX6DYrtxFGGFB6qxuP1rkIpRs -sTkAlpvOx3REiFjIkhsijKd/ijvqxjbMbuYU+EFACK/jQIRoj+LEEZ+haiqbALZB -Iqq/26HTqX0itDosBj6M94YWcIpbTDefQNWCGsSnZcw2+k+az/wAOZT6xAxlnEim -HpDDlgRsmaLrHpDPDoIRYOih0gbJTnn4mKex9Wgr0sZ+XFl03j+bvcXL1tiuQnwb -9dMRDe/OdXABT35W4ZzLbpost65ZW3Tx+oi/bLbmu6pbKCgs ------END CERTIFICATE----- diff --git a/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachambersignca-chain.pem b/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachambersignca-chain.pem deleted file mode 100644 index 2ab3091439cb9..0000000000000 --- a/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachambersignca-chain.pem +++ /dev/null @@ -1,62 +0,0 @@ -Owner: CN=AC Camerfirma - 2009, - L=Madrid (see current address at https://www.camerfirma.com/address), - SERIALNUMBER=A82743287, O=AC Camerfirma S.A., C=ES -Issuer: CN=Global Chambersign Root - 2008, - O=AC Camerfirma S.A., SERIALNUMBER=A82743287, - L=Madrid (see current address at www.camerfirma.com/address), C=EU -Serial number: 2 -Valid from: Mon Mar 16 10:16:25 PDT 2009 until: Sun Mar 11 10:16:25 PDT 2029 -Certificate fingerprints: - SHA1: BA:BA:69:CF:D5:CC:C9:4D:05:6B:5B:E7:80:5F:E2:03:CB:EB:5C:57 - SHA256: B6:8D:5D:9B:4E:A6:35:95:7C:0C:32:15:C2:0D:35:B2:21:7B:69:E3:49:C7:A3:04:C4:F9:7F:20:C4:08:1F:88 -Signature algorithm name: SHA1withRSA (weak) -Subject Public Key Algorithm: 4096-bit RSA key -Version: 3 - ------BEGIN CERTIFICATE----- -MIIIPzCCBiegAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBrDELMAkGA1UEBhMCRVUx -QzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2Ft -ZXJmaXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UE -ChMSQUMgQ2FtZXJmaXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNp -Z24gUm9vdCAtIDIwMDgwHhcNMDkwMzE2MTcxNjI1WhcNMjkwMzExMTcxNjI1WjCB -qjELMAkGA1UEBhMCRVMxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjESMBAG -A1UEBRMJQTgyNzQzMjg3MUswSQYDVQQHE0JNYWRyaWQgKHNlZSBjdXJyZW50IGFk -ZHJlc3MgYXQgaHR0cHM6Ly93d3cuY2FtZXJmaXJtYS5jb20vYWRkcmVzcykxHTAb -BgNVBAMTFEFDIENhbWVyZmlybWEgLSAyMDA5MIICIjANBgkqhkiG9w0BAQEFAAOC -Ag8AMIICCgKCAgEAmbHxFEYTJmMdPcYiPlWUGZu2+tQo4voohYi3dwCwoVuGdHSp -kyoqs1B3YGx4u5KT4n0A7+Bb8YQ/QzbNy7UQ4JXAK+rT8JpNeKIvfN4lHnQJaChE -4fdn0KpvHWymaNq2k+EbQClquZB6OsTLvsivwSuSnyLcUw5rbajj53wq77fwB12y -phMjwz2AnD1BvHZd3vLOaH1jRQP3zzNmyjT/Oj6+jdux7SBKlJWgQEaKflwcvYyc -DPFPhGM4KPwEGX61PCrS+l8Lw0Kdy6K4lE+GrfgJrXM5m1Ey1R0c9McYQQPAtYcm -cOnHHgkJdEAFVDa76T9C+lcMP6DNckbJIyc/ENrmM2v4rq/JnsJKEEx0VLyLizQx -cGU3gp4ckg0ImQ9hV3H/DLWEqfrPuD++zaV81gpstnc9+pLg0Jibvwg3qvIr7nS5 -acc//qqxH0iJGYoStHW5J5HoM9HcBvhACq5rjzjrNLPYSJqbPJwBHKcql/uUjQ6S -SVWe3/CeJp6/vGuY1aRXAk9c/8oO0ZDrLKE8LsUgZesTLnWGd1LQcyQf6UMG1nb9 -5C3eZRkCVpKma6Hl/SUQNukerlbLOU9InFGNPdeEVq1Jo62XeEi8KMbTPdXou6Yl -rpe99dFnOUjVOdY7gfBGSgIVJjORqf/V70jwsxcYz7j6PKl0XulJs06vpSECAwEA -AaOCAmowggJmMBIGA1UdEwEB/wQIMAYBAf8CAQIwHQYDVR0OBBYEFMgAD/zGUvyf -2ztkLjK5bi5x82V5MIHhBgNVHSMEgdkwgdaAFLkJypwe29NsOmuu7VTxW5MGNS5e -oYGypIGvMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy -cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG -A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl -BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwOIIJAMnN0+nVfSPO -MH0GCCsGAQUFBwEBBHEwbzBFBggrBgEFBQcwAoY5aHR0cDovL3d3dy5jYW1lcmZp -cm1hLmNvbS9jZXJ0cy9yb290X2NoYW1iZXJzaWduLTIwMDguY3J0MCYGCCsGAQUF -BzABhhpodHRwOi8vb2NzcC5jYW1lcmZpcm1hLmNvbTAOBgNVHQ8BAf8EBAMCAQYw -PgYDVR0gBDcwNTAzBgRVHSAAMCswKQYIKwYBBQUHAgEWHWh0dHBzOi8vcG9saWN5 -LmNhbWVyZmlybWEuY29tMH4GA1UdHwR3MHUwOKA2oDSGMmh0dHA6Ly9jcmwuY2Ft -ZXJmaXJtYS5jb20vY2hhbWJlcnNpZ25yb290LTIwMDguY3JsMDmgN6A1hjNodHRw -Oi8vY3JsMS5jYW1lcmZpcm1hLmNvbS9jaGFtYmVyc2lnbnJvb3QtMjAwOC5jcmww -DQYJKoZIhvcNAQEFBQADggIBABNYG4jBwoI7e8pCuUyDc6rwpE9H6AgrUdL7O1xK -TgTjDGBrMOBK+ZPS4Si8J3yZngvSrL694a1HmiiblJ+CmCdNGli2nBBM+OPK3tQB -4TW6hgkIe3vSNg/9o9y6+MAJcm8Kn0nPCBkSRME87NwvpehtekuF1G2ng1KDVwAn -F+eCXfNanEwY++vWbJAuPE69Z/0+rCgNyH1PzihiNu6vrUlSlLWKaG34O1DEttX+ -SsWTpEbpH9w5y9Vmw6WQ/B5nfhPM551HaMbiGgSxT9jHmf8APYQ3iT8EktcdTAdw -m1miiyxfKG+WjPT7P/x8Np1spJZw+sNIDTLdZ0T1XQ6obVkBTFUDSULKW8949HDu -VSwdl9Hu9lkDzzh9tyVYwwjEWVFZOiD/4TPVLfphf4ZEiyHt5YpNd9kZJIGGDxdc -CdtzPm2dQODFpv72LnPQHbuBQPJ71zkoAmyeM/1Qj0DlrFsPcYnbRasck1VmYgDc -Xc0+is0wcgCd7Gpx1zpEeVqwMD96am2xZPzd6nsbXvo+6TzsKLRMJo6nOERwrzuI -F+/eq3WXxYMt2UenJsHqwSgPJRMdl3SFz0+SZN0viHeLuwb7qaHN74qC6GP8yHGp -2xe6Z11mJDPLDSrQQ2dOceSJ1LurJgLP7amYmFlWwVnmM7LnfShhMWMV+MDrICnL -2ksL ------END CERTIFICATE----- From 3a28a2982ee93918b37ddf06f1fe196e319f503d Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Fri, 9 May 2025 09:19:39 +0000 Subject: [PATCH 252/846] 8350386: Test TestCodeCacheFull.java fails with option -XX:-UseCodeCacheFlushing Backport-of: c2ba777e0b2524359b23481f2c31afdcd5568827 --- test/jdk/jdk/jfr/event/compiler/TestCodeCacheFull.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/jdk/jdk/jfr/event/compiler/TestCodeCacheFull.java b/test/jdk/jdk/jfr/event/compiler/TestCodeCacheFull.java index 70cdb7c31da05..13a473100c864 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCodeCacheFull.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCodeCacheFull.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 @@ -36,6 +36,7 @@ /** * @test TestCodeCacheFull * @requires vm.hasJFR + * @requires vm.opt.UseCodeCacheFlushing == null | vm.opt.UseCodeCacheFlushing == true * * @library /test/lib * @modules jdk.jfr From 4f7c12676f870c36a505b866122a1f2218f51fb9 Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Sat, 10 May 2025 03:09:38 +0000 Subject: [PATCH 253/846] 8312246: NPE when HSDB visits bad oop Backport-of: a7427678e160bf54c57d5bec80650b053dfc9e9a --- src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java index 02b6651235396..4788185f06425 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java @@ -1087,7 +1087,9 @@ public void addAnnotation(Address addr, OopHandle handle) { G1CollectedHeap heap = (G1CollectedHeap)collHeap; HeapRegion region = heap.hrm().getByAddress(handle); - if (region.isFree()) { + if (region == null) { + // intentionally skip + } else if (region.isFree()) { anno = "Free "; bad = false; } else if (region.isYoung()) { From c1cc227d6266421ecb6eab709bfa5abb0ab01ea8 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 12 May 2025 14:33:33 +0000 Subject: [PATCH 254/846] 4850101: Setting mnemonic to VK_F4 underlines the letter S in a button. Backport-of: d6961045353897967bb734740225bd1cddf158e5 --- .../classes/javax/swing/SwingUtilities.java | 4 + .../swing/JButton/TestMnemonicAction.java | 125 ++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 test/jdk/javax/swing/JButton/TestMnemonicAction.java diff --git a/src/java.desktop/share/classes/javax/swing/SwingUtilities.java b/src/java.desktop/share/classes/javax/swing/SwingUtilities.java index 7a8aa2e316e6e..63d78a7d0b26c 100644 --- a/src/java.desktop/share/classes/javax/swing/SwingUtilities.java +++ b/src/java.desktop/share/classes/javax/swing/SwingUtilities.java @@ -2073,6 +2073,10 @@ static int findDisplayedMnemonicIndex(String text, int mnemonic) { return -1; } + if (mnemonic >= 'a' && mnemonic <= 'z') { + return -1; + } + char uc = Character.toUpperCase((char)mnemonic); char lc = Character.toLowerCase((char)mnemonic); diff --git a/test/jdk/javax/swing/JButton/TestMnemonicAction.java b/test/jdk/javax/swing/JButton/TestMnemonicAction.java new file mode 100644 index 0000000000000..e2621f14541c3 --- /dev/null +++ b/test/jdk/javax/swing/JButton/TestMnemonicAction.java @@ -0,0 +1,125 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 + * @key headful + * @bug 4850101 + * @summary Verifies if Setting mnemonic to VK_F4 underlines the letter S. + * @run main TestMnemonicAction + */ + +import java.io.File; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class TestMnemonicAction { + private static JFrame f; + private static JButton b; + + public static boolean compareBufferedImages(BufferedImage bufferedImage0, + BufferedImage bufferedImage1) { + int width = bufferedImage0.getWidth(); + int height = bufferedImage0.getHeight(); + + if (width != bufferedImage1.getWidth() || height != bufferedImage1.getHeight()) { + return false; + } + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + if (bufferedImage0.getRGB(x, y) != bufferedImage1.getRGB(x, y)) { + return false; + } + } + } + + return true; + } + + public static void main(String[] args) throws Exception { + + SwingUtilities.invokeAndWait(() -> { + f = new JFrame(); + b = new JButton("Shutdown"); + b.setMnemonic(KeyEvent.VK_F4); + b.setPreferredSize(new Dimension(100, 25)); + b.setToolTipText("Shutdown"); + f.getContentPane().add(b); + f.setDefaultCloseOperation(f.EXIT_ON_CLOSE); + f.setUndecorated(true); + f.setLocationRelativeTo(null); + f.pack(); + f.setVisible(true); + }); + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + Point p = b.getLocationOnScreen(); + BufferedImage imgmnemonic = robot.createScreenCapture( + new Rectangle(p.x, p.y, b.getWidth(), b.getHeight())); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + SwingUtilities.invokeAndWait(() -> { + f = new JFrame(); + b = new JButton("Shutdown"); + b.setPreferredSize(new Dimension(100, 25)); + f.getContentPane().add(b); + f.setDefaultCloseOperation(f.EXIT_ON_CLOSE); + f.setUndecorated(true); + f.setLocationRelativeTo(null); + f.pack(); + f.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + p = b.getLocationOnScreen(); + BufferedImage buttonimage = robot.createScreenCapture( + new Rectangle(p.x, p.y, b.getWidth(), b.getHeight())); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + if (!compareBufferedImages(imgmnemonic, buttonimage)) { + ImageIO.write(imgmnemonic, "png", new File("imgmnemonic.png")); + ImageIO.write(buttonimage, "png", new File("buttonimage.png")); + throw new RuntimeException("F4 mnemonic underlines S"); + } + } +} + From e6cfd33e6e5c0db648a608a5db25942c6aef5d7c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 12 May 2025 14:58:30 +0000 Subject: [PATCH 255/846] 8294038: Remove "Classpath" exception from javax/swing tests Backport-of: 27b8e2f49e372e09e8f070e9c90babd82e015dbf --- test/jdk/javax/swing/JButton/TestMnemonicAction.java | 5 +---- test/jdk/javax/swing/JComboBox/6406264/bug6406264.java | 4 +--- test/jdk/javax/swing/JPopupMenu/6583251/bug6583251.java | 4 +--- test/jdk/javax/swing/JScrollPane/6274267/bug6274267.java | 4 +--- test/jdk/javax/swing/JToolBar/4529206/bug4529206.java | 4 +--- test/jdk/javax/swing/Popup/6514582/bug6514582.java | 4 +--- test/jdk/javax/swing/regtesthelpers/JRobot.java | 4 +--- test/jdk/javax/swing/regtesthelpers/SwingTestHelper.java | 4 +--- .../DocumentInsert/DocumentInsertAtWrongPositionTest.java | 4 +--- test/jdk/javax/swing/text/GapContent/4496801/bug4496801.java | 4 +--- .../swing/text/html/CSS/ColorValue/RGBColorValueTest.java | 4 +--- 11 files changed, 11 insertions(+), 34 deletions(-) diff --git a/test/jdk/javax/swing/JButton/TestMnemonicAction.java b/test/jdk/javax/swing/JButton/TestMnemonicAction.java index e2621f14541c3..b26e2a4933f87 100644 --- a/test/jdk/javax/swing/JButton/TestMnemonicAction.java +++ b/test/jdk/javax/swing/JButton/TestMnemonicAction.java @@ -4,9 +4,7 @@ * * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. + * 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 @@ -122,4 +120,3 @@ public static void main(String[] args) throws Exception { } } } - diff --git a/test/jdk/javax/swing/JComboBox/6406264/bug6406264.java b/test/jdk/javax/swing/JComboBox/6406264/bug6406264.java index 75de8c97e2eef..6435e81e2ac7a 100644 --- a/test/jdk/javax/swing/JComboBox/6406264/bug6406264.java +++ b/test/jdk/javax/swing/JComboBox/6406264/bug6406264.java @@ -4,9 +4,7 @@ * * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. + * 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 diff --git a/test/jdk/javax/swing/JPopupMenu/6583251/bug6583251.java b/test/jdk/javax/swing/JPopupMenu/6583251/bug6583251.java index e77b60ad33a65..cba687e9cbaea 100644 --- a/test/jdk/javax/swing/JPopupMenu/6583251/bug6583251.java +++ b/test/jdk/javax/swing/JPopupMenu/6583251/bug6583251.java @@ -4,9 +4,7 @@ * * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. + * 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 diff --git a/test/jdk/javax/swing/JScrollPane/6274267/bug6274267.java b/test/jdk/javax/swing/JScrollPane/6274267/bug6274267.java index a141c43ac2a11..5584cec126c84 100644 --- a/test/jdk/javax/swing/JScrollPane/6274267/bug6274267.java +++ b/test/jdk/javax/swing/JScrollPane/6274267/bug6274267.java @@ -4,9 +4,7 @@ * * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. + * 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 diff --git a/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java b/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java index 8756e79d061ca..8844254dba463 100644 --- a/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java +++ b/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java @@ -4,9 +4,7 @@ * * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. + * 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 diff --git a/test/jdk/javax/swing/Popup/6514582/bug6514582.java b/test/jdk/javax/swing/Popup/6514582/bug6514582.java index b2d5d57984fdf..a54bfe8d1f331 100644 --- a/test/jdk/javax/swing/Popup/6514582/bug6514582.java +++ b/test/jdk/javax/swing/Popup/6514582/bug6514582.java @@ -4,9 +4,7 @@ * * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. + * 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 diff --git a/test/jdk/javax/swing/regtesthelpers/JRobot.java b/test/jdk/javax/swing/regtesthelpers/JRobot.java index aba18c3535b6f..5c4c4cbcf4064 100644 --- a/test/jdk/javax/swing/regtesthelpers/JRobot.java +++ b/test/jdk/javax/swing/regtesthelpers/JRobot.java @@ -4,9 +4,7 @@ * * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. + * 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 diff --git a/test/jdk/javax/swing/regtesthelpers/SwingTestHelper.java b/test/jdk/javax/swing/regtesthelpers/SwingTestHelper.java index 5b6d35fa49a0a..8c10397c1fcd6 100644 --- a/test/jdk/javax/swing/regtesthelpers/SwingTestHelper.java +++ b/test/jdk/javax/swing/regtesthelpers/SwingTestHelper.java @@ -4,9 +4,7 @@ * * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. + * 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 diff --git a/test/jdk/javax/swing/text/AbstractDocument/DocumentInsert/DocumentInsertAtWrongPositionTest.java b/test/jdk/javax/swing/text/AbstractDocument/DocumentInsert/DocumentInsertAtWrongPositionTest.java index a6da38699c611..54b1de1a03a68 100644 --- a/test/jdk/javax/swing/text/AbstractDocument/DocumentInsert/DocumentInsertAtWrongPositionTest.java +++ b/test/jdk/javax/swing/text/AbstractDocument/DocumentInsert/DocumentInsertAtWrongPositionTest.java @@ -4,9 +4,7 @@ * * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. + * 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 diff --git a/test/jdk/javax/swing/text/GapContent/4496801/bug4496801.java b/test/jdk/javax/swing/text/GapContent/4496801/bug4496801.java index aa258a8dc8650..d0d425668a113 100644 --- a/test/jdk/javax/swing/text/GapContent/4496801/bug4496801.java +++ b/test/jdk/javax/swing/text/GapContent/4496801/bug4496801.java @@ -4,9 +4,7 @@ * * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. + * 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 diff --git a/test/jdk/javax/swing/text/html/CSS/ColorValue/RGBColorValueTest.java b/test/jdk/javax/swing/text/html/CSS/ColorValue/RGBColorValueTest.java index fce9408717dca..c3a563d42b54e 100644 --- a/test/jdk/javax/swing/text/html/CSS/ColorValue/RGBColorValueTest.java +++ b/test/jdk/javax/swing/text/html/CSS/ColorValue/RGBColorValueTest.java @@ -4,9 +4,7 @@ * * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. + * 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 From 41e2cccce18d9d358914aae127d5b55b43b8c8c5 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 12 May 2025 14:59:36 +0000 Subject: [PATCH 256/846] 8314246: javax/swing/JToolBar/4529206/bug4529206.java fails intermittently on Linux Backport-of: 808bb1f7bc5025b4ab01e4e9057feebd253b95a7 --- .../swing/JToolBar/4529206/bug4529206.java | 52 +++++++------------ 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java b/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java index 8844254dba463..ed4f062b24cc2 100644 --- a/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java +++ b/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -21,19 +21,9 @@ * questions. */ -/* - * @test - * @key headful - * @bug 4529206 - * @summary JToolBar - setFloating does not work correctly - * @run main bug4529206 - */ - import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Robot; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; @@ -41,6 +31,14 @@ import javax.swing.JToolBar; import javax.swing.SwingUtilities; +/* + * @test + * @key headful + * @bug 4529206 + * @summary JToolBar - setFloating does not work correctly + * @run main bug4529206 + */ + public class bug4529206 { static JFrame frame; static JToolBar jToolBar1; @@ -58,11 +56,7 @@ private static void test() { JTextField tf = new JTextField("click here"); jPanFrame.add(tf); jToolBar1.add(jButton1, null); - jButton1.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - buttonPressed(e); - } - }); + jButton1.addActionListener(e -> buttonPressed()); frame.setUndecorated(true); frame.setLocationRelativeTo(null); @@ -77,32 +71,24 @@ private static void makeToolbarFloat() { } } - private static void buttonPressed(ActionEvent e) { + private static void buttonPressed() { makeToolbarFloat(); } public static void main(String[] args) throws Exception { try { - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - test(); - } - }); + SwingUtilities.invokeAndWait(() -> test()); Robot robot = new Robot(); - robot.waitForIdle(); + robot.setAutoWaitForIdle(true); robot.delay(1000); - SwingUtilities.invokeAndWait(() -> { - makeToolbarFloat(); - }); + SwingUtilities.invokeAndWait(() -> makeToolbarFloat()); + robot.delay(300); - robot.waitForIdle(); - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - if (frame.isFocused()) { - throw - new RuntimeException("setFloating does not work correctly"); - } + SwingUtilities.invokeAndWait(() -> { + if (frame.isFocused()) { + throw + new RuntimeException("setFloating does not work correctly"); } }); } finally { From 05cc91a8e39acf973a61b02968a77e5d0a57cabb Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 12 May 2025 15:00:52 +0000 Subject: [PATCH 257/846] 8333117: Remove support of remote and manual debuggee launchers Reviewed-by: mbaesken Backport-of: 99e4d77aac72cdddb4973805d28c225f17ea965f --- .../vmTestbase/nsk/share/jdb/Debuggee.java | 115 +--- .../vmTestbase/nsk/share/jdb/Launcher.java | 116 +--- .../nsk/share/jdi/ArgumentHandler.java | 14 +- .../vmTestbase/nsk/share/jdi/Binder.java | 563 +----------------- .../vmTestbase/nsk/share/jdi/Debugee.java | 11 +- .../vmTestbase/nsk/share/jdwp/Binder.java | 343 +---------- .../vmTestbase/nsk/share/jdwp/Debugee.java | 10 +- .../share/jpda/DebugeeArgumentHandler.java | 73 +-- .../nsk/share/jpda/DebugeeBinder.java | 355 ----------- .../nsk/share/jpda/DebugeeProcess.java | 44 +- 10 files changed, 104 insertions(+), 1540 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Debuggee.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Debuggee.java index b0467a7e73ce7..f7472e2db035c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Debuggee.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Debuggee.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,55 +30,15 @@ import java.io.*; /** - * Interface defining methods to control mirror of debuggee (i.e. debugged VM). + * Class defining methods to control mirror of debuggee (i.e. debugged VM). */ -public interface Debuggee { +public class Debuggee extends LocalProcess { /** Default prefix for log messages. */ public static final String LOG_PREFIX = "debuggee> "; public static final String DEBUGEE_STDOUT_LOG_PREFIX = "debuggee.stdout> "; public static final String DEBUGEE_STDERR_LOG_PREFIX = "debuggee.stderr> "; - /** - * Launch debuggee. - * - * @throws IOException - */ - public void launch (String[] args) throws IOException; - - /** Return exit status. */ - public int getStatus (); - - /** Check whether the process has been terminated. */ - public boolean terminated(); - - /** Kill the debuggee VM. */ - public void killDebuggee (); - - /** Wait until the debuggee VM shutdown or crash. */ - public int waitForDebuggee () throws InterruptedException; - - /** Get a pipe to write to the debuggee's stdin stream. */ - public OutputStream getInPipe (); - - /** Get a pipe to read the debuggee's stdout stream. */ - public InputStream getOutPipe (); - - /** Get a pipe to read the debuggee's stderr stream. */ - public InputStream getErrPipe (); - - /** Redirect stdout stream to Log */ - public void redirectStdout(Log log, String prefix); - - /** Redirect stderr stream to Log */ - public void redirectStderr(Log log, String prefix); -} - -/** - * Mirror of locally launched debuggee. - */ -final class LocalLaunchedDebuggee extends LocalProcess implements Debuggee { - private IORedirector stdoutRedirector = null; private IORedirector stderrRedirector = null; private IORedirector stdinRedirector = null; @@ -90,7 +50,7 @@ final class LocalLaunchedDebuggee extends LocalProcess implements Debuggee { private Launcher launcher = null; /** Enwrap the existing VM mirror. */ - LocalLaunchedDebuggee (Launcher launcher) { + Debuggee(Launcher launcher) { super(); this.launcher = launcher; } @@ -235,70 +195,3 @@ public void redirectStderr(Log log, String prefix) { } -/** - * Mirror of remotely launched debuggee. - */ -final class RemoteLaunchedDebuggee implements Debuggee { - - /** Launcher that creates this debuggee. */ - private Launcher launcher = null; - - /** Enwrap the existing VM mirror. */ - RemoteLaunchedDebuggee (Launcher launcher) { - super(); - this.launcher = launcher; - } - - /** - * Launch debugee on remote host via Launcher object. - */ - public void launch(String[] args) throws IOException { - String cmdLine = ArgumentHandler.joinArguments(args, "\""); - launcher.display("Starting remote java process:\n" + cmdLine); - launcher.launchRemoteProcess(args); - } - - /** Return exit status of the debuggee VM. */ - public int getStatus () { - return launcher.getRemoteProcessStatus(); - } - - /** Check whether the debuggee VM has been terminated. */ - public boolean terminated () { - return launcher.isRemoteProcessTerminated(); - } - - // ---------------------------------------------- // - - /** Kill the debuggee VM. */ - public void killDebuggee () { - launcher.killRemoteProcess(); - } - - /** Wait until the debuggee VM shutdown or crash. */ - public int waitForDebuggee () { - return launcher.waitForRemoteProcess(); - } - - /** Get a pipe to write to the debuggee's stdin stream. */ - public OutputStream getInPipe () { - return null; - } - - /** Get a pipe to read the debuggee's stdout stream. */ - public InputStream getOutPipe () { - return null; - } - - /** Get a pipe to read the debuggee's stderr stream. */ - public InputStream getErrPipe () { - return null; - } - - public void redirectStdout(Log log, String prefix) { - } - - public void redirectStderr(Log log, String prefix) { - } - -} diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java index a960c7dfc810a..ff763ce72d621 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,52 +103,21 @@ public void launchJdbAndDebuggee (String classToExecute) throws IOException { String[] jdbCmdArgs = makeJdbCmdLine(classToExecute); - if (argumentHandler.isLaunchedLocally()) { - - if (argumentHandler.isDefaultConnector()) { - - localDefaultLaunch(jdbCmdArgs, classToExecute); - - } else if (argumentHandler.isRawLaunchingConnector()) { - - localRawLaunch(jdbCmdArgs, classToExecute); - - } else if (argumentHandler.isLaunchingConnector()) { - - localLaunch(jdbCmdArgs, classToExecute); - - } else if (argumentHandler.isAttachingConnector()) { - - localLaunchAndAttach(jdbCmdArgs, classToExecute); - - } else if (argumentHandler.isListeningConnector()) { - - localLaunchAndListen(jdbCmdArgs, classToExecute); - - } else { - throw new TestBug("Unexpected connector type for local launch mode" - + argumentHandler.getConnectorType()); - } - - } else if (argumentHandler.isLaunchedRemotely()) { - - connectToBindServer(classToExecute); - - if (argumentHandler.isAttachingConnector()) { - - remoteLaunchAndAttach(jdbCmdArgs, classToExecute); - - } else if (argumentHandler.isListeningConnector()) { - - remoteLaunchAndListen(jdbCmdArgs, classToExecute); - - } else { - throw new TestBug("Unexpected connector type for remote launch mode" - + argumentHandler.getConnectorType()); - } + if (argumentHandler.isDefaultConnector()) { + localDefaultLaunch(jdbCmdArgs, classToExecute); + } else if (argumentHandler.isRawLaunchingConnector()) { + localRawLaunch(jdbCmdArgs, classToExecute); + } else if (argumentHandler.isLaunchingConnector()) { + localLaunch(jdbCmdArgs, classToExecute); + } else if (argumentHandler.isAttachingConnector()) { + localLaunchAndAttach(jdbCmdArgs, classToExecute); + } else if (argumentHandler.isListeningConnector()) { + localLaunchAndListen(jdbCmdArgs, classToExecute); } else { - throw new Failure("Unexpected launching mode: " + argumentHandler.getLaunchMode()); + throw new TestBug("Unexpected connector type for local launch mode" + + argumentHandler.getConnectorType()); } + } /** @@ -189,11 +158,7 @@ private String[] makeJdbCmdLine (String classToExecute) { if (argumentHandler.isRawLaunchingConnector()) { if (argumentHandler.isSocketTransport()) { - if (argumentHandler.isLaunchedLocally()) { - connectorAddress = argumentHandler.getTransportPort(); - } else { - connectorAddress = argumentHandler.getDebugeeHost() + ":" + argumentHandler.getTransportPort(); - } + connectorAddress = argumentHandler.getTransportPort(); } else if (argumentHandler.isShmemTransport() ) { connectorAddress = argumentHandler.getTransportSharedName(); } else { @@ -235,8 +200,6 @@ private String[] makeJdbCmdLine (String classToExecute) { if (argumentHandler.isSocketTransport()) { connect.append("port=" + argumentHandler.getTransportPort().trim()); - if (argumentHandler.isLaunchedRemotely()) - connect.append(",hostname=" + argumentHandler.getDebugeeHost().trim()); } else if (argumentHandler.isShmemTransport()) { connect.append("name=" + argumentHandler.getTransportSharedName().trim()); } else { @@ -312,7 +275,7 @@ private String[] makeJdbCmdLine (String classToExecute) { private void localLaunchAndAttach (String[] jdbCmdArgs, String classToExecute) throws IOException { - debuggee = new LocalLaunchedDebuggee(this); + debuggee = new Debuggee(this); String address = makeTransportAddress(); String[] javaCmdArgs = makeCommandLineArgs(classToExecute, address); debuggee.launch(javaCmdArgs); @@ -334,57 +297,12 @@ private String[] makeJdbCmdLine (String classToExecute) { String address = jdb.waitForListeningJdb(); display("Listening address found: " + address); - debuggee = new LocalLaunchedDebuggee(this); + debuggee = new Debuggee(this); String[] javaCmdArgs = makeCommandLineArgs(classToExecute, address); debuggee.launch(javaCmdArgs); // jdb.waitForPrompt(0, false); } - /** - * Run test in remote mode using attaching connector. - */ - private void remoteLaunchAndAttach - (String[] jdbCmdArgs, String classToExecute) throws IOException { - - debuggee = new RemoteLaunchedDebuggee(this); - String address = makeTransportAddress(); - String[] javaCmdArgs = makeCommandLineArgs(classToExecute, address); - try { - debuggee.launch(javaCmdArgs); - } catch (IOException e) { - throw new Failure("Caught exception while launching debuggee VM process:\n\t" - + e); - }; - - display("Start jdb attaching to remote debuggee"); - jdb = Jdb.startAttachingJdb (this, jdbCmdArgs, JDB_STARTED); -// jdb.waitForPrompt(0, false); - } - - /** - * Run test in remote mode using listening connector. - */ - private void remoteLaunchAndListen - (String[] jdbCmdArgs, String classToExecute) throws IOException { - - jdb = new Jdb(this); - display("Starting jdb listening to remote debuggee"); - jdb.launch(jdbCmdArgs); - String address = jdb.waitForListeningJdb(); - display("Listening address found: " + address); - - debuggee = new RemoteLaunchedDebuggee(this); - String[] javaCmdArgs = makeCommandLineArgs(classToExecute); - try { - debuggee.launch(javaCmdArgs); - } catch (IOException e) { - throw new Failure("Caught exception while launching debuggee VM process:\n\t" - + e); - }; - - jdb.waitForMessage(0, JDB_STARTED); -// jdb.waitForPrompt(0, false); - } } // End of Launcher diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/ArgumentHandler.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/ArgumentHandler.java index 1686318950027..3f924c6ac47b8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/ArgumentHandler.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/ArgumentHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -457,18 +457,6 @@ protected void checkOptions() { } */ - if (! isLaunchedLocally() && ! isDefaultDebugeeSuspendMode()) { - throw new BadOption("inconsistent options: " - + "-debugee.launch=" + getLaunchMode() - + " and -debugee.suspend=" + getDebugeeSuspendMode()); - } - - if (! isLaunchedLocally() && isLaunchingConnector()) { - throw new BadOption("inconsistent options: " - + "-debugee.launch=" + getLaunchMode() - + " and -connector=" + getConnectorType()); - } - if (isLaunchingConnector() && ! isDefaultTransport()) { throw new BadOption("inconsistent options: " + "-connector=" + getConnectorType() diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Binder.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Binder.java index 76ff5a28696b6..ccb74586e96a6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Binder.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Binder.java @@ -127,7 +127,7 @@ public Binder (ArgumentHandler argumentHandler, Log log) { * started with launching connector. */ public Debugee makeLocalDebugee(Process process) { - LocalLaunchedDebugee debugee = new LocalLaunchedDebugee(process, this); + Debugee debugee = new Debugee(process, this); Finalizer finalizer = new Finalizer(debugee); finalizer.activate(); @@ -194,51 +194,22 @@ public Debugee bindToDebugeeNoWait(String classToExecute) { prepareForPipeConnection(argumentHandler); - if (argumentHandler.isLaunchedLocally()) { - - if (argumentHandler.isDefaultConnector()) { - debugee = localDefaultLaunchDebugee(vmm, classToExecute, classPath); - } else if (argumentHandler.isRawLaunchingConnector()) { - debugee = localRawLaunchDebugee(vmm, classToExecute, classPath); - } else if (argumentHandler.isLaunchingConnector()) { - debugee = localLaunchDebugee(vmm, classToExecute, classPath); - } else if (argumentHandler.isAttachingConnector()) { - debugee = localLaunchAndAttachDebugee(vmm, classToExecute, classPath); - } else if (argumentHandler.isListeningConnector()) { - debugee = localLaunchAndListenDebugee(vmm, classToExecute, classPath); - } else { - throw new TestBug("Unexpected connector type for local debugee launch mode" - + argumentHandler.getConnectorType()); - } - - } else if (argumentHandler.isLaunchedRemotely()) { - - connectToBindServer(classToExecute); - - if (argumentHandler.isAttachingConnector()) { - debugee = remoteLaunchAndAttachDebugee(vmm, classToExecute, classPath); - } else if (argumentHandler.isListeningConnector()) { - debugee = remoteLaunchAndListenDebugee(vmm, classToExecute, classPath); - } else { - throw new TestBug("Unexpected connector type for remote debugee launch mode" - + argumentHandler.getConnectorType()); - } - - } else if (argumentHandler.isLaunchedManually()) { - - if (argumentHandler.isAttachingConnector()) { - debugee = manualLaunchAndAttachDebugee(vmm, classToExecute, classPath); - } else if (argumentHandler.isListeningConnector()) { - debugee = manualLaunchAndListenDebugee(vmm, classToExecute, classPath); - } else { - throw new TestBug("Unexpected connector type for manual debugee launch mode" - + argumentHandler.getConnectorType()); - } - + if (argumentHandler.isDefaultConnector()) { + debugee = localDefaultLaunchDebugee(vmm, classToExecute, classPath); + } else if (argumentHandler.isRawLaunchingConnector()) { + debugee = localRawLaunchDebugee(vmm, classToExecute, classPath); + } else if (argumentHandler.isLaunchingConnector()) { + debugee = localLaunchDebugee(vmm, classToExecute, classPath); + } else if (argumentHandler.isAttachingConnector()) { + debugee = localLaunchAndAttachDebugee(vmm, classToExecute, classPath); + } else if (argumentHandler.isListeningConnector()) { + debugee = localLaunchAndListenDebugee(vmm, classToExecute, classPath); } else { - throw new Failure("Unexpected debugee launching mode: " + argumentHandler.getLaunchMode()); + throw new TestBug("Unexpected connector type for local debugee launch mode" + + argumentHandler.getConnectorType()); } + return debugee; } @@ -491,194 +462,6 @@ private Debugee localLaunchAndListenDebugee (VirtualMachineManager vmm, // -------------------------------------------------- // - /** - * Launch debugee VM remotely via BindServer and connect to it using - * AttachingConnector. - */ - private Debugee remoteLaunchAndAttachDebugee (VirtualMachineManager vmm, - String classToExecute, - String classPath) { - display("Finding connector: " + argumentHandler.getConnectorName() ); - AttachingConnector connector = - (AttachingConnector) findConnector(argumentHandler.getConnectorName(), - vmm.attachingConnectors()); - - Map arguments = setupAttachingConnector(connector, classToExecute, classPath); - - String address = makeTransportAddress(); - String[] cmdLineArgs = makeCommandLineArgs(classToExecute, address); - String javaCmdLine = makeCommandLineString(classToExecute, address, "\""); - - display("Starting remote java process:\n\t" + javaCmdLine); - Debugee debugee = startRemoteDebugee(cmdLineArgs); - - display("Attaching to debugee"); - VirtualMachine vm; - IOException ioe = null; - for (int i = 0; i < CONNECT_TRIES; i++) { - try { - vm = connector.attach(arguments); - display("Debugee attached"); - debugee.setupVM(vm); - return debugee; - } catch (IOException e) { - display("Attempt #" + i + " to connect to debugee VM failed:\n\t" + e); - ioe = e; - if (debugee.terminated()) { - throw new Failure("Unable to connect to debuggee VM: VM process is terminated"); - } - try { - Thread.currentThread().sleep(CONNECT_TRY_DELAY); - } catch (InterruptedException ie) { - ie.printStackTrace(log.getOutStream()); - throw new Failure("Thread interrupted while pausing connection attempts:\n\t" - + ie); - } - } catch (IllegalConnectorArgumentsException e) { - e.printStackTrace(log.getOutStream()); - throw new TestBug("Wrong connector arguments used to attach to debuggee VM:\n\t" + e); - } - } - throw new Failure("Unable to connect to debugee VM after " + CONNECT_TRIES - + " tries:\n\t" + ioe); - } - - /** - * Launch debugee VM remotely via BindServer and connect to it using - * ListeningConnector. - */ - private Debugee remoteLaunchAndListenDebugee (VirtualMachineManager vmm, - String classToExecute, - String classPath) { - display("Finding connector: " + argumentHandler.getConnectorName() ); - ListeningConnector connector = - (ListeningConnector) findConnector(argumentHandler.getConnectorName(), - vmm.listeningConnectors()); - Map arguments = setupListeningConnector(connector, classToExecute, classPath); - - String address = null; - try { - display("Listening for connection from debugee"); - address = connector.startListening(arguments); - } catch (IllegalConnectorArgumentsException e) { - e.printStackTrace(log.getOutStream()); - throw new TestBug("Wrong connector arguments used to listen debuggee VM:\n\t" + e); - } catch (IOException e) { - e.printStackTrace(log.getOutStream()); - throw new Failure("Caught exception while starting listening debugee VM:\n\t" + e); - }; - - String[] cmdLineArgs = makeCommandLineArgs(classToExecute, address); - String javaCmdLine = makeCommandLineString(classToExecute, address, "\""); - - display("Starting remote java process:\n\t" + javaCmdLine); - Debugee debugee = startRemoteDebugee(cmdLineArgs); - - display("Waiting for connection from debugee"); - VirtualMachine vm; - IOException ioe = null; - for (int i = 0; i < CONNECT_TRIES; i++) { - try { - vm = connector.accept(arguments); - connector.stopListening(arguments); - display("Debugee attached"); - debugee.setupVM(vm); - return debugee; - } catch (IOException e) { - display("Attempt #" + i + " to listen debugee VM failed:\n\t" + e); - ioe = e; - if (debugee.terminated()) { - throw new Failure("Unable to connect to debuggee VM: VM process is terminated"); - } - try { - Thread.currentThread().sleep(CONNECT_TRY_DELAY); - } catch (InterruptedException ie) { - ie.printStackTrace(log.getOutStream()); - throw new Failure("Thread interrupted while pausing connection attempts:\n\t" - + ie); - } - } catch (IllegalConnectorArgumentsException e) { - e.printStackTrace(log.getOutStream()); - throw new TestBug("Wrong connector arguments used to listen debuggee VM:\n\t" + e); - } - } - throw new Failure("Unable to connect to debugee VM after " + CONNECT_TRIES - + " tries:\n\t" + ioe); - } - - // -------------------------------------------------- // - - /** - * Prompt to manually launch debugee VM and connect to it using - * AttachingConnector. - */ - private Debugee manualLaunchAndAttachDebugee (VirtualMachineManager vmm, - String classToExecute, - String classPath) { - display("Finding connector: " + argumentHandler.getConnectorName() ); - AttachingConnector connector = - (AttachingConnector) findConnector(argumentHandler.getConnectorName(), - vmm.attachingConnectors()); - Map arguments = setupAttachingConnector(connector, classToExecute, classPath); - - String address = makeTransportAddress(); - String javaCmdLine = makeCommandLineString(classToExecute, address, "\""); - - display("Starting manual java process:\n\t" + javaCmdLine); - ManualLaunchedDebugee debugee = startManualDebugee(javaCmdLine); - - VirtualMachine vm; - try { - display("Attaching to debugee"); - vm = connector.attach(arguments); - } catch (IllegalConnectorArgumentsException e) { - e.printStackTrace(log.getOutStream()); - throw new TestBug("Wrong connector arguments used to attach to debuggee VM:\n\t" + e); - } catch (IOException e) { - e.printStackTrace(log.getOutStream()); - throw new Failure("Caught exception while attaching to debugee VM:\n\t" + e); - }; - display("Debugee attached"); - - debugee.setupVM(vm); - return debugee; - } - - /** - * Prompt to manually launch debugee VM and connect to it using - * ListeningConnector. - */ - private Debugee manualLaunchAndListenDebugee (VirtualMachineManager vmm, - String classToExecute, - String classPath) { - display("Finding connector: " + argumentHandler.getConnectorName() ); - ListeningConnector connector = - (ListeningConnector) findConnector(argumentHandler.getConnectorName(), - vmm.listeningConnectors()); - Map arguments = setupListeningConnector(connector, classToExecute, classPath); - - VirtualMachine vm; - try { - display("Listening for connection from debugee"); - String address = connector.startListening(arguments); - String javaCmdLine = makeCommandLineString(classToExecute, address, "\""); - display("Starting manual java process:\n\t" + javaCmdLine); - ManualLaunchedDebugee debugee = startManualDebugee(javaCmdLine); - display("Waiting for connection from debugee"); - vm = connector.accept(arguments); - display("Debugee attached"); - connector.stopListening(arguments); - debugee.setupVM(vm); - return debugee; - } catch (IllegalConnectorArgumentsException e) { - e.printStackTrace(log.getOutStream()); - throw new TestBug("Wrong connector arguments used to listen debuggee VM:\n\t" + e); - } catch (IOException e) { - e.printStackTrace(log.getOutStream()); - throw new Failure("Caught exception while listening to debugee VM:\n\t" + e); - } - } - // -------------------------------------------------- // /** @@ -913,41 +696,6 @@ protected Debugee startLocalDebugee(String[] cmdArgs) { return makeLocalDebugee(process); } - /** - * Launch remote debuggee process with specified command line arguments - * and make initial Debugee mirror. - */ - protected RemoteLaunchedDebugee startRemoteDebugee(String[] cmdArgs) { - try { - launchRemoteProcess(cmdArgs); - } catch (IOException e) { - e.printStackTrace(log.getOutStream()); - throw new Failure("Caught exception while launching remote debuggee VM process:\n\t" - + e); - } - - RemoteLaunchedDebugee debugee = new RemoteLaunchedDebugee(this); - - Finalizer finalizer = new Finalizer(debugee); - finalizer.activate(); - - return debugee; - } - - /** - * Launch manual debuggee process with specified command line arguments - * and make initial Debugee mirror. - */ - protected ManualLaunchedDebugee startManualDebugee(String cmd) { - ManualLaunchedDebugee debugee = new ManualLaunchedDebugee(this); - debugee.launchDebugee(cmd); - - Finalizer finalizer = new Finalizer(debugee); - finalizer.activate(); - - return debugee; - } - public static String readVMStartExceptionOutput(VMStartException e, PrintStream log) { StringBuffer msg = new StringBuffer(); try (InputStream is = e.process().getInputStream()) { @@ -997,286 +745,3 @@ private static byte[] readAllBytes(InputStream is) throws IOException { } } - - -/** - * Mirror of locally launched debugee. - */ -final class LocalLaunchedDebugee extends Debugee { - - /** Enwrap the locally started VM process. */ - public LocalLaunchedDebugee (Process process, Binder binder) { - super(binder); - this.process = process; - checkTermination = true; - } - - // ---------------------------------------------- // - - /** Return exit status of the debugee VM. */ - public int getStatus () { - return process.exitValue(); - } - - /** Check whether the debugee VM has been terminated. */ - public boolean terminated () { - if (process == null) - return true; - - try { - int value = process.exitValue(); - return true; - } catch (IllegalThreadStateException e) { - return false; - } - } - - // ---------------------------------------------- // - - /** Kill the debugee VM. */ - protected void killDebugee () { - super.killDebugee(); - if (!terminated()) { - log.display("Killing debugee VM process"); - process.destroy(); - } - } - - /** Wait until the debugee VM shutdown or crash. */ - protected int waitForDebugee () throws InterruptedException { - int code = process.waitFor(); - return code; - } - - /** Get a pipe to write to the debugee's stdin stream. */ - protected OutputStream getInPipe () { - return process.getOutputStream(); - } - - /** Get a pipe to read the debugee's stdout stream. */ - protected InputStream getOutPipe () { - return process.getInputStream(); - } - - /** Get a pipe to read the debugee's stderr stream. */ - protected InputStream getErrPipe () { - return process.getErrorStream(); - } -} - - -/** - * Mirror of remotely launched debugee. - */ -final class RemoteLaunchedDebugee extends Debugee { - - /** Enwrap the remotely started VM process. */ - public RemoteLaunchedDebugee (Binder binder) { - super(binder); - } - - // ---------------------------------------------- // - - /** Return exit status of the debugee VM. */ - public int getStatus () { - return binder.getRemoteProcessStatus(); - } - - /** Check whether the debugee VM has been terminated. */ - public boolean terminated () { - return binder.isRemoteProcessTerminated(); - } - - // ---------------------------------------------- // - - /** Kill the debugee VM. */ - protected void killDebugee () { - super.killDebugee(); - if (!terminated()) { - binder.killRemoteProcess(); - } - } - - /** Wait until the debugee VM shutdown or crash. */ - protected int waitForDebugee () { - return binder.waitForRemoteProcess(); - } - - /** Get a pipe to write to the debugee's stdin stream. */ - protected OutputStream getInPipe () { - return null; - } - - /** Get a pipe to read the debugee's stdout stream. */ - protected InputStream getOutPipe () { - return null; - } - - /** Get a pipe to read the debugee's stderr stream. */ - protected InputStream getErrPipe () { - return null; - } - - public void redirectStdout(OutputStream out) { - } - - public void redirectStdout(Log log, String prefix) { - } - - public void redirectStderr(OutputStream out) { - } - - public void redirectStderr(Log log, String prefix) { - } -} - - -/** - * Mirror of manually launched debugee. - */ -final class ManualLaunchedDebugee extends Debugee { - /** Enwrap the manually started VM process. */ - public ManualLaunchedDebugee (Binder binder) { - super(binder); - makeInputReader(); - } - - // ---------------------------------------------- // - - private int exitCode = 0; - private boolean finished = false; - private static BufferedReader bin = null; - - public void launchDebugee(String commandLine) { - makeInputReader(); - - putMessage("Launch target VM using such command line:\n" - + commandLine); - String answer = askQuestion("Has the VM successfully started? (yes/no)", "yes"); - for ( ; ; ) { - if (answer.equals("yes")) - break; - if (answer.equals("no")) - throw new Failure ("Unable to manually launch debugee VM"); - answer = askQuestion("Wrong answer. Please type yes or no", "yes"); - } - } - - private static void makeInputReader() { - if (bin == null) { - bin = new BufferedReader(new InputStreamReader(System.in)); - } - } - - private static void destroyInputReader() { - if (bin != null) { - try { - bin.close(); - } catch (IOException e) { -// e.printStackTrace(log.getOutStream()); - throw new Failure("Caught exception while closing input stream:\n\t" + e); - } - bin = null; - } - } - - private static void putMessage(String msg) { - System.out.println("\n>>> " + msg); - } - - private static String askQuestion(String question, String defaultAnswer) { - try { - System.out.print("\n>>> " + question); - System.out.print(" [" + defaultAnswer + "] "); - System.out.flush(); - String answer = bin.readLine(); - if (answer.equals("")) - return defaultAnswer; - return answer; - } catch (IOException e) { -// e.printStackTrace(log.getOutStream()); - throw new Failure("Caught exception while reading answer:\n\t" + e); - } - } - - /** Return exit status of the debugee VM. */ - public int getStatus () { - if (! finished) { - throw new Failure("Unable to get status of debugee VM: process still alive"); - } - return exitCode; - } - - /** Check whether the debugee VM has been terminated. */ - public boolean terminated () { - return finished; - } - - // ---------------------------------------------- // - - /** Kill the debugee VM. */ - protected void killDebugee () { - super.killDebugee(); - if (!terminated()) { - putMessage("Kill launched VM"); - String answer = askQuestion("Has the VM successfully terminated? (yes/no)", "yes"); - for ( ; ; ) { - if (answer.equals("yes")) { - finished = true; - break; - } - if (answer.equals("no")) - throw new Failure ("Unable to manually kill debugee VM"); - answer = askQuestion("Wrong answer. Please type yes or no", "yes"); - } - } - } - - /** Wait until the debugee VM shutdown or crash. */ - protected int waitForDebugee () { - putMessage("Wait for launched VM to exit."); - String answer = askQuestion("What is VM exit code?", "95"); - for ( ; ; ) { - try { - exitCode = Integer.parseInt(answer); - break; - } catch (NumberFormatException e) { - answer = askQuestion("Wrong answer. Please type integer value", "95"); - } - } - finished = true; - return exitCode; - } - - /** Get a pipe to write to the debugee's stdin stream. */ - protected OutputStream getInPipe () { - return null; - } - - /** Get a pipe to read the debugee's stdout stream. */ - protected InputStream getOutPipe () { - return null; - } - - /** Get a pipe to read the debugee's stderr stream. */ - protected InputStream getErrPipe () { - return null; - } - - public void redirectStdout(OutputStream out) { - } - - public void redirectStdout(Log log, String prefix) { - } - - public void redirectStderr(OutputStream out) { - } - - public void redirectStderr(Log log, String prefix) { - } - - public void close() { - destroyInputReader(); - super.close(); - } -} diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Debugee.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Debugee.java index 3f82781b8e2a5..5ba44ee9cbf3d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Debugee.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Debugee.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ * @see Binder * @see DebugeeProcess */ -abstract public class Debugee extends DebugeeProcess { +public class Debugee extends DebugeeProcess { /** * Mirror of the debugee VM. This must be initialized by every @@ -68,6 +68,13 @@ protected Debugee (Binder binder) { this.argumentHandler = (ArgumentHandler)binder.getArgumentHandler(); } + protected Debugee (Process process, Binder binder) { + super(binder); + this.process = process; + this.binder = binder; + this.argumentHandler = (ArgumentHandler)binder.getArgumentHandler(); + } + /** Setup Debugee object with given VM mirror. */ public void setupVM(VirtualMachine vm) { if (this.vm != null) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/Binder.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/Binder.java index 2424a9a56edb9..8776b5be89e8d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/Binder.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/Binder.java @@ -98,13 +98,8 @@ public Debugee bindToDebugee (String classToExecute) { prepareForPipeConnection(argumentHandler); - if (argumentHandler.isLaunchedRemotely()) { - connectToBindServer(classToExecute); - debugee = launchDebugee(classToExecute); - } else { - debugee = launchDebugee(classToExecute); - debugee.redirectOutput(log); - } + debugee = launchDebugee(classToExecute); + debugee.redirectOutput(log); Finalizer finalizer = new Finalizer(debugee); finalizer.activate(); @@ -120,334 +115,16 @@ public Debugee bindToDebugee (String classToExecute) { public Debugee launchDebugee (String classToExecute) { try { - - if (argumentHandler.isLaunchedLocally()) { - LocalLaunchedDebugee debugee = new LocalLaunchedDebugee(this); - String address = debugee.prepareTransport(argumentHandler); - if (address == null) - address = makeTransportAddress(); - String[] argsArray = makeCommandLineArgs(classToExecute, address); - debugee.launch(argsArray); - return debugee; - } - - if (argumentHandler.isLaunchedRemotely()) { - RemoteLaunchedDebugee debugee = new RemoteLaunchedDebugee(this); - String address = debugee.prepareTransport(argumentHandler); - if (address == null) - address = makeTransportAddress(); - String[] argsArray = makeCommandLineArgs(classToExecute, address); - debugee.launch(argsArray); - return debugee; - } - - if (argumentHandler.isLaunchedManually()) { - ManualLaunchedDebugee debugee = new ManualLaunchedDebugee(this); - String address = debugee.prepareTransport(argumentHandler); - if (address == null) - address = makeTransportAddress(); - String cmdLine = makeCommandLineString(classToExecute, address, "\""); - debugee.launch(cmdLine); - return debugee; - } - - throw new TestBug("Unexpected launching mode: " - + argumentHandler.getLaunchMode()); + Debugee debugee = new Debugee(this); + String address = debugee.prepareTransport(argumentHandler); + if (address == null) + address = makeTransportAddress(); + String[] argsArray = makeCommandLineArgs(classToExecute, address); + debugee.launch(argsArray); + return debugee; } catch (IOException e) { e.printStackTrace(log.getOutStream()); throw new Failure("Caught exception while launching debugee:\n\t" + e); } } - -} - -/** - * Mirror of locally launched debugee. - */ -final class LocalLaunchedDebugee extends Debugee { - - /** Enwrap the existing VM mirror. */ - public LocalLaunchedDebugee (Binder binder) { - super(binder); - checkTermination = true; - } - - // ---------------------------------------------- // - - public void launch(String[] args) throws IOException { - String cmdLine = ArgumentHandler.joinArguments(args, "\""); - display("Starting java process:\n" + cmdLine); - process = binder.launchProcess(args); - } - - /** Return exit status of the debugee VM. */ - public int getStatus () { - return process.exitValue(); - } - - /** Check whether the debugee VM has been terminated. */ - public boolean terminated () { - if (process == null) - return true; - - try { - int value = process.exitValue(); - return true; - } catch (IllegalThreadStateException e) { - return false; - } - } - - // ---------------------------------------------- // - - /** Kill the debugee VM. */ - protected void killDebugee () { - super.killDebugee(); - if (!terminated()) { - log.display("Killing debugee VM process"); - process.destroy(); - } - } - - /** Wait until the debugee VM shutdown or crash. */ - protected int waitForDebugee () throws InterruptedException { - return process.waitFor(); - } - - /** Get a pipe to write to the debugee's stdin stream. */ - protected OutputStream getInPipe () { - return process.getOutputStream(); - } - - /** Get a pipe to read the debugee's stdout stream. */ - protected InputStream getOutPipe () { - return process.getInputStream(); - } - - /** Get a pipe to read the debugee's stderr stream. */ - protected InputStream getErrPipe () { - return process.getErrorStream(); - } -} - - -/** - * Mirror of remotely launched debugee. - */ -final class RemoteLaunchedDebugee extends Debugee { - - /** Enwrap the existing VM mirror. */ - public RemoteLaunchedDebugee (Binder binder) { - super(binder); - } - - // ---------------------------------------------- // - - public void launch(String[] args) throws IOException { - String cmdLine = ArgumentHandler.joinArguments(args, "\""); - display("Starting remote java process:\n" + cmdLine); - binder.launchRemoteProcess(args); - } - - /** Return exit status of the debugee VM. */ - public int getStatus () { - return binder.getRemoteProcessStatus(); - } - - /** Check whether the debugee VM has been terminated. */ - public boolean terminated () { - return binder.isRemoteProcessTerminated(); - } - - // ---------------------------------------------- // - - /** Kill the debugee VM. */ - protected void killDebugee () { - super.killDebugee(); - if (!terminated()) { - log.display("Killing debugee VM process"); - binder.killRemoteProcess(); - } - } - - /** Wait until the debugee VM shutdown or crash. */ - protected int waitForDebugee () { - return binder.waitForRemoteProcess(); - } - - /** Get a pipe to write to the debugee's stdin stream. */ - protected OutputStream getInPipe () { - return null; - } - - /** Get a pipe to read the debugee's stdout stream. */ - protected InputStream getOutPipe () { - return null; - } - - /** Get a pipe to read the debugee's stderr stream. */ - protected InputStream getErrPipe () { - return null; - } - - public void redirectStdout(OutputStream out) { - } - - public void redirectStdout(Log log, String prefix) { - } - - public void redirectStderr(OutputStream out) { - } - - public void redirectStderr(Log log, String prefix) { - } -} - - -/** - * Mirror of manually launched debugee. - */ -final class ManualLaunchedDebugee extends Debugee { - - private int exitCode = 0; - private boolean finished = false; - private static BufferedReader bin = new BufferedReader(new InputStreamReader(System.in)); - - /** Enwrap the existing VM mirror. */ - public ManualLaunchedDebugee (Binder binder) { - super(binder); - } - - // ---------------------------------------------- // - - public void launch(String commandLine) throws IOException { - putMessage("Launch target VM using such command line:\n" - + commandLine); - String answer = askQuestion("Has the VM successfully started? (yes/no)", "yes"); - for ( ; ; ) { - if (answer.equals("yes")) - break; - if (answer.equals("no")) - throw new Failure ("Unable to manually launch debugee VM"); - answer = askQuestion("Wrong answer. Please type yes or no", "yes"); - } - } - - private void putMessage(String msg) { - System.out.println("\n>>> " + msg); - } - - private String askQuestion(String question, String defaultAnswer) { - try { - System.out.print("\n>>> " + question); - System.out.print(" [" + defaultAnswer + "] "); - System.out.flush(); - String answer = bin.readLine(); - if (answer.equals("")) - return defaultAnswer; - return answer; - } catch (IOException e) { - e.printStackTrace(log.getOutStream()); - throw new Failure("Caught exception while reading answer:\n\t" + e); - } - } - - /** Return exit status of the debugee VM. */ - public int getStatus () { - if (! terminated()) { - throw new Failure("Unable to get status of debugee VM: process still alive"); - } - return exitCode; - } - - /** Check whether the debugee VM has been terminated. */ - public boolean terminated () { - if(! finished) { - String answer = askQuestion("Has the VM exited?", "no"); - for ( ; ; ) { - if (answer.equals("no")) - return false; - if (answer.equals("yes")) { - finished = true; - waitForDebugee(); - break; - } - answer = askQuestion("Wrong answer. Please type yes or no", "yes"); - } - } - return finished; - } - - // ---------------------------------------------- // - - /** Kill the debugee VM. */ - protected void killDebugee () { - super.killDebugee(); - if (!terminated()) { - putMessage("Kill launched VM"); - String answer = askQuestion("Has the VM successfully terminated? (yes/no)", "yes"); - for ( ; ; ) { - if (answer.equals("yes")) { - finished = true; - break; - } - if (answer.equals("no")) - throw new Failure ("Unable to manually kill debugee VM"); - answer = askQuestion("Wrong answer. Please type yes or no", "yes"); - } - } - } - - /** Wait until the debugee VM shutdown or crash. */ - protected int waitForDebugee () { - putMessage("Wait for launched VM to exit."); - String answer = askQuestion("What is VM exit code?", "95"); - for ( ; ; ) { - try { - exitCode = Integer.parseInt(answer); - break; - } catch (NumberFormatException e) { - answer = askQuestion("Wrong answer. Please type integer value", "95"); - } - } - finished = true; - return exitCode; - } - - /** Get a pipe to write to the debugee's stdin stream. */ - protected OutputStream getInPipe () { - return null; - } - - /** Get a pipe to read the debugee's stdout stream. */ - protected InputStream getOutPipe () { - return null; - } - - /** Get a pipe to read the debugee's stderr stream. */ - protected InputStream getErrPipe () { - return null; - } - - public void redirectStdout(OutputStream out) { - } - - public void redirectStdout(Log log, String prefix) { - } - - public void redirectStderr(OutputStream out) { - } - - public void redirectStderr(Log log, String prefix) { - } - - public void close() { - try { - bin.close(); - } catch (IOException e) { - log.display("WARNING: Caught IOException while closing InputStream"); - } - bin = null; - super.close(); - } -} +} \ No newline at end of file diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/Debugee.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/Debugee.java index ba1b4129cc796..ef95ee885604c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/Debugee.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/Debugee.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @see Transport * @see DebugeeProcess */ -abstract public class Debugee extends DebugeeProcess { +public class Debugee extends DebugeeProcess { /** Binder that creates this debugee. */ protected Binder binder = null; @@ -63,6 +63,12 @@ protected Debugee (Binder binder) { prefix = "Debugee> "; } + public void launch(String[] args) throws IOException { + String cmdLine = ArgumentHandler.joinArguments(args, "\""); + display("Starting java process:\n" + cmdLine); + process = binder.launchProcess(args); + } + /** Return Binder of the debugee object. */ public Binder getBinder() { return binder; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeArgumentHandler.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeArgumentHandler.java index 98f11a426eaa5..72461a5230994 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeArgumentHandler.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeArgumentHandler.java @@ -57,8 +57,6 @@ * (this works only with -connector=listening and -transport=socket) *

  • -debugee.suspend=[yes|no|default] - * should debugee start in suspend mode or not - *
  • -debugee.launch=[local|remote|manual] - - * launch and bind to debugee VM locally, remotely (via BindSever) or manually *
  • -debugee.vmhome=<path> - * path to JDK used for launching debugee VM *
  • -debugee.vmkind=<name> - @@ -275,11 +273,8 @@ public boolean isDefaultDebugeeSuspendMode() { * @see #isDefaultDebugeeSuspendMode() */ public boolean willDebugeeSuspended() { - if (isLaunchedLocally()) { - String mode = getDebugeeSuspendMode(); - return mode.equals("no"); - } - return true; + String mode = getDebugeeSuspendMode(); + return mode.equals("no"); } private boolean pipePortInited = false; @@ -337,54 +332,6 @@ public void setPipePortNumber(int port) { setOption("-", "pipe.port", value); } - /** - * Return debugee VM launching mode, specified by - * -launch.mode command line option, or - * "local" string by default. - * - * Possible values for this option are: - *
      - *
    • "local" - *
    • "remote" - *
    • "manual" - *
    - * - * @see #isLaunchedLocally() - * @see #isLaunchedRemotely() - * @see #isLaunchedManually() - * @see #setRawArguments(String[]) - */ - public String getLaunchMode() { - return options.getProperty("debugee.launch", "local"); - } - - /** - * Return true if debugee should be launched locally. - * - * @see #getLaunchMode() - */ - public boolean isLaunchedLocally() { - return getLaunchMode().equals("local"); - } - - /** - * Return true if debugee should be launched remotely via - * BindServer. - * - * @see #getLaunchMode() - */ - public boolean isLaunchedRemotely() { - return getLaunchMode().equals("remote"); - } - - /** - * Return true if debugee should be launched manually by user. - * - * @see #getLaunchMode() - */ - public boolean isLaunchedManually() { - return getLaunchMode().equals("manual"); - } /** * Return additional options for launching debugee VM, specified by @@ -710,9 +657,7 @@ protected boolean checkOption(String option, String value) { } // option with any nonempty string value - if (option.equals("test.host") - || option.equals("debugee.host") - || option.equals("debugee.vmkind") + if (option.equals("debugee.vmkind") || option.equals("debugee.vmhome") || option.equals("transport.shname")) { if (value.length() <= 0) { @@ -748,14 +693,10 @@ protected boolean checkOption(String option, String value) { return true; } - if (option.equals("debugee.launch")) { - if ((!value.equals("local")) - && (!value.equals("remote")) - && (!value.equals("manual"))) { - throw new BadOption(option + ": must be one of: " - + "local, remote, manual " + value); - } - return true; + if (option.equals("debugee.launch") + || option.equals("debugee.host") + || option.equals("test.host")) { + throw new RuntimeException("option " + option + " is not supported."); } if (option.equals("jvmdi.strict")) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java index 2500dfeb8ebc0..6cf4dde7d1d74 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java @@ -34,15 +34,6 @@ * debuggee VM and to make connection to it using JDI connector or * JDWP transport. *

    - * The present version of Binder allows - * to launch debuggee VM either on local machine (local launch mode), - * or on remote host using BindServer utility - * (remote launch mode). Also there is an ability to launch - * debuggee VM manually as a separate process on local or remote machine - * (manual launch mode), which is usefull for debugging. - * All these launching modes are specified by command line option - * -debugee.launch recognized by DebugeeArgumentHandler. - *

    * Binder also makes it possible to establish TCP/IP * connection between debugger and debuggee throw IOPipe * object. This connection allows debugger to communicate with debuggee @@ -104,8 +95,6 @@ public static String getVersion () { } // -------------------------------------------------- // - - private BindServerListener bindServerListener = null; private ServerSocket pipeServerSocket = null; // -------------------------------------------------- // @@ -382,161 +371,11 @@ public String[] makeCommandLineArgs(String classToExecute) { return makeCommandLineArgs(classToExecute, makeTransportAddress()); } - /** - * Make connection to remote BindServer and start BindServerListener thread. - * - * @throws IOException if I/O error occured while connecting - */ - public void connectToBindServer(String taskID) { - if (bindServerListener != null) { - throw new Failure("Connection to BindServer already exists"); - } - try { - bindServerListener = new BindServerListener(this); - bindServerListener.setDaemon(true); - bindServerListener.connect(taskID); - bindServerListener.start(); - } catch (IOException e) { - e.printStackTrace(getOutStream()); - throw new Failure("Caught exception while connecting to BindServer:\n\t" + e); - } - } - - /** - * Split string into list of substrings using specified separator. - */ - private static String[] splitString(String givenString, String separator) { - Vector tmpList = new Vector(); - StringTokenizer tokenizer = new StringTokenizer(givenString, separator); - while(tokenizer.hasMoreTokens()) { - tmpList.add(tokenizer.nextToken()); - } - String[] list = new String[tmpList.size()]; - for (int i = 0; i < tmpList.size(); i++) { - list[i] = tmpList.elementAt(i); - } - return list; - } - - /** - * Send command to remote BindServer and receive reply. - * - * @throws IOException if I/O error occured while launching process - */ - public synchronized Object sendRemoteCommand(Object command) { - try { - bindServerListener.sendCommand(command); - Object reply = bindServerListener.getReply(); - return reply; - } catch (IOException e) { - e.printStackTrace(log.getOutStream()); - throw new Failure("Unexpected exception while sending command to BindServer:\n\t" - + e); - } - } - - /** - * Launch remote process using request to BindServer. - * - * @throws IOException if I/O error occured - */ - public void launchRemoteProcess(String[] args) throws IOException { - String pathSeparator = System.getProperty("path.separator"); - BindServer.LaunchDebugee command = - new BindServer.LaunchDebugee(args, - System.getProperty("file.separator"), - System.getProperty("user.dir"), - splitString(System.getProperty("java.library.path"), pathSeparator), - splitString(System.getProperty("java.class.path"), pathSeparator), - splitString(System.getProperty("java.library.path"), pathSeparator)); - - Object reply = sendRemoteCommand(command); - if (reply instanceof BindServer.OK) { - // do nothing - } else if (reply instanceof BindServer.RequestFailed) { - BindServer.RequestFailed castedReply = (BindServer.RequestFailed)reply; - throw new Failure("BindServer error: " + castedReply.reason); - } else { - throw new Failure("Wrong reply from BindServer: " + reply); - } - } - - /** - * Return exit status of the remotely launched process - * using request to BindServer. - */ - public int getRemoteProcessStatus () { - Object reply = sendRemoteCommand(new BindServer.DebugeeExitCode()); - if (reply instanceof BindServer.OK) { - BindServer.OK castedReply = (BindServer.OK)reply; - return (int)castedReply.info; - } else if (reply instanceof BindServer.CaughtException) { - BindServer.CaughtException castedReply = (BindServer.CaughtException)reply; - throw new IllegalThreadStateException(castedReply.reason); - } else if (reply instanceof BindServer.RequestFailed) { - BindServer.RequestFailed castedReply = (BindServer.RequestFailed)reply; - throw new Failure("BindServer error: " + castedReply.reason); - } else { - throw new Failure("Wrong reply from BindServer: " + reply); - } - } - - /** - * Check whether the remotely launched process has been terminated - * using request to BindServer. - */ - public boolean isRemoteProcessTerminated () { - try { - int value = getRemoteProcessStatus(); - return true; - } catch (IllegalThreadStateException e) { - return false; - } - } - - // ---------------------------------------------- // - - /** - * Kill the remotely launched process - * using request to BindServer. - */ - public void killRemoteProcess () { - Object reply = sendRemoteCommand(new BindServer.KillDebugee()); - if (reply instanceof BindServer.OK) { - return; - } else if (reply instanceof BindServer.RequestFailed) { - BindServer.RequestFailed castedReply = (BindServer.RequestFailed)reply; - throw new Failure("BindServer error: " + castedReply.reason); - } else { - throw new Failure("Wrong reply from BindServer: " + reply); - } - } - - /** - * Wait until the remotely launched process exits or crashes - * using request to BindServer. - */ - public int waitForRemoteProcess () { - - Object reply = sendRemoteCommand(new BindServer.WaitForDebugee(0)); - if (reply instanceof BindServer.OK) { - BindServer.OK castedReply = (BindServer.OK)reply; - return (int)castedReply.info; - } else if (reply instanceof BindServer.RequestFailed) { - BindServer.RequestFailed castedReply = (BindServer.RequestFailed)reply; - throw new Failure("BindServer error: " + castedReply.reason); - } else { - throw new Failure("Wrong reply from BindServer: " + reply); - } - } /** * Close binder by closing all started threads. */ public void close() { - if (bindServerListener != null) { - bindServerListener.close(); - } closePipeServerSocket(); } @@ -559,198 +398,4 @@ public void finalizeAtExit() throws Throwable { finalize(); } - /** - * Separate thread for listening connection from BindServer. - */ - private class BindServerListener extends Thread { - private SocketConnection connection = null; - private Log.Logger logger = null; - - /** List of received responses from BindServer. */ - private LinkedList replies = new LinkedList(); - - /** - * Make thread. - */ - public BindServerListener(Log.Logger logger) { - this.logger = logger; - } - - /** - * Establish connection to BindServer. - */ - public void connect(String taskID) throws IOException { - String host = argumentHandler.getDebugeeHost(); - int port = argumentHandler.getBindPortNumber(); - display("Connecting to BindServer: " + host + ":" + port); - connection = new SocketConnection(logger, "BindServer"); -// connection.setPingTimeout(DebugeeBinder.PING_TIMEOUT); - connection.attach(host, port); - handshake(taskID); - } - - /** - * Receive OK(version) from BindServer and check received version number. - */ - private void handshake(String taskID) { - // receive OK(version) - trace(TRACE_LEVEL_ACTIONS, "Waiting for initial OK(version) from BindServer"); - Object reply = connection.readObject(); - trace(TRACE_LEVEL_ACTIONS, "Got initial OK(version) from BindServer: " + reply); - if (reply instanceof BindServer.RequestFailed) { - BindServer.RequestFailed castedReply = (BindServer.RequestFailed)reply; - trace(TRACE_LEVEL_ACTIONS, "Reply is RequestFailed: throw Failure"); - throw new Failure("BindServer error: " + castedReply.reason); - } else if (reply instanceof BindServer.OK) { - BindServer.OK castedReply = (BindServer.OK)reply; - trace(TRACE_LEVEL_ACTIONS, "Reply is OK: check BindServer version"); - if (castedReply.info != BindServer.VERSION) { - throw new Failure("Wrong version of BindServer: " + castedReply.info - + " (expected: " + BindServer.VERSION + ")"); - } - display("Connected to BindServer: version " + castedReply.info); - } else { - trace(TRACE_LEVEL_ACTIONS, "Reply is unknown: throw Failure"); - throw new Failure("Wrong reply from BindServer: " + reply); - } - - // send TaskID(id) - try { - trace(TRACE_LEVEL_ACTIONS, "Sending TaskID(id) to BindServer"); - sendCommand(new BindServer.TaskID(taskID)); - trace(TRACE_LEVEL_ACTIONS, "Sent TaskID(id) to BindServer"); - } catch (IOException e) { - throw new Failure("Caught IOException while sending TaskID(id) to BindServer:\n\t" - + e); - } - } - - /** - * Check if thread is connected to BindServer. - */ - public boolean isConnected() { - return (connection != null && connection.isConnected()); - } - - /** - * Send a command to BindServer. - */ - public synchronized void sendCommand(Object command) throws IOException { - connection.writeObject(command); - } - - /** - * Receive response from BindServer. - */ - public Object getReply() { - synchronized (replies) { - while (replies.isEmpty()) { - if (!isConnected()) { - throw new Failure("No reply from BindServer: connection lost"); - } - try { - replies.wait(TRY_DELAY); - } catch (InterruptedException e) { - e.printStackTrace(getOutStream()); - throw new Failure("Thread interrupted while waiting for reply from BindServer:\n\t" - + e); - } - } - Object reply = replies.removeFirst(); - if (reply == null) { - throw new Failure("No reply from BindServer: connection lost"); - } - return reply; - } - } - - /** - * Add response object to the list of received responses. - */ - private void addReply(BindServer.Response reply) { - synchronized (replies) { - replies.add(reply); - replies.notifyAll(); - } - } - - /** - * Read packets from BindServer connection and - * notify waiting thread if response or IOPipe message received. - * Received lines of redirected streams are put into log. - */ - public void run() { - trace(TRACE_LEVEL_THREADS, "BindServerListener thread started"); - try { - for (;;) { - Object reply = connection.readObject(); - if (reply == null) { - break; - } else if (reply instanceof BindServer.Disconnect) { - reply = null; - trace(TRACE_LEVEL_ACTIONS, "Packet is Disconnect: close connection"); - break; - } else if (reply instanceof BindServer.RedirectedStream) { - BindServer.RedirectedStream castedReply = (BindServer.RedirectedStream)reply; - trace(TRACE_LEVEL_ACTIONS, "Packet is RedirectedStream: put message into log"); - log.println(castedReply.line); - } else if (reply instanceof BindServer.Response) { - BindServer.Response castedReply = (BindServer.Response)reply; - trace(TRACE_LEVEL_ACTIONS, "Packet is reply: notify all threads waiting for reply"); - addReply(castedReply); - } else { - trace(TRACE_LEVEL_ACTIONS, "Packet is unknown: throw Failure"); - throw new Failure("Wrong reply from BindServer: " + reply); - } - } - } catch (Exception e) { - e.printStackTrace(getOutStream()); - complain("Caught exception while reading packets from BindServer:\n\t" + e); - } finally { - closeConnection(); - addReply(null); - trace(TRACE_LEVEL_THREADS, "BindServerListener thread finished"); - } - } - - /** - * Send Disconnect command to BindServer. - */ - public void disconnect() { - if (connection == null) return; - try { - sendCommand(new BindServer.Disconnect()); - } catch (IOException e) { - display("Caught IOException while requesting disconnection with BindServer"); - } - } - - /** - * Close socket connection. - */ - public void closeConnection() { - if (connection != null) { - connection.close(); - } - } - - /** - * Wait for thread finished in the specified timeout or interrupt it. - */ - public void waitForThread(long millis) { - DebugeeBinder.waitForThread(this, millis, logger); - } - - /** - * Close this thread by waiting for it finishes or interrupt it - * and close socket connection. - */ - public void close() { - disconnect(); - waitForThread(DebugeeBinder.THREAD_TIMEOUT); - closeConnection(); - } - - } // BindServerListener - } // DebugeeBinder diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeProcess.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeProcess.java index 40261018a12d2..6d72f86872932 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeProcess.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeProcess.java @@ -74,8 +74,8 @@ abstract public class DebugeeProcess extends FinalizableObject { /** Argument handler from binder. */ protected DebugeeArgumentHandler argumentHandler = null; - /** Need or not to check debuggee process termination at exit. */ - protected boolean checkTermination = false; + /** Need or not to check debuggee process termination. */ + private boolean checkTermination = true; /** Debugee VM process or null if not available. */ protected Process process = null; @@ -164,26 +164,50 @@ public void sendSignal(String signal) { // --------------------------------------------------- // /** Wait until the debugee VM shutdown or crash. */ - abstract protected int waitForDebugee () throws InterruptedException; + protected int waitForDebugee() throws InterruptedException { + return process.waitFor(); + } /** Kill the debugee VM. */ - abstract protected void killDebugee (); + protected void killDebugee() { + if (!terminated()) { + log.display("Killing debugee VM process"); + process.destroy(); + } + } /** Check whether the debugee VM has been terminated. */ - abstract public boolean terminated (); + public boolean terminated() { + if (process == null) + return true; + + try { + int value = process.exitValue(); + return true; + } catch (IllegalThreadStateException e) { + return false; + } + } /** Return the debugee VM exit status. */ - abstract public int getStatus (); + public int getStatus() { + return process.exitValue(); + } /** Get a pipe to write to the debugee's stdin stream. */ - abstract protected OutputStream getInPipe (); + protected OutputStream getInPipe() { + return process.getOutputStream(); + } /** Get a pipe to read the debugee's stdout stream. */ - abstract protected InputStream getOutPipe (); + protected InputStream getOutPipe() { + return process.getInputStream(); + } /** Get a pipe to read the debugee's stderr stream. */ - abstract protected InputStream getErrPipe (); - + protected InputStream getErrPipe() { + return process.getErrorStream(); + } // --------------------------------------------------- // /** From e1cda219b3fea2aa9db7953645299153e4e086df Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 12 May 2025 15:02:04 +0000 Subject: [PATCH 258/846] 8349492: Update sun/security/pkcs12/KeytoolOpensslInteropTest.java to use a recent Openssl version Backport-of: 23469f8de1c6340bc22ef6d9f99740ea9c0e3fe9 --- .../pkcs12/KeytoolOpensslInteropTest.java | 66 ++++++++----- .../lib/security/OpensslArtifactFetcher.java | 97 +++++++++++++------ 2 files changed, 109 insertions(+), 54 deletions(-) diff --git a/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java b/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java index c35bf47d56db1..846f036cd5f25 100644 --- a/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java +++ b/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, 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 @@ -22,7 +22,7 @@ */ /* - * @test + * @test id=GenerateOpensslPKCS12 * @bug 8076190 8242151 8153005 8266182 * @summary This is java keytool <-> openssl interop test. This test generates * some openssl keystores on the fly, java operates on it and @@ -31,13 +31,24 @@ * Note: This test executes some openssl command, so need to set * openssl path using system property "test.openssl.path" or it should * be available in /usr/bin or /usr/local/bin - * Required OpenSSL version : OpenSSL 1.1.* + * Required OpenSSL version : OpensslArtifactFetcher.OPENSSL_BUNDLE_VERSION * * @modules java.base/sun.security.pkcs * java.base/sun.security.util - * @library /test/lib - * @library /sun/security/pkcs11/ - * @run main/othervm/timeout=600 KeytoolOpensslInteropTest + * @library /test/lib /sun/security/pkcs11/ + * @run main/othervm KeytoolOpensslInteropTest true + */ + +/* + * @test id=UseExistingPKCS12 + * @bug 8076190 8242151 8153005 8266182 + * @summary This is java keytool <-> openssl interop test. This test uses + * the existing PKCS12 files located in ./params dir and java operates on it + * + * @modules java.base/sun.security.pkcs + * java.base/sun.security.util + * @library /test/lib /sun/security/pkcs11/ + * @run main/othervm KeytoolOpensslInteropTest false */ import jdk.test.lib.Asserts; @@ -45,6 +56,7 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.security.OpensslArtifactFetcher; +import jtreg.SkippedException; import java.io.File; import java.io.FileInputStream; @@ -67,22 +79,25 @@ public class KeytoolOpensslInteropTest { public static void main(String[] args) throws Throwable { - String opensslPath = OpensslArtifactFetcher.getOpenssl1dot1dotStar(); - if (opensslPath != null) { - // if preferred version of openssl is available perform all - // keytool <-> openssl interop tests - generateInitialKeystores(opensslPath); - testWithJavaCommands(); - testWithOpensslCommands(opensslPath); + boolean generatePKCS12 = Boolean.parseBoolean(args[0]); + if (generatePKCS12) { + String opensslPath = OpensslArtifactFetcher.getOpensslPath(); + if (opensslPath != null) { + // if the current version of openssl is available, perform all + // keytool <-> openssl interop tests + generateInitialKeystores(opensslPath); + testWithJavaCommands(); + testWithOpensslCommands(opensslPath); + } else { + String exMsg = "Can't find the version: " + + OpensslArtifactFetcher.getTestOpensslBundleVersion() + + " of openssl binary on this machine, please install" + + " and set openssl path with property 'test.openssl.path'"; + throw new SkippedException(exMsg); + } } else { - // since preferred version of openssl is not available skip all - // openssl command dependent tests with a warning - System.out.println("\n\u001B[31mWarning: Can't find openssl " - + "(version 1.1.*) binary on this machine, please install" - + " and set openssl path with property " - + "'test.openssl.path'. Now running only half portion of " - + "the test, skipping all tests which depends on openssl " - + "commands.\u001B[0m\n"); + // since this scenario is using preexisting PKCS12, skip all + // openssl command dependent tests // De-BASE64 textual files in ./params to `pwd` try (DirectoryStream stream = Files.newDirectoryStream( Path.of(System.getProperty("test.src"), "params"), @@ -103,6 +118,8 @@ public static void main(String[] args) throws Throwable { private static void generateInitialKeystores(String opensslPath) throws Throwable { + Path providerPath = OpensslArtifactFetcher.getProviderPath(opensslPath); + keytool("-keystore ks -keyalg ec -genkeypair -storepass" + " changeit -alias a -dname CN=A").shouldHaveExitValue(0); @@ -123,7 +140,8 @@ private static void generateInitialKeystores(String opensslPath) ProcessTools.executeCommand(opensslPath, "pkcs12", "-export", "-in", "kandc", "-out", "os4", "-name", "a", "-passout", "pass:changeit", "-certpbe", "PBE-SHA1-RC4-128", "-keypbe", - "PBE-SHA1-RC4-128", "-macalg", "SHA224") + "PBE-SHA1-RC4-128", "-macalg", "SHA224", + "-legacy", "-provider-path", providerPath.toString()) .shouldHaveExitValue(0); ProcessTools.executeCommand(opensslPath, "pkcs12", "-export", "-in", @@ -480,12 +498,14 @@ private static void testWithOpensslCommands(String opensslPath) output1 = ProcessTools.executeCommand(opensslPath, "pkcs12", "-in", "ksnopass", "-passin", "pass:changeit", "-info", "-nokeys", "-nocerts"); - output1.shouldNotHaveExitValue(0); + output1.shouldHaveExitValue(0) + .shouldContain("Warning: MAC is absent!"); output1 = ProcessTools.executeCommand(opensslPath, "pkcs12", "-in", "ksnopass", "-passin", "pass:changeit", "-info", "-nokeys", "-nocerts", "-nomacver"); output1.shouldHaveExitValue(0) + .shouldNotContain("Warning: MAC is absent!") .shouldNotContain("PKCS7 Encrypted data:") .shouldContain("Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC," + " Iteration 10000, PRF hmacWithSHA256") diff --git a/test/lib/jdk/test/lib/security/OpensslArtifactFetcher.java b/test/lib/jdk/test/lib/security/OpensslArtifactFetcher.java index 55ff8c9ef98b0..5035fae1bc4ca 100644 --- a/test/lib/jdk/test/lib/security/OpensslArtifactFetcher.java +++ b/test/lib/jdk/test/lib/security/OpensslArtifactFetcher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, 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 @@ -25,6 +25,7 @@ import java.io.File; +import java.nio.file.Path; import jdk.test.lib.Platform; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.artifacts.Artifact; @@ -33,43 +34,49 @@ public class OpensslArtifactFetcher { + private static final String OPENSSL_BUNDLE_VERSION = "3.0.14"; + private static final String OPENSSL_ORG = "jpg.tests.jdk.openssl"; + /** - * Gets the openssl binary path of version 1.1.* + * Gets the openssl binary path of OPENSSL_BUNDLE_VERSION * * Openssl selection flow: 1. Check whether property test.openssl.path is set and it's the - preferred version(1.1.*) of openssl, then return that path. - 2. Else look for already installed openssl (version 1.1.*) in system + current version of openssl, then return that path. + 2. Else look for already installed openssl in system path /usr/bin/openssl or /usr/local/bin/openssl, then return that path. - 3. Else try to download openssl (version 1.1.*) from the artifactory + 3. Else try to download the current version of openssl from the artifactory and return that path, if download fails then return null. * - * @return openssl binary path of version 1.1.* + * @return openssl binary path of the current version */ - public static String getOpenssl1dot1dotStar() { - String version = "1.1."; - String path = getOpensslFromSystemProp(version); + public static String getOpensslPath() { + String path = getOpensslFromSystemProp(OPENSSL_BUNDLE_VERSION); if (path != null) { return path; - } else { - path = getDefaultSystemOpensslPath(version); - if (path != null) { - return path; - } else if (Platform.is64bit()) { - if (Platform.isLinux()) { - path = fetchOpenssl(LINUX_X64.class); - } else if (Platform.isOSX()) { - path = fetchOpenssl(MACOSX_X64.class); - } else if (Platform.isWindows()) { - path = fetchOpenssl(WINDOWS_X64.class); - } - if (verifyOpensslVersion(path, version)) { - return path; - } + } + path = getDefaultSystemOpensslPath(OPENSSL_BUNDLE_VERSION); + if (path != null) { + return path; + } + if (Platform.isX64()) { + if (Platform.isLinux()) { + path = fetchOpenssl(LINUX_X64.class); + } else if (Platform.isOSX()) { + path = fetchOpenssl(MACOSX_X64.class); + } else if (Platform.isWindows()) { + path = fetchOpenssl(WINDOWS_X64.class); + } + } else if (Platform.isAArch64()) { + if (Platform.isLinux()) { + path = fetchOpenssl(LINUX_AARCH64.class); + } + if (Platform.isOSX()) { + path = fetchOpenssl(MACOSX_AARCH64.class); } } - return null; + return verifyOpensslVersion(path, OPENSSL_BUNDLE_VERSION) ? path : null; } private static String getOpensslFromSystemProp(String version) { @@ -124,24 +131,52 @@ private static String fetchOpenssl(Class clazz) { return path; } + // retrieve the provider directory path from /bin/openssl + public static Path getProviderPath(String opensslPath) { + Path openSslRootPath = Path.of(opensslPath).getParent().getParent(); + String libDir = "lib"; + if (Platform.isX64() && (Platform.isLinux() || Platform.isWindows())) { + libDir = "lib64"; + } + return openSslRootPath.resolve(libDir).resolve("ossl-modules"); + } + + public static String getTestOpensslBundleVersion() { + return OPENSSL_BUNDLE_VERSION; + } + @Artifact( - organization = "jpg.tests.jdk.openssl", + organization = OPENSSL_ORG, name = "openssl-linux_x64", - revision = "1.1.1g", + revision = OPENSSL_BUNDLE_VERSION, extension = "zip") private static class LINUX_X64 { } @Artifact( - organization = "jpg.tests.jdk.openssl", + organization = OPENSSL_ORG, + name = "openssl-linux_aarch64", + revision = OPENSSL_BUNDLE_VERSION, + extension = "zip") + private static class LINUX_AARCH64{ } + + @Artifact( + organization = OPENSSL_ORG, name = "openssl-macosx_x64", - revision = "1.1.1g", + revision = OPENSSL_BUNDLE_VERSION, extension = "zip") private static class MACOSX_X64 { } @Artifact( - organization = "jpg.tests.jdk.openssl", + organization = OPENSSL_ORG, + name = "openssl-macosx_aarch64", + revision = OPENSSL_BUNDLE_VERSION, + extension = "zip") + private static class MACOSX_AARCH64 { } + + @Artifact( + organization = OPENSSL_ORG, name = "openssl-windows_x64", - revision = "1.1.1g", + revision = OPENSSL_BUNDLE_VERSION, extension = "zip") private static class WINDOWS_X64 { } } From 9fe019ddca8d0dba79fe1841cb96ad5ce3d8e2fd Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Wed, 14 May 2025 22:19:04 +0000 Subject: [PATCH 259/846] 8356053: Test java/awt/Toolkit/Headless/HeadlessToolkit.java fails by timeout Backport-of: 375f3dc9ed0f1704e726d0d704420c38a0a5513c --- .../awt/Toolkit/Headless/HeadlessToolkit.java | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/test/jdk/java/awt/Toolkit/Headless/HeadlessToolkit.java b/test/jdk/java/awt/Toolkit/Headless/HeadlessToolkit.java index 87970aab10a25..ebf4c598a15c0 100644 --- a/test/jdk/java/awt/Toolkit/Headless/HeadlessToolkit.java +++ b/test/jdk/java/awt/Toolkit/Headless/HeadlessToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, 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 @@ -21,8 +21,20 @@ * questions. */ -import javax.imageio.ImageIO; -import java.awt.*; +import java.awt.AWTEvent; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.HeadlessException; +import java.awt.Image; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.event.AWTEventListener; import java.awt.event.KeyEvent; @@ -35,16 +47,16 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.net.URL; import java.util.Map; +import javax.imageio.ImageIO; + /* * @test * @summary Check that Toolkit methods do not throw unexpected exceptions * in headless mode * @run main/othervm -Djava.awt.headless=true HeadlessToolkit */ - public class HeadlessToolkit { class awtEventListener implements AWTEventListener { @@ -275,13 +287,12 @@ void doTest() throws IOException { im = tk.createImage(image.getAbsolutePath()); im.flush(); - } - - im = tk.getImage(new URL("https://openjdk.org/images/openjdk.png")); - im.flush(); + im = tk.getImage(image.toURI().toURL()); + im.flush(); - im = tk.createImage(new URL("https://openjdk.org/images/openjdk.png")); - im.flush(); + im = tk.createImage(image.toURI().toURL()); + im.flush(); + } MemoryImageSource mis; int pixels[] = new int[50 * 50]; From b5f25e0df4bec818c64d734f65425ab5620d834c Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Thu, 15 May 2025 17:02:36 +0000 Subject: [PATCH 260/846] 8356571: Re-enable -Wtype-limits for GCC in LCMS Reviewed-by: phh Backport-of: 9a0e6f338f34fb5da16d5f9eb710cdddd4302945 --- make/modules/java.desktop/lib/Awt2dLibraries.gmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/modules/java.desktop/lib/Awt2dLibraries.gmk b/make/modules/java.desktop/lib/Awt2dLibraries.gmk index 4ac1ea6acb943..5b92445774d81 100644 --- a/make/modules/java.desktop/lib/Awt2dLibraries.gmk +++ b/make/modules/java.desktop/lib/Awt2dLibraries.gmk @@ -299,7 +299,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBLCMS, \ common/awt/debug \ libawt/java2d, \ HEADERS_FROM_SRC := $(LIBLCMS_HEADERS_FROM_SRC), \ - DISABLED_WARNINGS_gcc := format-nonliteral type-limits \ + DISABLED_WARNINGS_gcc := format-nonliteral \ misleading-indentation undef unused-function stringop-truncation, \ DISABLED_WARNINGS_clang := tautological-compare format-nonliteral undef, \ DISABLED_WARNINGS_microsoft := 4819, \ From f3b92446a681413393bd51eb5771708b8e154d92 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 16 May 2025 08:19:06 +0000 Subject: [PATCH 261/846] 8286925: Move JSON parser used in JFR tests to test library Backport-of: ac7e019232903db38a03f644c3d31c858cbf3967 --- test/jdk/jdk/jfr/tool/TestPrintJSON.java | 3 ++- .../jdk/jfr/tool => lib/jdk/test/lib/json}/JSONValue.java | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) rename test/{jdk/jdk/jfr/tool => lib/jdk/test/lib/json}/JSONValue.java (99%) diff --git a/test/jdk/jdk/jfr/tool/TestPrintJSON.java b/test/jdk/jdk/jfr/tool/TestPrintJSON.java index bfa22aae8793a..6a8977a672e66 100644 --- a/test/jdk/jdk/jfr/tool/TestPrintJSON.java +++ b/test/jdk/jdk/jfr/tool/TestPrintJSON.java @@ -35,7 +35,8 @@ import jdk.jfr.consumer.RecordedEvent; import jdk.jfr.consumer.RecordedObject; import jdk.jfr.consumer.RecordingFile; -import jdk.jfr.tool.JSONValue.JSONArray; +import jdk.test.lib.json.JSONValue; +import jdk.test.lib.json.JSONValue.JSONArray; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; diff --git a/test/jdk/jdk/jfr/tool/JSONValue.java b/test/lib/jdk/test/lib/json/JSONValue.java similarity index 99% rename from test/jdk/jdk/jfr/tool/JSONValue.java rename to test/lib/jdk/test/lib/json/JSONValue.java index 27c63116c8825..d1092f06c3e13 100644 --- a/test/jdk/jdk/jfr/tool/JSONValue.java +++ b/test/lib/jdk/test/lib/json/JSONValue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, 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 @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.jfr.tool; +package jdk.test.lib.json; import java.util.ArrayList; import java.util.HashMap; From 3607554bdf7b1da5cc0750243770ff026b90bdaf Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 16 May 2025 08:20:13 +0000 Subject: [PATCH 262/846] 8287352: DockerTestUtils::execute shows incorrect elapsed time Backport-of: ec97da93c1d5bfcb80c19c15169f41926e59517b --- .../containers/docker/DockerTestUtils.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java index efabd79296420..2404394690ebd 100644 --- a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java +++ b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java @@ -275,7 +275,6 @@ public static OutputAnalyzer execute(List command) throws Exception { * @throws Exception */ public static OutputAnalyzer execute(String... command) throws Exception { - ProcessBuilder pb = new ProcessBuilder(command); System.out.println("[COMMAND]\n" + Utils.getCommandLine(pb)); @@ -284,14 +283,19 @@ public static OutputAnalyzer execute(String... command) throws Exception { long pid = p.pid(); OutputAnalyzer output = new OutputAnalyzer(p); - String stdoutLogFile = String.format("docker-stdout-%d.log", pid); + int max = MAX_LINES_TO_COPY_FOR_CHILD_STDOUT; + String stdout = output.getStdout(); + String stdoutLimited = limitLines(stdout, max); System.out.println("[ELAPSED: " + (System.currentTimeMillis() - started) + " ms]"); System.out.println("[STDERR]\n" + output.getStderr()); - System.out.println("[STDOUT]\n" + - trimLines(output.getStdout(),MAX_LINES_TO_COPY_FOR_CHILD_STDOUT)); - System.out.printf("Child process STDOUT is trimmed to %d lines \n", - MAX_LINES_TO_COPY_FOR_CHILD_STDOUT); - writeOutputToFile(output.getStdout(), stdoutLogFile); + System.out.println("[STDOUT]\n" + stdoutLimited); + if (stdout != stdoutLimited) { + System.out.printf("Child process STDOUT is limited to %d lines\n", + max); + } + + String stdoutLogFile = String.format("docker-stdout-%d.log", pid); + writeOutputToFile(stdout, stdoutLogFile); System.out.println("Full child process STDOUT was saved to " + stdoutLogFile); return output; @@ -305,7 +309,7 @@ private static void writeOutputToFile(String output, String fileName) throws Exc } - private static String trimLines(String buffer, int nrOfLines) { + private static String limitLines(String buffer, int nrOfLines) { List l = Arrays.asList(buffer.split("\\R")); if (l.size() < nrOfLines) { return buffer; From 27c553e53ea6e58bac411c1d752f0994714b75e4 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 16 May 2025 08:21:35 +0000 Subject: [PATCH 263/846] 8326389: [test] improve assertEquals failure output Backport-of: 9b1f1e5294e130ec444b08af1f73d08e86fd91ee --- test/lib/jdk/test/lib/Asserts.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/lib/jdk/test/lib/Asserts.java b/test/lib/jdk/test/lib/Asserts.java index 5abe03d6c47cb..2c1a750a91f82 100644 --- a/test/lib/jdk/test/lib/Asserts.java +++ b/test/lib/jdk/test/lib/Asserts.java @@ -199,10 +199,7 @@ public static void assertEquals(Object lhs, Object rhs) { */ public static void assertEquals(Object lhs, Object rhs, String msg) { if ((lhs != rhs) && ((lhs == null) || !(lhs.equals(rhs)))) { - msg = Objects.toString(msg, "assertEquals") - + ": expected " + Objects.toString(lhs) - + " to equal " + Objects.toString(rhs); - fail(msg); + fail((msg == null ? "assertEquals" : msg) + " expected: " + lhs + " but was: " + rhs); } } From 129a4bb15c44dbd3e0ade5a9e36dbff97500fd31 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 16 May 2025 08:22:55 +0000 Subject: [PATCH 264/846] 8328673: Convert closed text/html/CSS manual applet test to main Backport-of: cd534f8197341fbe3b3811f5be43c88090e16366 --- .../javax/swing/text/html/CSS/bug4271058.java | 92 +++++++++++++++++++ .../javax/swing/text/html/CSS/bug4286458.java | 69 ++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 test/jdk/javax/swing/text/html/CSS/bug4271058.java create mode 100644 test/jdk/javax/swing/text/html/CSS/bug4286458.java diff --git a/test/jdk/javax/swing/text/html/CSS/bug4271058.java b/test/jdk/javax/swing/text/html/CSS/bug4271058.java new file mode 100644 index 0000000000000..83aad377b1def --- /dev/null +++ b/test/jdk/javax/swing/text/html/CSS/bug4271058.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4270889 4271058 4285098 + * @summary Tests that ,
    and
    tags work + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4271058 +*/ + +import javax.swing.JEditorPane; +import javax.swing.JFrame; + +public class bug4271058 { + + private static String INSTRUCTIONS = """ + What should be seen is three 2x2 tables. + + The first table should have borders and lines distinguishing + table cells. If they are not shown, test fails (bug 4271058). + + In the second table, the first (left) column should be about + four times as wide as the second (right) column. + If this is not so, test fails (bug 4270889). + + The third table should be right aligned, i.e. its right edge + should be close to the right edge of the viewable area. + Otherwise test fails (bug 4285098). + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("CSS html tag verification Instructions") + .instructions(INSTRUCTIONS) + .rows(15) + .columns(30) + .testUI(bug4271058::createTestUI) + .screenCapture() + .build() + .awaitAndCheck(); + } + + private static JFrame createTestUI() { + String htmlText = + "" + + "" + + "" + + "" + + "" + + "
    col Acol B
    aaaaaabbbbbbb
    " + + "" + + "" + + "" + + "" + + "" + + "
    AB
    ab
    " + + "" + + "" + + "" + + "" + + "" + + "
    col Acol B
    aaaaaabbbbbbb
    "; + + JEditorPane lbl = new JEditorPane("text/html", htmlText); + JFrame frame = new JFrame("bug4271058"); + frame.add(lbl); + frame.pack(); + return frame; + } +} diff --git a/test/jdk/javax/swing/text/html/CSS/bug4286458.java b/test/jdk/javax/swing/text/html/CSS/bug4286458.java new file mode 100644 index 0000000000000..110967d9e1dd7 --- /dev/null +++ b/test/jdk/javax/swing/text/html/CSS/bug4286458.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4286458 + * @summary Tests if cellpadding in tables is non-negative number + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4286458 +*/ + +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.text.html.HTMLEditorKit; + +public class bug4286458 { + + private static String INSTRUCTIONS = """ + If you can clearly read the line of text in the appeared frame + press PASS. Otherwise test fails."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("CSS tag Instructions") + .instructions(INSTRUCTIONS) + .rows(5) + .columns(30) + .testUI(bug4286458::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createTestUI() { + + String text = + "" + + "" + + "
    This line should be clearly readable
    "; + + JFrame f = new JFrame("bug4286458"); + JEditorPane jep = new JEditorPane("text/html", text); + jep.setEditable(false); + + f.add(jep); + f.pack(); + return f; + } +} From 2f00379816f711b838b13be17b8e07b6e57f9e99 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 16 May 2025 08:24:32 +0000 Subject: [PATCH 265/846] 8345447: test/jdk/javax/swing/JToolBar/4529206/bug4529206.java fails in ubuntu22.04 Backport-of: 923321cfb1a9c66ca0e8f843ff029fd161a19b5b --- .../javax/swing/JToolBar/4529206/bug4529206.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java b/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java index ed4f062b24cc2..56f4a224e3b10 100644 --- a/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java +++ b/test/jdk/javax/swing/JToolBar/4529206/bug4529206.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import javax.swing.JTextField; import javax.swing.JToolBar; import javax.swing.SwingUtilities; +import javax.swing.plaf.basic.BasicToolBarUI; /* * @test @@ -45,7 +46,7 @@ public class bug4529206 { static JButton jButton1; private static void test() { - frame = new JFrame(); + frame = new JFrame("bug4529206"); JPanel jPanFrame = (JPanel) frame.getContentPane(); jPanFrame.setLayout(new BorderLayout()); frame.setSize(new Dimension(200, 100)); @@ -64,7 +65,7 @@ private static void test() { } private static void makeToolbarFloat() { - javax.swing.plaf.basic.BasicToolBarUI ui = (javax.swing.plaf.basic.BasicToolBarUI) jToolBar1.getUI(); + BasicToolBarUI ui = (BasicToolBarUI) jToolBar1.getUI(); if (!ui.isFloating()) { ui.setFloatingLocation(100, 100); ui.setFloating(true, jToolBar1.getLocation()); @@ -79,16 +80,17 @@ public static void main(String[] args) throws Exception { try { SwingUtilities.invokeAndWait(() -> test()); Robot robot = new Robot(); - robot.setAutoWaitForIdle(true); + robot.waitForIdle(); robot.delay(1000); SwingUtilities.invokeAndWait(() -> makeToolbarFloat()); + robot.waitForIdle(); robot.delay(300); SwingUtilities.invokeAndWait(() -> { if (frame.isFocused()) { - throw - new RuntimeException("setFloating does not work correctly"); + throw new RuntimeException( + "setFloating does not work correctly"); } }); } finally { From 4c6f3b407dd4ba55202b353a9afbed0f26477548 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 16 May 2025 08:25:40 +0000 Subject: [PATCH 266/846] 8345547: test/jdk/javax/swing/text/DefaultEditorKit/4278839/bug4278839.java fails in ubuntu22.04 Backport-of: e46d822aebee02d3cb4862c204293d388f6f3466 --- .../DefaultEditorKit/4278839/bug4278839.java | 51 +++++++++---------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/test/jdk/javax/swing/text/DefaultEditorKit/4278839/bug4278839.java b/test/jdk/javax/swing/text/DefaultEditorKit/4278839/bug4278839.java index e67d2ddb5884a..980a9c9f52819 100644 --- a/test/jdk/javax/swing/text/DefaultEditorKit/4278839/bug4278839.java +++ b/test/jdk/javax/swing/text/DefaultEditorKit/4278839/bug4278839.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,17 +26,22 @@ * @key headful * @bug 4278839 8233634 * @summary Incorrect cursor movement between words at the end of line - * @author Anton Nashatyrev * @library ../../../regtesthelpers * @build Util * @run main bug4278839 */ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.awt.event.InputEvent; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; -public class bug4278839 extends JFrame { +public class bug4278839 { private static boolean passed = true; private static JTextArea area; @@ -47,16 +52,12 @@ public static void main(String[] args) throws Exception { try { robo = new Robot(); - robo.setAutoDelay(200); + robo.setAutoDelay(100); - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { - createAndShowGUI(); - } - }); + SwingUtilities.invokeAndWait(() -> createAndShowGUI()); robo.waitForIdle(); + robo.delay(1000); clickMouse(); robo.waitForIdle(); @@ -100,33 +101,27 @@ private static int moveCaret(boolean right) throws Exception { final int[] result = new int[1]; - SwingUtilities.invokeAndWait(new Runnable() { - - @Override - public void run() { - result[0] = area.getCaretPosition(); - } + SwingUtilities.invokeAndWait(() -> { + result[0] = area.getCaretPosition(); }); - int pos = result[0]; - return pos; + return result[0]; } private static void clickMouse() throws Exception { final Rectangle result[] = new Rectangle[1]; - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { - result[0] = new Rectangle(area.getLocationOnScreen(), area.getSize()); - } + SwingUtilities.invokeAndWait(() -> { + result[0] = new Rectangle(area.getLocationOnScreen(), area.getSize()); }); Rectangle rect = result[0]; robo.mouseMove(rect.x + rect.width / 2, rect.y + rect.width / 2); - robo.mousePress(InputEvent.BUTTON1_MASK); - robo.mouseRelease(InputEvent.BUTTON1_MASK); + robo.waitForIdle(); + robo.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robo.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robo.waitForIdle(); } /** From e1b5ce3b9544dd10c2e6e725ee8ff517c5a2a3ce Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 16 May 2025 08:27:07 +0000 Subject: [PATCH 267/846] 8350383: Test: add more test case for string compare (UL case) Backport-of: c73fead5caea8008586b31a5009c64011637b8cc --- .../jtreg/compiler/intrinsics/string/TestStringIntrinsics.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIntrinsics.java b/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIntrinsics.java index 659840293975b..062866d657f96 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIntrinsics.java +++ b/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIntrinsics.java @@ -155,6 +155,7 @@ private void checkIntrinsics(Operation op, Method m, String latin1, String utf16 char cL = latin1.charAt(indexL); char cU = utf16.charAt(indexU); invokeAndCheck(m, cL - cU, latin1, latin1.replace(cL, cU)); + invokeAndCheck(m, cU - cL, latin1.replace(cL, cU), latin1); invokeAndCheck(m, cU - cL, utf16, utf16.replace(cU, cL)); // Different lengths From fffc635079a0d9b281302676a0c5c4485a66c72a Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 16 May 2025 08:28:54 +0000 Subject: [PATCH 268/846] 8350546: Several java/net/InetAddress tests fails UnknownHostException Backport-of: caaf4098452476d981183ad4302b76b9c883a72b --- .../InetAddress/IsReachableViaLoopbackTest.java | 15 ++++++++------- .../java/net/InetAddress/getOriginalHostName.java | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/test/jdk/java/net/InetAddress/IsReachableViaLoopbackTest.java b/test/jdk/java/net/InetAddress/IsReachableViaLoopbackTest.java index 4d340a72fba21..2f2ad0ac7ddf4 100644 --- a/test/jdk/java/net/InetAddress/IsReachableViaLoopbackTest.java +++ b/test/jdk/java/net/InetAddress/IsReachableViaLoopbackTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -21,22 +21,24 @@ * questions. */ -import java.io.*; -import java.net.*; -import java.util.*; +import java.io.IOException; +import java.net.InetAddress; +import java.net.NetworkInterface; /** * @test * @bug 8135305 * @key intermittent + * @library /test/lib * @summary ensure we can't ping external hosts via loopback if + * @run main IsReachableViaLoopbackTest */ public class IsReachableViaLoopbackTest { public static void main(String[] args) { try { - InetAddress addr = InetAddress.getByName("localhost"); - InetAddress remoteAddr = InetAddress.getByName("bugs.openjdk.org"); + InetAddress addr = InetAddress.getLoopbackAddress(); + InetAddress remoteAddr = InetAddress.getByName("23.197.138.208"); // use literal address to avoid DNS checks if (!addr.isReachable(10000)) throw new RuntimeException("Localhost should always be reachable"); NetworkInterface inf = NetworkInterface.getByInetAddress(addr); @@ -54,7 +56,6 @@ public static void main(String[] args) { } else { System.out.println("inf == null"); } - } catch (IOException e) { throw new RuntimeException("Unexpected exception:" + e); } diff --git a/test/jdk/java/net/InetAddress/getOriginalHostName.java b/test/jdk/java/net/InetAddress/getOriginalHostName.java index 9f1e6e965d178..71567a7915d65 100644 --- a/test/jdk/java/net/InetAddress/getOriginalHostName.java +++ b/test/jdk/java/net/InetAddress/getOriginalHostName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -41,7 +41,9 @@ public class getOriginalHostName { public static void main(String[] args) throws Exception { final String HOST = "dummyserver.java.net"; InetAddress ia = null; - ia = InetAddress.getByName(HOST); + ia = getInetAddress(HOST); + if (ia != null) testInetAddress(ia, HOST); + ia = InetAddress.getByAddress(HOST, new byte[] { 1, 2, 3, 4}); testInetAddress(ia, HOST); ia = InetAddress.getByName("255.255.255.0"); testInetAddress(ia, null); @@ -53,6 +55,14 @@ public static void main(String[] args) throws Exception { testInetAddress(ia, ia.getHostName()); } + private static InetAddress getInetAddress(String host) { + try { + return InetAddress.getByName(host); + } catch (java.net.UnknownHostException uhe) { + System.out.println("Skipping " + host + " due to " + uhe); + return null; + } + } private static void testInetAddress(InetAddress ia, String expected) throws Exception { From 4c59024073b11cf7b1ad52d0da006494ed6c382f Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 16 May 2025 08:30:10 +0000 Subject: [PATCH 269/846] 8352676: Opensource JMenu tests - series1 Backport-of: c002b97ee99c1889aa89e0a8853beafaf0969e9c --- test/jdk/javax/swing/JMenu/bug4140643.java | 107 +++++++++++++++++++++ test/jdk/javax/swing/JMenu/bug4146588.java | 100 +++++++++++++++++++ test/jdk/javax/swing/JMenu/bug4342646.java | 90 +++++++++++++++++ 3 files changed, 297 insertions(+) create mode 100644 test/jdk/javax/swing/JMenu/bug4140643.java create mode 100644 test/jdk/javax/swing/JMenu/bug4146588.java create mode 100644 test/jdk/javax/swing/JMenu/bug4342646.java diff --git a/test/jdk/javax/swing/JMenu/bug4140643.java b/test/jdk/javax/swing/JMenu/bug4140643.java new file mode 100644 index 0000000000000..e9205dfcfc633 --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4140643.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2001, 2025, 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 4140643 + * @summary Tests that Motif menus open with both Alt-key and Meta-key + * @key headful + * @run main bug4140643 + */ + +import java.awt.Robot; +import java.awt.event.KeyEvent; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +public class bug4140643 { + private static JFrame frame; + private static JMenu menu; + private static volatile boolean isPopMenuVisible; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + try { + SwingUtilities.invokeAndWait(() -> { + try { + UIManager.setLookAndFeel( + "com.sun.java.swing.plaf.motif.MotifLookAndFeel"); + } catch (ClassNotFoundException | InstantiationException + | UnsupportedLookAndFeelException + | IllegalAccessException e) { + throw new RuntimeException(e); + } + frame = new JFrame("bug4140643"); + + menu = new JMenu("File"); + menu.setMnemonic(KeyEvent.VK_F); + menu.add(new JMenuItem("Open...")); + menu.add(new JMenuItem("Save")); + + JMenuBar mbar = new JMenuBar(); + mbar.add(menu); + frame.setJMenuBar(mbar); + + frame.add(new JButton("Click Here")); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + if (System.getProperty("os.name").contains("OS X")) { + robot.keyPress(KeyEvent.VK_CONTROL); + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_F); + robot.keyRelease(KeyEvent.VK_F); + robot.keyRelease(KeyEvent.VK_ALT); + robot.keyRelease(KeyEvent.VK_CONTROL); + } else { + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_F); + robot.keyRelease(KeyEvent.VK_F); + robot.keyRelease(KeyEvent.VK_ALT); + } + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + isPopMenuVisible = menu.isPopupMenuVisible(); + }); + if (!isPopMenuVisible) { + throw new RuntimeException("Menu popup is not shown"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/javax/swing/JMenu/bug4146588.java b/test/jdk/javax/swing/JMenu/bug4146588.java new file mode 100644 index 0000000000000..a27380daa230a --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4146588.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2001, 2025, 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 4146588 + * @summary JMenu.setMenuLocation has no effect + * @key headful + * @run main bug4146588 + */ + +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.SwingUtilities; + +public class bug4146588 { + + private static JFrame fr; + private static JMenu menu; + private static volatile Point loc; + private static volatile Point popupLoc; + private static volatile Point menuLoc; + private static volatile Rectangle frameBounds; + private static volatile Rectangle popupBounds; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + try { + SwingUtilities.invokeAndWait(() -> { + fr = new JFrame("bug4146588 frame"); + + JMenuBar menubar = new JMenuBar(); + menu = new JMenu("Menu"); + menu.add("Item 1"); + menu.add("Item 2"); + menu.add("Item 3"); + menu.setMenuLocation(150, 150); + menubar.add(menu); + fr.setJMenuBar(menubar); + + fr.setSize(400, 400); + fr.setLocationRelativeTo(null); + fr.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + menu.doClick(0); + }); + robot.waitForIdle(); + robot.delay(200); + SwingUtilities.invokeAndWait(() -> { + popupLoc = menu.getPopupMenu().getLocationOnScreen(); + menuLoc = menu.getLocationOnScreen(); + frameBounds = fr.getBounds(); + popupBounds = menu.getPopupMenu().getBounds(); + }); + System.out.println(popupLoc); + System.out.println(popupBounds); + System.out.println(frameBounds); + System.out.println(menuLoc); + if (!(popupLoc.getX() + > ((frameBounds.getX() + frameBounds.getWidth() / 2) - popupBounds.getWidth())) + && (popupLoc.getY() + > ((frameBounds.getY() + frameBounds.getHeight() / 2) - popupBounds.getHeight()))) { + throw new RuntimeException("popup is not at center of frame"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (fr != null) { + fr.dispose(); + } + }); + } + } +} diff --git a/test/jdk/javax/swing/JMenu/bug4342646.java b/test/jdk/javax/swing/JMenu/bug4342646.java new file mode 100644 index 0000000000000..610eb349bcfde --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4342646.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2001, 2025, 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 4342646 + * @summary Tests that very long menus are properly placed on the screen. + * @key headful + * @run main bug4342646 + */ + +import java.awt.Point; +import java.awt.Robot; + +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.SwingUtilities; + +public class bug4342646 { + + private static JFrame frame; + private static JMenu menu; + private static volatile Point popupLoc; + private static volatile Point menuLoc; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + try { + SwingUtilities.invokeAndWait(() -> { + JMenuBar mbar = new JMenuBar(); + menu = new JMenu("Menu"); + menu.add(new JMenuItem( + "AAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAA")); + mbar.add(menu); + + frame = new JFrame("4342646"); + frame.setJMenuBar(mbar); + frame.setBounds(10, 10, 200, 100); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + menu.doClick(); + }); + robot.waitForIdle(); + robot.delay(200); + SwingUtilities.invokeAndWait(() -> { + popupLoc = menu.getPopupMenu().getLocationOnScreen(); + menuLoc = menu.getLocationOnScreen(); + }); + System.out.println(menuLoc); + System.out.println(popupLoc); + if (popupLoc.getX() < menuLoc.getX()) { + throw new RuntimeException("PopupMenu is incorrectly placed at left of menu"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} From 5be7a70c6015d509cbe00a36d44aa17afc139d92 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 19 May 2025 06:00:57 +0000 Subject: [PATCH 270/846] 8352680: Opensource few misc swing tests Backport-of: c0b61d3b8820a38a9757a1a3e69da43014d24439 --- test/jdk/javax/swing/JFrame/bug4614881.java | 66 +++++++ .../swing/JMenuItem/RightLeftOrientation.java | 166 ++++++++++++++++ .../jdk/javax/swing/JMenuItem/bug4729669.java | 186 ++++++++++++++++++ 3 files changed, 418 insertions(+) create mode 100644 test/jdk/javax/swing/JFrame/bug4614881.java create mode 100644 test/jdk/javax/swing/JMenuItem/RightLeftOrientation.java create mode 100644 test/jdk/javax/swing/JMenuItem/bug4729669.java diff --git a/test/jdk/javax/swing/JFrame/bug4614881.java b/test/jdk/javax/swing/JFrame/bug4614881.java new file mode 100644 index 0000000000000..bbefc1ebf3c29 --- /dev/null +++ b/test/jdk/javax/swing/JFrame/bug4614881.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2002, 2025, 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 4614881 + * @summary Ensure that client decorated frames can be brought to the front + * via mouse click on the title pane. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4614881 + */ + +import java.awt.FlowLayout; +import java.awt.Toolkit; +import javax.swing.JDialog; +import javax.swing.JFrame; + +public class bug4614881 { + + private static final String INSTRUCTIONS = """ + Select a native window so that it obscures the client decorated frame. + Select the decorated frame by clicking on the title pane. + If the decorated frame is brought to the front, then test passes else fails."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("bug4614881 Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(bug4614881::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createTestUI() { + Toolkit.getDefaultToolkit().setDynamicLayout(true); + JFrame.setDefaultLookAndFeelDecorated(true); + JDialog.setDefaultLookAndFeelDecorated(true); + final JFrame frame = new JFrame("4614881 - Decorated Frame"); + frame.setSize(600, 400); + frame.setResizable(false); + frame.getContentPane().setLayout(new FlowLayout()); + return frame; + } +} diff --git a/test/jdk/javax/swing/JMenuItem/RightLeftOrientation.java b/test/jdk/javax/swing/JMenuItem/RightLeftOrientation.java new file mode 100644 index 0000000000000..6c7185b547ac9 --- /dev/null +++ b/test/jdk/javax/swing/JMenuItem/RightLeftOrientation.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 1999, 2025, 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 4211052 + * @requires (os.family == "windows") + * @summary + * This test checks if menu items lay out correctly when their + * ComponentOrientation property is set to RIGHT_TO_LEFT. + * The tester is asked to compare left-to-right and + * right-to-left menus and judge whether they are mirror images of each + * other. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual RightLeftOrientation + */ + +import java.awt.Color; +import java.awt.Component; +import java.awt.ComponentOrientation; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; + +import javax.swing.Icon; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.KeyStroke; +import javax.swing.LookAndFeel; +import javax.swing.SwingConstants; +import javax.swing.UIManager; + +public class RightLeftOrientation { + + private static final String INSTRUCTIONS = """ + A menu bar is shown containing a menu for each look and feel. + A disabled menu means that the look and feel is not available for + testing in this environment. + Every effort should be made to run this test + in an environment that covers all look and feels. + + Each menu is divided into two halves. The upper half is oriented + left-to-right and the lower half is oriented right-to-left. + For each menu, ensure that the lower half mirrors the upper half. + + Note that when checking the positioning of the sub-menus, it + helps to position the frame away from the screen edges."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("RightLeftOrientation Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(RightLeftOrientation::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createTestUI() { + JFrame frame = new JFrame("RightLeftOrientation"); + JMenuBar menuBar = new JMenuBar(); + + menuBar.add(createMenu("javax.swing.plaf.metal.MetalLookAndFeel", + "Metal")); + menuBar.add(createMenu("com.sun.java.swing.plaf.motif.MotifLookAndFeel", + "Motif")); + menuBar.add(createMenu("com.sun.java.swing.plaf.windows.WindowsLookAndFeel", + "Windows")); + + frame.setJMenuBar(menuBar); + frame.pack(); + return frame; + } + + + static JMenu createMenu(String laf, String name) { + JMenu menu = new JMenu(name); + try { + LookAndFeel save = UIManager.getLookAndFeel(); + UIManager.setLookAndFeel(laf); + addMenuItems(menu, ComponentOrientation.LEFT_TO_RIGHT); + menu.addSeparator(); + addMenuItems(menu, ComponentOrientation.RIGHT_TO_LEFT); + UIManager.setLookAndFeel(save); + } catch (Exception e) { + menu = new JMenu(name); + menu.setEnabled(false); + } + return menu; + } + + static void addMenuItems(JMenu menu, ComponentOrientation o) { + + JMenuItem menuItem; + + menuItem = new JMenuItem("Menu Item"); + menuItem.setComponentOrientation(o); + menu.add(menuItem); + + menuItem = new JMenuItem("Text trails icon", new MyMenuItemIcon()); + menuItem.setComponentOrientation(o); + menu.add(menuItem); + + menuItem = new JMenuItem("Text leads icon", new MyMenuItemIcon()); + menuItem.setComponentOrientation(o); + menuItem.setHorizontalTextPosition(SwingConstants.LEADING); + menu.add(menuItem); + + menuItem = new JRadioButtonMenuItem("Radio Button Menu Item"); + menuItem.setComponentOrientation(o); + menuItem.setSelected(true); + menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK)); + menu.add(menuItem); + + menuItem = new JCheckBoxMenuItem("Check box Menu Item"); + menuItem.setComponentOrientation(o); + menuItem.setSelected(true); + menuItem.setFont( new Font("Serif",Font.PLAIN, 24) ); + menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_2, ActionEvent.ALT_MASK)); + menu.add(menuItem); + + menuItem = new JMenu("Sub Menu"); + menuItem.setComponentOrientation(o); + menuItem.add(new JMenuItem("Sub Menu One")).setComponentOrientation(o); + menuItem.add(new JMenuItem("Sub Menu Two")).setComponentOrientation(o); + menu.add(menuItem); + } + + + private static class MyMenuItemIcon implements Icon { + public void paintIcon(Component c, Graphics g, int x, int y) { + Color oldColor = g.getColor(); + g.setColor(Color.orange); + g.fill3DRect(x, y, getIconWidth(), getIconHeight(), true); + g.setColor(oldColor); + } + public int getIconWidth() { return 15; } + public int getIconHeight() { return 15; } + } +} diff --git a/test/jdk/javax/swing/JMenuItem/bug4729669.java b/test/jdk/javax/swing/JMenuItem/bug4729669.java new file mode 100644 index 0000000000000..815558fc8fdc6 --- /dev/null +++ b/test/jdk/javax/swing/JMenuItem/bug4729669.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2005, 2025, 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 4729669 + * @summary 1.4 REGRESSION: Text edge of different types of JMenuItems are not aligned + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4729669 + */ + +import java.awt.Color; +import java.awt.ComponentOrientation; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.KeyStroke; + +import java.util.List; + +public class bug4729669 { + + private static final String INSTRUCTIONS = """ + Two windows should appear: Left-to-right and Right-to-left. + Check that text on all the menu items of all menus + is properly vertically aligned."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("bug4729669 Instructions") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(bug4729669::createTestUI) + .position(PassFailJFrame.Position.TOP_LEFT_CORNER) + .logArea() + .build() + .awaitAndCheck(); + } + + private static List createTestUI() { + JFrame f1 = MenuItemTest.doMenuItemTest(true); + f1.setLocation(300, 300); + JFrame f2 = MenuItemTest.doMenuItemTest(false); + f2.setLocation(500, 300); + return List.of(f1, f2); + } +} + +class MenuItemTest { + public static JFrame doMenuItemTest(boolean isLeft) { + JMenu menu = new JMenu("View"); + menu.setMnemonic('V'); + + menu.add(new JMenuItem("Refresh")); + menu.add(new JMenuItem("Customize...")); + menu.add(new JCheckBoxMenuItem("Show Toolbar")); + menu.addSeparator(); + menu.add(new JRadioButtonMenuItem("List")); + menu.add(new JRadioButtonMenuItem("Icons")); + JRadioButtonMenuItem rm2 = new JRadioButtonMenuItem("And icon."); + rm2.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, + KeyEvent.SHIFT_MASK)); + menu.add(rm2); + JRadioButtonMenuItem mi3 = new JRadioButtonMenuItem("Radio w/icon"); + + Icon myIcon = new Icon() { // 10 pixel red + public void paintIcon(Component c, Graphics g, int x, int y) { + Color color = g.getColor(); + g.setColor(Color.RED); + g.fillRect(x, y, 10, 10); + g.setColor(color); + } + + public int getIconWidth() { + return 10; + } + + public int getIconHeight() { + return 10; + } + }; + + Icon myIcon2 = new Icon() { // 15 pixel green + public void paintIcon(Component c, Graphics g, int x, int y) { + Color color = g.getColor(); + g.setColor(Color.GREEN); + g.fillRect(x, y, 15, 10); + g.setColor(color); + } + + public int getIconWidth() { + return 15; + } + + public int getIconHeight() { + return 10; + } + }; + + rm2.setIcon(myIcon2); + + mi3.setIcon(myIcon); + menu.add(mi3); + menu.add(new JMenuItem(myIcon2)); + + final JMenu menu2 = new JMenu("No nothing"); + menu2.add("One").addActionListener(new AbstractAction() { + public void actionPerformed(ActionEvent e) { + PassFailJFrame.log("menu.width = " + menu2.getPopupMenu().getWidth()); + } + }); + menu2.add("Two").addActionListener(new AbstractAction() { + public void actionPerformed(ActionEvent e) { + PassFailJFrame.log("menu.width = " + menu2.getPopupMenu().getWidth()); + } + }); + menu2.add("Threeee").addActionListener(new AbstractAction() { + public void actionPerformed(ActionEvent e) { + PassFailJFrame.log("menu.width = " + menu2.getPopupMenu().getWidth()); + } + }); + + JMenuItem mi4 = new JMenuItem("Item with icon"); + mi4.setIcon(myIcon); + menu.addSeparator(); + menu.add(mi4); + String title = "Menu Item Test " + (isLeft ? "(Left-to-right)" : "(Right-to-left)"); + JFrame frame = new JFrame(title); + + JMenuBar menuBar = new JMenuBar(); + menuBar.add(menu); + menuBar.add(menu2); + + JMenu someIcons = new JMenu("Some icons"); + JMenuItem imi1 = new JMenuItem("Icon!"); + imi1.setIcon(myIcon); + someIcons.add(imi1); + JMenuItem imi2 = new JMenuItem("Wide icon!"); + imi2.setIcon(myIcon2); + someIcons.add(imi2); + someIcons.add(new JCheckBoxMenuItem("CheckBox")); + someIcons.add(new JRadioButtonMenuItem("RadioButton")); + menuBar.add(someIcons); + frame.setJMenuBar(menuBar); + ComponentOrientation co = (isLeft ? + ComponentOrientation.LEFT_TO_RIGHT : + ComponentOrientation.RIGHT_TO_LEFT); + frame.applyComponentOrientation(co); + frame.setSize(300, 300); + int frameX = isLeft ? 0 : 600; + frame.setLocation(frameX, 20); + return frame; + } + +} From 5d7281992efdb690063546f3f0ec3f308610a6cd Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 19 May 2025 06:02:21 +0000 Subject: [PATCH 271/846] 8353320: Open source more Swing text tests Backport-of: 74c2d8f41bbb770e959a77ae1ce468162d68beaf --- .../html/FrameView/4463014/bug4463014.java | 74 +++++++++++++++++ .../text/html/FrameView/4463014/frame1.html | 9 +++ .../text/html/FrameView/4463014/frame2.html | 4 + .../html/FrameView/4463014/frameresult.html | 7 ++ .../text/html/FrameView/4463014/frameset.html | 11 +++ .../text/html/HTMLEditorKit/bug4102068.java | 77 ++++++++++++++++++ .../text/html/HTMLEditorKit/bug4198022.java | 81 +++++++++++++++++++ .../text/html/HTMLEditorKit/bug4245401.java | 78 ++++++++++++++++++ .../text/html/StyleSheet/bug4619595.java | 77 ++++++++++++++++++ 9 files changed, 418 insertions(+) create mode 100644 test/jdk/javax/swing/text/html/FrameView/4463014/bug4463014.java create mode 100644 test/jdk/javax/swing/text/html/FrameView/4463014/frame1.html create mode 100644 test/jdk/javax/swing/text/html/FrameView/4463014/frame2.html create mode 100644 test/jdk/javax/swing/text/html/FrameView/4463014/frameresult.html create mode 100644 test/jdk/javax/swing/text/html/FrameView/4463014/frameset.html create mode 100644 test/jdk/javax/swing/text/html/HTMLEditorKit/bug4102068.java create mode 100644 test/jdk/javax/swing/text/html/HTMLEditorKit/bug4198022.java create mode 100644 test/jdk/javax/swing/text/html/HTMLEditorKit/bug4245401.java create mode 100644 test/jdk/javax/swing/text/html/StyleSheet/bug4619595.java diff --git a/test/jdk/javax/swing/text/html/FrameView/4463014/bug4463014.java b/test/jdk/javax/swing/text/html/FrameView/4463014/bug4463014.java new file mode 100644 index 0000000000000..4b7199c901754 --- /dev/null +++ b/test/jdk/javax/swing/text/html/FrameView/4463014/bug4463014.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2005, 2025, 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 4463014 + * @summary Tests if JEditorPane updates the correct frame when using
    + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4463014 + */ + +import java.io.File; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.text.html.HTMLEditorKit; + +public class bug4463014 { + + static final String INSTRUCTIONS = """ + The test window displays an HTML frameset with a frame + on the left and another to the right. + Follow the instructions displayed in the left frame to perform testing. + The test PASSES only if the test behaves as per instructions. + """; + + static JFrame createUI() { + JFrame frame = new JFrame("bug4463014"); + JEditorPane jep = new JEditorPane(); + jep.setEditorKit(new HTMLEditorKit()); + jep.setEditable(false); + + try { + File file = new File(System.getProperty("test.src", "."), "frameset.html"); + System.out.println(file.toURL()); + jep.setPage(file.toURL()); + } catch (Exception e) { + } + + frame.add(jep); + frame.setSize(500,500); + return frame; + } + + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(bug4463014::createUI) + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/javax/swing/text/html/FrameView/4463014/frame1.html b/test/jdk/javax/swing/text/html/FrameView/4463014/frame1.html new file mode 100644 index 0000000000000..833bc1f635297 --- /dev/null +++ b/test/jdk/javax/swing/text/html/FrameView/4463014/frame1.html @@ -0,0 +1,9 @@ + + +Push the Submit query button + +
    + +
    + + diff --git a/test/jdk/javax/swing/text/html/FrameView/4463014/frame2.html b/test/jdk/javax/swing/text/html/FrameView/4463014/frame2.html new file mode 100644 index 0000000000000..5bc6dba57fc4c --- /dev/null +++ b/test/jdk/javax/swing/text/html/FrameView/4463014/frame2.html @@ -0,0 +1,4 @@ + + + + diff --git a/test/jdk/javax/swing/text/html/FrameView/4463014/frameresult.html b/test/jdk/javax/swing/text/html/FrameView/4463014/frameresult.html new file mode 100644 index 0000000000000..a31045833b5c6 --- /dev/null +++ b/test/jdk/javax/swing/text/html/FrameView/4463014/frameresult.html @@ -0,0 +1,7 @@ + + +If you see this text in the RIGHT frame the test PASSED. +

    If you see this text in the LEFT frame the test FAILED. + + + diff --git a/test/jdk/javax/swing/text/html/FrameView/4463014/frameset.html b/test/jdk/javax/swing/text/html/FrameView/4463014/frameset.html new file mode 100644 index 0000000000000..1e7f8298d628b --- /dev/null +++ b/test/jdk/javax/swing/text/html/FrameView/4463014/frameset.html @@ -0,0 +1,11 @@ + + + + Manual test for bug 4463014 + + + + + + + \ No newline at end of file diff --git a/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4102068.java b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4102068.java new file mode 100644 index 0000000000000..39dd1d539255a --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4102068.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 1999, 2025, 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 4102068 + * @summary Tests HTML editor JEditorPane change mouse icon over the link + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4102068 + */ + +import java.awt.Cursor; +import javax.swing.JFrame; +import javax.swing.JTextPane; +import javax.swing.text.html.HTMLEditorKit; + +public class bug4102068 { + + static final String INSTRUCTIONS = """ + The test window contains an HTML frame containing a string with one hyperlink. + Move the mouse pointer over this hyperlink. + If the pointer over the hyperlink became a HAND cursor then the test PASSES, + otherwise the test FAILS. + """; + + static JFrame createUI() { + + JFrame frame = new JFrame("bug4102068"); + JTextPane ep = new JTextPane(); + ep.setContentType("text/html"); + HTMLEditorKit ek = new HTMLEditorKit(); + ep.setEditorKit(ek); + ep.setText("Here is a HyperLink Cursor Test"); + ek.setDefaultCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + Cursor ct = ek.getDefaultCursor(); + ek.setLinkCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + Cursor cl = ek.getLinkCursor(); + if (ct.getType() != Cursor.DEFAULT_CURSOR || cl.getType() != Cursor.HAND_CURSOR) { + throw new RuntimeException("Error with cursor settings..."); + } + ep.setEditable(false); + + frame.add(ep); + frame.setSize(300, 300); + return frame; + } + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(50) + .testUI(bug4102068::createUI) + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4198022.java b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4198022.java new file mode 100644 index 0000000000000..2d26ace21318c --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4198022.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1999, 2025, 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 4198022 + * @summary Tests if HTML tags , and are supported in JEditorPane + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4198022 + */ + +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.text.html.HTMLEditorKit; + +public class bug4198022 { + + static final String INSTRUCTIONS = """ + There are two "lines" of text in the displayed HTML window + The first line/string contains and HTML elements. + The word "subscript" should be subscripted (placed lower than the word "Testing"), + and the word "superscript" should be superscripted (placed higher than "Testing"). + If instead these words are placed on the same level then the test FAILS. + + The second line/string contains a sentence marked with tag. + It should be presented as one long line without breaks. + It is OK for the line to extend past the end of the window and not be all visible. + If the line is broken up so you see multiple lines the test FAILS. + + If all behaves as expected, the test PASSES. + """; + + static JFrame createUI() { + + JFrame frame = new JFrame("bug4198022"); + JEditorPane ep = new JEditorPane(); + HTMLEditorKit ek = new HTMLEditorKit(); + ep.setEditorKit(ek); + ep.setText( + "Testing subscript and superscript.
    " + + "
    This text is intended to be presented as a single line without " + + "any word wrapping, regardless of whether it fits the viewable area of " + + "the editor pane or not."); + + ep.setEditable(false); + + frame.add(ep); + frame.setSize(500, 300); + return frame; + } + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(60) + .testUI(bug4198022::createUI) + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4245401.java b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4245401.java new file mode 100644 index 0000000000000..1f9bc7da914e7 --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4245401.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1999, 2025, 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 4245401 + * @summary Tests that JTextPane with HTMLEditorKit handles the HEAD tag properly + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4245401 + */ + +import java.io.StringReader; +import javax.swing.JFrame; +import javax.swing.JTextPane; +import javax.swing.text.html.HTMLDocument; +import javax.swing.text.html.HTMLEditorKit; + +public class bug4245401 { + + static final String INSTRUCTIONS = """ + Place the cursor before the "H" in the word "HTML" + Then press and . + If an extra HEAD tag appear, the test FAILS, otherwise it PASSES. + """; + + static JFrame createUI() { + + JFrame frame = new JFrame("bug4245401"); + JTextPane ep = new JTextPane(); + ep.setEditable(true); + ep.setContentType("text/html"); + HTMLEditorKit kit = (HTMLEditorKit) ep.getEditorKit(); + ep.setEditorKit(kit); + HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument(); + ep.setDocument(doc); + + try { + String text = "HTML Test... Test is a test..."; + kit.read(new StringReader(text), doc, 0); + } catch (Exception e) { + throw new RuntimeException(e); + } + + frame.add(ep); + frame.setSize(300, 300); + return frame; + } + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(bug4245401::createUI) + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/javax/swing/text/html/StyleSheet/bug4619595.java b/test/jdk/javax/swing/text/html/StyleSheet/bug4619595.java new file mode 100644 index 0000000000000..2d99d867cddd3 --- /dev/null +++ b/test/jdk/javax/swing/text/html/StyleSheet/bug4619595.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2003, 2025, 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 4619595 + * @summary Tests that embedded list items do not inherit the 'value' + * property from their parent list item + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4619595 + */ + +import javax.swing.JEditorPane; +import javax.swing.JFrame; + +public class bug4619595 { + + static final String INSTRUCTIONS = """ + The test window contains numbered lists. + Look at the three indented/embedded list items (the ones that are bold). + If they are not numbered 1, 2 and 3, then press FAIL. + + Below the lists there should also be a line saying: "The quick brown fox". + If you don't see this, press FAIL. + + If all is as expected, PASS the test. + """; + + final static String HTML = "" + + "

    1. Let's start
    2. Look @ inner list" + + "
      1. Inner list starts
      2. Second inner item" + + "
      3. Inner list ends
      " + + "
    3. That's all
    " + + "

    The quick brown fox

    " + + " "; + + static JFrame createUI() { + + JFrame frame = new JFrame("bug4619595"); + JEditorPane pane = new JEditorPane(); + pane.setContentType("text/html"); + pane.setText(HTML); + frame.add(pane); + frame.setSize(400, 400); + return frame; + } + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(bug4619595::createUI) + .build() + .awaitAndCheck(); + } +} From 2f10251d776c73b011f65d23ca5821c5bd1a5f2c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 19 May 2025 06:03:44 +0000 Subject: [PATCH 272/846] 8352684: Opensource JInternalFrame tests - series1 Backport-of: 66435c27b3e0a89e4350caf6207e36f5a9b82b7f --- .../swing/JInternalFrame/bug4131008.java | 86 +++++++++++++++++++ .../swing/JInternalFrame/bug4176136.java | 70 +++++++++++++++ .../swing/JInternalFrame/bug4244536.java | 75 ++++++++++++++++ .../swing/JInternalFrame/bug4305284.java | 73 ++++++++++++++++ 4 files changed, 304 insertions(+) create mode 100644 test/jdk/javax/swing/JInternalFrame/bug4131008.java create mode 100644 test/jdk/javax/swing/JInternalFrame/bug4176136.java create mode 100644 test/jdk/javax/swing/JInternalFrame/bug4244536.java create mode 100644 test/jdk/javax/swing/JInternalFrame/bug4305284.java diff --git a/test/jdk/javax/swing/JInternalFrame/bug4131008.java b/test/jdk/javax/swing/JInternalFrame/bug4131008.java new file mode 100644 index 0000000000000..9f45175a7857d --- /dev/null +++ b/test/jdk/javax/swing/JInternalFrame/bug4131008.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2000, 2025, 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 4131008 + * @summary JInternalFrame should refresh title after it changing + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4131008 +*/ + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.UIManager; + +public class bug4131008 { + + private static final String INSTRUCTIONS = """ + Press button "Change title" at the internal frame "Old". + If title of this frame will replaced by "New", + then test passed, else test fails."""; + + public static void main(String[] args) throws Exception { + + UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); + + PassFailJFrame.builder() + .title("bug4131008 Instructions") + .instructions(INSTRUCTIONS) + .columns(50) + .testUI(bug4131008::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createTestUI() { + JFrame frame = new JFrame("bug4131008"); + JInternalFrame jif = new JInternalFrame("Old"); + JDesktopPane jdp = new JDesktopPane(); + frame.setContentPane(jdp); + + jif.setSize(150, 100); + jif.setVisible(true); + JButton bt = new JButton("Change title"); + bt.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + jif.setTitle("New"); + } + }); + jif.getContentPane().add(bt); + jdp.add(jif); + try { + jif.setSelected(true); + } catch (Exception e) { + throw new RuntimeException(e); + } + frame.setSize(300, 200); + return frame; + } +} diff --git a/test/jdk/javax/swing/JInternalFrame/bug4176136.java b/test/jdk/javax/swing/JInternalFrame/bug4176136.java new file mode 100644 index 0000000000000..019e453750c64 --- /dev/null +++ b/test/jdk/javax/swing/JInternalFrame/bug4176136.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1999, 2025, 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 4176136 + * @summary Default close operation JInternalFrame.DO_NOTHING_ON_CLOSE works correctly + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4176136 + */ + + +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; + +public class bug4176136 { + + private static final String INSTRUCTIONS = """ + Click the close button of the internal frame. + You will see the close button activate, + but nothing else should happen. + If the internal frame closes, the test fails. + If it doesn't close, the test passes."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("bug4176136 Instructions") + .instructions(INSTRUCTIONS) + .columns(25) + .testUI(bug4176136::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createTestUI() { + JFrame frame = new JFrame("bug4176136"); + JDesktopPane dp = new JDesktopPane(); + frame.add(dp); + JInternalFrame inf = new JInternalFrame(); + dp.add(inf); + inf.setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE); + inf.setSize(100, 100); + inf.setClosable(true); + inf.setVisible(true); + frame.setSize(200, 200); + return frame; + } +} diff --git a/test/jdk/javax/swing/JInternalFrame/bug4244536.java b/test/jdk/javax/swing/JInternalFrame/bug4244536.java new file mode 100644 index 0000000000000..85acb833d2aa8 --- /dev/null +++ b/test/jdk/javax/swing/JInternalFrame/bug4244536.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 1999, 2025, 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 4244536 + * @summary Tests that Motif JInternalFrame can be maximized + * after it was iconified. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4244536 + */ + +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.UIManager; + +public class bug4244536 { + + private static final String INSTRUCTIONS = """ + Minimize the internal frame using the minimize button. + Then double-click on it to restore its size. + Then press the maximize button. + If the frame gets maximized, test passes. + If its size don't change, test fails."""; + + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel( + "com.sun.java.swing.plaf.motif.MotifLookAndFeel"); + + PassFailJFrame.builder() + .title("bug4244536 Instructions") + .instructions(INSTRUCTIONS) + .columns(50) + .testUI(bug4244536::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createTestUI() { + JFrame frame = new JFrame("bug4244536"); + JDesktopPane desktop = new JDesktopPane(); + JInternalFrame jif = new JInternalFrame("Internal Frame"); + jif.setSize(150, 150); + jif.setMaximizable(true); + jif.setIconifiable(true); + jif.setVisible(true); + desktop.add(jif); + frame.add("Center", desktop); + frame.setSize(300, 300); + return frame; + } + +} diff --git a/test/jdk/javax/swing/JInternalFrame/bug4305284.java b/test/jdk/javax/swing/JInternalFrame/bug4305284.java new file mode 100644 index 0000000000000..8801c8c678c6f --- /dev/null +++ b/test/jdk/javax/swing/JInternalFrame/bug4305284.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2000, 2025, 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 4305284 + * @summary JInternalFrames can't be sized off of the desktop + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4305284 + */ + +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; + +public class bug4305284 { + + private static final String INSTRUCTIONS = """ + Try to resize the shown internal frame. + If it can't be sized of the desktop bounds, + then test passes, else test fails."""; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("bug4305284 Instructions") + .instructions(INSTRUCTIONS) + .columns(25) + .testUI(bug4305284::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createTestUI() { + JFrame frame = new JFrame("bug4305284"); + JInternalFrame jif = new JInternalFrame("Test", + true, true, true, true); + JDesktopPane dp = new JDesktopPane(); + frame.setContentPane(dp); + dp.add(jif); + + try { + jif.setBounds(50, 50, 200, 200); + jif.setMaximum(false); + jif.setVisible(true); + } catch (Exception e) { + e.printStackTrace(); + } + frame.setSize(300, 300); + return frame; + } + +} From 99c9fc74e11524fe76865f178d9f8b8abcd4debc Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 19 May 2025 06:05:06 +0000 Subject: [PATCH 273/846] 8353475: Open source two Swing DefaultCaret tests Backport-of: e08441c03352543f800aef166afabec1dacaf4bf --- .../swing/text/DefaultCaret/PaintTest.java | 63 ++++++++++++++++ .../swing/text/DefaultCaret/bug4785160.java | 71 +++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 test/jdk/javax/swing/text/DefaultCaret/PaintTest.java create mode 100644 test/jdk/javax/swing/text/DefaultCaret/bug4785160.java diff --git a/test/jdk/javax/swing/text/DefaultCaret/PaintTest.java b/test/jdk/javax/swing/text/DefaultCaret/PaintTest.java new file mode 100644 index 0000000000000..c554764527eaa --- /dev/null +++ b/test/jdk/javax/swing/text/DefaultCaret/PaintTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 1999, 2025, 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 4193062 + * @summary Tests that when a TextField first gets focus, if modelToView fails + * (null is returned) that the caret will start to blink again. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual PaintTest +*/ + +import java.awt.FlowLayout; +import javax.swing.JFrame; +import javax.swing.JTextField; + +public class PaintTest { + + static final String INSTRUCTIONS = """ + If the test window displays with the text caret flashing (do wait at + least several second for it to start) the test PASSES, otherwise it FAILS. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("PaintTest Test Instructions") + .instructions(INSTRUCTIONS) + .columns(50) + .testUI(PaintTest::createUI) + .build() + .awaitAndCheck(); + } + + static JFrame createUI() { + JFrame frame = new JFrame("PaintTest"); + JTextField tf = new JTextField(20); + frame.setLayout(new FlowLayout()); + frame.add(tf); + frame.setSize(300, 300); + return frame; + } +} diff --git a/test/jdk/javax/swing/text/DefaultCaret/bug4785160.java b/test/jdk/javax/swing/text/DefaultCaret/bug4785160.java new file mode 100644 index 0000000000000..644becf8ae6ac --- /dev/null +++ b/test/jdk/javax/swing/text/DefaultCaret/bug4785160.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2003, 2025, 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 4785160 + * @summary Test that the cursor is always visible when typing in JTextArea with JScrollBar + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4785160 +*/ + +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; + +public class bug4785160 { + + static final String INSTRUCTIONS = """ + Ensure that the horizontal scrollbar is visible in the JTextArea. + If necessary, reduce the width of the window so that the scrollbar becomes visible. + Scroll all the way to the right so the end of the line is visible. + If necessary, move the text caret in the text area to the end of line. + The test PASSES if the caret is visible at the end of the line. + The test FAILS if the caret disappears when moved to the end of the line. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("bug4785160 Test Instructions") + .instructions(INSTRUCTIONS) + .columns(50) + .testUI(bug4785160::createUI) + .build() + .awaitAndCheck(); + } + + static JFrame createUI() { + JFrame frame = new JFrame("bug4785160"); + JTextArea area = new JTextArea(); + String s = ""; + for (int i = 0; i < 80; i++) { + s += "m"; + } + area.setText(s); + area.getCaret().setDot(area.getText().length() + 1); + frame.add(new JScrollPane(area)); + frame.setSize(300, 300); + return frame; + } +} From 08de2ba0e60cf968d2dd6fee3fec83a2471c62ce Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 19 May 2025 06:06:28 +0000 Subject: [PATCH 274/846] 8352908: Open source several swing tests batch1 Backport-of: a2dc9c71e47a1cdf70ab351c557a5f1835eb5f4a --- .../javax/swing/JSplitPane/bug4749792.java | 77 ++++++++++++ test/jdk/javax/swing/JToolBar/bug4188825.java | 70 +++++++++++ test/jdk/javax/swing/JToolBar/bug4251592.java | 93 ++++++++++++++ test/jdk/javax/swing/JToolBar/bug5035668.java | 113 ++++++++++++++++++ 4 files changed, 353 insertions(+) create mode 100644 test/jdk/javax/swing/JSplitPane/bug4749792.java create mode 100644 test/jdk/javax/swing/JToolBar/bug4188825.java create mode 100644 test/jdk/javax/swing/JToolBar/bug4251592.java create mode 100644 test/jdk/javax/swing/JToolBar/bug5035668.java diff --git a/test/jdk/javax/swing/JSplitPane/bug4749792.java b/test/jdk/javax/swing/JSplitPane/bug4749792.java new file mode 100644 index 0000000000000..1d9823073b72d --- /dev/null +++ b/test/jdk/javax/swing/JSplitPane/bug4749792.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2003, 2025, 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 4749792 + * @requires (os.family == "windows") + * @summary Split pane border is not painted properly + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4749792 + */ + +import java.awt.BorderLayout; +import java.awt.Dimension; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JSplitPane; + +public class bug4749792 { + static final String INSTRUCTIONS = """ + If the right/bottom edges of JSplitPane's border is missing then the + test fails. If it is visible, then the test passes. + """; + + static JFrame createUI() { + JFrame frame = new JFrame("JSplitPane Border Test"); + frame.setSize(450, 220); + JPanel left = new JPanel(); + JPanel right = new JPanel(); + left.setPreferredSize(new Dimension(200, 200)); + right.setPreferredSize(new Dimension(200, 200)); + JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, right); + frame.add(sp); + + JPanel south = new JPanel(); + south.setPreferredSize(new Dimension(20, 20)); + frame.add(south, BorderLayout.SOUTH); + + JPanel east = new JPanel(); + east.setPreferredSize(new Dimension(20, 20)); + frame.add(east, BorderLayout.EAST); + + return frame; + } + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("bug4749792 Test Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(bug4749792::createUI) + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/javax/swing/JToolBar/bug4188825.java b/test/jdk/javax/swing/JToolBar/bug4188825.java new file mode 100644 index 0000000000000..e5dd6538de42c --- /dev/null +++ b/test/jdk/javax/swing/JToolBar/bug4188825.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2000, 2025, 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 4188825 + * @summary Tests if toolbars return to original location when closed + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4188825 + */ + +import java.awt.BorderLayout; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JToolBar; + +public class bug4188825 { + static final String INSTRUCTIONS = """ + Drag the toolbar out of frame and close it. If it returns to + the original location, then the test succeeded, otherwise it failed. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("bug4188825 Test Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(bug4188825::createUI) + .build() + .awaitAndCheck(); + } + + static JFrame createUI() { + JFrame frame = new JFrame("Toolbar Drag Test"); + frame.setLayout(new BorderLayout()); + JToolBar tb = new JToolBar(); + tb.setOrientation(JToolBar.VERTICAL); + tb.add(new JButton("a")); + tb.add(new JButton("b")); + tb.add(new JButton("c")); + frame.add(tb, BorderLayout.WEST); + JButton l = new JButton("Get me!!!"); + l.setSize(200, 200); + frame.add(l); + frame.setSize(200, 200); + return frame; + } +} diff --git a/test/jdk/javax/swing/JToolBar/bug4251592.java b/test/jdk/javax/swing/JToolBar/bug4251592.java new file mode 100644 index 0000000000000..add4eb8ec923e --- /dev/null +++ b/test/jdk/javax/swing/JToolBar/bug4251592.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2000, 2025, 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 4251592 + * @summary JToolBar should have ability to set custom layout. + * @key headful + * @run main bug4251592 + */ + +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JToolBar; +import javax.swing.SwingUtilities; + +public class bug4251592 { + private static final int OFFSET = 3; + private static volatile Point loc; + private static JFrame frame; + private static JToolBar toolBar; + private static GridLayout customLayout; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("Toolbar Layout Save Test"); + toolBar = new JToolBar(); + customLayout = new GridLayout(); + frame.setLayout(new BorderLayout()); + frame.add(toolBar, BorderLayout.NORTH); + + toolBar.setLayout(customLayout); + toolBar.add(new JButton("Button1")); + toolBar.add(new JButton("Button2")); + toolBar.add(new JButton("Button3")); + toolBar.setFloatable(true); + + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> loc = toolBar.getLocationOnScreen()); + + robot.mouseMove(loc.x + OFFSET, loc.y + OFFSET); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseMove(loc.x + OFFSET, loc.y + 50); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + if (toolBar.getLayout() != customLayout) { + throw new RuntimeException("Custom layout not saved..."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/javax/swing/JToolBar/bug5035668.java b/test/jdk/javax/swing/JToolBar/bug5035668.java new file mode 100644 index 0000000000000..b0cdef7c7ef70 --- /dev/null +++ b/test/jdk/javax/swing/JToolBar/bug5035668.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2004, 2025, 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 5035668 + * @summary Test that metal ToolBar border correctly sizes the MetalBumps used + * for the grip + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug5035668 + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.ComponentOrientation; +import java.awt.GridLayout; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JToolBar; +import javax.swing.UIManager; +import javax.swing.border.CompoundBorder; +import javax.swing.border.EmptyBorder; + +public class bug5035668 { + static final String INSTRUCTIONS = """ + This test is for Metal LaF only. + + All of them have an empty border around their own border. + If you see that in any toolbar the grip (little dotted strip) overlaps + the empty border press Fail. If you see that grips are completely + inside empty borders press Pass. + """; + + public static void main(String[] args) throws Exception { + // Set metal l&f + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + PassFailJFrame.builder() + .title("bug4251592 Test Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(bug5035668::createUI) + .build() + .awaitAndCheck(); + } + + static JFrame createUI() { + JFrame frame = new JFrame("Metal JToolBar Border Overlap Test"); + frame.setLayout(new BorderLayout()); + frame.setBackground(Color.white); + + // Horizontal toolbar left-to-right + final JToolBar toolBar = new JToolBar(); + toolBar.setBorder(new CompoundBorder(new EmptyBorder(10, 10, 10, 10), + toolBar.getBorder())); + toolBar.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); + toolBar.add(new ToolBarButton(toolBar)); + + // Horizontal toolbar right-to-left + JToolBar toolBar2 = new JToolBar(); + toolBar2.setBorder(new CompoundBorder(new EmptyBorder(10, 10, 10, 10), + toolBar2.getBorder())); + toolBar2.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); + toolBar2.add(new ToolBarButton(toolBar2)); + + JPanel topPanel = new JPanel(new GridLayout(2, 0)); + topPanel.add(toolBar); + topPanel.add(toolBar2); + frame.add(topPanel, BorderLayout.NORTH); + + JToolBar toolBar3 = new JToolBar(); + toolBar3.setBorder(new CompoundBorder(new EmptyBorder(10, 10, 10, 10), + toolBar3.getBorder())); + toolBar3.setOrientation(JToolBar.VERTICAL); + toolBar3.add(new ToolBarButton(toolBar3)); + frame.add(toolBar3, BorderLayout.EAST); + + frame.setSize(200, 200); + return frame; + } + + static class ToolBarButton extends JButton { + final JToolBar toolBar; + + public ToolBarButton(JToolBar p_toolBar) { + super("Change toolbar's orientation"); + this.toolBar = p_toolBar; + addActionListener(e -> toolBar.setOrientation(1 - toolBar.getOrientation())); + } + } +} From fa1c19ec68344efd41c7a80508163f8338211fe4 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 21 May 2025 17:19:32 +0000 Subject: [PATCH 275/846] 8310525: DynamicLauncher for JDP test needs to try harder to find a free port Backport-of: 59407faf7b6861d142dbc3700a6fa9615567a275 --- test/jdk/sun/management/jdp/DynamicLauncher.java | 6 ++++-- .../jmxremote/bootstrap/JMXInterfaceBindingTest.java | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/test/jdk/sun/management/jdp/DynamicLauncher.java b/test/jdk/sun/management/jdp/DynamicLauncher.java index 9102fe32a94de..b79672211b1ef 100644 --- a/test/jdk/sun/management/jdp/DynamicLauncher.java +++ b/test/jdk/sun/management/jdp/DynamicLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,8 @@ */ public abstract class DynamicLauncher { + private static final int MAX_RETRY_ATTEMPTS = 10; + final String jdpName = UUID.randomUUID().toString(); OutputAnalyzer output; int jmxPort; @@ -52,7 +54,7 @@ protected void run() throws Exception { try { output.shouldNotContain("Port already in use"); } catch (RuntimeException e) { - if (retries < 3) { + if (retries < MAX_RETRY_ATTEMPTS) { retries++; tryAgain = true; } diff --git a/test/jdk/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java b/test/jdk/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java index cb0ba50e5972f..945824832cca6 100644 --- a/test/jdk/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java +++ b/test/jdk/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java @@ -52,7 +52,7 @@ public class JMXInterfaceBindingTest { public static final int JMX_PORT_RANGE_UPPER = 9200; public static final int JMX_PORT_RANGE_LOWER_SSL = 9201; // 9200 might be RMI Port public static final int JMX_PORT_RANGE_UPPER_SSL = 9300; - private static final int MAX_RETRY_ATTEMTS = 10; + private static final int MAX_RETRY_ATTEMPTS = 10; public static final String READY_MSG = "MainThread: Ready for connections"; public static final String TEST_CLASS = JMXAgentInterfaceBinding.class.getSimpleName(); public static final String KEYSTORE_LOC = System.getProperty("test.src", ".") + @@ -159,7 +159,7 @@ public void run() { System.err.println("Retrying the test for " + name); } needRetry = runTest(); - } while (needRetry && (attempts++ < MAX_RETRY_ATTEMTS)); + } while (needRetry && (attempts++ < MAX_RETRY_ATTEMPTS)); if (testFailed) { int exitValue = output.getExitValue(); From 3f39815d044eca5b15ded5b69f0a7d2b1bfe9325 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 21 May 2025 17:21:15 +0000 Subject: [PATCH 276/846] 8345838: Remove the appcds/javaldr/AnonVmClassesDuringDump.java test Reviewed-by: phh Backport-of: f8974ba718b3a631abafa8987d3fb98164fb35e5 --- .../javaldr/AnonVmClassesDuringDump.java | 92 ------------------- .../AnonVmClassesDuringDumpTransformer.java | 67 -------------- .../AnonVmClassesDuringDumpTransformer.mf | 5 - 3 files changed, 164 deletions(-) delete mode 100644 test/hotspot/jtreg/runtime/cds/appcds/javaldr/AnonVmClassesDuringDump.java delete mode 100644 test/hotspot/jtreg/runtime/cds/appcds/javaldr/AnonVmClassesDuringDumpTransformer.java delete mode 100644 test/hotspot/jtreg/runtime/cds/appcds/javaldr/AnonVmClassesDuringDumpTransformer.mf diff --git a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/AnonVmClassesDuringDump.java b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/AnonVmClassesDuringDump.java deleted file mode 100644 index 7d8a45e4c784f..0000000000000 --- a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/AnonVmClassesDuringDump.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2018, 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. - * - */ - -/* - * @test - * @summary When dumping the CDS archive, try to load VM anonymous classes to make sure they - * are handled properly. Note: these are not "anonymous inner classes" in the Java source code, - * but rather classes that are not recorded in any ClassLoaderData::dictionary(), - * such as classes that are generated for Lambda expressions. - * See https://blogs.oracle.com/jrose/anonymous-classes-in-the-vm. - * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes - * @requires vm.cds - * @requires vm.jvmti - * @run driver AnonVmClassesDuringDump - */ - -import jdk.test.lib.helpers.ClassFileInstaller; - -public class AnonVmClassesDuringDump { - public static String appClasses[] = { - Hello.class.getName(), - }; - public static String agentClasses[] = { - AnonVmClassesDuringDumpTransformer.class.getName(), - }; - - public static String cdsDiagnosticOption = "-XX:+AllowArchivingWithJavaAgent"; - - public static final boolean dynamicMode = - Boolean.getBoolean(System.getProperty("test.dynamic.cds.archive", "false")); - - public static void main(String[] args) throws Throwable { - String agentJar = - ClassFileInstaller.writeJar("AnonVmClassesDuringDumpTransformer.jar", - ClassFileInstaller.Manifest.fromSourceFile("AnonVmClassesDuringDumpTransformer.mf"), - agentClasses); - - String appJar = - ClassFileInstaller.writeJar("AnonVmClassesDuringDumpApp.jar", appClasses); - - TestCommon.testDump(appJar, TestCommon.list(Hello.class.getName()), - "-javaagent:" + agentJar, - "-XX:+UnlockDiagnosticVMOptions", cdsDiagnosticOption, - // Set the following property to see logs for dynamically generated classes - // in STDOUT - "-Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=true"); - - String prefix = ".class.load. "; - // class name pattern like the following: - // jdk.internal.loader.BuiltinClassLoader$$Lambda$1/1816757085 - // java.lang.invoke.LambdaForm$MH/1585787493 - String class_pattern = ".*Lambda([a-z0-9$]+)/([0-9]+).*"; - String suffix = ".*source: shared objects file.*"; - String pattern = prefix + class_pattern + suffix; - // during run time, anonymous classes shouldn't be loaded from the archive - TestCommon.run("-cp", appJar, - "-XX:+UnlockDiagnosticVMOptions", cdsDiagnosticOption, Hello.class.getName()) - .assertNormalExit(dynamicMode ? - output -> output.shouldMatch(pattern) : - output -> output.shouldNotMatch(pattern)); - - // inspect the archive and make sure no anonymous class is in there - TestCommon.run("-cp", appJar, - "-XX:+UnlockDiagnosticVMOptions", cdsDiagnosticOption, - "-XX:+PrintSharedArchiveAndExit", "-XX:+PrintSharedDictionary", Hello.class.getName()) - .assertNormalExit(dynamicMode ? - output -> output.shouldMatch(pattern) : - output -> output.shouldNotMatch(pattern)); - } -} - diff --git a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/AnonVmClassesDuringDumpTransformer.java b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/AnonVmClassesDuringDumpTransformer.java deleted file mode 100644 index 056111ee3284b..0000000000000 --- a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/AnonVmClassesDuringDumpTransformer.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.Instrumentation; -import java.lang.instrument.IllegalClassFormatException; -import java.security.ProtectionDomain; - -public class AnonVmClassesDuringDumpTransformer implements ClassFileTransformer { - public byte[] transform(ClassLoader loader, String name, Class classBeingRedefined, - ProtectionDomain pd, byte[] buffer) throws IllegalClassFormatException { - return null; - } - - private static Instrumentation savedInstrumentation; - - public static void premain(String agentArguments, Instrumentation instrumentation) { - System.out.println("ClassFileTransformer.premain() is called"); - instrumentation.addTransformer(new AnonVmClassesDuringDumpTransformer(), /*canRetransform=*/true); - savedInstrumentation = instrumentation; - - // This will create a Lambda, which will result in some Anonymous VM Classes - // being generated. - // - // Look for something like these in the STDOUT: - // ---------------- - // ClassFileTransformer.premain() is called - // Dumping class files to DUMP_CLASS_FILES/... - // dump: DUMP_CLASS_FILES/java/lang/invoke/LambdaForm$MH000.class - // dump: DUMP_CLASS_FILES/java/lang/invoke/LambdaForm$MH001.class - // Invoked inside a Lambda - // ---------------- - Runnable r = () -> { - System.out.println("Invoked inside a Lambda"); - }; - r.run(); - } - - public static Instrumentation getInstrumentation() { - return savedInstrumentation; - } - - public static void agentmain(String args, Instrumentation inst) throws Exception { - premain(args, inst); - } -} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/AnonVmClassesDuringDumpTransformer.mf b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/AnonVmClassesDuringDumpTransformer.mf deleted file mode 100644 index a2140595dba61..0000000000000 --- a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/AnonVmClassesDuringDumpTransformer.mf +++ /dev/null @@ -1,5 +0,0 @@ -Manifest-Version: 1.0 -Premain-Class: AnonVmClassesDuringDumpTransformer -Agent-Class: AnonVmClassesDuringDumpTransformer -Can-Retransform-Classes: true -Can-Redefine-Classes: true From f9eff38a9f2f8b683d88804905c0c086896f0ea4 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 21 May 2025 17:23:20 +0000 Subject: [PATCH 277/846] 8347000: Bug in com/sun/net/httpserver/bugs/B6361557.java test Backport-of: 5e6cda4799a6bf12370bc6a04b218ebed32dee53 --- test/jdk/com/sun/net/httpserver/bugs/B6361557.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/com/sun/net/httpserver/bugs/B6361557.java b/test/jdk/com/sun/net/httpserver/bugs/B6361557.java index 57e831ec693d0..66094230d6974 100644 --- a/test/jdk/com/sun/net/httpserver/bugs/B6361557.java +++ b/test/jdk/com/sun/net/httpserver/bugs/B6361557.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, 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 @@ -65,7 +65,7 @@ public void handle (HttpExchange t) } final static String request = "GET /test/foo.html HTTP/1.1\r\nContent-length: 0\r\n\r\n"; - final static ByteBuffer requestBuf = ByteBuffer.allocate(64).put(request.getBytes()); + final static ByteBuffer requestBuf = ByteBuffer.wrap(request.getBytes()); public static void main (String[] args) throws Exception { Handler handler = new Handler(); From 613778a0fc6c0a13eed824d127ed4cafa8225399 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 21 May 2025 17:25:01 +0000 Subject: [PATCH 278/846] 8347083: Incomplete logging in nsk/jvmti/ResourceExhausted/resexhausted00* tests Backport-of: 33f9be8de730e664e335e36848732397393abd94 --- .../nsk/jvmti/ResourceExhausted/resexhausted001.java | 4 ++-- .../nsk/jvmti/ResourceExhausted/resexhausted002.java | 4 ++-- .../nsk/jvmti/ResourceExhausted/resexhausted003.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java index b147757f9e0a1..1009f2d353800 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, 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 @@ -62,7 +62,7 @@ public static int run(String args[], PrintStream out) { makeThread(); } - System.out.println("Can't reproduce OOME due to a limit on iterations/execution time. Test was useless." + System.out.println("Test resexhausted001: Can't reproduce OOME due to a limit on iterations/execution time. Test was useless." + " threadCount=" + threadCount.get()); throw new SkippedException("Test did not get an OutOfMemory error"); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java index 46832df7dc30c..c1a6e111c9f8d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, 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 @@ -55,7 +55,7 @@ public static int run(String args[], PrintStream out) { ++count; } - System.out.println("Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); + System.out.println("Test resexhausted002: Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); throw new SkippedException("Test did not get an OutOfMemory error"); } catch (OutOfMemoryError e) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java index f336c1bf3d57d..8cc997fa4ab75 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, 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 @@ -115,7 +115,7 @@ public static int run(String args[], PrintStream out) { ++count; } - System.out.println("Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); + System.out.println("Test resexhausted003: Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); throw new SkippedException("Test did not get an OutOfMemory error"); } catch (OutOfMemoryError e) { From 37f3baecdb96585fcd25ae3c9ca59d6c11c2d004 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 21 May 2025 17:25:20 +0000 Subject: [PATCH 279/846] 8353070: Clean up and open source couple AWT Graphics related tests (Part 1) Backport-of: 566092256861d6c7142fe22cc709ecb70f9db937 --- .../java/awt/Graphics/LineLocationTest.java | 106 ++++++++++++++ .../java/awt/Graphics/NativeWin32Clear.java | 136 ++++++++++++++++++ .../java/awt/Graphics/PolygonFillTest.java | 96 +++++++++++++ test/jdk/java/awt/Graphics/TallText.java | 69 +++++++++ 4 files changed, 407 insertions(+) create mode 100644 test/jdk/java/awt/Graphics/LineLocationTest.java create mode 100644 test/jdk/java/awt/Graphics/NativeWin32Clear.java create mode 100644 test/jdk/java/awt/Graphics/PolygonFillTest.java create mode 100644 test/jdk/java/awt/Graphics/TallText.java diff --git a/test/jdk/java/awt/Graphics/LineLocationTest.java b/test/jdk/java/awt/Graphics/LineLocationTest.java new file mode 100644 index 0000000000000..5c382ceac959c --- /dev/null +++ b/test/jdk/java/awt/Graphics/LineLocationTest.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2006, 2025, 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 4094059 + * @summary drawing to a subclass of canvas didn't draw to the correct location. + * @key headful + * @run main LineLocationTest + */ + +import java.awt.AWTException; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import java.lang.reflect.InvocationTargetException; + +public class LineLocationTest extends Frame { + private DrawScreen screen; + + public void initialize() { + setSize(400, 400); + setLocationRelativeTo(null); + setTitle("Line Location Test"); + Panel p = new Panel(); + screen = new DrawScreen(); + p.add(screen); + p.setLocation(50, 50); + p.setSize(300, 300); + add(p); + setBackground(Color.white); + setForeground(Color.blue); + setVisible(true); + } + + public void requestCoordinates(Rectangle r) { + Point location = screen.getLocationOnScreen(); + Dimension size = screen.getSize(); + r.setBounds(location.x, location.y, size.width, size.height); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + LineLocationTest me = new LineLocationTest(); + EventQueue.invokeAndWait(me::initialize); + try { + Robot robot = new Robot(); + robot.delay(1000); + Rectangle coords = new Rectangle(); + EventQueue.invokeAndWait(() -> { + me.requestCoordinates(coords); + }); + BufferedImage capture = robot.createScreenCapture(coords); + robot.delay(2000); + for (int y = 0; y < capture.getHeight(); y++) { + for (int x = 0; x < capture.getWidth(); x++) { + int blue = Color.blue.getRGB(); + if (capture.getRGB(x, y) == blue) { + throw new RuntimeException("Blue detected at " + x + ", " + y); + } + } + } + } finally { + EventQueue.invokeAndWait(me::dispose); + } + } +} + +class DrawScreen extends Canvas { + public Dimension getPreferredSize() { + return new Dimension(300, 300); + } + + public void paint(Graphics g) { + g.setColor(Color.blue); + g.drawLine(5, -3145583, 50, -3145583); + } +} diff --git a/test/jdk/java/awt/Graphics/NativeWin32Clear.java b/test/jdk/java/awt/Graphics/NativeWin32Clear.java new file mode 100644 index 0000000000000..6cef4fa810aa3 --- /dev/null +++ b/test/jdk/java/awt/Graphics/NativeWin32Clear.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 1999, 2025, 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 4216180 + * @summary This test verifies that Graphics2D.setBackground and clearRect + * performs correctly regardless of antialiasing hint. + * @key headful + * @run main NativeWin32Clear + */ + +import java.awt.AWTException; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import java.lang.reflect.InvocationTargetException; + +public class NativeWin32Clear extends Frame { + + public void initialize() { + setLocationRelativeTo(null); + setSize(300, 200); + setBackground(Color.red); + setVisible(true); + } + + public void paint(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + Dimension d = getSize(); + g2.setBackground(Color.green); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g2.clearRect(0, 0, d.width / 2, d.height); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_OFF); + g2.clearRect(d.width / 2, 0, d.width / 2, d.height); + g2.setColor(Color.black); + } + + public void cleanup() { + setVisible(false); + dispose(); + } + + public void requestCoordinates(Rectangle r) { + Insets insets = getInsets(); + Point location = getLocationOnScreen(); + Dimension size = getSize(); + r.x = location.x + insets.left + 5; + r.y = location.y + insets.top + 5; + r.width = size.width - (insets.left + insets.right + 10); + r.height = size.height - (insets.top + insets.bottom + 10); + } + + /* + * Check color match within allowed deviation. + * Prints first non-matching pixel coordinates and actual and expected values. + * Returns true if image is filled with the provided color, false otherwise. + */ + private boolean checkColor(BufferedImage img, Color c, int delta) { + int cRed = c.getRed(); + int cGreen = c.getGreen(); + int cBlue = c.getBlue(); + for (int y = 0; y < img.getHeight(); y++) { + for (int x = 0; x < img.getWidth(); x++) { + int rgb = img.getRGB(x, y); + int red = (rgb & 0x00ff0000) >> 16; + int green = (rgb & 0x0000ff00) >> 8; + int blue = rgb & 0x000000ff; + if (cRed > (red + delta) || cRed < (red - delta) + || cGreen > (green + delta) || cGreen < (green - delta) + || cBlue > (blue + delta) || cBlue < (blue - delta)) { + System.err.println("Color at coordinates (" + x + ", " + y + ") does not match"); + System.err.println("Expected color: " + c.getRGB()); + System.err.println("Actual color: " + rgb); + System.err.println("Allowed deviation: " + delta); + return false; + } + } + } + return true; + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + NativeWin32Clear test = new NativeWin32Clear(); + try { + EventQueue.invokeAndWait(test::initialize); + Robot robot = new Robot(); + Rectangle coords = new Rectangle(); + EventQueue.invokeAndWait(() -> { + test.requestCoordinates(coords); + }); + robot.delay(2000); + robot.mouseMove(coords.x - 50, coords.y - 50); + robot.waitForIdle(); + BufferedImage capture = robot.createScreenCapture(coords); + robot.delay(2000); + if (!test.checkColor(capture, Color.green, 5)) { + throw new RuntimeException("Incorrect color encountered, check error log for details"); + } + } finally { + EventQueue.invokeAndWait(test::cleanup); + } + } +} diff --git a/test/jdk/java/awt/Graphics/PolygonFillTest.java b/test/jdk/java/awt/Graphics/PolygonFillTest.java new file mode 100644 index 0000000000000..72c216f9e4b56 --- /dev/null +++ b/test/jdk/java/awt/Graphics/PolygonFillTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2001, 2025, 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 4465509 4453725 4489667 + * @summary verify that fillPolygon completely fills area defined by drawPolygon + * @key headful + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual PolygonFillTest +*/ + +import java.awt.Color; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Polygon; +import java.lang.reflect.InvocationTargetException; + +public class PolygonFillTest extends Frame { + Polygon poly; + static String INSTRUCTIONS = """ + There should be two hourglass shapes drawn inside the window + called "Polygon Fill Test". The outline should be blue + and the interior should be green and there should be no gaps + between the filled interior and the outline nor should the green + filler spill outside the blue outline. You may need + to use a screen magnifier to inspect the smaller shape + on the left to verify that there are no gaps. + + If both polygons painted correctly press "Pass" otherwise press "Fail". + """; + + public PolygonFillTest() { + poly = new Polygon(); + poly.addPoint(0, 0); + poly.addPoint(10, 10); + poly.addPoint(0, 10); + poly.addPoint(10, 0); + setSize(300, 300); + setTitle("Polygon Fill Test"); + } + + public void paint(Graphics g) { + int w = getWidth(); + int h = getHeight(); + Image img = createImage(20, 20); + Graphics g2 = img.getGraphics(); + drawPolys(g2, 20, 20, 5, 5); + g2.dispose(); + drawPolys(g, w, h, (w / 4) - 5, (h / 2) - 5); + g.drawImage(img, (3 * w / 4) - 40, (h / 2) - 40, 80, 80, null); + } + + public void drawPolys(Graphics g, int w, int h, int x, int y) { + g.setColor(Color.white); + g.fillRect(0, 0, w, h); + g.translate(x, y); + g.setColor(Color.green); + g.fillPolygon(poly); + g.setColor(Color.blue); + g.drawPolygon(poly); + g.translate(-x, -y); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Polygon Fill Instructions") + .instructions(INSTRUCTIONS) + .testUI(PolygonFillTest::new) + .build() + .awaitAndCheck(); + } +} diff --git a/test/jdk/java/awt/Graphics/TallText.java b/test/jdk/java/awt/Graphics/TallText.java new file mode 100644 index 0000000000000..b21b8a985d04b --- /dev/null +++ b/test/jdk/java/awt/Graphics/TallText.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2004, 2025, 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 4844952 + * @summary test large text draws properly to the screen + * @key headful + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual TallText + */ + +import java.awt.Color; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics; +import java.lang.reflect.InvocationTargetException; + +public class TallText extends Frame { + static String INSTRUCTIONS = """ + There should be a window called "Tall Text Test" that contains text "ABCDEFGHIJ". + Test should be properly displayed: no missing letters + and all letters fit within the frame without overlapping. + If all letters are properly displayed press "Pass", otherwise press "Fail". + """; + + public TallText() { + setSize(800, 200); + setTitle("Tall Text Test"); + } + + public void paint(Graphics g) { + Font font = new Font("dialog", Font.PLAIN, 99); + g.setFont(font); + g.setColor(Color.black); + g.drawString("ABCDEFGHIJ", 10, 150); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PassFailJFrame.builder() + .title("Tall Text Instructions") + .instructions(INSTRUCTIONS) + .testUI(TallText::new) + .build() + .awaitAndCheck(); + } +} From 524c8214575b8da0e866f6e2345a9ff206468b52 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 21 May 2025 17:27:33 +0000 Subject: [PATCH 280/846] 8353942: Open source Swing Tests - Set 5 Backport-of: 9a0cff692d6f96b8c89b1510cd2b4b1a8e318b6e --- .../DataTransfer/DragOverFeedbackTest.java | 117 +++++++++++++++++ .../ListDragOverFeedbackTest.java | 119 ++++++++++++++++++ .../javax/swing/DataTransfer/bug4655513.java | 106 ++++++++++++++++ .../swing/SwingUtilities/bug4369355.java | 87 +++++++++++++ .../swing/SwingUtilities/bug4967768.java | 66 ++++++++++ 5 files changed, 495 insertions(+) create mode 100644 test/jdk/javax/swing/DataTransfer/DragOverFeedbackTest.java create mode 100644 test/jdk/javax/swing/DataTransfer/ListDragOverFeedbackTest.java create mode 100644 test/jdk/javax/swing/DataTransfer/bug4655513.java create mode 100644 test/jdk/javax/swing/SwingUtilities/bug4369355.java create mode 100644 test/jdk/javax/swing/SwingUtilities/bug4967768.java diff --git a/test/jdk/javax/swing/DataTransfer/DragOverFeedbackTest.java b/test/jdk/javax/swing/DataTransfer/DragOverFeedbackTest.java new file mode 100644 index 0000000000000..824f651a1a097 --- /dev/null +++ b/test/jdk/javax/swing/DataTransfer/DragOverFeedbackTest.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2001, 2025, 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 4514071 + * @summary Tests that JTable, JList and JTree provide drag-over feedback. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DragOverFeedbackTest + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.datatransfer.DataFlavor; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.JTree; +import javax.swing.TransferHandler; + +public class DragOverFeedbackTest { + private static final String INSTRUCTIONS = """ + This test is designed to make sure that JTable, JTree, and JList + provide visual feedback when a DnD drag operation occurs over them. + + Click on the label where it says "DRAG FROM HERE" and begin dragging. + Drag over each of the three components (JTable, JTree, JList). + While you're dragging over them, they should visually indicate the + location where a drop would occur. This visual indication may use the + selection but could be some other visual. + + If above is true press PASS else press FAIL. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .columns(50) + .testUI(DragOverFeedbackTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static final TransferHandler handler = new TransferHandler() { + public boolean canImport(JComponent comp, DataFlavor[] flavors) { + return true; + } + }; + + private static JFrame createTestUI() { + JFrame frame = new JFrame("DragOverFeedbackTest"); + final JLabel label = new JLabel("DRAG FROM HERE"); + label.setPreferredSize(new Dimension(400, 25)); + label.setTransferHandler(new TransferHandler("text")); + label.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + label.getTransferHandler().exportAsDrag(label, me, TransferHandler.COPY); + } + }); + JTable table = new JTable( + new String[][] {{"one"}, {"two"}, {"three"}, {"four"}}, + new String[] {"1"}); + table.setRowSelectionInterval(1, 1); + table.setTransferHandler(handler); + + JList list = new JList(new String[] {"one", "two", "three", "four"}); + list.setSelectedIndex(1); + list.setTransferHandler(handler); + + JTree tree = new JTree(); + tree.setSelectionRow(1); + tree.setTransferHandler(handler); + + frame.add(label, BorderLayout.NORTH); + + JPanel wrapper = new JPanel(); + wrapper.setLayout(new GridLayout(3, 1)); + table.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + wrapper.add(table); + list.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + wrapper.add(list); + tree.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + wrapper.add(tree); + frame.add(wrapper); + frame.setSize(500, 500); + return frame; + } +} diff --git a/test/jdk/javax/swing/DataTransfer/ListDragOverFeedbackTest.java b/test/jdk/javax/swing/DataTransfer/ListDragOverFeedbackTest.java new file mode 100644 index 0000000000000..b41327a106ed6 --- /dev/null +++ b/test/jdk/javax/swing/DataTransfer/ListDragOverFeedbackTest.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2002, 2025, 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 4546134 + * @summary Tests that JList shows the right drop location when it has multiple columns. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ListDragOverFeedbackTest + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.datatransfer.DataFlavor; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.TransferHandler; + +public class ListDragOverFeedbackTest { + private static final String INSTRUCTIONS = """ + JList should provide visual feedback when a DnD drag operation is + occurring over it. This test is to check that it provides the + feedback about the drop location correctly. + + Click on the label where it says "DRAG FROM HERE" and begin dragging. + Drag over each column in each of the three JLists and make sure that + the drop location indicated is appropriate for the mouse location. For + instance, if the mouse is in the first column, the drop location should + also be indicated in that first column. + + If above is true press PASS else press FAIL. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .columns(50) + .testUI(ListDragOverFeedbackTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static final TransferHandler handler = new TransferHandler() { + public boolean canImport(JComponent comp, DataFlavor[] flavors) { + return true; + } + }; + + private static JFrame createTestUI() { + String[] vals = new String[] { + "one", "two", "three", "four", "five", "six", "seven", "eight", + "nine", "ten", "eleven", "twelve", "thirteen", "fourteen"}; + + JFrame frame = new JFrame("ListDragOverFeedbackTest"); + final JLabel label = new JLabel("DRAG FROM HERE"); + label.setPreferredSize(new Dimension(400, 25)); + label.setTransferHandler(new TransferHandler("text")); + label.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + label.getTransferHandler().exportAsDrag(label, me, + TransferHandler.COPY); + } + }); + + JList list1 = new JList(vals); + list1.setTransferHandler(handler); + list1.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + + JList list2 = new JList(vals); + list2.setLayoutOrientation(JList.VERTICAL_WRAP); + list2.setTransferHandler(handler); + list2.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + + JList list3 = new JList(vals); + list3.setLayoutOrientation(JList.HORIZONTAL_WRAP); + list3.setTransferHandler(handler); + list3.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + + JPanel wrapper = new JPanel(); + wrapper.setLayout(new GridLayout(3, 1)); + wrapper.add(list1); + wrapper.add(list2); + wrapper.add(list3); + + frame.add(label, BorderLayout.NORTH); + frame.add(wrapper); + frame.setSize(400, 500); + return frame; + } +} diff --git a/test/jdk/javax/swing/DataTransfer/bug4655513.java b/test/jdk/javax/swing/DataTransfer/bug4655513.java new file mode 100644 index 0000000000000..c9f49f98939eb --- /dev/null +++ b/test/jdk/javax/swing/DataTransfer/bug4655513.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2002, 2025, 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 + * @key headful + * @bug 4655513 + * @summary TransferHandler doesn't recognize ACTION_LINK + as a valid drop action + * @library /javax/swing/regtesthelpers + * @build Util + * @run main bug4655513 + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.StringSelection; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; + +public class bug4655513 { + private static final String LINK_URL = "http://www.example.com"; + private static volatile JEditorPane editor; + private static volatile JLabel dragSource; + private static JFrame frame; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + SwingUtilities.invokeAndWait(bug4655513::createAndShowGUI); + robot.waitForIdle(); + robot.delay(1000); + + Point dragStartLoc = Util.getCenterPoint(dragSource); + Point dragEndLoc = Util.getCenterPoint(editor); + robot.mouseMove(dragStartLoc.x, dragStartLoc.y); + robot.mousePress(MouseEvent.BUTTON1_DOWN_MASK); + for (int y = dragStartLoc.y; y < dragEndLoc.y; y += 3) { + robot.mouseMove(dragStartLoc.x, y); + robot.delay(50); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(500); + + SwingUtilities.invokeAndWait(() -> { + if (!editor.getText().contains(LINK_URL)) { + throw new RuntimeException("Test Failed! Drag & Drop did not work."); + } + }); + } finally { + SwingUtilities.invokeAndWait(frame::dispose); + } + } + + private static void createAndShowGUI() { + frame = new JFrame("Bug4655513 - Data Transfer"); + dragSource = new JLabel("To Test DnD, drag this label."); + dragSource.setForeground(Color.RED); + dragSource.setPreferredSize(new Dimension(250, 50)); + frame.add(dragSource, BorderLayout.NORTH); + + editor = new JEditorPane("text/plain", "Drop here."); + editor.setPreferredSize(new Dimension(250, 50)); + frame.add(new JScrollPane(editor), BorderLayout.CENTER); + + DragSource ds = new DragSource(); + DragGestureRecognizer rec = + ds.createDefaultDragGestureRecognizer(dragSource, + DnDConstants.ACTION_LINK, + dge -> dge.startDrag(null, new StringSelection(LINK_URL))); + frame.setSize(300, 150); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } +} diff --git a/test/jdk/javax/swing/SwingUtilities/bug4369355.java b/test/jdk/javax/swing/SwingUtilities/bug4369355.java new file mode 100644 index 0000000000000..f55d888ef3179 --- /dev/null +++ b/test/jdk/javax/swing/SwingUtilities/bug4369355.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2000, 2025, 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 + * @key headful + * @bug 4369355 + * @summary To verify if SwingUtilities.convertPointToScreen() (for invisible frame) + * and SwingUtilities.convertPointFromScreen() return correct values + * @run main bug4369355 + */ + +import java.awt.Point; +import java.awt.Robot; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class bug4369355 { + private static JFrame frame; + + private static volatile Point frameToScreenLoc; + private static volatile Point frameFromScreenLoc; + + private static final Point EXPECTED_FROM_SCREEN_LOC = new Point(0, 0); + private static final Point EXPECTED_TO_SCREEN_LOC = new Point(100, 100); + + public static void main (String[] args) throws Exception { + try { + Robot robot = new Robot(); + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("bug4369355"); + frame.setBounds(100, 100, 100, 100); + }); + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + frameToScreenLoc = new Point(0, 0); + SwingUtilities.convertPointToScreen(frameToScreenLoc, frame); + }); + robot.delay(100); + + if (!frameToScreenLoc.equals(EXPECTED_TO_SCREEN_LOC)) { + throw new RuntimeException("SwingUtilities.convertPointToScreen()" + + " returns incorrect point " + frameToScreenLoc + "\n" + + "Should be " + EXPECTED_TO_SCREEN_LOC); + } + + SwingUtilities.invokeAndWait(() -> frame.setVisible(true)); + robot.delay(500); + + SwingUtilities.invokeAndWait(() -> { + frameFromScreenLoc = frame.getLocationOnScreen(); + SwingUtilities.convertPointFromScreen(frameFromScreenLoc, frame); + }); + robot.delay(100); + + if (!frameFromScreenLoc.equals(EXPECTED_FROM_SCREEN_LOC)) { + throw new RuntimeException("SwingUtilities.convertPointFromScreen()" + + " returns incorrect point " + frameFromScreenLoc + "\n" + + "Should be " + EXPECTED_FROM_SCREEN_LOC); + } + } finally { + SwingUtilities.invokeAndWait(frame::dispose); + } + } +} diff --git a/test/jdk/javax/swing/SwingUtilities/bug4967768.java b/test/jdk/javax/swing/SwingUtilities/bug4967768.java new file mode 100644 index 0000000000000..43f9f7cabfbeb --- /dev/null +++ b/test/jdk/javax/swing/SwingUtilities/bug4967768.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2004, 2025, 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 4967768 + * @requires (os.family != "mac") + * @summary Tests that underline is painted correctly in mnemonics + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4967768 + */ + +import java.awt.Font; +import javax.swing.JButton; +import javax.swing.JPanel; + +public class bug4967768 { + private static final String INSTRUCTIONS = """ + When the test starts you'll see a button "Oops" + with the "p" letter underlined at the bottom + of the instruction frame. + + Ensure the underline cuts through the descender + of letter "p", i.e. the underline is painted + not below the letter but below the baseline. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .columns(35) + .splitUIBottom(bug4967768::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JPanel createTestUI() { + JPanel panel = new JPanel(); + JButton but = new JButton("Oops"); + but.setFont(new Font("Dialog", Font.BOLD, 24)); + but.setMnemonic('p'); + panel.add(but); + return panel; + } +} From 94560a1e0a8e0790b1016a35dc5c3cefbbfd2e39 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 21 May 2025 17:28:42 +0000 Subject: [PATCH 281/846] 8353446: Open source several AWT Menu tests - Batch 2 Backport-of: 17b080b2c90f7fd9986fe38daebb76363d012469 --- .../Menu/DestroyMenuTest/DestroyMenuTest.java | 139 ++++++++++++++ .../awt/Menu/DestroyMenuTest/MenuTest.java | 172 ++++++++++++++++++ .../jdk/java/awt/Menu/MenuAddRemoveCrash.java | 102 +++++++++++ test/jdk/java/awt/Menu/MenuZOrderTest.java | 80 ++++++++ .../java/awt/Menu/OnFlyRepaintMenuTest.java | 103 +++++++++++ 5 files changed, 596 insertions(+) create mode 100644 test/jdk/java/awt/Menu/DestroyMenuTest/DestroyMenuTest.java create mode 100644 test/jdk/java/awt/Menu/DestroyMenuTest/MenuTest.java create mode 100644 test/jdk/java/awt/Menu/MenuAddRemoveCrash.java create mode 100644 test/jdk/java/awt/Menu/MenuZOrderTest.java create mode 100644 test/jdk/java/awt/Menu/OnFlyRepaintMenuTest.java diff --git a/test/jdk/java/awt/Menu/DestroyMenuTest/DestroyMenuTest.java b/test/jdk/java/awt/Menu/DestroyMenuTest/DestroyMenuTest.java new file mode 100644 index 0000000000000..b75ba047dfbe2 --- /dev/null +++ b/test/jdk/java/awt/Menu/DestroyMenuTest/DestroyMenuTest.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 1999, 2025, 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 4209511 + * @summary Regression test DestroyMenuTest.java Failing + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual DestroyMenuTest + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Canvas; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Label; +import java.awt.Panel; +import java.awt.Scrollbar; +import java.awt.TextField; + +public class DestroyMenuTest { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Create many windows by randomly clicking 'Show Menu Test 1', + 'Show Menu Test 2', 'Show Menu Test 3' buttons. + 2. Ignore the contents of the windows. + Go to the windows created and select menu items inside the menus. + 3. Close the windows by selecting menu item File--> Quit. + 4. Do the above menu item selections as quickly as possible. + If the program crashes when you select File--> Quit, + then the test FAILS. Otherwise the test is PASS. + """; + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .columns(38) + .testUI(DestroyMenuTest::initialize) + .build() + .awaitAndCheck(); + } + + static Frame initialize() { + Frame f = new Frame("Destroy Menu Test"); + Button launchButton = new Button("Show Menu Test 1..."); + Button launchButton2 = new Button("Show Menu Test 2..."); + Button launchButton3 = new Button("Show Menu Test 3..."); + f.setLayout(new FlowLayout()); + f.add(launchButton); + f.add(launchButton2); + f.add(launchButton3); + + launchButton.addActionListener(event -> { + MenuTest frame = new MenuTest("Menu Test 1"); + frame.setBounds(300, 300, 300, 300); + frame.setVisible(true); + }); + + launchButton2.addActionListener(event -> { + MenuTest frame = new MenuTest("Menu Test 2"); + + Button closeButton = new Button("Close"); + + Panel X = new Panel(); + X.setLayout(new BorderLayout()); + + Panel topPanel = new Panel(); + Panel bottomPanel = new Panel(); + + bottomPanel.add(closeButton); + + Scrollbar vScrollbar = new Scrollbar(Scrollbar.VERTICAL); + Scrollbar hScrollbar = new Scrollbar(Scrollbar.HORIZONTAL); + hScrollbar.setValues(hScrollbar.getValue(), 0, 0, 50); + vScrollbar.setValues(vScrollbar.getValue(), 0, 0, 50); + topPanel.setLayout(new BorderLayout()); + topPanel.add(vScrollbar, BorderLayout.EAST); + topPanel.add(hScrollbar, BorderLayout.SOUTH); + + X.add(topPanel, BorderLayout.NORTH); + X.add(bottomPanel, BorderLayout.SOUTH); + frame.add(X, BorderLayout.SOUTH); + frame.setBounds(350, 350, 300, 250); + frame.setVisible(true); + }); + + launchButton3.addActionListener(event -> { + MenuTest frame = new MenuTest("Menu Test 3"); + frame.setBounds(400, 400, 300, 300); + + mySimpleCanvas clock = new mySimpleCanvas(); + frame.add(clock, BorderLayout.CENTER); + + Panel p = new Panel(); + Button closeButton = new Button("Close"); + p.add(closeButton); + + p.add(new Label("Label")); + TextField textField = new TextField(8); + p.add(textField); + f.add(p, BorderLayout.EAST); + + frame.add(p, BorderLayout.SOUTH); + frame.setVisible(true); + }); + f.pack(); + return f; + } + + static class mySimpleCanvas extends Canvas { + @Override + public void paint(Graphics g) { + g.drawOval(0, 0, 100, 100); + g.drawOval(2, 2, 100, 100); + g.drawOval(4, 4, 100, 100); + } + } +} diff --git a/test/jdk/java/awt/Menu/DestroyMenuTest/MenuTest.java b/test/jdk/java/awt/Menu/DestroyMenuTest/MenuTest.java new file mode 100644 index 0000000000000..95569f13fa22e --- /dev/null +++ b/test/jdk/java/awt/Menu/DestroyMenuTest/MenuTest.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Canvas; +import java.awt.CardLayout; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Label; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.Panel; + +public class MenuTest extends Frame { + private MenuItem quitItem; + private final Panel cards; + private final CardLayout layout; + + public MenuTest(String s) { + super(s); + MenuBar mbar = new MenuBar(); + createMenus(mbar); + setMenuBar(mbar); + + cards = new Panel(); + layout = new CardLayout(); + cards.setLayout(layout); + + cards.add(new MyPanelOne("Options"), "Options"); + cards.add(new MyRectCanvas(), "MyRectCanvas"); + cards.add(new MycircleCanvas(), "MyCircleCanvas"); + + add(cards, "Center"); + } + + public void createMenus(MenuBar mbar) { + mbar.add(createFileMenu()); + mbar.add(createEditMenu()); + mbar.add(createOptionMenu1()); + mbar.add(createOptionMenu2()); + mbar.add(createOptionMenu3()); + mbar.add(createOptionMenu4()); + } + + private Menu createFileMenu() { + Menu fileMenu = new Menu("File"); + fileMenu.add(quitItem = new MenuItem("Quit")); + + quitItem.addActionListener(event -> { + MenuItem item = (MenuItem) event.getSource(); + if (item == quitItem) { + dispose(); + } + }); + return fileMenu; + } + + private Menu createEditMenu() { + Menu editMenu = new Menu("Edit"); + + editMenu.add("Cut"); + editMenu.add("Copy"); + editMenu.add("Paste"); + editMenu.addSeparator(); + editMenu.add("Select all"); + editMenu.addSeparator(); + editMenu.add("Find"); + editMenu.add("Find again"); + + return editMenu; + } + + private Menu createOptionMenu1() { + Menu optionMenu1 = new Menu("Option1"); + MenuItem item1, item2, item3; + optionMenu1.add(item1 = new MenuItem("Item1")); + optionMenu1.add(item2 = new MenuItem("Item2")); + optionMenu1.add(item3 = new MenuItem("Item3")); + + item1.addActionListener(event -> { + MenuItem mItem = (MenuItem) event.getSource(); + if (mItem == item1) { + layout.show(cards, "Options"); + } + }); + item2.addActionListener(event -> { + MenuItem mItem = (MenuItem) event.getSource(); + if (mItem == item2) { + layout.show(cards, "MyRectCanvas"); + } + }); + item3.addActionListener(event -> { + MenuItem mItem = (MenuItem) event.getSource(); + if (mItem == item3) { + layout.show(cards, "MyCircleCanvas"); + } + }); + return optionMenu1; + } + + private Menu createOptionMenu2() { + Menu optionMenu2 = new Menu("Option2"); + + optionMenu2.add("Item1"); + optionMenu2.add("Item2"); + + return optionMenu2; + } + + private Menu createOptionMenu3() { + Menu optionMenu3 = new Menu("Option3"); + + optionMenu3.add("Item1"); + optionMenu3.add("Item2"); + optionMenu3.add("Item3"); + optionMenu3.add("Item4"); + + return optionMenu3; + } + + private Menu createOptionMenu4() { + Menu optionMenu4 = new Menu("Option3"); + + optionMenu4.add("Item1"); + optionMenu4.add("Item2"); + optionMenu4.add("Item3"); + + return optionMenu4; + } +} + +class MyRectCanvas extends Canvas { + @Override + public void paint(Graphics g) { + g.drawRect(0, 0, 100, 100); + } +} + +class MyPanelOne extends Panel { + MyPanelOne(String name) { + add(new Label(name + " panel goes here")); + } +} + +class MycircleCanvas extends Canvas { + @Override + public void paint(Graphics g) { + g.drawOval(0, 0, 100, 100); + g.drawOval(2, 2, 100, 100); + g.drawOval(4, 4, 100, 100); + } +} diff --git a/test/jdk/java/awt/Menu/MenuAddRemoveCrash.java b/test/jdk/java/awt/Menu/MenuAddRemoveCrash.java new file mode 100644 index 0000000000000..d5c80c27a4f25 --- /dev/null +++ b/test/jdk/java/awt/Menu/MenuAddRemoveCrash.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2001, 2025, 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 4410477 + * @summary Tests that menu does not crash during simultaneous drawing + * and removal of items. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MenuAddRemoveCrash + */ + +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; + +public class MenuAddRemoveCrash { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Move and resize the frame. + 2. If the test crashes the test is FAILED. + Otherwise it is PASSED. + """; + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(MenuAddRemoveCrash::initialize) + .build() + .awaitAndCheck(); + } + + public static Frame initialize() { + final TestGui myTestGui = new TestGui(); + Thread test = new Thread() { + public void run() { + while (!Thread.interrupted()) { + myTestGui.changeMenuItems(); + } + } + }; + test.setDaemon(true); + test.start(); + return myTestGui; + } +} + +class TestGui extends Frame { + Menu myMenu1; + Menu myMenu2; + + public TestGui() { + this.setTitle("Try to resize this frame!"); + + this.setSize(300, 300); + this.setVisible(true); + + MenuBar myMenuBar = new MenuBar(); + myMenu1 = new Menu("DemoMenu1"); + myMenu2 = new Menu("DemoMenu2"); + + myMenuBar.add(myMenu1); + myMenuBar.add(myMenu2); + + this.setMenuBar(myMenuBar); + } + + public void changeMenuItems() { + myMenu1.removeAll(); + + for (int i = 0; i < 10; i++) { + MenuItem myMenuItem1 = new MenuItem("DemoMenuItem" + i); + myMenu1.add(myMenuItem1); + } + try { + Thread.sleep(100); + } catch (Exception e) { + throw new RuntimeException("Failed :" + e); + } + } +} diff --git a/test/jdk/java/awt/Menu/MenuZOrderTest.java b/test/jdk/java/awt/Menu/MenuZOrderTest.java new file mode 100644 index 0000000000000..fefd3d64c28f9 --- /dev/null +++ b/test/jdk/java/awt/Menu/MenuZOrderTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2005, 2025, 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 6267182 + * @summary Menu is not visible after showing and disposing a file dialog. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MenuZOrderTest + */ + +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class MenuZOrderTest { + static class Listener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + Frame f = new Frame("Menu Z order test frame"); + f.setBounds(200, 200, 200, 200); + f.setVisible(true); + } + } + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Choose Menu 1 --> Menu Item 1 several times. + 2. If menu window is shown correctly and each click + creates new frame - press PASS. + 3. If menu window is obscured by frame - press FAIL. + """; + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(MenuZOrderTest::initialize) + .build() + .awaitAndCheck(); + } + + static Frame initialize() { + Frame mf = new Frame("Menu Z order test"); + Listener l = new Listener(); + MenuBar mb = new MenuBar(); + Menu m1 = new Menu("Menu 1"); + MenuItem mi1 = new MenuItem("Menu Item 1"); + + mf.setSize(200, 200); + mi1.addActionListener(l); + m1.add(mi1); + mb.add(m1); + mf.setMenuBar(mb); + mf.setVisible(true); + return mf; + } +} diff --git a/test/jdk/java/awt/Menu/OnFlyRepaintMenuTest.java b/test/jdk/java/awt/Menu/OnFlyRepaintMenuTest.java new file mode 100644 index 0000000000000..617d640d90732 --- /dev/null +++ b/test/jdk/java/awt/Menu/OnFlyRepaintMenuTest.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2004, 2025, 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 5024051 + * @summary Tests if menu is repainted in enabling/disabling it and + * changing its label while it is visible, either on MenuBar + * or in other Menu. Menu items are covered as well + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual OnFlyRepaintMenuTest + */ + +import java.awt.Button; +import java.awt.CheckboxMenuItem; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; + +public class OnFlyRepaintMenuTest { + static boolean menuEnabled = true; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Click the button 'Change state' and wait for 5 secs. + 2. If menu is repainted correctly after its setLabel() + and setEnabled() methods called test PASSED, else FAILED. + (During a 5 secs delay you may select the menu to see + the effect for menu items and submenu) + """; + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(OnFlyRepaintMenuTest::initialize) + .build() + .awaitAndCheck(); + } + + static Frame initialize() { + Frame f = new Frame("OnFly Menu Repaint Test"); + + f.setSize(200, 100); + + MenuBar mb = new MenuBar(); + Menu menu = new Menu("Menu"); + MenuItem menuItem = new MenuItem("MenuItem"); + menu.add(menuItem); + Menu submenu = new Menu("SubMenu"); + MenuItem submenuItem = new MenuItem("SubmenuItem"); + submenu.add(submenuItem); + CheckboxMenuItem checkMenuItem = new CheckboxMenuItem("CheckboxmenuItem"); + checkMenuItem.setState(true); + menu.add(checkMenuItem); + menu.add(submenu); + mb.add(menu); + f.setMenuBar(mb); + + Button b = new Button("Change state"); + b.addActionListener(ev -> new Thread(() -> { + try { + Thread.sleep(5000); + } catch (Exception e) { + } + menuEnabled = !menuEnabled; + String label = menuEnabled ? "Enabled" : "Disabled"; + menu.setLabel(label); + menuItem.setLabel(label); + submenu.setLabel(label); + submenuItem.setLabel(label); + checkMenuItem.setLabel(label); + checkMenuItem.setEnabled(menuEnabled); + checkMenuItem.setState(menuEnabled); + submenuItem.setEnabled(menuEnabled); + submenu.setEnabled(menuEnabled); + menuItem.setEnabled(menuEnabled); + menu.setEnabled(menuEnabled); + }).start()); + f.add(b); + return f; + } +} From fbe033de9f3a629762fd95559f8821fbbe2571f3 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 21 May 2025 17:29:59 +0000 Subject: [PATCH 282/846] 8353685: Open some JComboBox bugs 4 Backport-of: 0b2a2f38d0b0133a562a898836d7a1b2dbd73a5e --- .../jdk/javax/swing/JComboBox/bug4212498.java | 86 +++++++++++++++++ .../jdk/javax/swing/JComboBox/bug4459267.java | 75 +++++++++++++++ .../jdk/javax/swing/JComboBox/bug4519269.java | 94 +++++++++++++++++++ 3 files changed, 255 insertions(+) create mode 100644 test/jdk/javax/swing/JComboBox/bug4212498.java create mode 100644 test/jdk/javax/swing/JComboBox/bug4459267.java create mode 100644 test/jdk/javax/swing/JComboBox/bug4519269.java diff --git a/test/jdk/javax/swing/JComboBox/bug4212498.java b/test/jdk/javax/swing/JComboBox/bug4212498.java new file mode 100644 index 0000000000000..b60470fdd327c --- /dev/null +++ b/test/jdk/javax/swing/JComboBox/bug4212498.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.event.ActionListener; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; + +/* + * @test + * @bug 4212498 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4212498 + */ + +public class bug4212498 { + static JPanel panel = new JPanel(); + static JComboBox comboBox = new JComboBox(new Object[]{ + "Coma Berenices", + "Triangulum", + "Camelopardis", + "Cassiopea"}); + + private static final String INSTRUCTIONS = """ + Edit the value in the text field (without using the popup) + and then press the tab key. If the number doesn't increase, + then test fails. + + Also, try tabbing out without making a change. The number + should NOT increase unless the user changes something. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("Instructions") + .instructions(INSTRUCTIONS) + .columns(50) + .testUI(bug4212498::createTestUI) + .build() + .awaitAndCheck(); + } + + public static JFrame createTestUI() { + JFrame frame = new JFrame("bug4212498"); + comboBox.setEditable(true); + + final JLabel label = new JLabel("0"); + + ActionListener actionListener = + e -> label.setText("" + (Integer.parseInt(label.getText()) + 1)); + + comboBox.addActionListener(actionListener); + + panel.add(comboBox); + panel.add(label); + panel.add(new JButton("B")); + + frame.getContentPane().add(panel); + frame.pack(); + frame.setLocationRelativeTo(null); + return frame; + } +} diff --git a/test/jdk/javax/swing/JComboBox/bug4459267.java b/test/jdk/javax/swing/JComboBox/bug4459267.java new file mode 100644 index 0000000000000..85049936ea7fd --- /dev/null +++ b/test/jdk/javax/swing/JComboBox/bug4459267.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +/* + * @test + * @bug 4459267 + * @summary Tests that pressing PageUp in combo popup list doesn't cause + * stack overflow + * @key headful + * @run main bug4459267 + */ + +public class bug4459267 { + static JFrame frame; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoDelay(250); + + SwingUtilities.invokeAndWait(() -> createTestUI()); + robot.waitForIdle(); + robot.delay(1000); + + robot.keyPress(KeyEvent.VK_PAGE_UP); + robot.keyRelease(KeyEvent.VK_PAGE_UP); + robot.waitForIdle(); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public static void createTestUI() { + frame = new JFrame("bug4459267"); + JComboBox jcmb = new JComboBox(); + jcmb.addItem("JComobo1"); + jcmb.addItem("Item2"); + jcmb.addItem("Item3"); + frame.getContentPane().add(jcmb, BorderLayout.NORTH); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } +} diff --git a/test/jdk/javax/swing/JComboBox/bug4519269.java b/test/jdk/javax/swing/JComboBox/bug4519269.java new file mode 100644 index 0000000000000..29147998d0a4c --- /dev/null +++ b/test/jdk/javax/swing/JComboBox/bug4519269.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +/* + * @test + * @bug 4519269 + * @summary Tests that DefaultKeySelectionManager doesn't throw NPE + * @key headful + * @run main bug4519269 + */ + +public class bug4519269 { + static JFrame frame; + static JComboBox combo; + static Point p; + static Object[] data = {new CustomString("Item 1"), new CustomString("Item 2"), + new CustomString("Item 3"), new CustomString("Item 4")}; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoDelay(250); + + SwingUtilities.invokeAndWait(() -> createTestUI()); + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> p = combo.getLocationOnScreen()); + robot.mouseMove(p.x + 5, p.y + 5); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + + robot.keyPress(KeyEvent.VK_SHIFT); + robot.keyRelease(KeyEvent.VK_SHIFT); + robot.waitForIdle(); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public static void createTestUI() { + frame = new JFrame("bug4519269"); + combo = new JComboBox(data); + frame.getContentPane().add(combo); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + static class CustomString { + String string; + + public CustomString(String s) { + string = s; + } + + public String toString() { + return null; + } + } +} From e65f836ea61f6071714094be4672b8c149920a97 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 21 May 2025 17:31:05 +0000 Subject: [PATCH 283/846] 8354554: Open source several clipboard tests batch1 Backport-of: 4873eec06f25227fe221a86b07c6072e676f7d5d --- test/jdk/ProblemList.txt | 3 + test/jdk/java/awt/Clipboard/ClipRWTest.java | 104 ++++++++ .../SystemClipboard2ProcTest.java | 171 +++++++++++++ .../awt/Clipboard/NoOwnerNoTargetsTest.java | 131 ++++++++++ .../PasteNullToTextComponentsTest.java | 228 ++++++++++++++++++ 5 files changed, 637 insertions(+) create mode 100644 test/jdk/java/awt/Clipboard/ClipRWTest.java create mode 100644 test/jdk/java/awt/Clipboard/LostOwnershipChainTest/SystemClipboard2ProcTest.java create mode 100644 test/jdk/java/awt/Clipboard/NoOwnerNoTargetsTest.java create mode 100644 test/jdk/java/awt/Clipboard/PasteNullToTextComponentsTest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 24e33f61c102f..06c32a5cb5c68 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -263,6 +263,9 @@ java/awt/print/PrinterJob/GlyphPositions.java 7003378 generic-all java/awt/Choice/ChoiceMouseWheelTest/ChoiceMouseWheelTest.java 7100044 macosx-all,linux-all java/awt/Component/GetScreenLocTest/GetScreenLocTest.java 4753654 generic-all java/awt/Component/SetEnabledPerformance/SetEnabledPerformance.java 8165863 macosx-all +java/awt/Clipboard/PasteNullToTextComponentsTest.java 8234140 macosx-all,windows-all +java/awt/Clipboard/NoOwnerNoTargetsTest.java 8234140 macosx-all +java/awt/Clipboard/LostOwnershipChainTest/SystemClipboard2ProcTest.java 8234140 macosx-all java/awt/Clipboard/HTMLTransferTest/HTMLTransferTest.java 8017454 macosx-all java/awt/Frame/MiscUndecorated/RepaintTest.java 8266244 macosx-aarch64 java/awt/Robot/ModifierRobotKey/ModifierRobotKeyTest.java 8157173 generic-all diff --git a/test/jdk/java/awt/Clipboard/ClipRWTest.java b/test/jdk/java/awt/Clipboard/ClipRWTest.java new file mode 100644 index 0000000000000..c173dd17f0dff --- /dev/null +++ b/test/jdk/java/awt/Clipboard/ClipRWTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2002, 2025, 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 4177171 4180145 4180148 + * @summary Can't copy to clipboard + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual ClipRWTest + */ + +import java.awt.Button; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.TextField; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; + +public class ClipRWTest { + private static final String INSTRUCTIONS = """ + 1. Type some text in the text field and press Copy Text. + 2. Switch to a _native_ application (e.g. Notepad) and paste the text in + 3. Verify the text that is pasted matches what you typed in the Java window + 4. In the native app, type some new text and copy it + 5. Switch back to the test frame and press Paste Text + 6. Verify the text that is pasted matches what you typed in the native app + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("ClipRWTest Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(ClipFrame::new) + .build() + .awaitAndCheck(); + } + + private static class ClipFrame extends Frame { + TextField field =new TextField(50); + Button copyText = new Button("Copy Text"); + Button pasteText = new Button("Paste Text"); + Clipboard clipboard; + + public ClipFrame() { + super("ClipRWTest 4177171"); + setLayout(new FlowLayout()); + + clipboard = getToolkit().getSystemClipboard(); + + add(field); + add(copyText); + add(pasteText); + + copyText.addActionListener( + ev -> { + String text = field.getText(); + try { + clipboard.setContents(new StringSelection(text), null); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + ); + + pasteText.addActionListener( + ev -> { + String text = ""; + try { + text = (String) clipboard.getContents(null) + .getTransferData(DataFlavor.stringFlavor); + } catch (Exception ex) { + ex.printStackTrace(); + } + field.setText(text); + } + ); + + pack(); + } + } +} diff --git a/test/jdk/java/awt/Clipboard/LostOwnershipChainTest/SystemClipboard2ProcTest.java b/test/jdk/java/awt/Clipboard/LostOwnershipChainTest/SystemClipboard2ProcTest.java new file mode 100644 index 0000000000000..9bd76ad096266 --- /dev/null +++ b/test/jdk/java/awt/Clipboard/LostOwnershipChainTest/SystemClipboard2ProcTest.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2002, 2025, 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 4683804 + * @summary Tests that in ClipboardOwner.lostOwnership() Clipboard.getContents() + * returns actual contents of the clipboard and Clipboard.setContents() + * can set contents of the clipboard and its owner. The clipboard is + * the system clipboard and the owners of the clipboard are in + * 2 different processes. + * @key headful + * @library /test/lib + * @run main SystemClipboard2ProcTest +*/ + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class SystemClipboard2ProcTest { + + public static void main(String[] args) throws Exception { + SystemClipboardOwner.run(); + + if (SystemClipboardOwner.failed) { + throw new RuntimeException("test failed: can not get actual " + + "contents of the clipboard or set owner of the clipboard"); + } else { + System.err.println("test passed"); + } + } +} + +class SystemClipboardOwner implements ClipboardOwner { + static volatile boolean failed; + + private static final Object LOCK = new Object(); + + private static final int CHAIN_LENGTH = 5; + private final static Clipboard clipboard = + Toolkit.getDefaultToolkit().getSystemClipboard(); + + private int m, id; + + public SystemClipboardOwner(int m) { this.m = m; id = m; } + + public void lostOwnership(Clipboard cb, Transferable contents) { + System.err.println(id + " lost clipboard ownership"); + + Transferable t = getClipboardContents(cb, null); + // for test passing if t.getTransferData() will throw an exception + String msg = "" + (m + 1); + try { + msg = (String)t.getTransferData(DataFlavor.stringFlavor); + } catch (Exception e) { + System.err.println(id + " can't getTransferData: " + e); + } + System.err.println(id + " Clipboard.getContents(): " + msg); + if (!msg.equals("" + (m + 1))) { + failed = true; + System.err.println("Clipboard.getContents() returned incorrect contents!"); + } + + m += 2; + if (m <= CHAIN_LENGTH) { + System.err.println(id + " Clipboard.setContents(): " + m); + setClipboardContents(cb, new StringSelection(m + ""), this); + } + if (m >= CHAIN_LENGTH) { + synchronized (LOCK) { + LOCK.notifyAll(); + } + } + } + + public static void run() throws Exception { + SystemClipboardOwner cbo1 = new SystemClipboardOwner(0); + System.err.println(cbo1.m + " Clipboard.setContents(): " + cbo1.m); + setClipboardContents(clipboard, new StringSelection(cbo1.m + ""), + cbo1); + + ProcessBuilder pb = ProcessTools + .createTestJavaProcessBuilder(SystemClipboardOwner.class.getName()); + + Process process = ProcessTools.startProcess("Child", pb); + OutputAnalyzer outputAnalyzer = new OutputAnalyzer(process); + + if (!process.waitFor(15, TimeUnit.SECONDS)) { + process.destroyForcibly(); + throw new TimeoutException("Timed out waiting for Child"); + } + + outputAnalyzer.shouldHaveExitValue(0); + + if (cbo1.m < CHAIN_LENGTH) { + failed = true; + System.err.println("chain of calls of lostOwnership() broken!"); + } + } + + public static void main(String[] args) throws InterruptedException { + SystemClipboardOwner cbo2 = new SystemClipboardOwner(1); + System.err.println(cbo2.m + " Clipboard.setContents(): " + cbo2.m); + synchronized (LOCK) { + setClipboardContents(clipboard, new StringSelection(cbo2.m + ""), + cbo2); + LOCK.wait(); + } + } + + private static void setClipboardContents(Clipboard cb, + Transferable contents, + ClipboardOwner owner) { + synchronized (cb) { + boolean set = false; + while (!set) { + try { + cb.setContents(contents, owner); + set = true; + } catch (IllegalStateException ise) { + try { Thread.sleep(100); } + catch (InterruptedException e) { e.printStackTrace(); } + } + } + } + } + + private static Transferable getClipboardContents(Clipboard cb, + Object requestor) { + synchronized (cb) { + while (true) { + try { + Transferable t = cb.getContents(requestor); + return t; + } catch (IllegalStateException ise) { + try { Thread.sleep(100); } + catch (InterruptedException e) { e.printStackTrace(); } + } + } + } + } +} diff --git a/test/jdk/java/awt/Clipboard/NoOwnerNoTargetsTest.java b/test/jdk/java/awt/Clipboard/NoOwnerNoTargetsTest.java new file mode 100644 index 0000000000000..178fe9b707456 --- /dev/null +++ b/test/jdk/java/awt/Clipboard/NoOwnerNoTargetsTest.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2002, 2025, 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 4655996 + * @summary tests that getting the system clipboard contents doesn't cause + * IOException if there is no clipboard owner or the owner doesn't + * export any target types + * @key headful + * @library /test/lib + * @run main NoOwnerNoTargetsTest + */ + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class NoOwnerNoTargetsTest implements ClipboardOwner { + + final Clipboard clipboard = + Toolkit.getDefaultToolkit().getSystemClipboard(); + public static final int CLIPBOARD_DELAY = 1000; + + public static void main(String[] args) throws Exception { + if (args.length > 0) { + NoOwnerNoTargetsTest test = new NoOwnerNoTargetsTest(); + test.execute(); + return; + } + + new NoOwnerNoTargetsTest().start(); + } + + public void execute() { + final ClipboardOwner clipboardOwner = new ClipboardOwner() { + public void lostOwnership(Clipboard clip, + Transferable contents) { + System.exit(0); + } + }; + final Transferable emptyTransferable = new Transferable() { + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[0]; + } + public boolean isDataFlavorSupported(DataFlavor df) { + return false; + } + public Object getTransferData(DataFlavor df) + throws UnsupportedFlavorException { + throw new UnsupportedFlavorException(df); + } + }; + + clipboard.setContents(emptyTransferable, clipboardOwner); + final Object o = new Object(); + synchronized (o) { + try { + o.wait(); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + } + + public void start() throws Exception { + clipboard.getContents(null); + + Transferable transferable = new StringSelection("TEXT"); + clipboard.setContents(transferable, this); + + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + NoOwnerNoTargetsTest.class.getName(), + "child" + ); + + Process process = ProcessTools.startProcess("Child", pb); + OutputAnalyzer outputAnalyzer = new OutputAnalyzer(process); + + if (!process.waitFor(15, TimeUnit.SECONDS)) { + process.destroyForcibly(); + throw new TimeoutException("Timed out waiting for Child"); + } + + outputAnalyzer.shouldHaveExitValue(0); + } + + public void lostOwnership(Clipboard clip, Transferable contents) { + final Transferable transferable = new StringSelection("TEXT"); + final Runnable r = () -> { + try { + Thread.sleep(CLIPBOARD_DELAY); + } catch (InterruptedException e) { + e.printStackTrace(); + } + clipboard.getContents(null); + clipboard.setContents(transferable, null); + }; + final Thread t = new Thread(r); + t.start(); + } +} diff --git a/test/jdk/java/awt/Clipboard/PasteNullToTextComponentsTest.java b/test/jdk/java/awt/Clipboard/PasteNullToTextComponentsTest.java new file mode 100644 index 0000000000000..191ba2288b7c1 --- /dev/null +++ b/test/jdk/java/awt/Clipboard/PasteNullToTextComponentsTest.java @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2002, 2025, 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 4401853 + * @summary Tests that pasting null to TextArea and TextField on Solaris/Linux + * removes selected text; doing it on Windows to TextArea does nothing, + * to TextField removes selected text. + * @key headful + * @run main PasteNullToTextComponentsTest + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; +import java.awt.TextComponent; +import java.awt.TextField; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +public class PasteNullToTextComponentsTest { + + private static final int NATIVE_EVENT_PROCESSING_TIMEOUT = 500; + private static final int WAIT_TIMEOUT = 3000; + + private boolean failed; + + private static final boolean isOSWindows = + System.getProperty("os.name").startsWith("Windows"); + + private final Object LOCK = new Object(); + + private Robot robot; + + private Frame frame; + private TextArea ta; + private TextField tf; + private Component initialFocusComp; + + private final String beg = "a"; + private final String sel = "b"; + private final String end = "c"; + private final String text = beg + sel + end; + private final String begEnd = beg + end; + + private boolean initialFocusGained; + + public void init() { + ta = new TextArea(text, 3, text.length() + 3); + tf = new TextField(text, text.length() + 3); + initialFocusComp = new Button("Initially focused button"); + + frame = new Frame(); + frame.add(initialFocusComp, BorderLayout.NORTH); + frame.add(ta, BorderLayout.CENTER); + frame.add(tf, BorderLayout.SOUTH); + frame.setSize(200, 200); + + FocusListener fl = new FocusAdapter() { + public void focusGained(FocusEvent e) { + System.out.println(e + "; source class=" + e.getSource().getClass()); + synchronized (LOCK) { + TextComponent tc = (TextComponent) e.getComponent(); + tc.select(1, 2); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.keyPress(KeyEvent.VK_V); + robot.keyRelease(KeyEvent.VK_V); + robot.keyRelease(KeyEvent.VK_CONTROL); + tc.removeFocusListener(this); + LOCK.notifyAll(); + } + } + }; + ta.addFocusListener(fl); + tf.addFocusListener(fl); + + initialFocusComp.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + System.out.println(e + "; source class=" + e.getSource().getClass()); + synchronized (LOCK) { + initialFocusGained = true; + LOCK.notifyAll(); + } + } + }); + + setClipboardContents(Toolkit.getDefaultToolkit().getSystemClipboard(), + new StringSelection(null), null); + + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + public void start() throws Exception { + robot = new Robot(); + robot.waitForIdle(); + robot.delay(500); + + Point iniFocusPoint = initialFocusComp.getLocationOnScreen(); + synchronized (LOCK) { + if (!initialFocusGained) { + robot.mouseMove(iniFocusPoint.x + 3, iniFocusPoint.y + 3); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + LOCK.wait(WAIT_TIMEOUT); + } + } + + initialFocusComp.requestFocusInWindow(); + robot.waitForIdle(); + + synchronized (LOCK) { + ta.requestFocusInWindow(); + LOCK.wait(WAIT_TIMEOUT); + } + + // wait until native control process key event (C^V) + robot.waitForIdle(); + robot.delay(NATIVE_EVENT_PROCESSING_TIMEOUT); + + synchronized (LOCK) { + tf.requestFocusInWindow(); + LOCK.wait(WAIT_TIMEOUT); + } + + // wait until native control process key event (C^V) + robot.waitForIdle(); + robot.delay(NATIVE_EVENT_PROCESSING_TIMEOUT); + + String taText = ta.getText(); + String tfText = tf.getText(); + + System.err.println("TextArea text=" + taText + + " TextField text=" + tfText); + + boolean taSelDeleted = begEnd.equals(taText); + boolean taSelRemained = text.equals(taText); + boolean tfSelDeleted = begEnd.equals(tfText); + + System.out.println("taSelDeleted = " + taSelDeleted); + System.out.println("taSelRemained = " + taSelRemained); + System.out.println("tfSelDeleted = " + tfSelDeleted); + + if (isOSWindows + ? !(taSelRemained && tfSelDeleted) + : !(taSelDeleted && tfSelDeleted)) { + failed = true; + } + + if (!initialFocusGained) { + System.err.println("Initial component did not gain focus"); + failed = false; + } + + if (failed) { + throw new RuntimeException("test failed: wrong behavior of text " + + "component on pasting null"); + } else { + System.err.println("test passed"); + } + } + + + private static void setClipboardContents(Clipboard cb, + Transferable contents, + ClipboardOwner owner) { + synchronized (cb) { + boolean set = false; + while (!set) { + try { + cb.setContents(contents, owner); + set = true; + } catch (IllegalStateException ise) { + try { Thread.sleep(100); } + catch (InterruptedException e) { e.printStackTrace(); } + } + } + } + } + + public static void main(String[] args) throws Exception { + PasteNullToTextComponentsTest app = new PasteNullToTextComponentsTest(); + try { + EventQueue.invokeAndWait(app::init); + app.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (app.frame != null) { + app.frame.dispose(); + } + }); + } + } +} From 1e85e6094de6365c8f415459adc97e69318f44c6 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Thu, 22 May 2025 07:29:01 +0000 Subject: [PATCH 284/846] 8297242: Use-after-free during library unloading on Linux Backport-of: 6f06f440bcf8a5db379b80e8765af38a15449356 --- src/hotspot/os/posix/os_posix.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index 4307a189edf12..1561f50fba79a 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -698,9 +698,20 @@ void* os::dll_lookup(void* handle, const char* name) { } void os::dll_unload(void *lib) { - const char* l_path = LINUX_ONLY(os::Linux::dll_path(lib)) - NOT_LINUX(""); - if (l_path == NULL) l_path = ""; + // os::Linux::dll_path returns a pointer to a string that is owned by the dynamic loader. Upon + // calling dlclose the dynamic loader may free the memory containing the string, thus we need to + // copy the string to be able to reference it after dlclose. + const char* l_path = NULL; +#ifdef LINUX + char* l_pathdup = NULL; + l_path = os::Linux::dll_path(lib); + if (l_path != NULL) { + l_path = l_pathdup = os::strdup(l_path); + } +#endif // LINUX + if (l_path == NULL) { + l_path = ""; + } int res = ::dlclose(lib); if (res == 0) { @@ -718,6 +729,7 @@ void os::dll_unload(void *lib) { log_info(os)("Attempt to unload shared library \"%s\" [" INTPTR_FORMAT "] failed, %s", l_path, p2i(lib), error_report); } + LINUX_ONLY(os::free(l_pathdup)); } jlong os::lseek(int fd, jlong offset, int whence) { From 961667fcc3238027aebfe5d7982f1d0f9157d52c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 22 May 2025 09:51:38 +0000 Subject: [PATCH 285/846] 8183348: Better cleanup for jdk/test/sun/security/pkcs12/P12SecretKey.java Backport-of: 03f0ec4a35855b59c8faaf4be2e7569a12b4d5db --- .../jdk/sun/security/pkcs12/P12SecretKey.java | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/test/jdk/sun/security/pkcs12/P12SecretKey.java b/test/jdk/sun/security/pkcs12/P12SecretKey.java index ed599a5596201..80f037138bf8e 100644 --- a/test/jdk/sun/security/pkcs12/P12SecretKey.java +++ b/test/jdk/sun/security/pkcs12/P12SecretKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -25,6 +25,7 @@ * @test * @bug 8149411 8007632 * @summary Get AES key from keystore (uses SecretKeySpec not SecretKeyFactory) + * @library /test/lib * @run main P12SecretKey pkcs12 AES 128 * @run main P12SecretKey pkcs12 DES 56 * @run main P12SecretKey pkcs12 DESede 168 @@ -33,14 +34,14 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.nio.file.Files; import java.security.KeyStore; -import java.security.cert.CertificateException; import java.util.Arrays; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; +import static jdk.test.lib.Utils.createTempFile; + public class P12SecretKey { private static final String ALIAS = "alias"; @@ -66,30 +67,32 @@ private void run(String keystoreType, String algName, int keySize) throws Except KeyStore.ProtectionParameter kspp = new KeyStore.PasswordProtection(pw); ks.setEntry(ALIAS, ske, kspp); - File ksFile = File.createTempFile("test", ".test"); + // temporary files are created in scratch directory + final File ksFile = createTempFile( + String.format("%s-%s-%d-", + keystoreType, + algName, + keySize), + ".ks").toFile(); - try { - try (FileOutputStream fos = new FileOutputStream(ksFile)) { - ks.store(fos, pw); - fos.flush(); - } + try (FileOutputStream fos = new FileOutputStream(ksFile)) { + ks.store(fos, pw); + fos.flush(); + } - // now see if we can get it back - try (FileInputStream fis = new FileInputStream(ksFile)) { - KeyStore ks2 = KeyStore.getInstance(keystoreType); - ks2.load(fis, pw); - KeyStore.Entry entry = ks2.getEntry(ALIAS, kspp); - SecretKey keyIn = ((KeyStore.SecretKeyEntry) entry).getSecretKey(); - if (Arrays.equals(key.getEncoded(), keyIn.getEncoded())) { - System.err.println("OK: worked just fine with " + keystoreType + - " keystore"); - } else { - System.err.println("ERROR: keys are NOT equal after storing in " - + keystoreType + " keystore"); - } + // now see if we can get it back + try (FileInputStream fis = new FileInputStream(ksFile)) { + KeyStore ks2 = KeyStore.getInstance(keystoreType); + ks2.load(fis, pw); + KeyStore.Entry entry = ks2.getEntry(ALIAS, kspp); + SecretKey keyIn = ((KeyStore.SecretKeyEntry) entry).getSecretKey(); + if (Arrays.equals(key.getEncoded(), keyIn.getEncoded())) { + System.err.println("OK: worked just fine with " + keystoreType + + " keystore"); + } else { + throw new RuntimeException("ERROR: keys are NOT equal after storing in " + + keystoreType + " keystore"); } - } finally { - Files.deleteIfExists(ksFile.toPath()); } } } From cf0fed77eacd3cf1e3588083cffc10281a15d139 Mon Sep 17 00:00:00 2001 From: Boris Ulasevich Date: Thu, 22 May 2025 14:19:20 +0000 Subject: [PATCH 286/846] 8321509: False positive in get_trampoline fast path causes crash Reviewed-by: phh Backport-of: 73e3e0edeb20c6f701b213423476f92fb05dd262 --- .../cpu/aarch64/globalDefinitions_aarch64.hpp | 4 +- .../cpu/aarch64/nativeInst_aarch64.cpp | 39 +++++++++---------- .../cpu/aarch64/nativeInst_aarch64.hpp | 7 ++-- src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp | 33 ++++++++++------ src/hotspot/share/code/relocInfo.cpp | 8 ++++ src/hotspot/share/code/relocInfo.hpp | 9 ++++- 6 files changed, 60 insertions(+), 40 deletions(-) diff --git a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp index 3c779bb11b15c..f9cc3a61f13ed 100644 --- a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -67,4 +67,6 @@ const bool CCallingConventionRequiresIntsAsLongs = false; #define NOT_R18_RESERVED(code) code #endif +#define USE_TRAMPOLINE_STUB_FIX_OWNER + #endif // CPU_AARCH64_GLOBALDEFINITIONS_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp index 66b2769aca5db..9795d6a7d8339 100644 --- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -158,13 +158,18 @@ void NativeGotJump::verify() const { } address NativeCall::destination() const { - address addr = (address)this; - address destination = instruction_address() + displacement(); + address addr = instruction_address(); + address destination = addr + displacement(); + + // Performance optimization: no need to call find_blob() if it is a self-call + if (destination == addr) { + return destination; + } // Do we use a trampoline stub for this call? CodeBlob* cb = CodeCache::find_blob_unsafe(addr); // Else we get assertion if nmethod is zombie. - assert(cb && cb->is_nmethod(), "sanity"); - nmethod *nm = (nmethod *)cb; + assert(cb != nullptr && cb->is_nmethod(), "nmethod expected"); + nmethod *nm = cb->as_nmethod(); if (nm->stub_contains(destination) && is_NativeCallTrampolineStub_at(destination)) { // Yes we do, so get the destination from the trampoline stub. const address trampoline_stub_addr = destination; @@ -179,12 +184,8 @@ address NativeCall::destination() const { // call instruction at all times. // // Used in the runtime linkage of calls; see class CompiledIC. -// -// Add parameter assert_lock to switch off assertion -// during code generation, where no patching lock is needed. -void NativeCall::set_destination_mt_safe(address dest, bool assert_lock) { - assert(!assert_lock || - (Patching_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) || +void NativeCall::set_destination_mt_safe(address dest) { + assert((Patching_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) || CompiledICLocker::is_safe(addr_at(0)), "concurrent code patching"); @@ -211,22 +212,18 @@ void NativeCall::set_destination_mt_safe(address dest, bool assert_lock) { } address NativeCall::get_trampoline() { - address call_addr = addr_at(0); + address call_addr = instruction_address(); CodeBlob *code = CodeCache::find_blob(call_addr); - assert(code != NULL, "Could not find the containing code blob"); + assert(code != nullptr && code->is_nmethod(), "nmethod expected"); + nmethod* nm = code->as_nmethod(); - address bl_destination - = MacroAssembler::pd_call_destination(call_addr); - if (code->contains(bl_destination) && + address bl_destination = call_addr + displacement(); + if (nm->stub_contains(bl_destination) && is_NativeCallTrampolineStub_at(bl_destination)) return bl_destination; - if (code->is_nmethod()) { - return trampoline_stub_Relocation::get_trampoline_for(call_addr, (nmethod*)code); - } - - return NULL; + return trampoline_stub_Relocation::get_trampoline_for(call_addr, nm); } // Inserts a native call instruction at a given pc diff --git a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp index 57366ad3c9c81..6a6834fbb9832 100644 --- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2108, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -212,6 +212,7 @@ class NativeCall: public NativeInstruction { int displacement() const { return (int_at(displacement_offset) << 6) >> 4; } address displacement_address() const { return addr_at(displacement_offset); } address return_address() const { return addr_at(return_address_offset); } + address raw_destination() const { return instruction_address() + displacement(); } address destination() const; void set_destination(address dest) { @@ -251,9 +252,7 @@ class NativeCall: public NativeInstruction { // // Used in the runtime linkage of calls; see class CompiledIC. // (Cf. 4506997 and 4479829, where threads witnessed garbage displacements.) - - // The parameter assert_lock disables the assertion during code generation. - void set_destination_mt_safe(address dest, bool assert_lock = true); + void set_destination_mt_safe(address dest); address get_trampoline(); #if INCLUDE_JVMCI diff --git a/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp b/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp index 49cc320709850..06c11af8a0195 100644 --- a/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp @@ -60,13 +60,12 @@ void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) { address Relocation::pd_call_destination(address orig_addr) { assert(is_call(), "should be a call here"); - if (NativeCall::is_call_at(addr())) { - address trampoline = nativeCall_at(addr())->get_trampoline(); - if (trampoline) { - return nativeCallTrampolineStub_at(trampoline)->destination(); + if (orig_addr == nullptr) { + if (NativeCall::is_call_at(addr())) { + NativeCall* call = nativeCall_at(addr()); + return call->destination(); } - } - if (orig_addr != NULL) { + } else { address new_addr = MacroAssembler::pd_call_destination(orig_addr); // If call is branch to self, don't try to relocate it, just leave it // as branch to self. This happens during code generation if the code @@ -82,16 +81,26 @@ address Relocation::pd_call_destination(address orig_addr) { void Relocation::pd_set_call_destination(address x) { assert(is_call(), "should be a call here"); if (NativeCall::is_call_at(addr())) { - address trampoline = nativeCall_at(addr())->get_trampoline(); - if (trampoline) { - nativeCall_at(addr())->set_destination_mt_safe(x, /* assert_lock */false); - return; - } + NativeCall* call = nativeCall_at(addr()); + call->set_destination(x); + } else { + MacroAssembler::pd_patch_instruction(addr(), x); } - MacroAssembler::pd_patch_instruction(addr(), x); assert(pd_call_destination(addr()) == x, "fail in reloc"); } +void trampoline_stub_Relocation::pd_fix_owner_after_move() { + NativeCall* call = nativeCall_at(owner()); + assert(call->raw_destination() == owner(), "destination should be empty"); + address trampoline = addr(); + address dest = nativeCallTrampolineStub_at(trampoline)->destination(); + if (!Assembler::reachable_from_branch_at(owner(), dest)) { + dest = trampoline; + } + call->set_destination(dest); +} + + address* Relocation::pd_address_in_code() { return (address*)(addr() + 8); } diff --git a/src/hotspot/share/code/relocInfo.cpp b/src/hotspot/share/code/relocInfo.cpp index 47769c53a5b70..986f40c9f2f8c 100644 --- a/src/hotspot/share/code/relocInfo.cpp +++ b/src/hotspot/share/code/relocInfo.cpp @@ -359,6 +359,14 @@ void CallRelocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer } +#ifdef USE_TRAMPOLINE_STUB_FIX_OWNER +void trampoline_stub_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { + // Finalize owner destination only for nmethods + if (dest->blob() != nullptr) return; + pd_fix_owner_after_move(); +} +#endif + //// pack/unpack methods void oop_Relocation::pack_data_to(CodeSection* dest) { diff --git a/src/hotspot/share/code/relocInfo.hpp b/src/hotspot/share/code/relocInfo.hpp index 55d4ac7c62dbb..2c6b570e01be0 100644 --- a/src/hotspot/share/code/relocInfo.hpp +++ b/src/hotspot/share/code/relocInfo.hpp @@ -1183,6 +1183,11 @@ class runtime_call_w_cp_Relocation : public CallRelocation { // in the code, it can patch it to jump to the trampoline where is // sufficient space for a far branch. Needed on PPC. class trampoline_stub_Relocation : public Relocation { +#ifdef USE_TRAMPOLINE_STUB_FIX_OWNER + void pd_fix_owner_after_move(); + void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) override; +#endif + public: static RelocationHolder spec(address static_call) { RelocationHolder rh = newHolder(); @@ -1204,8 +1209,8 @@ class trampoline_stub_Relocation : public Relocation { // Return the address of the NativeCall that owns the trampoline. address owner() { return _owner; } - void pack_data_to(CodeSection * dest); - void unpack_data(); + void pack_data_to(CodeSection * dest) override; + void unpack_data() override; // Find the trampoline stub for a call. static address get_trampoline_for(address call, nmethod* code); From b47daf1924975ca9fd11e3e3e009114331d3cb2a Mon Sep 17 00:00:00 2001 From: Taizo Kurashige Date: Thu, 22 May 2025 16:11:56 +0000 Subject: [PATCH 287/846] 8352942: jdk/jfr/startupargs/TestMemoryOptions.java fails with 32-bit build Backport-of: c3de94cee12471a11c457c11dd55c547633de5cb --- test/jdk/jdk/jfr/startupargs/TestMemoryOptions.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/jdk/jdk/jfr/startupargs/TestMemoryOptions.java b/test/jdk/jdk/jfr/startupargs/TestMemoryOptions.java index 9c90d04691ab1..00424760c942d 100644 --- a/test/jdk/jdk/jfr/startupargs/TestMemoryOptions.java +++ b/test/jdk/jdk/jfr/startupargs/TestMemoryOptions.java @@ -485,6 +485,7 @@ private static void launchTestVM(TestCase tc) throws Exception { if (flightRecorderOptions != null) { pb = ProcessTools.createTestJavaProcessBuilder("--add-exports=jdk.jfr/jdk.jfr.internal=ALL-UNNAMED", "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", + "-Xmx256m", flightRecorderOptions, "-XX:StartFlightRecording", SUT.class.getName(), @@ -493,6 +494,7 @@ private static void launchTestVM(TestCase tc) throws Exception { // default, no FlightRecorderOptions passed pb = ProcessTools.createTestJavaProcessBuilder("--add-exports=jdk.jfr/jdk.jfr.internal=ALL-UNNAMED", "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", + "-Xmx256m", "-XX:StartFlightRecording", SUT.class.getName(), tc.getTestName()); From 01a62e385ef9852dac37acd3eb88a36665330275 Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Thu, 22 May 2025 16:52:02 +0000 Subject: [PATCH 288/846] 8306997: C2: "malformed control flow" assert due to missing safepoint on backedge with a switch Backport-of: e0774bed2d2fcd850f5ca6884dd7aeb45f0bdaef --- src/hotspot/share/opto/parse2.cpp | 4 +- .../parsing/MissingSafepointOnSwitch.jasm | 67 +++++++++++++++++++ .../parsing/TestMissingSafepointOnSwitch.java | 37 ++++++++++ 3 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/parsing/MissingSafepointOnSwitch.jasm create mode 100644 test/hotspot/jtreg/compiler/parsing/TestMissingSafepointOnSwitch.java diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp index aedf9485bae8b..57addc1bbd281 100644 --- a/src/hotspot/share/opto/parse2.cpp +++ b/src/hotspot/share/opto/parse2.cpp @@ -434,7 +434,7 @@ void Parse::do_tableswitch() { // generate decision tree, using trichotomy when possible int rnum = len+2; - bool makes_backward_branch = false; + bool makes_backward_branch = (default_dest <= bci()); SwitchRange* ranges = NEW_RESOURCE_ARRAY(SwitchRange, rnum); int rp = -1; if (lo_index != min_jint) { @@ -536,7 +536,7 @@ void Parse::do_lookupswitch() { } int rnum = len*2+1; - bool makes_backward_branch = false; + bool makes_backward_branch = (default_dest <= bci()); SwitchRange* ranges = NEW_RESOURCE_ARRAY(SwitchRange, rnum); int rp = -1; for (int j = 0; j < len; j++) { diff --git a/test/hotspot/jtreg/compiler/parsing/MissingSafepointOnSwitch.jasm b/test/hotspot/jtreg/compiler/parsing/MissingSafepointOnSwitch.jasm new file mode 100644 index 0000000000000..13b1a2cc2de9a --- /dev/null +++ b/test/hotspot/jtreg/compiler/parsing/MissingSafepointOnSwitch.jasm @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023, Red Hat, Inc. 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. + */ + +super public class MissingSafepointOnSwitch + version 52:0 +{ + public Method "":"()V" + stack 1 locals 1 + { + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; + } + /* Same as: + public static void test(boolean flag, int v) { + if (flag) { + loop: + for (; ; ) { + switch(v) { + case 0: + case 1: + case 2: + break loop; + default: + } + } + } + } + but with the default: set to the loop entry + */ + public static Method test:"(ZI)V" + stack 1 locals 2 + { + iload_0; + ifeq L32; + L4: stack_frame_type same; + iload_1; + tableswitch{ //0 to 2 + 0: L32; + 1: L32; + 2: L32; + default: L4 }; + L32: stack_frame_type same; + return; + } + +} // end Class TestMissingSafepointOnSwitch diff --git a/test/hotspot/jtreg/compiler/parsing/TestMissingSafepointOnSwitch.java b/test/hotspot/jtreg/compiler/parsing/TestMissingSafepointOnSwitch.java new file mode 100644 index 0000000000000..3f527967d249f --- /dev/null +++ b/test/hotspot/jtreg/compiler/parsing/TestMissingSafepointOnSwitch.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023, Red Hat, Inc. 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 8306997 + * @summary C2: "malformed control flow" assert due to missing safepoint on backedge with a switch + * @compile MissingSafepointOnSwitch.jasm + * @run main/othervm -Xcomp -XX:CompileOnly=MissingSafepointOnSwitch::test TestMissingSafepointOnSwitch + */ + +public class TestMissingSafepointOnSwitch { + public static void main(String[] args) { + MissingSafepointOnSwitch.test(false, 0); + } + +} From a4770b5dbc06bc0b1285c6d4487826c96e3d92e1 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Fri, 23 May 2025 15:19:58 +0000 Subject: [PATCH 289/846] 8357193: [VS 2022 17.14] Warning C5287 in debugInit.c: enum type mismatch during build Backport-of: 5f38d1bb94d008c33c1a7af12c81ee0e15371e13 --- make/modules/jdk.jdwp.agent/Lib.gmk | 1 + 1 file changed, 1 insertion(+) diff --git a/make/modules/jdk.jdwp.agent/Lib.gmk b/make/modules/jdk.jdwp.agent/Lib.gmk index aef358c14bd5f..0a041fed9c888 100644 --- a/make/modules/jdk.jdwp.agent/Lib.gmk +++ b/make/modules/jdk.jdwp.agent/Lib.gmk @@ -55,6 +55,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJDWP, \ DISABLED_WARNINGS_gcc := unused-function, \ DISABLED_WARNINGS_clang := sometimes-uninitialized format-nonliteral \ self-assign, \ + DISABLED_WARNINGS_microsoft_debugInit.c := 5287, \ EXTRA_HEADER_DIRS := \ include \ libjdwp/export, \ From a16a779109538f1e7c5ca6de1a5fb09126e3b3e5 Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Fri, 23 May 2025 18:07:20 +0000 Subject: [PATCH 290/846] 8343037: Missing @since tag on JColorChooser.showDialog overload Backport-of: bd795946e777fccf797b1b69806217f988212f73 --- src/java.desktop/share/classes/javax/swing/JColorChooser.java | 2 ++ .../javax/swing/colorchooser/AbstractColorChooserPanel.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/java.desktop/share/classes/javax/swing/JColorChooser.java b/src/java.desktop/share/classes/javax/swing/JColorChooser.java index 29bf7009b4ffc..f1f753833f6c9 100644 --- a/src/java.desktop/share/classes/javax/swing/JColorChooser.java +++ b/src/java.desktop/share/classes/javax/swing/JColorChooser.java @@ -175,7 +175,9 @@ public static Color showDialog(Component component, * @return the selected color or null if the user opted out * @exception HeadlessException if GraphicsEnvironment.isHeadless() * returns true. + * * @see java.awt.GraphicsEnvironment#isHeadless + * @since 9 */ @SuppressWarnings("deprecation") public static Color showDialog(Component component, String title, diff --git a/src/java.desktop/share/classes/javax/swing/colorchooser/AbstractColorChooserPanel.java b/src/java.desktop/share/classes/javax/swing/colorchooser/AbstractColorChooserPanel.java index 2f2163c89397b..7fa56fb07f902 100644 --- a/src/java.desktop/share/classes/javax/swing/colorchooser/AbstractColorChooserPanel.java +++ b/src/java.desktop/share/classes/javax/swing/colorchooser/AbstractColorChooserPanel.java @@ -229,6 +229,7 @@ void setSelectedColor(Color color) { * * @param b true if the transparency of a color can be selected * @see #isColorTransparencySelectionEnabled() + * @since 9 */ @BeanProperty(description = "Sets the transparency of a color selection on or off.") @@ -241,6 +242,7 @@ public void setColorTransparencySelectionEnabled(boolean b){ * * @return true if the transparency of a color can be selected * @see #setColorTransparencySelectionEnabled(boolean) + * @since 9 */ public boolean isColorTransparencySelectionEnabled(){ return true; From 4070736f14d2c036243f8cb2745b2fa8b9d9af13 Mon Sep 17 00:00:00 2001 From: Paul Hohensee Date: Mon, 26 May 2025 13:23:56 +0000 Subject: [PATCH 291/846] 8320687: sun.jvmstat.monitor.MonitoredHost.getMonitoredHost() throws unexpected exceptions when invoked concurrently Reviewed-by: simonis Backport-of: 81484d8c0520cf55ec58fc7b4c81880e69537674 --- .../sun/jvmstat/monitor/MonitoredHost.java | 16 ++-- .../ConcurrentGetMonitoredHost.java | 92 +++++++++++++++++++ 2 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java diff --git a/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java b/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java index b119a00452090..fafcce1c47fab 100644 --- a/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java +++ b/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -50,7 +50,7 @@ * @see HostListener */ public abstract class MonitoredHost { - private static Map monitoredHosts = + private static final Map monitoredHosts = new HashMap(); /* @@ -133,13 +133,6 @@ public static MonitoredHost getMonitoredHost(VmIdentifier vmid) return getMonitoredHost(hostId); } - - /* - * Load the MonitoredHostServices - */ - private static ServiceLoader monitoredHostServiceLoader = - ServiceLoader.load(MonitoredHostService.class, MonitoredHostService.class.getClassLoader()); - /** * Factory method to construct a MonitoredHost instance to manage the * connection to the host indicated by {@code hostId}. @@ -167,9 +160,12 @@ public static MonitoredHost getMonitoredHost(HostIdentifier hostId) hostId = resolveHostId(hostId); - for (MonitoredHostService mhs : monitoredHostServiceLoader) { + ServiceLoader services = ServiceLoader.load( + MonitoredHostService.class, MonitoredHostService.class.getClassLoader()); + for (MonitoredHostService mhs : services) { if (mhs.getScheme().equals(hostId.getScheme())) { mh = mhs.getMonitoredHost(hostId); + break; } } diff --git a/test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java b/test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java new file mode 100644 index 0000000000000..65294f45e646c --- /dev/null +++ b/test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 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. + */ + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import sun.jvmstat.monitor.MonitoredHost; +import sun.jvmstat.monitor.VmIdentifier; + +/* + * @test + * @bug 8320687 + * @summary verify that sun.jvmstat.monitor.MonitoredHost.getMonitoredHost() doesn't + * unexpectedly throw an exception when invoked by concurrent threads + * + * @run main/othervm ConcurrentGetMonitoredHost + */ +public class ConcurrentGetMonitoredHost { + + /* + * Launches multiple concurrent threads and invokes MonitoredHost.getMonitoredHost() + * in each of these threads and expects the call to return successfully without any + * exceptions. + */ + public static void main(final String[] args) throws Exception { + final String pidStr = "12345"; + final VmIdentifier vmid = new VmIdentifier(pidStr); + final int numTasks = 100; + final List tasks = new ArrayList<>(); + for (int i = 0; i < numTasks; i++) { + tasks.add(new Task(vmid)); + } + System.out.println("Submitting " + numTasks + " concurrent tasks to" + + " get MonitoredHost for " + vmid); + try { + final ExecutorService executor = Executors.newCachedThreadPool(); + // wait for all tasks to complete + final List> results = executor.invokeAll(tasks); + // verify each one successfully completed and each of + // the returned MonitoredHost is not null + for (final Future result : results) { + final MonitoredHost mh = result.get(); + if (mh == null) { + throw new AssertionError("MonitoredHost.getMonitoredHost() returned" + + " null for vmid " + vmid); + } + } + } catch (Exception e) { + } + System.out.println("All " + numTasks + " completed successfully"); + } + + // a task which just calls MonitoredHost.getMonitoredHost(VmIdentifier) and + // returns the resultant MonitoredHost + private static final class Task implements Callable { + private final VmIdentifier vmid; + + private Task(final VmIdentifier vmid) { + this.vmid = Objects.requireNonNull(vmid); + } + + @Override + public MonitoredHost call() throws Exception { + return MonitoredHost.getMonitoredHost(this.vmid); + } + } +} From 5cce770209ac2220786f4d346154d3b63529ef95 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 27 May 2025 12:01:57 +0000 Subject: [PATCH 292/846] 8302226: failure_handler native.core should wait for coredump to finish Backport-of: 6120319afdba98b5ff547b870a0260479e8b683c --- test/failure_handler/src/share/conf/linux.properties | 7 +++++-- test/failure_handler/src/share/conf/mac.properties | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/test/failure_handler/src/share/conf/linux.properties b/test/failure_handler/src/share/conf/linux.properties index 0d5d95b465d8d..9bea97fd78ad1 100644 --- a/test/failure_handler/src/share/conf/linux.properties +++ b/test/failure_handler/src/share/conf/linux.properties @@ -54,8 +54,11 @@ native.stack.args.delimiter=\0 native.stack.params.repeat=6 # has to be the last command -native.core.app=kill -native.core.args=-ABRT %p +native.core.app=bash +# The below trick was found on https://stackoverflow.com/a/41613532 +native.core.args=-c\0kill -ABRT %p && tail --pid=%p -f /dev/null +native.core.args.delimiter=\0 +native.core.timeout=600000 cores=native.gdb native.gdb.app=gdb diff --git a/test/failure_handler/src/share/conf/mac.properties b/test/failure_handler/src/share/conf/mac.properties index 492d8116a0c11..c00e55c0fece6 100644 --- a/test/failure_handler/src/share/conf/mac.properties +++ b/test/failure_handler/src/share/conf/mac.properties @@ -62,8 +62,11 @@ native.stack.params.repeat=6 native.stack.args=-c\0DevToolsSecurity --status | grep -q enabled && lldb -o 'attach %p' -o 'thread backtrace all' -o 'detach' -o 'quit' # has to be the last command -native.core.app=kill -native.core.args=-ABRT %p +native.core.app=bash +# The below trick was found on https://stackoverflow.com/a/41613532 +native.core.args=-c\0kill -ABRT %p && lsof -p %p +r 1 &>/dev/null +native.core.delimiter=\0 +native.core.timeout=600000 cores=native.lldb native.lldb.app=lldb From 4859b49b9082cc23a86bbc5238e5a415dfbb6251 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 27 May 2025 12:03:20 +0000 Subject: [PATCH 293/846] 8336587: failure_handler lldb command times out on macosx-aarch64 core file Backport-of: 21a6cf848da00c795d833f926f831c7aea05dfa3 --- test/failure_handler/src/share/conf/mac.properties | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/failure_handler/src/share/conf/mac.properties b/test/failure_handler/src/share/conf/mac.properties index c00e55c0fece6..fa55f7c732184 100644 --- a/test/failure_handler/src/share/conf/mac.properties +++ b/test/failure_handler/src/share/conf/mac.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -71,6 +71,9 @@ native.core.timeout=600000 cores=native.lldb native.lldb.app=lldb native.lldb.delimiter=\0 +# Core files can be very big and take a long time to load on macosx-aarch64. +# The 20 seconds default timeout is not nearly enough. +native.lldb.timeout=120000 # Assume that java standard laucher has been used native.lldb.args=--core\0%p\0%java\0-o\0thread backtrace all\0-o\0quit From 291b18c14355ef4f21ba4bf31a91262de7056b78 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 27 May 2025 12:20:57 +0000 Subject: [PATCH 294/846] 8202100: Merge vm/share/InMemoryJavaCompiler w/ jdk/test/lib/compiler/InMemoryJavaCompiler Reviewed-by: phh Backport-of: 7404ddf24a162cff445cd0a26aec446461988bc8 --- .../LambdaProxyCallerIsHidden.java | 3 +- .../dynamicArchive/RegularHiddenClass.java | 5 +- .../redefineClass/RedefineBasicTest.java | 5 +- .../RedefineRunningMethods_Shared.java | 5 +- .../bytecode/BytecodeGeneratorFactory.java | 8 +- .../staticReferences/StaticReferences.java | 6 +- .../stressDictionary/StressDictionary.java | 8 +- .../GenerateHierarchyHelper.java | 4 +- .../jvmti/RedefineClasses/StressRedefine.java | 9 +- .../vm/share/InMemoryJavaCompiler.java | 125 -------------- .../lib/compiler/InMemoryJavaCompiler.java | 155 +++++++++++++----- 11 files changed, 138 insertions(+), 195 deletions(-) delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/InMemoryJavaCompiler.java diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LambdaProxyCallerIsHidden.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LambdaProxyCallerIsHidden.java index 198551a6123d4..13abce572e7a3 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LambdaProxyCallerIsHidden.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LambdaProxyCallerIsHidden.java @@ -37,7 +37,8 @@ * jdk/test/lib/compiler/InMemoryJavaCompiler * jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper$1 * jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper - * jdk/test/lib/compiler/InMemoryJavaCompiler$MemoryJavaFileObject + * jdk/test/lib/compiler/InMemoryJavaCompiler$SourceFile + * jdk/test/lib/compiler/InMemoryJavaCompiler$ClassFile * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. LambdaProxyCallerIsHidden */ diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RegularHiddenClass.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RegularHiddenClass.java index cc05e144444ed..f20b50efba2e3 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RegularHiddenClass.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RegularHiddenClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,8 @@ * jdk/test/lib/compiler/InMemoryJavaCompiler * jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper$1 * jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper - * jdk/test/lib/compiler/InMemoryJavaCompiler$MemoryJavaFileObject + * jdk/test/lib/compiler/InMemoryJavaCompiler$SourceFile + * jdk/test/lib/compiler/InMemoryJavaCompiler$ClassFile * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. RegularHiddenClass */ diff --git a/test/hotspot/jtreg/runtime/cds/appcds/redefineClass/RedefineBasicTest.java b/test/hotspot/jtreg/runtime/cds/appcds/redefineClass/RedefineBasicTest.java index 81d6e20321ec0..acbd0c948bef2 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/redefineClass/RedefineBasicTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/redefineClass/RedefineBasicTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,8 @@ public class RedefineBasicTest { "jdk/test/lib/compiler/InMemoryJavaCompiler", "jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper", "jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper$1", - "jdk/test/lib/compiler/InMemoryJavaCompiler$MemoryJavaFileObject" + "jdk/test/lib/compiler/InMemoryJavaCompiler$SourceFile", + "jdk/test/lib/compiler/InMemoryJavaCompiler$ClassFile" }; public static void main(String[] args) throws Exception { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/redefineClass/RedefineRunningMethods_Shared.java b/test/hotspot/jtreg/runtime/cds/appcds/redefineClass/RedefineRunningMethods_Shared.java index 35b93f30059ff..a9920ff43a8aa 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/redefineClass/RedefineRunningMethods_Shared.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/redefineClass/RedefineRunningMethods_Shared.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,8 @@ public class RedefineRunningMethods_Shared { "jdk/test/lib/compiler/InMemoryJavaCompiler", "jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper", "jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper$1", - "jdk/test/lib/compiler/InMemoryJavaCompiler$MemoryJavaFileObject" + "jdk/test/lib/compiler/InMemoryJavaCompiler$SourceFile", + "jdk/test/lib/compiler/InMemoryJavaCompiler$ClassFile" }; public static void main(String[] args) throws Exception { diff --git a/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/bytecode/BytecodeGeneratorFactory.java b/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/bytecode/BytecodeGeneratorFactory.java index cad856f553e23..73f74794394ff 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/bytecode/BytecodeGeneratorFactory.java +++ b/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/bytecode/BytecodeGeneratorFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ import java.util.Map; import java.util.Random; -import vm.share.InMemoryJavaCompiler; +import jdk.test.lib.compiler.InMemoryJavaCompiler; /** * BytecodeFactory that employs in memory compilation. @@ -44,12 +44,10 @@ public BytecodeGeneratorFactory(long seed) { @Override public Bytecode createBytecode(String className) { - Map sources = new HashMap(); - sources.put(className, sourceGenerator.generateSource(className, + byte[] bytecode = InMemoryJavaCompiler.compile(className, sourceGenerator.generateSource(className, "public static void main() { System.out.println(\"From main method in in-mem-compiled code " + random.nextGaussian() + " + str_bytesToReplace0 str_bytesToReplace1\"); }\n " + "public static int methodForCompilation(Object object) { int i = object.hashCode(); i = i * 2000 / 1994 + 153; return i; }\n")); - byte[] bytecode = InMemoryJavaCompiler.compile(sources).values().iterator().next(); return new Bytecode(className, bytecode); } diff --git a/test/hotspot/jtreg/vmTestbase/metaspace/staticReferences/StaticReferences.java b/test/hotspot/jtreg/vmTestbase/metaspace/staticReferences/StaticReferences.java index 690f2a6751708..1edf70d3a8c54 100644 --- a/test/hotspot/jtreg/vmTestbase/metaspace/staticReferences/StaticReferences.java +++ b/test/hotspot/jtreg/vmTestbase/metaspace/staticReferences/StaticReferences.java @@ -53,7 +53,7 @@ import java.util.Map; import java.util.Random; -import vm.share.InMemoryJavaCompiler; +import jdk.test.lib.compiler.InMemoryJavaCompiler; import nsk.share.gc.GCTestBase; import nsk.share.test.ExecutionController; import nsk.share.test.Stresser; @@ -210,9 +210,7 @@ private void checkStaticFields(Class clazz) { } private byte[] generateAndCompile(int[] fieldQuantities) { - Map sources = new HashMap(); - sources.put("A", generateSource(fieldQuantities)); - return InMemoryJavaCompiler.compile(sources).values().iterator().next(); + return InMemoryJavaCompiler.compile("A", generateSource(fieldQuantities)); } private StringBuffer generateSource(int[] fieldQuantities) { diff --git a/test/hotspot/jtreg/vmTestbase/metaspace/stressDictionary/StressDictionary.java b/test/hotspot/jtreg/vmTestbase/metaspace/stressDictionary/StressDictionary.java index b4c44a9a05970..0db2d24fa8f9d 100644 --- a/test/hotspot/jtreg/vmTestbase/metaspace/stressDictionary/StressDictionary.java +++ b/test/hotspot/jtreg/vmTestbase/metaspace/stressDictionary/StressDictionary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ import nsk.share.gc.GCTestBase; import nsk.share.test.*; -import vm.share.InMemoryJavaCompiler; +import jdk.test.lib.compiler.InMemoryJavaCompiler; /** * There is a data structure named "dictionary" in class BlockFreelist. It stores @@ -178,10 +178,8 @@ public void run() { } private byte[] generateAndCompile() { - Map sources = new HashMap(); String className = "MyClass" + classesCounter.incrementAndGet(); - sources.put(className, generateSource(className)); - return InMemoryJavaCompiler.compile(sources).values().iterator().next(); + return InMemoryJavaCompiler.compile(className, generateSource(className)); } private CharSequence generateSource(String className) { diff --git a/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/generateHierarchy/GenerateHierarchyHelper.java b/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/generateHierarchy/GenerateHierarchyHelper.java index daccf64439375..be6f1ebe85f33 100644 --- a/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/generateHierarchy/GenerateHierarchyHelper.java +++ b/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/generateHierarchy/GenerateHierarchyHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ import java.util.*; -import vm.share.InMemoryJavaCompiler; +import jdk.test.lib.compiler.InMemoryJavaCompiler; import jdk.test.lib.Utils; public class GenerateHierarchyHelper { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/StressRedefine.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/StressRedefine.java index bbdb6fe6fe0c8..c8b3fb4d2ceab 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/StressRedefine.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/StressRedefine.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -//package nsk.jvmti.RedefineClasses.StressRedefine; package nsk.jvmti.RedefineClasses; @@ -41,7 +40,7 @@ import nsk.share.test.Stresser; import nsk.share.test.Tests; -import vm.share.InMemoryJavaCompiler; +import jdk.test.lib.compiler.InMemoryJavaCompiler; /** * There is a data structure named "dictionary" in class BlockFreelist. It stores @@ -191,9 +190,7 @@ private void runIt() { } private static byte[] generateAndCompile() { - Map sources = new HashMap(); - sources.put(GenerateSourceHelper.CLASS_NAME, GenerateSourceHelper.generateSource()); - return InMemoryJavaCompiler.compile(sources).values().iterator().next(); + return InMemoryJavaCompiler.compile(GenerateSourceHelper.CLASS_NAME, GenerateSourceHelper.generateSource()); } // Auxiliary classloader. Used only once at the beginning. diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/InMemoryJavaCompiler.java b/test/hotspot/jtreg/vmTestbase/vm/share/InMemoryJavaCompiler.java deleted file mode 100644 index 6f5f1c0cbcd97..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/InMemoryJavaCompiler.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2013, 2018, 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 vm.share; - -import javax.tools.FileObject; -import javax.tools.ForwardingJavaFileManager; -import javax.tools.JavaCompiler; -import javax.tools.JavaFileManager; -import javax.tools.JavaFileObject; -import javax.tools.SimpleJavaFileObject; -import javax.tools.ToolProvider; -import java.io.ByteArrayOutputStream; -import java.io.StringWriter; -import java.io.Writer; -import java.net.URI; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.Map; -import java.util.Map.Entry; - - -public class InMemoryJavaCompiler { - - public static Map compile(Map inputMap) { - Collection sourceFiles = new LinkedList(); - for (Entry entry : inputMap.entrySet()) { - sourceFiles.add(new SourceFile(entry.getKey(), entry.getValue())); - } - - JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - FileManager fileManager = new FileManager(compiler.getStandardFileManager(null, null, null)); - - Writer writer = new StringWriter(); - Boolean exitCode = compiler.getTask(writer, fileManager, null, null, null, sourceFiles).call(); - if (!exitCode) { - System.out.println("*********** javac output begin ***********"); - System.out.println(writer.toString()); - System.out.println("*********** javac output end ***********"); - if (writer.toString().contains("java.lang.OutOfMemoryError")) { - System.out.println("Got OOME while performing in memory compilation. It happens on weak hosts and there is nothing we can do. "); - throw new OutOfMemoryError("Got OOME while performing in memory compilation."); - } - throw new RuntimeException("Test bug: in memory compilation failed."); - } - return fileManager.getByteCode(); - } - - // Wraper for class file - static class ClassFile extends SimpleJavaFileObject { - - private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - protected ClassFile(String name) { - super(URI.create("memo:///" + name.replace('.', '/') + Kind.CLASS.extension), Kind.CLASS); - } - - @Override - public ByteArrayOutputStream openOutputStream() { return this.baos; } - - byte[] toByteArray() { return baos.toByteArray(); } - } - - // File manager which spawns ClassFile instances by demand - static class FileManager extends ForwardingJavaFileManager { - - private Map classesMap = new HashMap(); - - protected FileManager(JavaFileManager fileManager) { - super(fileManager); - } - - @Override - public ClassFile getJavaFileForOutput(Location location, String name, JavaFileObject.Kind kind, FileObject source) { - ClassFile classFile = new ClassFile(name); - classesMap.put(name, classFile); - return classFile; - } - - public Map getByteCode() { - Map result = new HashMap(); - for (Entry entry : classesMap.entrySet()) { - result.put(entry.getKey(), entry.getValue().toByteArray()); - } - return result; - } - } - - // Wrapper for source file - static class SourceFile extends SimpleJavaFileObject { - - private CharSequence sourceCode; - - public SourceFile(String name, CharSequence sourceCode) { - super(URI.create("memo:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE); - this.sourceCode = sourceCode; - } - - @Override - public CharSequence getCharContent(boolean ignore) { - return this.sourceCode; - } - } - -} diff --git a/test/lib/jdk/test/lib/compiler/InMemoryJavaCompiler.java b/test/lib/jdk/test/lib/compiler/InMemoryJavaCompiler.java index 6016e48bf4e56..4722ef3b67a95 100644 --- a/test/lib/jdk/test/lib/compiler/InMemoryJavaCompiler.java +++ b/test/lib/jdk/test/lib/compiler/InMemoryJavaCompiler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,11 +26,18 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.io.StringWriter; +import java.io.Writer; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import javax.tools.FileObject; import javax.tools.ForwardingJavaFileManager; @@ -76,36 +83,6 @@ * */ public class InMemoryJavaCompiler { - private static class MemoryJavaFileObject extends SimpleJavaFileObject { - private final String className; - private final CharSequence sourceCode; - private final ByteArrayOutputStream byteCode; - - public MemoryJavaFileObject(String className, CharSequence sourceCode) { - super(URI.create("string:///" + className.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE); - this.className = className; - this.sourceCode = sourceCode; - this.byteCode = new ByteArrayOutputStream(); - } - - @Override - public CharSequence getCharContent(boolean ignoreEncodingErrors) { - return sourceCode; - } - - @Override - public OutputStream openOutputStream() throws IOException { - return byteCode; - } - - public byte[] getByteCode() { - return byteCode.toByteArray(); - } - - public String getClassName() { - return className; - } - } private static class FileManagerWrapper extends ForwardingJavaFileManager { private static final Location PATCH_LOCATION = new Location() { @@ -119,12 +96,13 @@ public boolean isOutputLocation() { return false; } }; - private final MemoryJavaFileObject file; + private final SourceFile srcFile; + private ClassFile clsFile; private final String moduleOverride; - public FileManagerWrapper(MemoryJavaFileObject file, String moduleOverride) { + public FileManagerWrapper(SourceFile file, String moduleOverride) { super(getCompiler().getStandardFileManager(null, null, null)); - this.file = file; + this.srcFile = file; this.moduleOverride = moduleOverride; } @@ -132,16 +110,17 @@ public FileManagerWrapper(MemoryJavaFileObject file, String moduleOverride) { public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException { - if (!file.getClassName().equals(className)) { - throw new IOException("Expected class with name " + file.getClassName() + + if (!srcFile.getClassName().equals(className)) { + throw new IOException("Expected class with name " + srcFile.getClassName() + ", but got " + className); } - return file; + clsFile = new ClassFile(className); + return clsFile; } @Override public Location getLocationForModule(Location location, JavaFileObject fo) throws IOException { - if (fo == file && moduleOverride != null) { + if (fo == srcFile && moduleOverride != null) { return PATCH_LOCATION; } return super.getLocationForModule(location, fo); @@ -160,6 +139,100 @@ public boolean hasLocation(Location location) { return super.hasLocation(location) || location == StandardLocation.PATCH_MODULE_PATH; } + public byte[] getByteCode() { + return clsFile.toByteArray(); + } + + } + + // Wraper for class file + static class ClassFile extends SimpleJavaFileObject { + + private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + protected ClassFile(String name) { + super(URI.create("memo:///" + name.replace('.', '/') + Kind.CLASS.extension), Kind.CLASS); + } + + @Override + public ByteArrayOutputStream openOutputStream() { return this.baos; } + + byte[] toByteArray() { return baos.toByteArray(); } + } + + // File manager which spawns ClassFile instances by demand + static class FileManager extends ForwardingJavaFileManager { + + private Map classesMap = new HashMap(); + + protected FileManager(JavaFileManager fileManager) { + super(fileManager); + } + + @Override + public ClassFile getJavaFileForOutput(Location location, String name, JavaFileObject.Kind kind, FileObject source) { + ClassFile classFile = new ClassFile(name); + classesMap.put(name, classFile); + return classFile; + } + + public Map getByteCode() { + Map result = new HashMap(); + for (Entry entry : classesMap.entrySet()) { + result.put(entry.getKey(), entry.getValue().toByteArray()); + } + return result; + } + } + + // Wrapper for source file + static class SourceFile extends SimpleJavaFileObject { + + private CharSequence sourceCode; + private String className; + + public SourceFile(String name, CharSequence sourceCode) { + super(URI.create("memo:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE); + this.sourceCode = sourceCode; + this.className = name; + } + + @Override + public CharSequence getCharContent(boolean ignore) { + return this.sourceCode; + } + + public String getClassName() { + return this.className; + } + } + + /** + * Compiles the list of classes with the given map of name and source code. + * This overloaded version of compile is useful for batch compile use cases. + * + * @param inputMap The map containing the name of the class and corresponding source code + * @throws RuntimeException if the compilation did not succeed + * @return The resulting byte code from the compilation + */ + public static Map compile(Map inputMap) { + Collection sourceFiles = new LinkedList(); + for (Entry entry : inputMap.entrySet()) { + sourceFiles.add(new SourceFile(entry.getKey(), entry.getValue())); + } + + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + FileManager fileManager = new FileManager(compiler.getStandardFileManager(null, null, null)); + + Writer writer = new StringWriter(); + Boolean exitCode = compiler.getTask(writer, fileManager, null, null, null, sourceFiles).call(); + if (!exitCode) { + System.out.println("*********** javac output begin ***********"); + System.out.println(writer.toString()); + System.out.println("*********** javac output end ***********"); + throw new RuntimeException("Test bug: in memory compilation failed."); + } + return fileManager.getByteCode(); } /** @@ -173,7 +246,7 @@ public boolean hasLocation(Location location) { * @return The resulting byte code from the compilation */ public static byte[] compile(String className, CharSequence sourceCode, String... options) { - MemoryJavaFileObject file = new MemoryJavaFileObject(className, sourceCode); + SourceFile file = new SourceFile(className, sourceCode); List opts = new ArrayList<>(); String moduleOverride = null; for (String opt : options) { @@ -183,13 +256,13 @@ public static byte[] compile(String className, CharSequence sourceCode, String.. opts.add(opt); } } - try (JavaFileManager fileManager = new FileManagerWrapper(file, moduleOverride)) { + try (FileManagerWrapper fileManager = new FileManagerWrapper(file, moduleOverride)) { CompilationTask task = getCompiler().getTask(null, fileManager, null, opts, null, Arrays.asList(file)); if (!task.call()) { throw new RuntimeException("Could not compile " + className + " with source code " + sourceCode); } - return file.getByteCode(); + return fileManager.getByteCode(); } catch (IOException ioe) { throw new RuntimeException(ioe); } From b8484be137a9d8bf6463188e1fc68b22db0b52c3 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 27 May 2025 12:23:25 +0000 Subject: [PATCH 295/846] 8356096: ISO 4217 Amendment 179 Update Reviewed-by: rrich Backport-of: b4ee5241cce000054eb45e50041371e8467e2510 --- make/data/currency/CurrencyData.properties | 6 +++--- .../classes/sun/util/resources/CurrencyNames.properties | 4 +++- test/jdk/java/util/Currency/ISO4217-list-one.txt | 6 +++--- test/jdk/java/util/Currency/ValidateISO4217.java | 3 ++- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/make/data/currency/CurrencyData.properties b/make/data/currency/CurrencyData.properties index 550662ec38a14..cc845e398f190 100644 --- a/make/data/currency/CurrencyData.properties +++ b/make/data/currency/CurrencyData.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2025, 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 @@ -32,7 +32,7 @@ formatVersion=3 # Version of the currency code information in this class. # It is a serial number that accompanies with each amendment. -dataVersion=177 +dataVersion=179 # List of all valid ISO 4217 currency codes. # To ensure compatibility, do not remove codes. @@ -54,7 +54,7 @@ all=ADP020-AED784-AFA004-AFN971-ALL008-AMD051-ANG532-AOA973-ARS032-ATS040-AUD036 SBD090-SCR690-SDD736-SDG938-SEK752-SGD702-SHP654-SIT705-SKK703-SLE925-SLL694-SOS706-\ SRD968-SRG740-SSP728-STD678-STN930-SVC222-SYP760-SZL748-THB764-TJS972-TMM795-TMT934-TND788-TOP776-\ TPE626-TRL792-TRY949-TTD780-TWD901-TZS834-UAH980-UGX800-USD840-USN997-USS998-UYI940-\ - UYU858-UZS860-VEB862-VED926-VEF937-VES928-VND704-VUV548-WST882-XAF950-XAG961-XAU959-XBA955-\ + UYU858-UZS860-VEB862-VED926-VEF937-VES928-VND704-VUV548-WST882-XAD396-XAF950-XAG961-XAU959-XBA955-\ XBB956-XBC957-XBD958-XCD951-XCG532-XDR960-XFO000-XFU000-XOF952-XPD964-XPF953-\ XPT962-XSU994-XTS963-XUA965-XXX999-YER886-YUM891-ZAR710-ZMK894-ZMW967-ZWD716-ZWG924-\ ZWL932-ZWN942-ZWR935 diff --git a/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties b/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties index 3ed4f873a3c63..e543398fac1c1 100644 --- a/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties +++ b/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2025, 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 @@ -258,6 +258,7 @@ VES=VES VND=VND VUV=VUV WST=WST +XAD=XAD XAF=XAF XAG=XAG XAU=XAU @@ -485,6 +486,7 @@ ves=Venezuelan Bol\u00edvar Soberano vnd=Vietnamese Dong vuv=Vanuatu Vatu wst=Samoan Tala +xad=Arab Accounting Dinar xaf=CFA Franc BEAC xag=Silver xau=Gold diff --git a/test/jdk/java/util/Currency/ISO4217-list-one.txt b/test/jdk/java/util/Currency/ISO4217-list-one.txt index 1912b5cc7dbb9..aa8c2725899e8 100644 --- a/test/jdk/java/util/Currency/ISO4217-list-one.txt +++ b/test/jdk/java/util/Currency/ISO4217-list-one.txt @@ -1,12 +1,12 @@ # # -# Amendments up until ISO 4217 AMENDMENT NUMBER 177 -# (As of 20 June 2024) +# Amendments up until ISO 4217 AMENDMENT NUMBER 179 +# (As of 02 May 2025) # # Version FILEVERSION=3 -DATAVERSION=177 +DATAVERSION=179 # ISO 4217 currency data AF AFN 971 2 diff --git a/test/jdk/java/util/Currency/ValidateISO4217.java b/test/jdk/java/util/Currency/ValidateISO4217.java index 01c225e531c67..90c7376abaadf 100644 --- a/test/jdk/java/util/Currency/ValidateISO4217.java +++ b/test/jdk/java/util/Currency/ValidateISO4217.java @@ -26,6 +26,7 @@ * @bug 4691089 4819436 4942982 5104960 6544471 6627549 7066203 7195759 * 8039317 8074350 8074351 8145952 8187946 8193552 8202026 8204269 * 8208746 8209775 8264792 8274658 8283277 8296239 8321480 8334653 + * 8356096 * @summary Validate ISO 4217 data for Currency class. * @modules java.base/java.util:open * jdk.localedata @@ -89,7 +90,7 @@ public class ValidateISO4217 { "ADP-AFA-ATS-AYM-AZM-BEF-BGL-BOV-BYB-BYR-CHE-CHW-CLF-COU-CUC-CYP-" + "DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-HRK-IEP-ITL-LTL-LUF-LVL-MGF-MRO-MTL-MXV-MZM-NLG-" + "PTE-ROL-RUR-SDD-SIT-SLL-SKK-SRG-STD-TMM-TPE-TRL-VEF-UYI-USN-USS-VEB-VED-" - + "XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-" + + "XAD-XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-" + "YUM-ZMK-ZWD-ZWL-ZWN-ZWR"; private static final String[][] extraCodes = { /* Defined in ISO 4217 list, but don't have code and minor unit info. */ From 6197c2dee1fe6b3b58f6e55e153e2bcc2a1718bd Mon Sep 17 00:00:00 2001 From: Michael De Vera Date: Tue, 27 May 2025 16:02:36 +0000 Subject: [PATCH 296/846] 8269516: AArch64: Assembler cleanups Backport-of: 1810b1c2ad86e6907db09fffee97fa04174cdec2 --- src/hotspot/cpu/aarch64/assembler_aarch64.cpp | 95 ++++++---- src/hotspot/cpu/aarch64/assembler_aarch64.hpp | 167 ++++++++---------- .../cpu/aarch64/foreign_globals_aarch64.cpp | 7 +- src/hotspot/cpu/aarch64/register_aarch64.hpp | 8 +- src/hotspot/share/asm/codeBuffer.hpp | 6 +- 5 files changed, 145 insertions(+), 138 deletions(-) diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.cpp b/src/hotspot/cpu/aarch64/assembler_aarch64.cpp index d31f638832b17..0c503e0b7fddc 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.cpp @@ -134,7 +134,16 @@ void Assembler::adrp(Register reg1, const Address &dest, uint64_t &byte_offset) #undef __ -#define starti Instruction_aarch64 do_not_use(this); set_current(&do_not_use) +#define starti Instruction_aarch64 current_insn(this); + +#define f current_insn.f +#define sf current_insn.sf +#define rf current_insn.rf +#define srf current_insn.srf +#define zrf current_insn.zrf +#define prf current_insn.prf +#define pgrf current_insn.pgrf +#define fixed current_insn.fixed void Assembler::adr(Register Rd, address adr) { intptr_t offset = adr - pc(); @@ -156,6 +165,53 @@ void Assembler::adrp(Register reg1, const Address &dest, uint64_t &byte_offset) rf(Rd, 0); } +// An "all-purpose" add/subtract immediate, per ARM documentation: +// A "programmer-friendly" assembler may accept a negative immediate +// between -(2^24 -1) and -1 inclusive, causing it to convert a +// requested ADD operation to a SUB, or vice versa, and then encode +// the absolute value of the immediate as for uimm24. +void Assembler::add_sub_immediate(Instruction_aarch64 ¤t_insn, + Register Rd, Register Rn, unsigned uimm, int op, + int negated_op) { + bool sets_flags = op & 1; // this op sets flags + union { + unsigned u; + int imm; + }; + u = uimm; + bool shift = false; + bool neg = imm < 0; + if (neg) { + imm = -imm; + op = negated_op; + } + assert(Rd != sp || imm % 16 == 0, "misaligned stack"); + if (imm >= (1 << 11) + && ((imm >> 12) << 12 == imm)) { + imm >>= 12; + shift = true; + } + f(op, 31, 29), f(0b10001, 28, 24), f(shift, 23, 22), f(imm, 21, 10); + + // add/subtract immediate ops with the S bit set treat r31 as zr; + // with S unset they use sp. + if (sets_flags) + zrf(Rd, 0); + else + srf(Rd, 0); + + srf(Rn, 5); +} + +#undef f +#undef sf +#undef rf +#undef srf +#undef zrf +#undef prf +#undef pgrf +#undef fixed + #undef starti Address::Address(address target, relocInfo::relocType rtype) : _mode(literal){ @@ -260,43 +316,6 @@ void Assembler::wrap_label(Label &L, prfop op, prefetch_insn insn) { } } -// An "all-purpose" add/subtract immediate, per ARM documentation: -// A "programmer-friendly" assembler may accept a negative immediate -// between -(2^24 -1) and -1 inclusive, causing it to convert a -// requested ADD operation to a SUB, or vice versa, and then encode -// the absolute value of the immediate as for uimm24. -void Assembler::add_sub_immediate(Register Rd, Register Rn, unsigned uimm, int op, - int negated_op) { - bool sets_flags = op & 1; // this op sets flags - union { - unsigned u; - int imm; - }; - u = uimm; - bool shift = false; - bool neg = imm < 0; - if (neg) { - imm = -imm; - op = negated_op; - } - assert(Rd != sp || imm % 16 == 0, "misaligned stack"); - if (imm >= (1 << 11) - && ((imm >> 12) << 12 == imm)) { - imm >>= 12; - shift = true; - } - f(op, 31, 29), f(0b10001, 28, 24), f(shift, 23, 22), f(imm, 21, 10); - - // add/subtract immediate ops with the S bit set treat r31 as zr; - // with S unset they use sp. - if (sets_flags) - zrf(Rd, 0); - else - srf(Rd, 0); - - srf(Rn, 5); -} - bool Assembler::operand_valid_for_add_sub_immediate(int64_t imm) { bool shift = false; uint64_t uimm = (uint64_t)uabs((jlong)imm); diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp index e755d4cee8819..5a8047bc2afdc 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp @@ -247,12 +247,12 @@ class Instruction_aarch64 { int nbits = msb - lsb + 1; guarantee(val < (1ULL << nbits), "Field too big for insn"); assert_cond(msb >= lsb); - unsigned mask = checked_cast(right_n_bits(nbits)); val <<= lsb; - mask <<= lsb; insn |= val; - assert_cond((bits & mask) == 0); #ifdef ASSERT + unsigned mask = checked_cast(right_n_bits(nbits)); + mask <<= lsb; + assert_cond((bits & mask) == 0); bits |= mask; #endif } @@ -313,7 +313,7 @@ class Instruction_aarch64 { } }; -#define starti Instruction_aarch64 do_not_use(this); set_current(&do_not_use) +#define starti Instruction_aarch64 current_insn(this); class PrePost { int _offset; @@ -695,46 +695,14 @@ class Assembler : public AbstractAssembler { static address locate_next_instruction(address inst); - Instruction_aarch64* current; - - void set_current(Instruction_aarch64* i) { current = i; } - - void f(unsigned val, int msb, int lsb) { - current->f(val, msb, lsb); - } - void f(unsigned val, int msb) { - current->f(val, msb, msb); - } - void sf(int64_t val, int msb, int lsb) { - current->sf(val, msb, lsb); - } - void rf(Register reg, int lsb) { - current->rf(reg, lsb); - } - void srf(Register reg, int lsb) { - current->srf(reg, lsb); - } - void zrf(Register reg, int lsb) { - current->zrf(reg, lsb); - } - void rf(FloatRegister reg, int lsb) { - current->rf(reg, lsb); - } - void prf(PRegister reg, int lsb) { - current->prf(reg, lsb); - } - void pgrf(PRegister reg, int lsb) { - current->pgrf(reg, lsb); - } - void fixed(unsigned value, unsigned mask) { - current->fixed(value, mask); - } - - void emit() { - emit_long(current->get_insn()); - assert_cond(current->get_bits() == 0xffffffff); - current = NULL; - } +#define f current_insn.f +#define sf current_insn.sf +#define rf current_insn.rf +#define srf current_insn.srf +#define zrf current_insn.zrf +#define prf current_insn.prf +#define pgrf current_insn.pgrf +#define fixed current_insn.fixed typedef void (Assembler::* uncond_branch_insn)(address dest); typedef void (Assembler::* compare_and_branch_insn)(Register Rt, address dest); @@ -765,8 +733,8 @@ class Assembler : public AbstractAssembler { #undef INSN - void add_sub_immediate(Register Rd, Register Rn, unsigned uimm, int op, - int negated_op); + void add_sub_immediate(Instruction_aarch64 ¤t_insn, Register Rd, Register Rn, + unsigned uimm, int op, int negated_op); // Add/subtract (immediate) #define INSN(NAME, decode, negated) \ @@ -778,7 +746,7 @@ class Assembler : public AbstractAssembler { \ void NAME(Register Rd, Register Rn, unsigned imm) { \ starti; \ - add_sub_immediate(Rd, Rn, imm, decode, negated); \ + add_sub_immediate(current_insn, Rd, Rn, imm, decode, negated); \ } INSN(addsw, 0b001, 0b011); @@ -791,7 +759,7 @@ class Assembler : public AbstractAssembler { #define INSN(NAME, decode, negated) \ void NAME(Register Rd, Register Rn, unsigned imm) { \ starti; \ - add_sub_immediate(Rd, Rn, imm, decode, negated); \ + add_sub_immediate(current_insn, Rd, Rn, imm, decode, negated); \ } INSN(addw, 0b000, 0b010); @@ -1093,7 +1061,7 @@ class Assembler : public AbstractAssembler { } void sys(int op1, int CRn, int CRm, int op2, - Register rt = (Register)0b11111) { + Register rt = as_Register(0b11111)) { system(0b01, op1, CRn, CRm, op2, rt); } @@ -1362,7 +1330,7 @@ class Assembler : public AbstractAssembler { starti; \ f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24), \ sf(offset, 23, 5); \ - rf((Register)Rt, 0); \ + rf(as_Register(Rt), 0); \ } INSN(ldrs, 0b00, 1); @@ -1376,7 +1344,7 @@ class Assembler : public AbstractAssembler { starti; \ f(size, 31, 30), f(0b111100, 29, 24), f(opc, 23, 22), f(0, 21); \ f(0, 20, 12), f(0b01, 11, 10); \ - rf(Rn, 5), rf((Register)Rt, 0); \ + rf(Rn, 5), rf(as_Register(Rt), 0); \ } INSN(ldrs, 0b10, 0b01); @@ -1409,9 +1377,9 @@ class Assembler : public AbstractAssembler { f(opc, 31, 30), f(p1, 29, 27), f(V, 26), f(L, 22); zrf(Rt2, 10), zrf(Rt1, 0); if (no_allocate) { - adr.encode_nontemporal_pair(current); + adr.encode_nontemporal_pair(¤t_insn); } else { - adr.encode_pair(current); + adr.encode_pair(¤t_insn); } } @@ -1437,7 +1405,8 @@ class Assembler : public AbstractAssembler { #define INSN(NAME, size, p1, V, L, no_allocate) \ void NAME(FloatRegister Rt1, FloatRegister Rt2, Address adr) { \ - ld_st1(size, p1, V, L, (Register)Rt1, (Register)Rt2, adr, no_allocate); \ + ld_st1(size, p1, V, L, \ + as_Register(Rt1), as_Register(Rt2), adr, no_allocate); \ } INSN(stps, 0b00, 0b101, 1, 0, false); @@ -1472,7 +1441,7 @@ class Assembler : public AbstractAssembler { f(size, 31, 30); f(op, 23, 22); // str - adr.encode(current); + adr.encode(¤t_insn); } #define INSN(NAME, size, op) \ @@ -1500,7 +1469,7 @@ class Assembler : public AbstractAssembler { #define INSN(NAME, size, op) \ void NAME(const Address &adr, prfop pfop = PLDL1KEEP) { \ - ld_st2((Register)pfop, adr, size, op); \ + ld_st2(as_Register(pfop), adr, size, op); \ } INSN(prfm, 0b11, 0b10); // FIXME: PRFM should not be used with @@ -1511,7 +1480,7 @@ class Assembler : public AbstractAssembler { #define INSN(NAME, size, op) \ void NAME(FloatRegister Rt, const Address &adr) { \ - ld_st2((Register)Rt, adr, size, op, 1); \ + ld_st2(as_Register(Rt), adr, size, op, 1); \ } INSN(strd, 0b11, 0b00); @@ -1548,7 +1517,7 @@ class Assembler : public AbstractAssembler { enum shift_kind { LSL, LSR, ASR, ROR }; - void op_shifted_reg(unsigned decode, + void op_shifted_reg(Instruction_aarch64 ¤t_insn, unsigned decode, enum shift_kind kind, unsigned shift, unsigned size, unsigned op) { f(size, 31); @@ -1559,14 +1528,14 @@ class Assembler : public AbstractAssembler { } // Logical (shifted register) -#define INSN(NAME, size, op, N) \ - void NAME(Register Rd, Register Rn, Register Rm, \ - enum shift_kind kind = LSL, unsigned shift = 0) { \ - starti; \ - guarantee(size == 1 || shift < 32, "incorrect shift"); \ - f(N, 21); \ - zrf(Rm, 16), zrf(Rn, 5), zrf(Rd, 0); \ - op_shifted_reg(0b01010, kind, shift, size, op); \ +#define INSN(NAME, size, op, N) \ + void NAME(Register Rd, Register Rn, Register Rm, \ + enum shift_kind kind = LSL, unsigned shift = 0) { \ + starti; \ + guarantee(size == 1 || shift < 32, "incorrect shift"); \ + f(N, 21); \ + zrf(Rm, 16), zrf(Rn, 5), zrf(Rd, 0); \ + op_shifted_reg(current_insn, 0b01010, kind, shift, size, op); \ } INSN(andr, 1, 0b00, 0); @@ -1586,7 +1555,7 @@ class Assembler : public AbstractAssembler { starti; \ f(N, 21); \ zrf(Rm, 16), zrf(Rn, 5), zrf(Rd, 0); \ - op_shifted_reg(0b01010, kind, shift, size, op); \ + op_shifted_reg(current_insn, 0b01010, kind, shift, size, op); \ } \ \ /* These instructions have no immediate form. Provide an overload so \ @@ -1633,7 +1602,7 @@ void mvnw(Register Rd, Register Rm, assert_cond(kind != ROR); \ guarantee(size == 1 || shift < 32, "incorrect shift");\ zrf(Rd, 0), zrf(Rn, 5), zrf(Rm, 16); \ - op_shifted_reg(0b01011, kind, shift, size, op); \ + op_shifted_reg(current_insn, 0b01011, kind, shift, size, op); \ } INSN(add, 1, 0b000); @@ -1654,10 +1623,10 @@ void mvnw(Register Rd, Register Rm, ext::operation option, int amount = 0) { \ starti; \ zrf(Rm, 16), srf(Rn, 5), srf(Rd, 0); \ - add_sub_extended_reg(op, 0b01011, Rd, Rn, Rm, 0b00, option, amount); \ + add_sub_extended_reg(current_insn, op, 0b01011, Rd, Rn, Rm, 0b00, option, amount); \ } - void add_sub_extended_reg(unsigned op, unsigned decode, + void add_sub_extended_reg(Instruction_aarch64 ¤t_insn, unsigned op, unsigned decode, Register Rd, Register Rn, Register Rm, unsigned opt, ext::operation option, unsigned imm) { guarantee(imm <= 4, "shift amount must be <= 4"); @@ -1677,7 +1646,7 @@ void mvnw(Register Rd, Register Rm, ext::operation option, int amount = 0) { \ starti; \ zrf(Rm, 16), srf(Rn, 5), zrf(Rd, 0); \ - add_sub_extended_reg(op, 0b01011, Rd, Rn, Rm, 0b00, option, amount); \ + add_sub_extended_reg(current_insn, op, 0b01011, Rd, Rn, Rm, 0b00, option, amount); \ } INSN(addsw, 0b001); @@ -1778,7 +1747,7 @@ void mvnw(Register Rd, Register Rm, } #define INSN(NAME, op, op2) \ - void NAME(Register Rd, Register Rn, Register Rm, Condition cond) { \ + void NAME(Register Rd, Register Rn, Register Rm, Condition cond) { \ conditional_select(op, op2, Rd, Rn, Rm, cond); \ } @@ -1794,7 +1763,7 @@ void mvnw(Register Rd, Register Rm, #undef INSN // Data processing - void data_processing(unsigned op29, unsigned opcode, + void data_processing(Instruction_aarch64 ¤t_insn, unsigned op29, unsigned opcode, Register Rd, Register Rn) { f(op29, 31, 29), f(0b11010110, 28, 21); f(opcode, 15, 10); @@ -1802,11 +1771,11 @@ void mvnw(Register Rd, Register Rm, } // (1 source) -#define INSN(NAME, op29, opcode2, opcode) \ - void NAME(Register Rd, Register Rn) { \ - starti; \ - f(opcode2, 20, 16); \ - data_processing(op29, opcode, Rd, Rn); \ +#define INSN(NAME, op29, opcode2, opcode) \ + void NAME(Register Rd, Register Rn) { \ + starti; \ + f(opcode2, 20, 16); \ + data_processing(current_insn, op29, opcode, Rd, Rn); \ } INSN(rbitw, 0b010, 0b00000, 0b00000); @@ -1825,11 +1794,11 @@ void mvnw(Register Rd, Register Rm, #undef INSN // (2 sources) -#define INSN(NAME, op29, opcode) \ - void NAME(Register Rd, Register Rn, Register Rm) { \ - starti; \ - rf(Rm, 16); \ - data_processing(op29, opcode, Rd, Rn); \ +#define INSN(NAME, op29, opcode) \ + void NAME(Register Rd, Register Rn, Register Rm) { \ + starti; \ + rf(Rm, 16); \ + data_processing(current_insn, op29, opcode, Rd, Rn); \ } INSN(udivw, 0b000, 0b000010); @@ -1874,9 +1843,9 @@ void mvnw(Register Rd, Register Rm, #undef INSN -#define INSN(NAME, op54, op31, o0) \ - void NAME(Register Rd, Register Rn, Register Rm) { \ - data_processing(op54, op31, o0, Rd, Rn, Rm, (Register)31); \ +#define INSN(NAME, op54, op31, o0) \ + void NAME(Register Rd, Register Rn, Register Rm) { \ + data_processing(op54, op31, o0, Rd, Rn, Rm, as_Register(31)); \ } INSN(smulh, 0b100, 0b010, 0); @@ -2055,7 +2024,7 @@ void mvnw(Register Rd, Register Rm, #define INSN(NAME, op31, type, rmode, opcode) \ void NAME(Register Rd, FloatRegister Vn) { \ - float_int_convert(op31, type, rmode, opcode, Rd, (Register)Vn); \ + float_int_convert(op31, type, rmode, opcode, Rd, as_Register(Vn)); \ } INSN(fcvtzsw, 0b000, 0b00, 0b11, 0b000); @@ -2072,7 +2041,7 @@ void mvnw(Register Rd, Register Rm, #define INSN(NAME, op31, type, rmode, opcode) \ void NAME(FloatRegister Vd, Register Rn) { \ - float_int_convert(op31, type, rmode, opcode, (Register)Vd, Rn); \ + float_int_convert(op31, type, rmode, opcode, as_Register(Vd), Rn); \ } INSN(fmovs, 0b000, 0b00, 0b00, 0b111); @@ -2127,7 +2096,7 @@ void mvnw(Register Rd, Register Rm, // Floating-point compare void float_compare(unsigned op31, unsigned type, unsigned op, unsigned op2, - FloatRegister Vn, FloatRegister Vm = (FloatRegister)0) { + FloatRegister Vn, FloatRegister Vm = as_FloatRegister(0)) { starti; f(op31, 31, 29); f(0b11110, 28, 24); @@ -2257,10 +2226,10 @@ void mvnw(Register Rd, Register Rm, static short SIMD_Size_in_bytes[]; public: -#define INSN(NAME, op) \ - void NAME(FloatRegister Rt, SIMD_RegVariant T, const Address &adr) { \ - ld_st2((Register)Rt, adr, (int)T & 3, op + ((T==Q) ? 0b10:0b00), 1); \ - } \ +#define INSN(NAME, op) \ + void NAME(FloatRegister Rt, SIMD_RegVariant T, const Address &adr) { \ + ld_st2(as_Register(Rt), adr, (int)T & 3, op + ((T==Q) ? 0b10:0b00), 1); \ + } INSN(ldr, 1); INSN(str, 0); @@ -3273,9 +3242,19 @@ inline Assembler::Membar_mask_bits operator|(Assembler::Membar_mask_bits a, } Instruction_aarch64::~Instruction_aarch64() { - assem->emit(); + assem->emit_int32(insn); + assert_cond(get_bits() == 0xffffffff); } +#undef f +#undef sf +#undef rf +#undef srf +#undef zrf +#undef prf +#undef pgrf +#undef fixed + #undef starti // Invert a condition diff --git a/src/hotspot/cpu/aarch64/foreign_globals_aarch64.cpp b/src/hotspot/cpu/aarch64/foreign_globals_aarch64.cpp index 6531eb03edc47..d08afc79a5245 100644 --- a/src/hotspot/cpu/aarch64/foreign_globals_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/foreign_globals_aarch64.cpp @@ -45,17 +45,18 @@ bool ABIDescriptor::is_volatile_reg(FloatRegister reg) const { const ABIDescriptor ForeignGlobals::parse_abi_descriptor_impl(jobject jabi) const { oop abi_oop = JNIHandles::resolve_non_null(jabi); ABIDescriptor abi; + const Register (*to_Register)(int) = as_Register; objArrayOop inputStorage = cast(abi_oop->obj_field(ABI.inputStorage_offset)); - loadArray(inputStorage, INTEGER_TYPE, abi._integer_argument_registers, as_Register); + loadArray(inputStorage, INTEGER_TYPE, abi._integer_argument_registers, to_Register); loadArray(inputStorage, VECTOR_TYPE, abi._vector_argument_registers, as_FloatRegister); objArrayOop outputStorage = cast(abi_oop->obj_field(ABI.outputStorage_offset)); - loadArray(outputStorage, INTEGER_TYPE, abi._integer_return_registers, as_Register); + loadArray(outputStorage, INTEGER_TYPE, abi._integer_return_registers, to_Register); loadArray(outputStorage, VECTOR_TYPE, abi._vector_return_registers, as_FloatRegister); objArrayOop volatileStorage = cast(abi_oop->obj_field(ABI.volatileStorage_offset)); - loadArray(volatileStorage, INTEGER_TYPE, abi._integer_additional_volatile_registers, as_Register); + loadArray(volatileStorage, INTEGER_TYPE, abi._integer_additional_volatile_registers, to_Register); loadArray(volatileStorage, VECTOR_TYPE, abi._vector_additional_volatile_registers, as_FloatRegister); abi._stack_alignment_bytes = abi_oop->int_field(ABI.stackAlignment_offset); diff --git a/src/hotspot/cpu/aarch64/register_aarch64.hpp b/src/hotspot/cpu/aarch64/register_aarch64.hpp index 459e24639fd83..9a4749e8673d1 100644 --- a/src/hotspot/cpu/aarch64/register_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/register_aarch64.hpp @@ -36,7 +36,7 @@ typedef VMRegImpl* VMReg; class RegisterImpl; typedef RegisterImpl* Register; -inline Register as_Register(int encoding) { +inline const Register as_Register(int encoding) { return (Register)(intptr_t) encoding; } @@ -53,7 +53,7 @@ class RegisterImpl: public AbstractRegisterImpl { Register successor() const { return as_Register(encoding() + 1); } // construction - inline friend Register as_Register(int encoding); + inline friend const Register as_Register(int encoding); VMReg as_VMReg(); @@ -426,4 +426,8 @@ inline FloatRegister AbstractRegSet::first() { return first ? as_FloatRegister(exact_log2(first)) : fnoreg; } +inline Register as_Register(FloatRegister reg) { + return as_Register(reg->encoding()); +} + #endif // CPU_AARCH64_REGISTER_AARCH64_HPP diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index be1e14ad86cf6..89dc70ae2d09e 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -222,7 +222,11 @@ class CodeSection { set_end(curr); } - void emit_int32(int32_t x) { *((int32_t*) end()) = x; set_end(end() + sizeof(int32_t)); } + void emit_int32(int32_t x) { + address curr = end(); + *((int32_t*) curr) = x; + set_end(curr + sizeof(int32_t)); + } void emit_int32(int8_t x1, int8_t x2, int8_t x3, int8_t x4) { address curr = end(); *((int8_t*) curr++) = x1; From 3a46af4ac3ba8d330a7fb6f0858113cca6e3d9a2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 5 Jun 2025 08:12:53 +0000 Subject: [PATCH 297/846] 8358660: Bump update version for OpenJDK: jdk-17.0.17 Reviewed-by: mbaesken, sgehwolf --- .jcheck/conf | 2 +- make/conf/version-numbers.conf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.jcheck/conf b/.jcheck/conf index e99bdd2e4165b..089f7de5616bd 100644 --- a/.jcheck/conf +++ b/.jcheck/conf @@ -1,7 +1,7 @@ [general] project=jdk-updates jbs=JDK -version=17.0.16 +version=17.0.17 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf index 9e08390395aa1..2076bc68a237e 100644 --- a/make/conf/version-numbers.conf +++ b/make/conf/version-numbers.conf @@ -28,12 +28,12 @@ DEFAULT_VERSION_FEATURE=17 DEFAULT_VERSION_INTERIM=0 -DEFAULT_VERSION_UPDATE=16 +DEFAULT_VERSION_UPDATE=17 DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2025-07-15 +DEFAULT_VERSION_DATE=2025-10-21 DEFAULT_VERSION_CLASSFILE_MAJOR=61 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 From c1c2475ebca1459213925920d2a173f7979247d3 Mon Sep 17 00:00:00 2001 From: Paul Hohensee Date: Thu, 5 Jun 2025 14:14:43 +0000 Subject: [PATCH 298/846] 8346285: Update jarsigner compatibility test for change in default digest algorithm Backport-of: e7d21fcf4949106e89afd413e9abc47d622dd47a --- .../jarsigner/compatibility/Compatibility.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java b/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java index 82ace9c755f4b..56ff670cd263f 100644 --- a/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java +++ b/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,6 +67,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import jdk.security.jarsigner.JarSigner; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.util.JarUtils; @@ -1430,7 +1431,9 @@ private SignItem digestAlgorithm(String digestAlgorithm) { String expectedDigestAlg() { return digestAlgorithm != null ? digestAlgorithm - : jdkInfo.majorVersion >= 20 ? "SHA-384" : "SHA-256"; + : jdkInfo.majorVersion >= 20 + ? JarSigner.Builder.getDefaultDigestAlgorithm() + : "SHA-256"; } private SignItem tsaDigestAlgorithm(String tsaDigestAlgorithm) { @@ -1439,7 +1442,11 @@ private SignItem tsaDigestAlgorithm(String tsaDigestAlgorithm) { } String expectedTsaDigestAlg() { - return tsaDigestAlgorithm != null ? tsaDigestAlgorithm : "SHA-256"; + return tsaDigestAlgorithm != null + ? tsaDigestAlgorithm + : jdkInfo.majorVersion >= 20 + ? JarSigner.Builder.getDefaultDigestAlgorithm() + : "SHA-256"; } private SignItem tsaIndex(int tsaIndex) { From 00ee0e1df47fd87f7c1cdc787b06cd560a9ed30a Mon Sep 17 00:00:00 2001 From: Ilarion Nakonechnyy Date: Mon, 9 Jun 2025 11:56:03 +0000 Subject: [PATCH 299/846] 8317804: com/sun/jdi/JdwpAllowTest.java fails on Alpine 3.17 / 3.18 Backport-of: b530c0281b5082994065b10addeb8366ffa58e2f --- .../share/native/libdt_socket/socketTransport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c b/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c index 9d4e589c358e1..d277223ebc198 100644 --- a/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c +++ b/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -755,7 +755,7 @@ socketTransport_startListening(jdwpTransportEnv* env, const char* address, if (isEqualIPv6Addr(listenAddr, mappedAny)) { for (ai = addrInfo; ai != NULL; ai = ai->ai_next) { - if (isEqualIPv6Addr(listenAddr, in6addr_any)) { + if (isEqualIPv6Addr(ai, in6addr_any)) { listenAddr = ai; break; } From de454c7faa2a2369d316bbea4407aab4e179c660 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 9 Jun 2025 12:55:47 +0000 Subject: [PATCH 300/846] 8357105: C2: compilation fails with "assert(false) failed: empty program detected during loop optimization" Backport-of: a300c356555019a42c19bf0c16184f6dee4ad96e --- src/hotspot/share/opto/stringopts.cpp | 13 ++++- .../TestStackedConcatsAppendUncommonTrap.java | 55 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/stringopts/TestStackedConcatsAppendUncommonTrap.java diff --git a/src/hotspot/share/opto/stringopts.cpp b/src/hotspot/share/opto/stringopts.cpp index 200e071db923e..f5cf5bcc413f9 100644 --- a/src/hotspot/share/opto/stringopts.cpp +++ b/src/hotspot/share/opto/stringopts.cpp @@ -1004,12 +1004,21 @@ bool StringConcat::validate_control_flow() { continue; } - // A test which leads to an uncommon trap which should be safe. - // Later this trap will be converted into a trap that restarts + // A test which leads to an uncommon trap. It is safe to convert the trap + // into a trap that restarts at the beginning as long as its test does not + // depend on intermediate results of the candidate chain. // at the beginning. if (otherproj->outcnt() == 1) { CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava(); if (call != nullptr && call->_name != nullptr && strcmp(call->_name, "uncommon_trap") == 0) { + // First check for dependency on a toString that is going away during stacked concats. + if (_multiple && + ((v1->is_Proj() && is_SB_toString(v1->in(0)) && ctrl_path.member(v1->in(0))) || + (v2->is_Proj() && is_SB_toString(v2->in(0)) && ctrl_path.member(v2->in(0))))) { + // iftrue -> if -> bool -> cmpp -> resproj -> tostring + fail = true; + break; + } // control flow leads to uct so should be ok _uncommon_traps.push(call); ctrl_path.push(call); diff --git a/test/hotspot/jtreg/compiler/stringopts/TestStackedConcatsAppendUncommonTrap.java b/test/hotspot/jtreg/compiler/stringopts/TestStackedConcatsAppendUncommonTrap.java new file mode 100644 index 0000000000000..2b72796836f63 --- /dev/null +++ b/test/hotspot/jtreg/compiler/stringopts/TestStackedConcatsAppendUncommonTrap.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025, 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 8357105 + * @summary Test stacked string concatenations where the toString result + * of the first StringBuilder chain is wired into an uncommon trap + * located in the second one. + * @run main/othervm compiler.stringopts.TestStackedConcatsAppendUncommonTrap + * @run main/othervm -XX:-TieredCompilation -Xbatch + * -XX:CompileOnly=compiler.stringopts.TestStackedConcatsAppendUncommonTrap::* + * compiler.stringopts.TestStackedConcatsAppendUncommonTrap + */ + +package compiler.stringopts; + +public class TestStackedConcatsAppendUncommonTrap { + + public static void main (String... args) { + for (int i = 0; i < 10000; i++) { + String s = f(" "); + if (!s.equals(" ")) { + throw new RuntimeException("wrong result."); + } + } + } + + static String f(String c) { + String s = " "; + s = new StringBuilder().append(s).append(s).toString(); + s = new StringBuilder().append(s).append(s == c ? s : " ").toString(); + return s; + } +} From 77bc699333c257c18a73ac3de0f5286eba60550f Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Mon, 9 Jun 2025 23:16:23 +0000 Subject: [PATCH 301/846] 8312191: ColorConvertOp.filter for the default destination is too slow Backport-of: e5f05b5a963774914751d9c241dd5693ed06af0b --- .../java/awt/image/ColorConvertOp.java | 21 ++++++- .../ColorConvertOp/CompatibleColorSpace.java | 61 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 test/jdk/sun/java2d/cmm/ColorConvertOp/CompatibleColorSpace.java diff --git a/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java b/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java index a32cb925e5cce..34ec923102983 100644 --- a/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java +++ b/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java @@ -622,7 +622,7 @@ public BufferedImage createCompatibleDestImage (BufferedImage src, "Destination ColorSpace is undefined"); } ICC_Profile destProfile = profileList[nProfiles - 1]; - cs = new ICC_ColorSpace(destProfile); + cs = createCompatibleColorSpace(destProfile); } else { /* non-ICC case */ int nSpaces = CSList.length; @@ -632,6 +632,25 @@ public BufferedImage createCompatibleDestImage (BufferedImage src, return createCompatibleDestImage(src, destCM, cs); } + private static ColorSpace createCompatibleColorSpace(ICC_Profile profile) { + if (profile == ICC_Profile.getInstance(ColorSpace.CS_sRGB)) { + return ColorSpace.getInstance(ColorSpace.CS_sRGB); + } + if (profile == ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB)) { + return ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); + } + if (profile == ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ)) { + return ColorSpace.getInstance(ColorSpace.CS_CIEXYZ); + } + if (profile == ICC_Profile.getInstance(ColorSpace.CS_PYCC)) { + return ColorSpace.getInstance(ColorSpace.CS_PYCC); + } + if (profile == ICC_Profile.getInstance(ColorSpace.CS_GRAY)) { + return ColorSpace.getInstance(ColorSpace.CS_GRAY); + } + return new ICC_ColorSpace(profile); + } + private BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM, ColorSpace destCS) { diff --git a/test/jdk/sun/java2d/cmm/ColorConvertOp/CompatibleColorSpace.java b/test/jdk/sun/java2d/cmm/ColorConvertOp/CompatibleColorSpace.java new file mode 100644 index 0000000000000..edf5c92628c81 --- /dev/null +++ b/test/jdk/sun/java2d/cmm/ColorConvertOp/CompatibleColorSpace.java @@ -0,0 +1,61 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.color.ColorSpace; +import java.awt.image.BufferedImage; +import java.awt.image.ColorConvertOp; + +/** + * @test + * @bug 8312191 + * @summary Standard color spaces should be reused for CompatibleDestImage + */ +public final class CompatibleColorSpace { + + private static final int[] spaces = { + ColorSpace.CS_CIEXYZ, ColorSpace.CS_GRAY, ColorSpace.CS_LINEAR_RGB, + ColorSpace.CS_PYCC, ColorSpace.CS_sRGB + }; + + public static void main(String[] args) { + for (int from : spaces) { + for (int to : spaces) { + test(from, to); + } + } + } + + private static void test(int from, int to) { + ColorSpace srcCS = ColorSpace.getInstance(from); + ColorSpace dstCS = ColorSpace.getInstance(to); + ColorConvertOp op = new ColorConvertOp(srcCS, dstCS, null); + BufferedImage src = new BufferedImage(10, 10, + BufferedImage.TYPE_INT_ARGB); + BufferedImage dst = op.filter(src, null); + // dst image is not set and will be created automatically, the dstCS + // should be reused + if (dst.getColorModel().getColorSpace() != dstCS) { + throw new RuntimeException("Wrong color space"); + } + } +} From 51b32f3cc1440deada65bc21a7449757283d54e9 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Tue, 10 Jun 2025 21:20:17 +0000 Subject: [PATCH 302/846] 8355051: Problemlist java/awt/Graphics2D/CopyAreaOOB.java on macosx-aarch64 Backport-of: abbf1a02cb00ae98ed7fdb7105aa4806756f898f --- test/jdk/ProblemList.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 06c32a5cb5c68..f7d97e64c9491 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -493,6 +493,7 @@ java/awt/MenuBar/TestNoScreenMenuBar.java 8265987 macosx-all java/awt/Graphics2D/DrawString/DrawRotatedStringUsingRotatedFont.java 8266283 generic-all java/awt/Graphics2D/DrawString/RotTransText.java 8316878 linux-all +java/awt/Graphics2D/CopyAreaOOB.java 8343106 macosx-aarch64 java/awt/KeyboardFocusmanager/TypeAhead/ButtonActionKeyTest/ButtonActionKeyTest.java 8257529 windows-x64 java/awt/KeyboardFocusmanager/ConsumeNextMnemonicKeyTypedTest/ConsumeNextMnemonicKeyTypedTest.java 8321303 linux-all From 42a0772283bad618d450378b3d0b513a26ed1156 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 12 Jun 2025 14:16:45 +0000 Subject: [PATCH 303/846] 8359170: Add 2 TLS and 2 CS Sectigo roots Reviewed-by: mdoerr, shade Backport-of: 9586817cea3f1cad8a49d43e9106e25dafa04765 --- make/data/cacerts/sectigocodesignroote46 | 21 ++ make/data/cacerts/sectigocodesignrootr46 | 39 +++ make/data/cacerts/sectigotlsroote46 | 21 ++ make/data/cacerts/sectigotlsrootr46 | 39 +++ .../certification/CAInterop.java | 39 ++- .../certification/SectigoCSRootCAs.java | 310 ++++++++++++++++++ .../security/lib/cacerts/VerifyCACerts.java | 14 +- 7 files changed, 479 insertions(+), 4 deletions(-) create mode 100644 make/data/cacerts/sectigocodesignroote46 create mode 100644 make/data/cacerts/sectigocodesignrootr46 create mode 100644 make/data/cacerts/sectigotlsroote46 create mode 100644 make/data/cacerts/sectigotlsrootr46 create mode 100644 test/jdk/security/infra/java/security/cert/CertPathValidator/certification/SectigoCSRootCAs.java diff --git a/make/data/cacerts/sectigocodesignroote46 b/make/data/cacerts/sectigocodesignroote46 new file mode 100644 index 0000000000000..7f13b28a40181 --- /dev/null +++ b/make/data/cacerts/sectigocodesignroote46 @@ -0,0 +1,21 @@ +Owner: CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB +Issuer: CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB +Serial number: 50249ba2ef8ea6bf6c2c1f1a6385d4c3 +Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICKDCCAa+gAwIBAgIQUCSbou+Opr9sLB8aY4XUwzAKBggqhkjOPQQDAzBWMQsw +CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRT +ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBFNDYwHhcNMjEwMzIyMDAw +MDAwWhcNNDYwMzIxMjM1OTU5WjBWMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2Vj +dGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25p +bmcgUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQIMoEDH487om+BR4zl +e7m6wWmyW0nAKLkUWG8kM85Qm3PZO8FoOZx6Yc5c0iJHRKuAhanllayqrmZYhlan +uIODzLTRDqlR+EtnOX+MubY5aDSPGUq6jiHrQrisVp0J3AejQjBAMB0GA1UdDgQW +BBTPfSygkHqYHd22XoXC4NoVcdLlXjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjACd++zAerlV83j8HflRwwwlLmgchbs +aGX/4g44dv/oG8KfzCVTRg6sZHMobtK0IqYCMGk5W6+oBFyZMtOebrSwXs8lGjll +/zHz43Zy8DMXO+iiqzSEwWGneZ6KupkGGqfVKw== +-----END CERTIFICATE----- diff --git a/make/data/cacerts/sectigocodesignrootr46 b/make/data/cacerts/sectigocodesignrootr46 new file mode 100644 index 0000000000000..38270cb0c5265 --- /dev/null +++ b/make/data/cacerts/sectigocodesignrootr46 @@ -0,0 +1,39 @@ +Owner: CN=Sectigo Public Code Signing Root R46, O=Sectigo Limited, C=GB +Issuer: CN=Sectigo Public Code Signing Root R46, O=Sectigo Limited, C=GB +Serial number: 4b2c3b01018bad2abc8c7b5b3eed9057 +Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046 +Signature algorithm name: SHA384withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFeDCCA2CgAwIBAgIQSyw7AQGLrSq8jHtbPu2QVzANBgkqhkiG9w0BAQwFADBW +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQD +EyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwHhcNMjEwMzIy +MDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBWMQswCQYDVQQGEwJHQjEYMBYGA1UEChMP +U2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNp +Z25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCN +55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+shJHjUoq14pbe0IdjJImK +/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCDJ9qaDStQ6Utbs7hkNqR+ +Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7P2bSlDFp+m2zNKzBenjc +klDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extmeme/G3h+pDHazJyCh1rr9 +gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUzT2MuuC3hv2WnBGsY2HH6 +zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6qRT5uWl+PoVvLnTCGMOgD +s0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mczmrYI4IAFSEDu9oJkRqj1 +c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEcQNYWFyn8XJwYK+pF9e+9 +1WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2TOglmmVhcKaO5DKYwODzQ +RjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/AZwQsRb8zG4Y3G9i/qZQ +p7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QIDAQABo0IwQDAdBgNVHQ4E +FgQUMuuSmv81lkgvKEBCcCA2kVwXheYwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAHZlwuPXIkrXHYle/2lexhQCTXOm +zc0oyrA36r+nySGqql/av/aDbNCA0QpcAKTL88w5D55BcYjVPOiKe4wXI/fKNHSR +bAauUD8AWbImPDwXg1cDPi3RGj3UzwdUskMLUnKoiPXEF/Jv0Vil0WjkPZgIGO42 +9EhImvpUcPCI1HAWMEJJ0Nk/dUtFcdiuorthDoiFUFe5uhErNikfjyBynlyeidGC +2kWNapnahHFrM6UQu3nwl/Z0gaA/V8eGjDCMDjiVrgHGHqvcqB9vL9f/dh6uF3Nt +5bl1s2EGqJUzwk5vsjfylb6FVBK5yL1iQnb3Kvz1NzEDJlf+0ebb8BYCcoOMCLOE +rKnkB/ihiMQTWlBHVEKm7dBBNCyYsT6iNKEMXb2s9395p79tDFYyhRtLl7jhrOSk +PHHxo+FOY9b0Rrr1CwjhYzztolkvCtQsayOinqFN7tESzRgzUO1Bbst/PUFgC2ML +ePV170MVtzYLEK/cXBipmNk22R3YhLMGioLjexskp0LO7g8+VlwyfexL3lYrOzu6 ++XpY0FG2bNb2WKJSJHpEhqEcYD9J0/z6+YQcBcI0v+Lm8RkqmS9WVzWctfUHw0Yv +3jg9GQ37o/HfE57nqXJYMa+96trX1m13MzOO9Kz9wb9Jh9JwBWd0Bqb2eEAtFgSR +Dx/TFsS4ehcNJMmy +-----END CERTIFICATE----- diff --git a/make/data/cacerts/sectigotlsroote46 b/make/data/cacerts/sectigotlsroote46 new file mode 100644 index 0000000000000..60e0b83c97e43 --- /dev/null +++ b/make/data/cacerts/sectigotlsroote46 @@ -0,0 +1,21 @@ +Owner: CN=Sectigo Public Server Authentication Root E46, O=Sectigo Limited, C=GB +Issuer: CN=Sectigo Public Server Authentication Root E46, O=Sectigo Limited, C=GB +Serial number: 42f2ccda1b6937445f15fe752810b8f4 +Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw +CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN +MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG +A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC +WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+ +6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B +Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa +qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q +4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw== +-----END CERTIFICATE----- diff --git a/make/data/cacerts/sectigotlsrootr46 b/make/data/cacerts/sectigotlsrootr46 new file mode 100644 index 0000000000000..7ec1b263de743 --- /dev/null +++ b/make/data/cacerts/sectigotlsrootr46 @@ -0,0 +1,39 @@ +Owner: CN=Sectigo Public Server Authentication Root R46, O=Sectigo Limited, C=GB +Issuer: CN=Sectigo Public Server Authentication Root R46, O=Sectigo Limited, C=GB +Serial number: 758dfd8bae7c0700faa925a7e1c7ad14 +Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046 +Signature algorithm name: SHA384withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD +Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw +HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY +MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp +YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa +ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz +SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf +iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X +ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3 +IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS +VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE +SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu ++Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt +8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L +HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt +zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ +YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52 +gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA +Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB +JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX +DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui +TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5 +dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65 +LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp +0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY +QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java index 3f16717153bda..cc348f5af8526 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, 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 @@ -557,6 +557,36 @@ * @run main/othervm/manual -Djava.security.debug=certpath CAInterop ssltlsrootrsa2022 CRL */ +/* + * @test id=sectigotlsrootr46 + * @bug 8359170 + * @summary Interoperability tests with Sectigo Public Server Authentication + * Root R46 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop + * sectigotlsrootr46 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp + * -Dcom.sun.security.ocsp.useget=false CAInterop sectigotlsrootr46 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop + * sectigotlsrootr46 CRL + */ + +/* + * @test id=sectigotlsroote46 + * @bug 8359170 + * @summary Interoperability tests with Sectigo Public Server Authentication + * Root E46 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop + * sectigotlsroote46 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp + * -Dcom.sun.security.ocsp.useget=false CAInterop sectigotlsroote46 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop + * sectigotlsroote46 CRL + */ + /** * Collection of certificate validation tests for interoperability with external CAs. * These tests are marked as manual as they depend on external infrastructure and may fail @@ -742,6 +772,13 @@ private CATestURLs getTestURLs(String alias) { new CATestURLs("https://test-root-2022-rsa.ssl.com", "https://revoked-root-2022-rsa.ssl.com"); + case "sectigotlsrootr46" -> + new CATestURLs("https://sectigopublicserverauthenticationrootr46-ev.sectigo.com", + "https://sectigopublicserverauthenticationrootr46-ev.sectigo.com:444"); + case "sectigotlsroote46" -> + new CATestURLs("https://sectigopublicserverauthenticationroote46-ev.sectigo.com", + "https://sectigopublicserverauthenticationroote46-ev.sectigo.com:444"); + default -> throw new RuntimeException("No test setup found for: " + alias); }; } diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/SectigoCSRootCAs.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/SectigoCSRootCAs.java new file mode 100644 index 0000000000000..80cd1d41cbc6b --- /dev/null +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/SectigoCSRootCAs.java @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2025, 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 8359170 + * @summary Interoperability tests with Sectigo Public Code Signing Root CAs + * @build ValidatePathWithParams + * @run main/othervm/manual -Djava.security.debug=ocsp,certpath SectigoCSRootCAs OCSP + * @run main/othervm/manual -Djava.security.debug=certpath SectigoCSRootCAs CRL + */ + +public class SectigoCSRootCAs { + + public static void main(String[] args) throws Exception { + + ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); + + if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { + pathValidator.enableCRLCheck(); + } else { + // OCSP check by default + pathValidator.enableOCSPCheck(); + } + + new SectigoCSRootCA_R46().runTest(pathValidator); + new SectigoCSRootCA_E46().runTest(pathValidator); + } +} + +class SectigoCSRootCA_R46 { + + // Owner: CN=Sectigo Public Code Signing CA R36, O=Sectigo Limited, C=GB + // Issuer: CN=Sectigo Public Code Signing Root R46, O=Sectigo Limited, C=GB + // Serial number: 621d6d0c52019e3b9079152089211c0a + // Valid from: Sun Mar 21 17:00:00 PDT 2021 until: Fri Mar 21 16:59:59 + // PDT 2036 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIIGGjCCBAKgAwIBAgIQYh1tDFIBnjuQeRUgiSEcCjANBgkqhkiG9w0BAQwFADBW\n" + + "MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQD\n" + + "EyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwHhcNMjEwMzIy\n" + + "MDAwMDAwWhcNMzYwMzIxMjM1OTU5WjBUMQswCQYDVQQGEwJHQjEYMBYGA1UEChMP\n" + + "U2VjdGlnbyBMaW1pdGVkMSswKQYDVQQDEyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNp\n" + + "Z25pbmcgQ0EgUjM2MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAmyud\n" + + "U/o1P45gBkNqwM/1f/bIU1MYyM7TbH78WAeVF3llMwsRHgBGRmxDeEDIArCS2VCo\n" + + "Vk4Y/8j6stIkmYV5Gej4NgNjVQ4BYoDjGMwdjioXan1hlaGFt4Wk9vT0k2oWJMJj\n" + + "L9G//N523hAm4jF4UjrW2pvv9+hdPX8tbbAfI3v0VdJiJPFy/7XwiunD7mBxNtec\n" + + "M6ytIdUlh08T2z7mJEXZD9OWcJkZk5wDuf2q52PN43jc4T9OkoXZ0arWZVeffvMr\n" + + "/iiIROSCzKoDmWABDRzV/UiQ5vqsaeFaqQdzFf4ed8peNWh1OaZXnYvZQgWx/SXi\n" + + "JDRSAolRzZEZquE6cbcH747FHncs/Kzcn0Ccv2jrOW+LPmnOyB+tAfiWu01TPhCr\n" + + "9VrkxsHC5qFNxaThTG5j4/Kc+ODD2dX/fmBECELcvzUHf9shoFvrn35XGf2RPaNT\n" + + "O2uSZ6n9otv7jElspkfK9qEATHZcodp+R4q2OIypxR//YEb3fkDn3UayWW9bAgMB\n" + + "AAGjggFkMIIBYDAfBgNVHSMEGDAWgBQy65Ka/zWWSC8oQEJwIDaRXBeF5jAdBgNV\n" + + "HQ4EFgQUDyrLIIcouOxvSK4rVKYpqhekzQwwDgYDVR0PAQH/BAQDAgGGMBIGA1Ud\n" + + "EwEB/wQIMAYBAf8CAQAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwGwYDVR0gBBQwEjAG\n" + + "BgRVHSAAMAgGBmeBDAEEATBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsLnNl\n" + + "Y3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ1Jvb3RSNDYuY3JsMHsG\n" + + "CCsGAQUFBwEBBG8wbTBGBggrBgEFBQcwAoY6aHR0cDovL2NydC5zZWN0aWdvLmNv\n" + + "bS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdSb290UjQ2LnA3YzAjBggrBgEFBQcw\n" + + "AYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wDQYJKoZIhvcNAQEMBQADggIBAAb/\n" + + "guF3YzZue6EVIJsT/wT+mHVEYcNWlXHRkT+FoetAQLHI1uBy/YXKZDk8+Y1LoNqH\n" + + "rp22AKMGxQtgCivnDHFyAQ9GXTmlk7MjcgQbDCx6mn7yIawsppWkvfPkKaAQsiqa\n" + + "T9DnMWBHVNIabGqgQSGTrQWo43MOfsPynhbz2Hyxf5XWKZpRvr3dMapandPfYgoZ\n" + + "8iDL2OR3sYztgJrbG6VZ9DoTXFm1g0Rf97Aaen1l4c+w3DC+IkwFkvjFV3jS49ZS\n" + + "c4lShKK6BrPTJYs4NG1DGzmpToTnwoqZ8fAmi2XlZnuchC4NPSZaPATHvNIzt+z1\n" + + "PHo35D/f7j2pO1S8BCysQDHCbM5Mnomnq5aYcKCsdbh0czchOm8bkinLrYrKpii+\n" + + "Tk7pwL7TjRKLXkomm5D1Umds++pip8wH2cQpf93at3VDcOK4N7EwoIJB0kak6pSz\n" + + "Eu4I64U6gZs7tS/dGNSljf2OSSnRr7KWzq03zl8l75jy+hOds9TWSenLbjBQUGR9\n" + + "6cFr6lEUfAIEHVC1L68Y1GGxx4/eRI82ut83axHMViw1+sVpbPxg51Tbnio1lB93\n" + + "079WPFnYaOvfGAA0e0zcfF/M9gXr+korwQTh2Prqooq2bYNMvUoUKD85gnJ+t0sm\n" + + "rWrb8dee2CvYZXD5laGtaAxOfy/VKNmwuWuAh9kc\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Sectigo Limited, O=Sectigo Limited, ST=West Yorkshire, C=GB + // Issuer: CN=Sectigo Public Code Signing CA R36, O=Sectigo Limited, C=GB + // Serial number: c1de046377578f1605414f3fa91bf5f6 + // Valid from: Wed Jun 04 17:00:00 PDT 2025 until: Fri Jun 05 16:59:59 + // PDT 2026 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIGRDCCBKygAwIBAgIRAMHeBGN3V48WBUFPP6kb9fYwDQYJKoZIhvcNAQEMBQAw\n" + + "VDELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UE\n" + + "AxMiU2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIFIzNjAeFw0yNTA2MDUw\n" + + "MDAwMDBaFw0yNjA2MDUyMzU5NTlaMFoxCzAJBgNVBAYTAkdCMRcwFQYDVQQIDA5X\n" + + "ZXN0IFlvcmtzaGlyZTEYMBYGA1UECgwPU2VjdGlnbyBMaW1pdGVkMRgwFgYDVQQD\n" + + "DA9TZWN0aWdvIExpbWl0ZWQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\n" + + "AQDCYjakgsoYkqVpENW0MuN5hBZDdIM60WJgBXU7zTAXORntSu/Grn/SQywwTg4o\n" + + "ltRcKuCp0Cd5zLAIjtgpVDDACWHgxKUtxerjjBZeGp0+viR+biLL0mVNPXgZZ5bQ\n" + + "AnDYVKJaGnPsXQD8l+Bn/R2c4cw7mXjBYp2KrTuqOBkPzk4LmdgpKXjxiw1yYb+n\n" + + "WKZ+3BMLIU6/k+LB9+WB6Odrl4Lff1jB4C6XhQELGjZAbpkFB2+Qr0ajIA3ZFXqU\n" + + "IMh0j5oD5juuXxryOvCgSBkEwxPHnlXxZBNd3DmrZ9NGClBIGE2f9FOjzo5Rl7lV\n" + + "KlzFdFmcH8LaLtWjniF+iT+YZw3Ld1O9VMK7RaHePsS4JYfbjeapoCEgudecmIz4\n" + + "5Q2tTjCdR5s/SxiVbynfEw+cAGeiv4sRXNSg0uhZ2eGMHh6mPley2pUoRMR8Qx1U\n" + + "0Uzg2NtPsHAo0DIH3jKEWU2zP5UPwCfqKYGaZLNLeGh07NZHBCp3TGp9kPVen5Ib\n" + + "tnJssu+pab7fixvbpDM4/r9MkKU6C1IsE6lffyON0PA6LaywwecYTJGpieXqoz03\n" + + "5UmQXvAzkb9omIAcQ6yWMZNrqwwG9XRKQEhvG3v7sbFkck1KZOz4r/KHkLx9sIxm\n" + + "vngdD/qLFebxPIvPT0GKnvSzuGcdQXVTdkZBBBrunv+XpQIDAQABo4IBiTCCAYUw\n" + + "HwYDVR0jBBgwFoAUDyrLIIcouOxvSK4rVKYpqhekzQwwHQYDVR0OBBYEFGMpbbJO\n" + + "xiuD6t+HEyA3hjp4devXMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBMG\n" + + "A1UdJQQMMAoGCCsGAQUFBwMDMEoGA1UdIARDMEEwNQYMKwYBBAGyMQECAQMCMCUw\n" + + "IwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAgGBmeBDAEEATBJ\n" + + "BgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLnNlY3RpZ28uY29tL1NlY3RpZ29Q\n" + + "dWJsaWNDb2RlU2lnbmluZ0NBUjM2LmNybDB5BggrBgEFBQcBAQRtMGswRAYIKwYB\n" + + "BQUHMAKGOGh0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVT\n" + + "aWduaW5nQ0FSMzYuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdv\n" + + "LmNvbTANBgkqhkiG9w0BAQwFAAOCAYEAP2OCzJ+0hrg4XK3w+Ypoe0G5hKfzZ9RH\n" + + "nDcgY8BjgWYVOlN9ad2bU70RfgkZzylkaSt02KHOpkXmYpgfjZsovmyUchvlZ4fU\n" + + "RmivZleuO3G/ZvDFX373S40QFDd+lC1LYYUolRVz7/ZU2Vzql4FxsM1psRaW17xj\n" + + "jf9qaAvDlOH45eEEkfRUbIDdn1UYqDxdCN+90jtD1vRWkYINvE1T6mq3rHpEVoTS\n" + + "dIOgmcSL3MAKMB0LxWUPfoVdhnoUuoIxIAcV1SuR6zej4wHjClEaR8ReT/C23Jr3\n" + + "hQ4VDbfGu3gvlZG8/+lNmT+t4WaNPECxbFP0BgbD70FP594mSVH3fgptYiiRN7ez\n" + + "iUfOSBeCZpSMm7Z5P0KkxkagyFIR3vzgvqbJS/iaomvd9ZIkd9AwMEhugJpITeZj\n" + + "lKSXs+2q2UHQdLTPGVoOjmqyPhDGKAeVVF+jLIUWwtAaAoJm6ooXSp8sAeLA+e+K\n" + + "6RUFETVxhCefCjkbWq64OYLXriDb0l+W\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Sectigo Limited, O=Sectigo Limited, ST=West Yorkshire, C=GB + // Issuer: CN=Sectigo Public Code Signing CA R36, O=Sectigo Limited, C=GB + // Serial number: 5ca6fb60da04db99dedbbc0c37131ec + // Valid from: Wed Jun 04 17:00:00 PDT 2025 until: Sun Jun 04 16:59:59 + // PDT 2028 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIGQzCCBKugAwIBAgIQBcpvtg2gTbmd7bvAw3Ex7DANBgkqhkiG9w0BAQwFADBU\n" + + "MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSswKQYDVQQD\n" + + "EyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2MB4XDTI1MDYwNTAw\n" + + "MDAwMFoXDTI4MDYwNDIzNTk1OVowWjELMAkGA1UEBhMCR0IxFzAVBgNVBAgMDldl\n" + + "c3QgWW9ya3NoaXJlMRgwFgYDVQQKDA9TZWN0aWdvIExpbWl0ZWQxGDAWBgNVBAMM\n" + + "D1NlY3RpZ28gTGltaXRlZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB\n" + + "ALDjoFCMN16zlrcv/saieSYT7FXEhTVDPLNzGAbNdBEX09FoL5EIkiN3biVIbDki\n" + + "bIocCFpo/yTrjARG/zz82AjdWHyomdtDjL35CQmgiUX7V8tu64xUfUAgadqm+0PL\n" + + "by1LRddKE7chpdJu+EDEmeYDPqcRGM+u8suPgosFf6XfVNFy/FZJiD1c7q6JNZ8i\n" + + "5NrvTs0zA9HckKE3uvPO9rw56EyF3SfUz9+zHKHwSElv8nCYpREudUf4yCzPNisK\n" + + "MVovzeCo36nzJFEdWTnDOr4mtvfCEGvJOU3mgzpECK7QF+yFifr90SG4lvrwzkig\n" + + "wYQymukXmB2gxN1tGOvgLig3Q/b4vljBiEeRPEba/L8YQnaXpR/BnPze8yb2t39l\n" + + "bzmnghkWkGA0PAB2vrzpi7pq12fGOD0+ErtAzAl/TAD/UFWwXDQLWX9LXRRKi5E+\n" + + "ScTlqLl9U1q9HsWYfM6CvLbc32TByaQ8yBytvsSRB0C0blp7CtP5MAc8j9xJdwAs\n" + + "Mj2bvSOfA+NJ0Kdg/tqdHHU6hex2HnGzDiEhovm6u/oAfDp/i2bBKLgARglMfGaC\n" + + "hFWeHLL6GAyBezMv+AQNCDCTYDMlqAihVMRUAfYgoHcVCfvTSETTTGdRUDFzIdCA\n" + + "wNwSVfykpadsev43I2IF+F3aNgJYuXnpxSCLPngemcgxAgMBAAGjggGJMIIBhTAf\n" + + "BgNVHSMEGDAWgBQPKssghyi47G9IritUpimqF6TNDDAdBgNVHQ4EFgQUlff/C/GC\n" + + "faJ+Y7ua3hKsCsrW9y4wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwEwYD\n" + + "VR0lBAwwCgYIKwYBBQUHAwMwSgYDVR0gBEMwQTA1BgwrBgEEAbIxAQIBAwIwJTAj\n" + + "BggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQQBMEkG\n" + + "A1UdHwRCMEAwPqA8oDqGOGh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1\n" + + "YmxpY0NvZGVTaWduaW5nQ0FSMzYuY3JsMHkGCCsGAQUFBwEBBG0wazBEBggrBgEF\n" + + "BQcwAoY4aHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNp\n" + + "Z25pbmdDQVIzNi5jcnQwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3RpZ28u\n" + + "Y29tMA0GCSqGSIb3DQEBDAUAA4IBgQAfVq3mY7ggMcTJeWKKrGxs9RUiuAY0p4Xv\n" + + "CHNQViM/tHAn0t/nkPp+d2Ji3Zr6PefN+1F6zmsxsbZHse52JNHWYUwCb/Dx4Vw6\n" + + "3Wnc1zhXtZnvUTUfgrivuIsMjUG8yzTdEt/taMKEO0KqlKPsBPgFKveDVVaq9UZa\n" + + "FfxTWqgrnvkvP/Lag/YeKKj4cJG+a/MJZJm7kvyaBNKXVAamr/bumoxKDzpD67ds\n" + + "n9qwBi2Mv0rRXvZ2SHQXzsJ/zjNKWUhpPVrpypaER7EUxjNuSgC4L8AmfvHiO67v\n" + + "9EVIEud+beP3FtCXl/cSHhVeDxiC0KBXXBl9zLBaYvCH+8iABnZLStLgBDtfdkfk\n" + + "TZEAGbrNOXJDMnKRxr8y377Zq+KHwfiTnyizACHyMMTi+CCwg1ZFGcLOHa5shByc\n" + + "Ln9lYysM1/5vrEjt3ZUw11+pDqbPCGS++xgAwcftKfJ0TZrW/g6NZ9URg+11H9ad\n" + + "WalBv2VkhJAFJam9P2Y+pi9luk85sGo=\n" + + "-----END CERTIFICATE-----"; + + public void runTest(ValidatePathWithParams pathValidator) throws Exception { + // Validate valid + pathValidator.validate(new String[]{VALID, INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT}, + ValidatePathWithParams.Status.REVOKED, + "Thu Jun 05 10:27:45 PDT 2025", System.out); + } +} + +class SectigoCSRootCA_E46 { + + // Owner: CN=Sectigo Public Code Signing CA EV E36, O=Sectigo Limited, C=GB + // Issuer: CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB + // Serial number: 3774434f9eb40e221f9236ca1f2f2717 + // Valid from: Sun Mar 21 17:00:00 PDT 2021 until: Fri Mar 21 16:59:59 + // PDT 2036 + private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIDMDCCAragAwIBAgIQN3RDT560DiIfkjbKHy8nFzAKBggqhkjOPQQDAzBWMQsw\n" + + "CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRT\n" + + "ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBFNDYwHhcNMjEwMzIyMDAw\n" + + "MDAwWhcNMzYwMzIxMjM1OTU5WjBXMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2Vj\n" + + "dGlnbyBMaW1pdGVkMS4wLAYDVQQDEyVTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25p\n" + + "bmcgQ0EgRVYgRTM2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3mMV9nNViYoH\n" + + "4aSrPwFjpbbeXHw2pMbqezwDGb45uEZQr3qI9Hgt0k4R26o5upfXzJt03F8efu0r\n" + + "RNEs4yDDz6OCAWMwggFfMB8GA1UdIwQYMBaAFM99LKCQepgd3bZehcLg2hVx0uVe\n" + + "MB0GA1UdDgQWBBQadKQ417m2DrNb+txerj+28HM9iDAOBgNVHQ8BAf8EBAMCAYYw\n" + + "EgYDVR0TAQH/BAgwBgEB/wIBADATBgNVHSUEDDAKBggrBgEFBQcDAzAaBgNVHSAE\n" + + "EzARMAYGBFUdIAAwBwYFZ4EMAQMwSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2Ny\n" + + "bC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdSb290RTQ2LmNy\n" + + "bDB7BggrBgEFBQcBAQRvMG0wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jcnQuc2VjdGln\n" + + "by5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nUm9vdEU0Ni5wN2MwIwYIKwYB\n" + + "BQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3RpZ28uY29tMAoGCCqGSM49BAMDA2gAMGUC\n" + + "MQCger3L4CYx2W7HyHzvLaAnNee9QVqOwOrBYZyyqXERLtZg1DscsdoYZ2gszEW3\n" + + "zaUCMAaLtcwdoV35ADpru29wChS7kFgXt599Ex27wmL++uJCJth6xYr3nyF2b2YJ\n" + + "DAatOw==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Sectigo Public Code Signing CA E36, O=Sectigo Limited, C=GB + // Issuer: CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB + // Serial number: 3602617636e7034b9cc1fc5ffeac2d54 + // Valid from: Sun Mar 21 17:00:00 PDT 2021 until: Fri Mar 21 16:59:59 + // PDT 2036 + private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIDLjCCArSgAwIBAgIQNgJhdjbnA0ucwfxf/qwtVDAKBggqhkjOPQQDAzBWMQsw\n" + + "CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRT\n" + + "ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBFNDYwHhcNMjEwMzIyMDAw\n" + + "MDAwWhcNMzYwMzIxMjM1OTU5WjBUMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2Vj\n" + + "dGlnbyBMaW1pdGVkMSswKQYDVQQDEyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25p\n" + + "bmcgQ0EgRTM2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAElDe1m6jawDhrwMxJ\n" + + "yFPhKYf8EGu+lBw3bF5CzmfaH1I7Zi+WAmkeEwS3tiNxzPh8GbBBLtdaRuqGuyWc\n" + + "W6ERmaOCAWQwggFgMB8GA1UdIwQYMBaAFM99LKCQepgd3bZehcLg2hVx0uVeMB0G\n" + + "A1UdDgQWBBQlDZtt2Bh3t4rDOFFW5cfytf+DajAOBgNVHQ8BAf8EBAMCAYYwEgYD\n" + + "VR0TAQH/BAgwBgEB/wIBADATBgNVHSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDAS\n" + + "MAYGBFUdIAAwCAYGZ4EMAQQBMEsGA1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwu\n" + + "c2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nUm9vdEU0Ni5jcmww\n" + + "ewYIKwYBBQUHAQEEbzBtMEYGCCsGAQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28u\n" + + "Y29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ1Jvb3RFNDYucDdjMCMGCCsGAQUF\n" + + "BzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTAKBggqhkjOPQQDAwNoADBlAjBM\n" + + "ykNTSVvegC1m17yIi87qgx6QIGbw1Mw2bQ4gtOWBVb/C8ALByC1YK7yQJNLJFTkC\n" + + "MQCNBv3fe1eLrGELS5KQD0cEFbXGlzQ5r1mnOHePMqlK5d+rmMxff58/t6bo3QEb\n" + + "8SQ=\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Sectigo Limited, O=Sectigo Limited, ST=West Yorkshire, C=GB, + // OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB, + // SERIALNUMBER=04058690 + // Issuer: CN=Sectigo Public Code Signing CA EV E36, O=Sectigo Limited, C=GB + // Serial number: fa2aa131f36b337717ac73f606a6ec49 + // Valid from: Tue Feb 13 16:00:00 PST 2024 until: Sat Feb 13 15:59:59 + // PST 2027 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIDrjCCA1SgAwIBAgIRAPoqoTHzazN3F6xz9gam7EkwCgYIKoZIzj0EAwIwVzEL\n" + + "MAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEuMCwGA1UEAxMl\n" + + "U2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIEVWIEUzNjAeFw0yNDAyMTQw\n" + + "MDAwMDBaFw0yNzAyMTMyMzU5NTlaMIGhMREwDwYDVQQFEwgwNDA1ODY5MDETMBEG\n" + + "CysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24x\n" + + "CzAJBgNVBAYTAkdCMRcwFQYDVQQIDA5XZXN0IFlvcmtzaGlyZTEYMBYGA1UECgwP\n" + + "U2VjdGlnbyBMaW1pdGVkMRgwFgYDVQQDDA9TZWN0aWdvIExpbWl0ZWQwWTATBgcq\n" + + "hkjOPQIBBggqhkjOPQMBBwNCAASwXGEU01WkW/hWNYza08ZT7i0ZeZ9M1s93JYEB\n" + + "rZ/f1Ho1YzxtToqgIK2o+32afablPFYWlE6wGyuL/TYggBpKo4IBtDCCAbAwHwYD\n" + + "VR0jBBgwFoAUGnSkONe5tg6zW/rcXq4/tvBzPYgwHQYDVR0OBBYEFHEcsJgcYuDO\n" + + "dv1raL6h83a6j9C/MA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBMGA1Ud\n" + + "JQQMMAoGCCsGAQUFBwMDMEkGA1UdIARCMEAwNQYMKwYBBAGyMQECAQYBMCUwIwYI\n" + + "KwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAcGBWeBDAEDMEsGA1Ud\n" + + "HwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1Ymxp\n" + + "Y0NvZGVTaWduaW5nQ0FFVkUzNi5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsGAQUF\n" + + "BzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2ln\n" + + "bmluZ0NBRVZFMzYuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdv\n" + + "LmNvbTAmBgNVHREEHzAdoBsGCCsGAQUFBwgDoA8wDQwLR0ItMDQwNTg2OTAwCgYI\n" + + "KoZIzj0EAwIDSAAwRQIgQVp7IIkEZNmC7GfmT1MSEhDebIjjzd75ZVEEbPP/4ocC\n" + + "IQDSyfPDKNMbKNOKrweDLwSE2GZV6nDWbiLz6ZmSZHob8w==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Sectigo Limited, O=Sectigo Limited, ST=West Yorkshire, C=GB + // Issuer: CN=Sectigo Public Code Signing CA E36, O=Sectigo Limited, C=GB + // Serial number: a1f601514271f24ca0a31c0d7b856705 + // Valid from: Wed Jun 04 17:00:00 PDT 2025 until: Sun Jun 04 16:59:59 + // PDT 2028 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIDOTCCAt6gAwIBAgIRAKH2AVFCcfJMoKMcDXuFZwUwCgYIKoZIzj0EAwIwVDEL\n" + + "MAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UEAxMi\n" + + "U2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIEUzNjAeFw0yNTA2MDUwMDAw\n" + + "MDBaFw0yODA2MDQyMzU5NTlaMFoxCzAJBgNVBAYTAkdCMRcwFQYDVQQIDA5XZXN0\n" + + "IFlvcmtzaGlyZTEYMBYGA1UECgwPU2VjdGlnbyBMaW1pdGVkMRgwFgYDVQQDDA9T\n" + + "ZWN0aWdvIExpbWl0ZWQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASwXGEU01Wk\n" + + "W/hWNYza08ZT7i0ZeZ9M1s93JYEBrZ/f1Ho1YzxtToqgIK2o+32afablPFYWlE6w\n" + + "GyuL/TYggBpKo4IBiTCCAYUwHwYDVR0jBBgwFoAUJQ2bbdgYd7eKwzhRVuXH8rX/\n" + + "g2owHQYDVR0OBBYEFHEcsJgcYuDOdv1raL6h83a6j9C/MA4GA1UdDwEB/wQEAwIH\n" + + "gDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMEoGA1UdIARDMEEw\n" + + "NQYMKwYBBAGyMQECAQMCMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5j\n" + + "b20vQ1BTMAgGBmeBDAEEATBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLnNl\n" + + "Y3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ0NBRTM2LmNybDB5Bggr\n" + + "BgEFBQcBAQRtMGswRAYIKwYBBQUHMAKGOGh0dHA6Ly9jcnQuc2VjdGlnby5jb20v\n" + + "U2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nQ0FFMzYuY3J0MCMGCCsGAQUFBzABhhdo\n" + + "dHRwOi8vb2NzcC5zZWN0aWdvLmNvbTAKBggqhkjOPQQDAgNJADBGAiEAlEkiISLz\n" + + "PdJsFmVzJ2VZ8hnnVsOBXKbqISFQvIdguJoCIQCH4T0vwxn6uVkJpMvtxiMG/rYg\n" + + "jRFhfbxDcVee6likOw==\n" + + "-----END CERTIFICATE-----"; + + public void runTest(ValidatePathWithParams pathValidator) throws Exception { + // Validate valid + pathValidator.validate(new String[]{VALID, INT_VALID}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT_REVOKED}, + ValidatePathWithParams.Status.REVOKED, + "Thu Jun 05 10:27:19 PDT 2025", System.out); + } +} diff --git a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java index 434df6e013e35..32498bd747be8 100644 --- a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java +++ b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java @@ -28,7 +28,7 @@ * 8223499 8225392 8232019 8234245 8233223 8225068 8225069 8243321 8243320 * 8243559 8225072 8258630 8259312 8256421 8225081 8225082 8225083 8245654 * 8305975 8304760 8307134 8295894 8314960 8317373 8317374 8318759 8319187 - * 8321408 8316138 8341057 8303770 8350498 + * 8321408 8316138 8341057 8303770 8350498 8359170 * @summary Check root CA entries in cacerts file */ import java.io.ByteArrayInputStream; @@ -47,12 +47,12 @@ public class VerifyCACerts { + File.separator + "security" + File.separator + "cacerts"; // The numbers of certs now. - private static final int COUNT = 109; + private static final int COUNT = 113; // SHA-256 of cacerts, can be generated with // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95 private static final String CHECKSUM - = "07:21:E0:F8:EA:55:CC:93:24:2E:74:07:4B:6B:CE:F3:81:C3:BB:47:5B:85:A2:F1:9E:44:CD:C0:99:55:D7:5F"; + = "1E:63:88:DF:34:AD:7E:61:3F:06:BD:C4:DC:FE:05:52:9B:0D:86:6E:64:DA:E8:25:7C:C0:15:8F:31:C0:2C:78"; // Hex formatter to upper case with ":" delimiter private static final HexFormat HEX = HexFormat.ofDelimiter(":").withUpperCase(); @@ -279,6 +279,14 @@ public class VerifyCACerts { "C3:2F:FD:9F:46:F9:36:D1:6C:36:73:99:09:59:43:4B:9A:D6:0A:AF:BB:9E:7C:F3:36:54:F1:44:CC:1B:A1:43"); put("ssltlsrootrsa2022 [jdk]", "8F:AF:7D:2E:2C:B4:70:9B:B8:E0:B3:36:66:BF:75:A5:DD:45:B5:DE:48:0F:8E:A8:D4:BF:E6:BE:BC:17:F2:ED"); + put("sectigotlsrootr46 [jdk]", + "7B:B6:47:A6:2A:EE:AC:88:BF:25:7A:A5:22:D0:1F:FE:A3:95:E0:AB:45:C7:3F:93:F6:56:54:EC:38:F2:5A:06"); + put("sectigotlsroote46 [jdk]", + "C9:0F:26:F0:FB:1B:40:18:B2:22:27:51:9B:5C:A2:B5:3E:2C:A5:B3:BE:5C:F1:8E:FE:1B:EF:47:38:0C:53:83"); + put("sectigocodesignrootr46 [jdk]", + "7E:76:26:0A:E6:9A:55:D3:F0:60:B0:FD:18:B2:A8:C0:14:43:C8:7B:60:79:10:30:C9:FA:0B:05:85:10:1A:38"); + put("sectigocodesignroote46 [jdk]", + "8F:63:71:D8:CC:5A:A7:CA:14:96:67:A9:8B:54:96:39:89:51:E4:31:9F:7A:FB:CC:6A:66:0D:67:3E:43:8D:0B"); } }; From c254ea6e54de397015468d5249d161b324f2cf8d Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 12 Jun 2025 15:25:37 +0000 Subject: [PATCH 304/846] 8285773: Replace Algorithms.eatMemory(...) with WB.fullGC() in vmTestbase/gc/gctests/ReferencesGC/ReferencesGC.java Backport-of: 95d38bbd6b33a965b2312fd9409c6879ca2772ab --- .../gc/gctests/ReferencesGC/ReferencesGC.java | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/ReferencesGC/ReferencesGC.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/ReferencesGC/ReferencesGC.java index 0c75473bd22f6..d358185d2f268 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/ReferencesGC/ReferencesGC.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/ReferencesGC/ReferencesGC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -30,8 +30,12 @@ * * @library /vmTestbase * /test/lib + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm - * -XX:-UseGCOverheadLimit + * -Xbootclasspath/a:. + * -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI * gc.gctests.ReferencesGC.ReferencesGC * -range 200 * -ratio 0.9 @@ -41,12 +45,11 @@ package gc.gctests.ReferencesGC; import java.lang.ref.*; + +import jdk.test.whitebox.WhiteBox; import nsk.share.TestFailure; -import nsk.share.gc.Algorithms; import nsk.share.gc.GC; import nsk.share.gc.ThreadedGCTest; -import nsk.share.gc.gp.GarbageProducer; -import nsk.share.gc.gp.GarbageUtils; import nsk.share.test.ExecutionController; public class ReferencesGC extends ThreadedGCTest { @@ -87,7 +90,6 @@ private class Worker implements Runnable { WeakReference wr[] = new WeakReference[RANGE]; SoftReference sr[] = new SoftReference[RANGE]; PhantomReference phr[] = new PhantomReference[RANGE]; - GarbageProducer gp = GarbageUtils.getArrayProducers().get(0); int iter = 0; @Override @@ -98,21 +100,16 @@ public void run() { while (stresser.continueExecution()) { int totalLive = 0; - try { - refq = new ReferenceQueue(); - alive = new int[3]; - wrong = new int[3]; - for (int j = 0; j < RANGE; j++) { - holder[j] = new CircularLinkedList(); - holder[j].addNelements(300); - wr[j] = new WeakReference(holder[j], refq); - sr[j] = new SoftReference(holder[j], refq); - phr[j] = new PhantomReference(holder[j], refq); - } - } catch (OutOfMemoryError oome) { - // we should just skip the test - // the other thread could eat all memory - continue; + + refq = new ReferenceQueue(); + alive = new int[3]; + wrong = new int[3]; + for (int j = 0; j < RANGE; j++) { + holder[j] = new CircularLinkedList(); + holder[j].addNelements(300); + wr[j] = new WeakReference(holder[j], refq); + sr[j] = new SoftReference(holder[j], refq); + phr[j] = new PhantomReference(holder[j], refq); } for (int i = 0; i < RANGE; i++) { @@ -134,12 +131,11 @@ public void run() { holder[i] = null; } - Algorithms.eatMemory(stresser); + // WB.fullGC() is guaranteed to clear all kinds of weak references. + WhiteBox.getWhiteBox().fullGC(); if (!stresser.continueExecution()) { break; } - // At this point OOME was thrown and accordingly to spec - // all weak refs should be processed long waitTime = System.currentTimeMillis() + finalizationMaxTime; int totalQ = 0; From 5f5edeceb98cadae16017cd65d291d44c946a8ce Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 12 Jun 2025 15:26:44 +0000 Subject: [PATCH 305/846] 8285951: Replace Algorithms.eatMemory(...) with WB.fullGC() in vmTestbase_vm_gc_ref tests Backport-of: 61cb4b7448e96cb1ae218af4c39f44a5c66c0f9f --- .../PhantomReferenceEvilTest.java | 11 +- .../PhantomReferenceTest.java | 10 +- .../phantom001/phantom001.java | 234 ++++++++---------- .../phantom002/TEST.properties | 23 -- .../phantom002/TestDescription.java | 60 ----- .../SoftReference/soft001/soft001.java | 185 +++++++------- .../SoftReference/soft002/TEST.properties | 23 -- .../soft002/TestDescription.java | 57 ----- .../SoftReference/soft003/TEST.properties | 23 -- .../SoftReference/soft003/soft003.java | 14 +- .../SoftReference/soft004/TEST.properties | 23 -- .../SoftReference/soft004/soft004.java | 11 +- .../SoftReference/soft005/TEST.properties | 23 -- .../SoftReference/soft005/soft005.java | 13 +- .../WeakReference/weak001/weak001.java | 188 +++++++------- .../WeakReference/weak002/TEST.properties | 23 -- .../weak002/TestDescription.java | 57 ----- .../WeakReference/weak003/TEST.properties | 23 -- .../WeakReference/weak003/weak003.java | 17 +- .../WeakReference/weak004/TEST.properties | 23 -- .../WeakReference/weak004/weak004.java | 11 +- .../WeakReference/weak005/TEST.properties | 23 -- .../WeakReference/weak005/weak005.java | 13 +- .../WeakReference/weak006/TEST.properties | 23 -- .../WeakReference/weak006/weak006.java | 15 +- .../WeakReference/weak007/TEST.properties | 23 -- .../WeakReference/weak007/weak007.java | 13 +- .../WeakReferenceGC/WeakReferenceGC.java | 12 +- 28 files changed, 367 insertions(+), 807 deletions(-) delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom002/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom002/TestDescription.java delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft002/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft002/TestDescription.java delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft003/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft004/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft005/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak002/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak002/TestDescription.java delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak003/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak004/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak005/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak006/TEST.properties delete mode 100644 test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak007/TEST.properties diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/PhantomReferenceEvilTest/PhantomReferenceEvilTest.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/PhantomReferenceEvilTest/PhantomReferenceEvilTest.java index 6ce98d5b8ed4a..982b92b52f9aa 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/PhantomReferenceEvilTest/PhantomReferenceEvilTest.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/PhantomReferenceEvilTest/PhantomReferenceEvilTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -39,8 +39,10 @@ * * @library /vmTestbase * /test/lib + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm - * -XX:-UseGCOverheadLimit + * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * gc.gctests.PhantomReference.PhantomReferenceEvilTest.PhantomReferenceEvilTest */ @@ -52,11 +54,12 @@ import java.util.ArrayList; import java.util.Random; import java.util.HashMap; + +import jdk.test.whitebox.WhiteBox; import nsk.share.TestFailure; import nsk.share.gc.GC; import nsk.share.gc.GCTestBase; import nsk.share.gc.Memory; -import nsk.share.gc.gp.GarbageUtils; import nsk.share.test.Stresser; /** @@ -152,7 +155,7 @@ public final void run() { Stresser stresser = new Stresser(runParams.getStressOptions()); stresser.start(0); - GarbageUtils.eatMemory(stresser); + WhiteBox.getWhiteBox().fullGC(); if (!stresser.continueExecution()) { return; //we couldn't be sure that FullGC is triggered } diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/PhantomReferenceTest/PhantomReferenceTest.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/PhantomReferenceTest/PhantomReferenceTest.java index c76bc2263389e..7953499205551 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/PhantomReferenceTest/PhantomReferenceTest.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/PhantomReferenceTest/PhantomReferenceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -36,8 +36,10 @@ * * @library /vmTestbase * /test/lib + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm - * -XX:-UseGCOverheadLimit + * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * gc.gctests.PhantomReference.PhantomReferenceTest.PhantomReferenceTest */ @@ -49,6 +51,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Random; + +import jdk.test.whitebox.WhiteBox; import nsk.share.TestFailure; import nsk.share.gc.GC; import nsk.share.gc.GCTestBase; @@ -109,7 +113,7 @@ public final void run() { Stresser stresser = new Stresser(runParams.getStressOptions()); stresser.start(0); - GarbageUtils.eatMemory(stresser); + WhiteBox.getWhiteBox().fullGC(); if (!stresser.continueExecution()) { return; //we couldn't be sure that FullGC is triggered } diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom001/phantom001.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom001/phantom001.java index fb1967aa765c0..d45adbf4efd1a 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom001/phantom001.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom001/phantom001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -40,36 +40,35 @@ * PhantomRefence for NonbranchyTree and Referent calsses does not refer to * arrays, but to instances of the classes. * After that a thread performs next checks for the reference: - * 1. The reference is in queue after GC is provoked with - * Algorithms.eatMemory() method (a single thread eats the memory). + * 1. The reference is in queue after GC is provoked with WB.fullGC() * 2. reference.get() returns null. * 3. queue.poll() returns the reference that was created. * 4. queue.poll() again returns null. * 5. If the checked type is class (Referent), then it must be finalized, * since the reference is already enqueued. - * 6. reference.clear() does not throw any exception. * The test extends ThreadedGCTest and implements GarbageProducerAware and * MemoryStrategyAware interfaces. The corresponding javadoc documentation * for additional test configuration. * * @library /vmTestbase * /test/lib - * @run main/othervm gc.gctests.PhantomReference.phantom001.phantom001 -ms low + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.gctests.PhantomReference.phantom001.phantom001 */ package gc.gctests.PhantomReference.phantom001; import java.lang.ref.*; import java.time.LocalTime; + +import jdk.test.whitebox.WhiteBox; import nsk.share.gc.*; -import nsk.share.gc.gp.*; import nsk.share.gc.gp.string.InternedStringProducer; import nsk.share.gc.gp.string.RandomStringProducer; -public class phantom001 extends ThreadedGCTest implements GarbageProducerAware, MemoryStrategyAware { +public class phantom001 extends ThreadedGCTest { - private GarbageProducer garbageProducer; - private MemoryStrategy memoryStrategy; private InternedStringProducer internedStringProducer = new InternedStringProducer(new RandomStringProducer(10)); // Total number of types to test final static int TYPES_COUNT = 12; @@ -81,20 +80,12 @@ protected Runnable createRunnable(int i) { return new Test(); } - public void setGarbageProducer(GarbageProducer garbageProducer) { - this.garbageProducer = garbageProducer; - } - - public void setMemoryStrategy(MemoryStrategy memoryStrategy) { - this.memoryStrategy = memoryStrategy; - } - public static void main(String[] args) { GC.runTest(new phantom001(), args); } // The class implements the logic of the testcase - class Test implements Runnable, OOMStress { + class Test implements Runnable { int iteration; private volatile boolean finalized; @@ -124,131 +115,120 @@ private boolean shouldTerminate() { return !getExecutionController().continueExecution(); } - private void eatMemory(int initialFactor) { - GarbageUtils.eatMemory(getExecutionController(), - garbageProducer, - initialFactor, 10, 0); - } - public void run() { - try { - int code = iteration % TYPES_COUNT; - info("start code " + code); - ReferenceQueue queue = new ReferenceQueue(); - PhantomReference reference; - String type; - // Define a specific type for each thread to test - switch (code) { - case 0: - reference = new PhantomReference(new byte[SIZE], queue); - type = "byte"; - break; - case 1: - reference = new PhantomReference(new short[SIZE], queue); - type = "short"; - break; - case 2: - reference = new PhantomReference(new int[SIZE], queue); - type = "int"; - break; - case 3: - reference = new PhantomReference(new long[SIZE], queue); - type = "long"; - break; - case 4: - reference = new PhantomReference(new char[SIZE], queue); - type = "char"; - break; - case 5: - reference = new PhantomReference(new boolean[SIZE], queue); - type = "boolean"; - break; - case 6: - reference = new PhantomReference(new double[SIZE], queue); - type = "double"; - break; - case 7: - reference = new PhantomReference(new float[SIZE], queue); - type = "float"; - break; - case 8: - reference = new PhantomReference(new Object[SIZE], queue); - type = "Object"; - break; - case 9: - reference = new PhantomReference(new NonbranchyTree(SIZE, 0.3f, SIZE), - queue); - type = "NonbranchyTree"; - break; - case 10: - reference = new PhantomReference(internedStringProducer.create(SIZE), queue); - type = "InternedString"; - break; - default: - reference = new PhantomReference(new Referent(), queue); - type = "class"; - } - - int initialFactor = memoryStrategy.equals(MemoryStrategy.HIGH) ? 1 : (memoryStrategy.equals(MemoryStrategy.LOW) ? 10 : 2); - // If referent is finalizable, provoke GCs and wait for finalization. - if (type.equals("class")) { - progress("Waiting for finalization: " + type); - for (int checks = 0; !finalized && !shouldTerminate(); ++checks) { - // There are scenarios where one eatMemory() isn't enough, - // but 10 iterations really ought to be sufficient. - if (checks > 10) { - fail("Waiting for finalization: " + type); - return; - } - eatMemory(initialFactor); - // Give some time for finalizer to run. - try { - Thread.sleep(100); - } catch (InterruptedException e) {} - } - } + int code = iteration % TYPES_COUNT; + info("start code " + code); + ReferenceQueue queue = new ReferenceQueue(); + PhantomReference reference; + String type; + // Define a specific type for each thread to test + switch (code) { + case 0: + reference = new PhantomReference(new byte[SIZE], queue); + type = "byte"; + break; + case 1: + reference = new PhantomReference(new short[SIZE], queue); + type = "short"; + break; + case 2: + reference = new PhantomReference(new int[SIZE], queue); + type = "int"; + break; + case 3: + reference = new PhantomReference(new long[SIZE], queue); + type = "long"; + break; + case 4: + reference = new PhantomReference(new char[SIZE], queue); + type = "char"; + break; + case 5: + reference = new PhantomReference(new boolean[SIZE], queue); + type = "boolean"; + break; + case 6: + reference = new PhantomReference(new double[SIZE], queue); + type = "double"; + break; + case 7: + reference = new PhantomReference(new float[SIZE], queue); + type = "float"; + break; + case 8: + reference = new PhantomReference(new Object[SIZE], queue); + type = "Object"; + break; + case 9: + reference = new PhantomReference(new NonbranchyTree(SIZE, 0.3f, SIZE), + queue); + type = "NonbranchyTree"; + break; + case 10: + reference = new PhantomReference(internedStringProducer.create(SIZE), queue); + type = "InternedString"; + break; + default: + reference = new PhantomReference(new Referent(), queue); + type = "class"; + } - // Provoke GCs and wait for reference to be enqueued. - progress("Waiting for enqueue: " + type); - Reference polled = queue.poll(); - for (int checks = 0; polled == null && !shouldTerminate(); ++checks) { - // There are scenarios where one eatMemory() isn't enough, + // If referent is finalizable, provoke GCs and wait for finalization. + if (type.equals("class")) { + progress("Waiting for finalization: " + type); + for (int checks = 0; !finalized && !shouldTerminate(); ++checks) { + // There are scenarios where one WB.fillGC() isn't enough, // but 10 iterations really ought to be sufficient. if (checks > 10) { - fail("Waiting for enqueue: " + type); + fail("Waiting for finalization: " + type); return; } - eatMemory(initialFactor); - // Give some time for reference to be enqueued. + WhiteBox.getWhiteBox().fullGC(); + // Give some time for finalizer to run. try { - polled = queue.remove(100); + Thread.sleep(checks * 100); } catch (InterruptedException e) {} } + } - if (polled == null && shouldTerminate()) { - info("Terminated: " + type); + // Provoke GCs and wait for reference to be enqueued. + progress("Waiting for enqueue: " + type); + Reference polled = queue.poll(); + for (int checks = 0; polled == null && !shouldTerminate(); ++checks) { + // There are scenarios where one WB.fillGC() isn't enough, + // but 10 iterations really ought to be sufficient. + if (checks > 10) { + fail("Waiting for enqueue: " + type); return; } + WhiteBox.getWhiteBox().fullGC(); + // Give some time for reference to be enqueued. + try { + polled = queue.remove(checks * 100); + } catch (InterruptedException e) {} + } - // The polled reference must be equal to the one enqueued to - // the queue - if (polled != reference) { - fail("The original reference is not equal to polled reference."); - return; - } + if (polled == null && shouldTerminate()) { + info("Terminated: " + type); + return; + } - // queue.poll() once again must return null now, since there is - // only one reference in the queue - if (queue.poll() != null) { - fail("There are more than one reference in the queue."); - return; - } - progress("Finished: " + type); - } catch (OutOfMemoryError e) { - } finally { - iteration++; + // The polled reference must be equal to the one enqueued to + // the queue + if (polled != reference) { + fail("The original reference is not equal to polled reference."); + return; + } + + // queue.poll() once again must return null now, since there is + // only one reference in the queue + if (queue.poll() != null) { + fail("There are more than one reference in the queue."); + return; } + progress("Finished: " + type); + iteration++; } class Referent { diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom002/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom002/TEST.properties deleted file mode 100644 index 04b22a107ac61..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom002/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom002/TestDescription.java deleted file mode 100644 index 7e4baaf2fb1de..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom002/TestDescription.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2017, 2020, 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 - * @key stress randomness - * - * @summary converted from VM Testbase gc/gctests/PhantomReference/phantom002. - * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent] - * VM Testbase readme: - * DESCRIPTION - * The test checks that Garbage Collector correctly works with - * PhantomReferences. It also checks that no unexpected exceptions and errors - * are thrown or the JVM is not crashed. - * The test starts a number of threads. Each thread run tests for some time - * or serveral iterations. See javadoc StressOptions for configuration. - * First of all each thread defines what type to check (there are 11 types - * totally). As soon as the type is defined, a PhantomRefence is created that - * refers to an array of tested type and is registered with in a queue. A - * PhantomRefence for NonbranchyTree and Referent calsses does not refer to - * arrays, but to instances of the classes. - * After that a thread performs next checks for the reference: - * 1. The reference is in queue after GC is provoked with - * Algorithms.eatMemory() method (a single thread eats the memory). - * 2. reference.get() returns null. - * 3. queue.poll() returns the reference that was created. - * 4. queue.poll() again returns null. - * 5. If the checked type is class (Referent), then it must be finalized, - * since the reference is already enqueued. - * 6. reference.clear() does not throw any exception. - * The test extends ThreadedGCTest and implements GarbageProducerAware and - * MemoryStrategyAware interfaces. The corresponding javadoc documentation - * for additional test configuration. - * - * @library /vmTestbase - * /test/lib - * @run main/othervm gc.gctests.PhantomReference.phantom001.phantom001 -ms high - */ - diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft001/soft001.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft001/soft001.java index e20fff16e41a7..00e6ddcf77bce 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft001/soft001.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft001/soft001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -40,8 +40,7 @@ * SoftRefence for NonbranchyTree class does not refer to an array, but to * instances of the class. * After that a thread performs next checks for the reference: - * 1. The reference is in queue after GC is provoked with - * Algorithms.eatMemory() method (a single thread eats the memory). + * 1. The reference is in queue after GC is provoked with WB.fullGC() * 2. queue.remove() returns reference from the queue. * 3. queue.poll() returns null. * 4. reference.clear() does not throw any exception. @@ -51,7 +50,9 @@ * * @library /vmTestbase * /test/lib - * @run main/othervm gc.gctests.SoftReference.soft001.soft001 -ms low + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.gctests.SoftReference.soft001.soft001 */ package gc.gctests.SoftReference.soft001; @@ -60,23 +61,16 @@ import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; +import jdk.test.whitebox.WhiteBox; import nsk.share.gc.GC; import nsk.share.gc.NonbranchyTree; -import nsk.share.gc.OOMStress; import nsk.share.gc.ThreadedGCTest; -import nsk.share.gc.gp.GarbageProducer; -import nsk.share.gc.gp.GarbageProducerAware; -import nsk.share.gc.gp.GarbageUtils; -import nsk.share.gc.gp.MemoryStrategy; -import nsk.share.gc.gp.MemoryStrategyAware; import nsk.share.gc.gp.string.InternedStringProducer; import nsk.share.gc.gp.string.RandomStringProducer; -public class soft001 extends ThreadedGCTest implements GarbageProducerAware, MemoryStrategyAware { +public class soft001 extends ThreadedGCTest { - private GarbageProducer garbageProducer; private InternedStringProducer internedStringProducer = new InternedStringProducer(new RandomStringProducer(10)); - private MemoryStrategy memoryStrategy; // Total number of types to test final static int TYPES_COUNT = 11; // Size of array of each tested type. The constant also specifies the @@ -87,114 +81,107 @@ protected Runnable createRunnable(int i) { return new Test(); } - public void setGarbageProducer(GarbageProducer garbageProducer) { - this.garbageProducer = garbageProducer; - } - - public void setMemoryStrategy(MemoryStrategy memoryStrategy) { - this.memoryStrategy = memoryStrategy; - } public static void main(String[] args) { GC.runTest(new soft001(), args); } // The class implements the logic of the testcase - class Test implements Runnable, OOMStress { + class Test implements Runnable { int iteration; public void run() { - // Pre-allocated OOME message to avoid OOME when logging it - String oomMsg = "Ignored OOME in run()"; - try { - - log.info("iteration " + iteration); - ReferenceQueue queue = new ReferenceQueue(); - SoftReference reference; - int code = iteration % TYPES_COUNT; - String type; - // Define a specific type for each thread to test - switch (code) { - case 0: - reference = new SoftReference(new byte[SIZE], queue); - type = "byte"; - break; - case 1: - reference = new SoftReference(new short[SIZE], queue); - type = "short"; - break; - case 2: - reference = new SoftReference(new int[SIZE], queue); - type = "int"; - break; - case 3: - reference = new SoftReference(new long[SIZE], queue); - type = "long"; - break; - case 4: - reference = new SoftReference(new char[SIZE], queue); - type = "char"; - break; - case 5: - reference = new SoftReference(new boolean[SIZE], queue); - type = "boolean"; - break; - case 6: - reference = new SoftReference(new double[SIZE], queue); - type = "double"; - break; - case 7: - reference = new SoftReference(new float[SIZE], queue); - type = "float"; - break; - case 8: - reference = new SoftReference(new Object[SIZE], queue); - type = "Object"; - break; - case 9: - reference = new SoftReference(internedStringProducer.create(SIZE), queue); - type = "InternedString"; - break; - default: - reference = new SoftReference(new NonbranchyTree(SIZE, 0.3f, SIZE), - queue); - type = "NonbranchyTree"; - break; - } - int initialFactor = memoryStrategy.equals(MemoryStrategy.HIGH) ? 1 : (memoryStrategy.equals(MemoryStrategy.LOW) ? 10 : 2); - GarbageUtils.eatMemory(getExecutionController(), garbageProducer, initialFactor , 10, 0); + log.info("iteration " + iteration); + ReferenceQueue queue = new ReferenceQueue(); + SoftReference reference; + int code = iteration % TYPES_COUNT; + String type; + // Define a specific type for each thread to test + switch (code) { + case 0: + reference = new SoftReference(new byte[SIZE], queue); + type = "byte"; + break; + case 1: + reference = new SoftReference(new short[SIZE], queue); + type = "short"; + break; + case 2: + reference = new SoftReference(new int[SIZE], queue); + type = "int"; + break; + case 3: + reference = new SoftReference(new long[SIZE], queue); + type = "long"; + break; + case 4: + reference = new SoftReference(new char[SIZE], queue); + type = "char"; + break; + case 5: + reference = new SoftReference(new boolean[SIZE], queue); + type = "boolean"; + break; + case 6: + reference = new SoftReference(new double[SIZE], queue); + type = "double"; + break; + case 7: + reference = new SoftReference(new float[SIZE], queue); + type = "float"; + break; + case 8: + reference = new SoftReference(new Object[SIZE], queue); + type = "Object"; + break; + case 9: + reference = new SoftReference(internedStringProducer.create(SIZE), queue); + type = "InternedString"; + break; + default: + reference = new SoftReference(new NonbranchyTree(SIZE, 0.3f, SIZE), + queue); + type = "NonbranchyTree"; + break; + } + Reference polledReference = null; + for (int i = 0; i < 10 && polledReference == null; i++) { + WhiteBox.getWhiteBox().fullGC(); if (!getExecutionController().continueExecution()) { // we were interrrupted by stresser. just exit... return; } - Reference polledReference = null; try { - polledReference = queue.remove(); + polledReference = queue.remove(i * 100); } catch (InterruptedException e) { log.error("Unexpected InterruptedException during queue.remove()."); setFailed(true); } - // Check the reference and the queue - // The polled reference must be equal to the one enqueued to - // the queue + } - if (polledReference != reference) { - log.error("The original reference is not equal to polled reference."); - setFailed(true); - } + if (polledReference == null) { + log.error("Haven't polled reference after 10 GC."); + setFailed(true); + } - // queue.poll() once again must return null now, since there is - // only one reference in the queue - polledReference = queue.poll(); - if (polledReference != null) { - log.error("There are more than one references in the queue."); - setFailed(true); - } - reference.clear(); - } catch (OutOfMemoryError e) { - log.info(oomMsg); + // Check the reference and the queue + // The polled reference must be equal to the one enqueued to + // the queue + + if (polledReference != reference) { + log.error("The original reference is not equal to polled reference."); + setFailed(true); + } + + // queue.poll() once again must return null now, since there is + // only one reference in the queue + polledReference = queue.poll(); + if (polledReference != null) { + log.error("There are more than one references in the queue."); + setFailed(true); } + reference.clear(); iteration++; } } diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft002/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft002/TEST.properties deleted file mode 100644 index 04b22a107ac61..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft002/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft002/TestDescription.java deleted file mode 100644 index 4418a6c6f8df6..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft002/TestDescription.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2017, 2020, 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 - * @key stress randomness - * - * @summary converted from VM Testbase gc/gctests/SoftReference/soft002. - * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent] - * VM Testbase readme: - * DESCRIPTION - * The test checks that Garbage Collector correctly works with - * SoftReferences. It also checks that no unexpected exceptions and errors - * are thrown or the JVM is not crashed. - * The test starts a number of threads. Each thread run tests for some time - * or serveral iterations. See javadoc StressOptions for configuration. - * First of all each thread defines what type to check (there are 10 types - * totally). As soon as the type is defined, a SoftRefence is created that - * refers to an array of tested type and is registered with in a queue. A - * SoftRefence for NonbranchyTree class does not refer to an array, but to - * instances of the class. - * After that a thread performs next checks for the reference: - * 1. The reference is in queue after GC is provoked with - * Algorithms.eatMemory() method (a single thread eats the memory). - * 2. queue.remove() returns reference from the queue. - * 3. queue.poll() returns null. - * 4. reference.clear() does not throw any exception. - * The test extends ThreadedGCTest and implements GarbageProducerAware and - * MemoryStrategyAware interfaces. The corresponding javadoc documentation - * for additional test configuration. - * - * @library /vmTestbase - * /test/lib - * @run main/othervm gc.gctests.SoftReference.soft001.soft001 -ms high - */ - diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft003/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft003/TEST.properties deleted file mode 100644 index 04b22a107ac61..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft003/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft003/soft003.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft003/soft003.java index 0424a6d4e45cc..5cd961ad6dd43 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft003/soft003.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft003/soft003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -30,12 +30,16 @@ * * @library /vmTestbase * /test/lib - * @run main/othervm -XX:-UseGCOverheadLimit gc.gctests.SoftReference.soft003.soft003 -t 1 + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.gctests.SoftReference.soft003.soft003 -t 1 */ package gc.gctests.SoftReference.soft003; import java.lang.ref.Reference; + +import jdk.test.whitebox.WhiteBox; import nsk.share.test.*; import nsk.share.gc.*; import nsk.share.TestFailure; @@ -45,12 +49,12 @@ * Test that GC clears soft references before throwing OOM. * * This test creates a number of soft references, then provokes - * GC with Algorithms.eatMemory() and checks that all references + * GC with WB.fullGC() and checks that all references * have been cleared. */ public class soft003 extends ThreadedGCTest { - class Worker implements Runnable, OOMStress { + class Worker implements Runnable { private int arrayLength; private int objectSize = 100; @@ -60,7 +64,7 @@ public void run() { for (int i = 0; i < arrayLength; ++i) { references[i] = new SoftReference(new MemoryObject(LocalRandom.nextInt(objectSize))); } - Algorithms.eatMemory(getExecutionController()); + WhiteBox.getWhiteBox().fullGC(); if (!getExecutionController().continueExecution()) { return; } diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft004/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft004/TEST.properties deleted file mode 100644 index 04b22a107ac61..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft004/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft004/soft004.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft004/soft004.java index 9d6694589c1f7..ba9b6d7575069 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft004/soft004.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft004/soft004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -30,11 +30,14 @@ * * @library /vmTestbase * /test/lib - * @run main/othervm -XX:-UseGCOverheadLimit gc.gctests.SoftReference.soft004.soft004 -t 1 + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.gctests.SoftReference.soft004.soft004 -t 1 */ package gc.gctests.SoftReference.soft004; +import jdk.test.whitebox.WhiteBox; import nsk.share.gc.*; import java.lang.ref.SoftReference; @@ -48,7 +51,7 @@ */ public class soft004 extends ThreadedGCTest { - class Worker implements Runnable, OOMStress { + class Worker implements Runnable { private int arrayLength; private int objectSize = 100; @@ -66,7 +69,7 @@ public void run() { arrayLength = Memory.getArrayLength(runParams.getTestMemory() - objectSize, Memory.getReferenceSize() + objectSize); System.out.println("Array size: " + arrayLength); makeReferences(); - Algorithms.eatMemory(getExecutionController()); + WhiteBox.getWhiteBox().fullGC(); if (!getExecutionController().continueExecution()) { return; } diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft005/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft005/TEST.properties deleted file mode 100644 index 04b22a107ac61..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft005/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft005/soft005.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft005/soft005.java index 9486db64a64f9..4952854f1524d 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft005/soft005.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft005/soft005.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -30,11 +30,14 @@ * * @library /vmTestbase * /test/lib - * @run main/othervm -XX:-UseGCOverheadLimit gc.gctests.SoftReference.soft005.soft005 -t 1 + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.gctests.SoftReference.soft005.soft005 -t 1 */ package gc.gctests.SoftReference.soft005; +import jdk.test.whitebox.WhiteBox; import nsk.share.gc.*; import java.lang.ref.SoftReference; @@ -43,12 +46,12 @@ * * This test creates a number of soft references, * each of which points to the next, - * then provokes GC with Algorithms.eatMemory(). Then + * then provokes GC with WB.fullGC(). Then * checks that first reference has been cleared. */ public class soft005 extends ThreadedGCTest { - class Worker implements Runnable, OOMStress { + class Worker implements Runnable { private int length = 10000; private int objectSize = 10000; @@ -74,7 +77,7 @@ private void makeReferences() { public void run() { makeReferences(); - Algorithms.eatMemory(getExecutionController()); + WhiteBox.getWhiteBox().fullGC(); if (!getExecutionController().continueExecution()) { return; } diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak001/weak001.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak001/weak001.java index 9e0cc527f715e..5115c4ccd0272 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak001/weak001.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak001/weak001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -33,15 +33,14 @@ * WeakReferences. It also checks that no unexpected exceptions and errors * are thrown or the JVM is not crashed. * The test starts a number of threads. Each thread run tests for some time - * or serveral iterations. See javadoc StressOptions for configuration. + * or serveral iterations. * First of all each test defines what type to check (there are 10 types * totally). As soon as the type is defined, a WeakReference is created that * refers to an array of tested type and is registered with in a queue. A * WeakReference for NonbranchyTree class does not refer to an array, but to * instances of the class. * After that a thread performs next checks for the reference: - * 1. The reference is in queue after GC is provoked with - * Algorithms.eatMemory() method (a single thread eats the memory). + * 1. The reference is in queue after GC is provoked with WB.fullGC() * 2. queue.remove() returns reference from the queue. * 3. queue.poll() returns null. * 4. reference.clear() does not throw any exception. @@ -51,31 +50,27 @@ * * @library /vmTestbase * /test/lib - * @run main/othervm gc.gctests.WeakReference.weak001.weak001 -ms low + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.gctests.WeakReference.weak001.weak001 */ + package gc.gctests.WeakReference.weak001; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; +import jdk.test.whitebox.WhiteBox; import nsk.share.gc.GC; import nsk.share.gc.NonbranchyTree; -import nsk.share.gc.OOMStress; import nsk.share.gc.ThreadedGCTest; -import nsk.share.gc.gp.GarbageProducer; -import nsk.share.gc.gp.GarbageProducerAware; -import nsk.share.gc.gp.GarbageUtils; -import nsk.share.gc.gp.MemoryStrategy; -import nsk.share.gc.gp.MemoryStrategyAware; import nsk.share.gc.gp.string.InternedStringProducer; import nsk.share.gc.gp.string.RandomStringProducer; -public class weak001 extends ThreadedGCTest implements GarbageProducerAware, MemoryStrategyAware { +public class weak001 extends ThreadedGCTest { - private GarbageProducer garbageProducer; - private MemoryStrategy memoryStrategy; private InternedStringProducer internedStringProducer = new InternedStringProducer(new RandomStringProducer(10)); // Total number of types to test final static int TYPES_COUNT = 11; @@ -87,114 +82,105 @@ protected Runnable createRunnable(int i) { return new Test(); } - public void setGarbageProducer(GarbageProducer garbageProducer) { - this.garbageProducer = garbageProducer; - } - - public void setMemoryStrategy(MemoryStrategy memoryStrategy) { - this.memoryStrategy = memoryStrategy; - } - public static void main(String[] args) { GC.runTest(new weak001(), args); } // The class implements the logic of the testcase - class Test implements Runnable, OOMStress { + class Test implements Runnable { int iteration; public void run() { - // Pre-allocated OOME message to avoid OOME when logging it - String oomMsg = "Ignored OOME in run()"; - try { - - log.info("iteration " + iteration); - ReferenceQueue queue = new ReferenceQueue(); - WeakReference reference; - int code = iteration % TYPES_COUNT; - String type; - // Define a specific type for each thread to test - switch (code) { - case 0: - reference = new WeakReference(new byte[SIZE], queue); - type = "byte"; - break; - case 1: - reference = new WeakReference(new short[SIZE], queue); - type = "short"; - break; - case 2: - reference = new WeakReference(new int[SIZE], queue); - type = "int"; - break; - case 3: - reference = new WeakReference(new long[SIZE], queue); - type = "long"; - break; - case 4: - reference = new WeakReference(new char[SIZE], queue); - type = "char"; - break; - case 5: - reference = new WeakReference(new boolean[SIZE], queue); - type = "boolean"; - break; - case 6: - reference = new WeakReference(new double[SIZE], queue); - type = "double"; - break; - case 7: - reference = new WeakReference(new float[SIZE], queue); - type = "float"; - break; - case 8: - reference = new WeakReference(new Object[SIZE], queue); - type = "Object"; - break; - case 9: - reference = new WeakReference(internedStringProducer.create(SIZE), queue); - type = "InternedString"; - break; - default: - reference = new WeakReference(new NonbranchyTree(SIZE, 0.3f, SIZE), - queue); - type = "NonbranchyTree"; - break; - } - int initialFactor = memoryStrategy.equals(MemoryStrategy.HIGH) ? 1 : (memoryStrategy.equals(MemoryStrategy.LOW) ? 10 : 2); - GarbageUtils.eatMemory(getExecutionController(), garbageProducer, initialFactor , 10, 0); + log.info("iteration " + iteration); + ReferenceQueue queue = new ReferenceQueue(); + WeakReference reference; + int code = iteration % TYPES_COUNT; + String type; + // Define a specific type for each thread to test + switch (code) { + case 0: + reference = new WeakReference(new byte[SIZE], queue); + type = "byte"; + break; + case 1: + reference = new WeakReference(new short[SIZE], queue); + type = "short"; + break; + case 2: + reference = new WeakReference(new int[SIZE], queue); + type = "int"; + break; + case 3: + reference = new WeakReference(new long[SIZE], queue); + type = "long"; + break; + case 4: + reference = new WeakReference(new char[SIZE], queue); + type = "char"; + break; + case 5: + reference = new WeakReference(new boolean[SIZE], queue); + type = "boolean"; + break; + case 6: + reference = new WeakReference(new double[SIZE], queue); + type = "double"; + break; + case 7: + reference = new WeakReference(new float[SIZE], queue); + type = "float"; + break; + case 8: + reference = new WeakReference(new Object[SIZE], queue); + type = "Object"; + break; + case 9: + reference = new WeakReference(internedStringProducer.create(SIZE), queue); + type = "InternedString"; + break; + default: + reference = new WeakReference(new NonbranchyTree(SIZE, 0.3f, SIZE), + queue); + type = "NonbranchyTree"; + break; + } + Reference polledReference = null; + for (int i = 0; i < 10 && polledReference == null; i++) { + WhiteBox.getWhiteBox().fullGC(); if (!getExecutionController().continueExecution()) { // we were interrrupted by stresser. just exit... return; } - Reference polledReference = null; try { - polledReference = queue.remove(); + polledReference = queue.remove(i * 100); } catch (InterruptedException e) { log.error("Unexpected InterruptedException during queue.remove()."); setFailed(true); } - // Check the reference and the queue - // The polled reference must be equal to the one enqueued to - // the queue + } - if (polledReference != reference) { - log.error("The original reference is not equal to polled reference."); - setFailed(true); - } + if (polledReference == null) { + log.error("Haven't polled reference after 10 GC."); + setFailed(true); + } - // queue.poll() once again must return null now, since there is - // only one reference in the queue - polledReference = queue.poll(); - if (polledReference != null) { - log.error("There are more than one references in the queue."); - setFailed(true); - } - reference.clear(); - } catch (OutOfMemoryError e) { - log.info(oomMsg); + // Check the reference and the queue + // The polled reference must be equal to the one enqueued to + // the queue + if (polledReference != reference) { + log.error("The original reference is not equal to polled reference."); + setFailed(true); + } + + // queue.poll() once again must return null now, since there is + // only one reference in the queue + polledReference = queue.poll(); + if (polledReference != null) { + log.error("There are more than one references in the queue."); + setFailed(true); } + reference.clear(); iteration++; } } diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak002/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak002/TEST.properties deleted file mode 100644 index 04b22a107ac61..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak002/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak002/TestDescription.java deleted file mode 100644 index 26307420a2e2e..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak002/TestDescription.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2017, 2020, 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 - * @key stress randomness - * - * @summary converted from VM Testbase gc/gctests/WeakReference/weak002. - * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent] - * VM Testbase readme: - * DESCRIPTION - * The test checks that Garbage Collector correctly works with - * WeakReferences. It also checks that no unexpected exceptions and errors - * are thrown or the JVM is not crashed. - * The test starts a number of threads. Each thread run tests for some time - * or serveral iterations. See javadoc StressOptions for configuration. - * First of all each test defines what type to check (there are 10 types - * totally). As soon as the type is defined, a WeakReference is created that - * refers to an array of tested type and is registered with in a queue. A - * WeakReference for NonbranchyTree class does not refer to an array, but to - * instances of the class. - * After that a thread performs next checks for the reference: - * 1. The reference is in queue after GC is provoked with - * Algorithms.eatMemory() method (a single thread eats the memory). - * 2. queue.remove() returns reference from the queue. - * 3. queue.poll() returns null. - * 4. reference.clear() does not throw any exception. - * The test extends ThreadedGCTest and implements GarbageProducerAware and - * MemoryStrategyAware interfaces. The corresponding javadoc documentation - * for additional test configuration. - * - * @library /vmTestbase - * /test/lib - * @run main/othervm gc.gctests.WeakReference.weak001.weak001 -ms high - */ - diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak003/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak003/TEST.properties deleted file mode 100644 index 04b22a107ac61..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak003/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak003/weak003.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak003/weak003.java index d8b2c4db30019..b81cb85bd2b2a 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak003/weak003.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak003/weak003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -30,14 +30,17 @@ * * @library /vmTestbase * /test/lib - * @run main/othervm -XX:-UseGCOverheadLimit gc.gctests.WeakReference.weak003.weak003 -t 1 + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.gctests.WeakReference.weak003.weak003 -t 1 */ package gc.gctests.WeakReference.weak003; import java.lang.ref.Reference; + +import jdk.test.whitebox.WhiteBox; import nsk.share.test.*; -import nsk.share.TestFailure; import nsk.share.gc.*; import java.lang.ref.WeakReference; @@ -45,7 +48,7 @@ * Test that GC clears weak references before throwing OOM. * * This test creates a number of weak references, then provokes - * GC with Algorithms.eatMemory and checks that all references + * GC with WB.fullGC() and checks that all references * have been cleared. * * This assertion is not clearly stated in javadoc for WeakReference, @@ -54,7 +57,7 @@ */ public class weak003 extends ThreadedGCTest { - class Worker implements Runnable, OOMStress { + class Worker implements Runnable { private int arrayLength; private int objectSize = 100; @@ -64,7 +67,7 @@ public void run() { for (int i = 0; i < arrayLength; ++i) { references[i] = new WeakReference(new MemoryObject(LocalRandom.nextInt(objectSize))); } - Algorithms.eatMemory(getExecutionController()); + WhiteBox.getWhiteBox().fullGC(); if (!getExecutionController().continueExecution()) { return; } @@ -77,7 +80,7 @@ public void run() { } if (n != 0) { references = null; - throw new TestFailure("Some of the references have been not cleared: " + n); + throw new RuntimeException("Some of the references have been not cleared: " + n); } } diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak004/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak004/TEST.properties deleted file mode 100644 index 04b22a107ac61..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak004/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak004/weak004.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak004/weak004.java index 331c62c8650ee..bf86f5d8045d0 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak004/weak004.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak004/weak004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -30,11 +30,14 @@ * * @library /vmTestbase * /test/lib - * @run main/othervm -XX:-UseGCOverheadLimit gc.gctests.WeakReference.weak004.weak004 -t 1 + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.gctests.WeakReference.weak004.weak004 -t 1 */ package gc.gctests.WeakReference.weak004; +import jdk.test.whitebox.WhiteBox; import nsk.share.gc.*; import java.lang.ref.WeakReference; @@ -46,7 +49,7 @@ */ public class weak004 extends ThreadedGCTest { - class Worker implements Runnable, OOMStress { + class Worker implements Runnable { private int arrayLength; private int objectSize = 100; @@ -64,7 +67,7 @@ public void run() { arrayLength = Memory.getArrayLength(runParams.getTestMemory() - objectSize, Memory.getReferenceSize() + objectSize); System.out.println("Array size: " + arrayLength); makeReferences(); - Algorithms.eatMemory(getExecutionController()); + WhiteBox.getWhiteBox().fullGC(); if (!getExecutionController().continueExecution()) { return; } diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak005/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak005/TEST.properties deleted file mode 100644 index 04b22a107ac61..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak005/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak005/weak005.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak005/weak005.java index 90b8e731531b4..c1593aea9799c 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak005/weak005.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak005/weak005.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -30,11 +30,14 @@ * * @library /vmTestbase * /test/lib - * @run main/othervm -XX:-UseGCOverheadLimit gc.gctests.WeakReference.weak005.weak005 -t 1 + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.gctests.WeakReference.weak005.weak005 -t 1 */ package gc.gctests.WeakReference.weak005; +import jdk.test.whitebox.WhiteBox; import nsk.share.gc.*; import java.lang.ref.WeakReference; @@ -43,12 +46,12 @@ * * This test creates a number of weak references, * each of which points to the next, then provokes - * GC with Algorithms.eatMemory(). The test succeeds + * GC with WB.fullGC(). The test succeeds * if last reference has been cleared. */ public class weak005 extends ThreadedGCTest { - class Worker implements Runnable, OOMStress { + class Worker implements Runnable { private int length = 10000; private int objectSize = 10000; @@ -74,7 +77,7 @@ private void makeReferences() { public void run() { makeReferences(); - Algorithms.eatMemory(getExecutionController()); + WhiteBox.getWhiteBox().fullGC(); if (!getExecutionController().continueExecution()) { return; } diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak006/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak006/TEST.properties deleted file mode 100644 index 04b22a107ac61..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak006/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak006/weak006.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak006/weak006.java index ff88bcf3a97e9..fee38db3ba117 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak006/weak006.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak006/weak006.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -30,11 +30,14 @@ * * @library /vmTestbase * /test/lib - * @run main/othervm -XX:-UseGCOverheadLimit gc.gctests.WeakReference.weak006.weak006 -t 1 + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.gctests.WeakReference.weak006.weak006 -t 1 */ package gc.gctests.WeakReference.weak006; +import jdk.test.whitebox.WhiteBox; import nsk.share.test.*; import nsk.share.gc.*; import nsk.share.TestFailure; @@ -48,12 +51,12 @@ * * This test randomly creates a number of weak, soft, * phantom and strong references, each of which points - * to the next, then provokes GC with Algorithms.eatMemory(). + * to the next, then provokes GC with WB.fullGC(). * The test succedes if last reference has been cleared. */ public class weak006 extends ThreadedGCTest { - class Worker implements Runnable, OOMStress { + class Worker implements Runnable { private int length; private int objectSize = 100; @@ -122,7 +125,7 @@ private void makeReferences(int n) { public void run() { makeReferences(0); ExecutionController stresser = getExecutionController(); - Algorithms.eatMemory(stresser); + WhiteBox.getWhiteBox().fullGC(); if (!stresser.continueExecution()) { return; } @@ -131,7 +134,7 @@ public void run() { throw new TestFailure("Last weak reference has not been cleared"); } makeReferences(1); - Algorithms.eatMemory(stresser); + WhiteBox.getWhiteBox().fullGC(); if (!stresser.continueExecution()) { return; } diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak007/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak007/TEST.properties deleted file mode 100644 index 04b22a107ac61..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak007/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2017, 2018, 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak007/weak007.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak007/weak007.java index 9c18a84740d74..ced02b3b27c46 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak007/weak007.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReference/weak007/weak007.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -30,11 +30,14 @@ * * @library /vmTestbase * /test/lib - * @run main/othervm -XX:-UseGCOverheadLimit gc.gctests.WeakReference.weak007.weak007 -t 1 + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.gctests.WeakReference.weak007.weak007 -t 1 */ package gc.gctests.WeakReference.weak007; +import jdk.test.whitebox.WhiteBox; import nsk.share.TestFailure; import nsk.share.gc.*; import java.lang.ref.WeakReference; @@ -45,13 +48,13 @@ * * This test creates a number of weak references, * each of which points to the next, then provokes - * GC with Algorithms.eatMemory(). The test succeeds + * GC with WB.fullGC(). The test succeeds * if last reference has been cleared and the object * has been finalized. */ public class weak007 extends ThreadedGCTest { - class Worker implements Runnable, OOMStress { + class Worker implements Runnable { private int length = 10000; private int objectSize = 10000; @@ -71,7 +74,7 @@ private void makeReferences() { public void run() { makeReferences(); - Algorithms.eatMemory(getExecutionController()); + WhiteBox.getWhiteBox().fullGC(); if (getExecutionController().continueExecution()) { if (references[length - 1].get() != null) { throw new TestFailure("Last weak reference has not been cleared"); diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReferenceGC/WeakReferenceGC.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReferenceGC/WeakReferenceGC.java index 205897d90997e..7339fbe2d38fd 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReferenceGC/WeakReferenceGC.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/WeakReferenceGC/WeakReferenceGC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -82,7 +82,10 @@ * * @library /vmTestbase * /test/lib + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm + * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * gc.gctests.WeakReferenceGC.WeakReferenceGC * -numList 50 * -qFactor 0.9 @@ -94,10 +97,11 @@ import java.util.*; import java.lang.ref.*; + +import jdk.test.whitebox.WhiteBox; import nsk.share.TestFailure; import nsk.share.gc.GC; import nsk.share.gc.ThreadedGCTest; -import nsk.share.gc.gp.GarbageUtils; public class WeakReferenceGC extends ThreadedGCTest { @@ -198,9 +202,7 @@ private void persistentGC() { if (!getExecutionController().continueExecution()) { return; } - if (GarbageUtils.eatMemory(getExecutionController()) == 0) { - return; // We were unable to provoke OOME before timeout is over - } + WhiteBox.getWhiteBox().fullGC(); try { while ((numEnqueued < numLists) && (refQueue.remove(1000) != null)) { From 4dceddffdecd53bde8235e5714d71567017155bd Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 12 Jun 2025 15:44:17 +0000 Subject: [PATCH 306/846] 8294839: Disable StressLongCountedLoop in compiler/loopopts/TestRemoveEmptyLoop.java Backport-of: 73f06468ae7f9eebb8e37f2a534d2c19a8dac60d --- test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyLoop.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyLoop.java b/test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyLoop.java index 7f8810d9f338c..99548ae3fcf6f 100644 --- a/test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyLoop.java +++ b/test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyLoop.java @@ -28,6 +28,7 @@ * @summary Unexpected test result caused by C2 IdealLoopTree::do_remove_empty_loop * * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation + * -XX:StressLongCountedLoop=0 * compiler.loopopts.TestRemoveEmptyLoop */ From f453734a357b6699737c62260502aa68386483d5 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 12 Jun 2025 15:53:07 +0000 Subject: [PATCH 307/846] 8295005: compiler/loopopts/TestRemoveEmptyLoop.java fails with release VMs after JDK-8294839 Backport-of: 6ed74ef654f0b3e5c748895654d6925e2b832732 --- test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyLoop.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyLoop.java b/test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyLoop.java index 99548ae3fcf6f..9868797ab2248 100644 --- a/test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyLoop.java +++ b/test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyLoop.java @@ -28,7 +28,7 @@ * @summary Unexpected test result caused by C2 IdealLoopTree::do_remove_empty_loop * * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation - * -XX:StressLongCountedLoop=0 + * -XX:+IgnoreUnrecognizedVMOptions -XX:StressLongCountedLoop=0 * compiler.loopopts.TestRemoveEmptyLoop */ From ac37921d9222e9828377407624a48f9ed25f7c3d Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 12 Jun 2025 15:54:50 +0000 Subject: [PATCH 308/846] 8264207: CodeStrings does not honour fixed address assumption. 8273539: [PPC64] gtest build error after JDK-8264207 Reviewed-by: mdoerr, phh Backport-of: 7bd4f496b493b804990615f6ce2cb1b4abd29a86 --- src/hotspot/share/asm/codeBuffer.cpp | 475 +++++++++++------- src/hotspot/share/asm/codeBuffer.hpp | 142 +++--- src/hotspot/share/code/codeBlob.cpp | 10 +- src/hotspot/share/code/codeBlob.hpp | 32 +- src/hotspot/share/code/icBuffer.hpp | 3 +- src/hotspot/share/code/stubs.cpp | 13 +- src/hotspot/share/code/stubs.hpp | 15 +- src/hotspot/share/compiler/disassembler.cpp | 55 +- src/hotspot/share/compiler/disassembler.hpp | 5 +- src/hotspot/share/interpreter/interpreter.cpp | 29 +- src/hotspot/share/interpreter/interpreter.hpp | 17 +- .../share/interpreter/interpreterRuntime.cpp | 3 +- src/hotspot/share/runtime/sharedRuntime.cpp | 3 +- .../share/runtime/stubCodeGenerator.cpp | 16 +- .../share/runtime/stubCodeGenerator.hpp | 31 +- test/hotspot/gtest/code/test_codestrings.cpp | 263 ++++++++++ 16 files changed, 760 insertions(+), 352 deletions(-) create mode 100644 test/hotspot/gtest/code/test_codestrings.cpp diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index 2d219121cc7dd..48ae3a73523a5 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -88,7 +88,7 @@ typedef CodeBuffer::csize_t csize_t; // file-local definition // External buffer, in a predefined CodeBlob. // Important: The code_start must be taken exactly, and not realigned. -CodeBuffer::CodeBuffer(CodeBlob* blob) { +CodeBuffer::CodeBuffer(CodeBlob* blob) DEBUG_ONLY(: Scrubber(this, sizeof(*this))) { // Provide code buffer with meaningful name initialize_misc(blob->name()); initialize(blob->content_begin(), blob->content_size()); @@ -126,11 +126,9 @@ void CodeBuffer::initialize(csize_t code_size, csize_t locs_size) { CodeBuffer::~CodeBuffer() { verify_section_allocation(); - // If we allocate our code buffer from the CodeCache - // via a BufferBlob, and it's not permanent, then - // free the BufferBlob. - // The rest of the memory will be freed when the ResourceObj - // is released. + // If we allocated our code buffer from the CodeCache via a BufferBlob, and + // it's not permanent, then free the BufferBlob. The rest of the memory + // will be freed when the ResourceObj is released. for (CodeBuffer* cb = this; cb != NULL; cb = cb->before_expand()) { // Previous incarnations of this buffer are held live, so that internal // addresses constructed before expansions will not be confused. @@ -140,18 +138,9 @@ CodeBuffer::~CodeBuffer() { // free any overflow storage delete _overflow_arena; } - // Claim is that stack allocation ensures resources are cleaned up. - // This is resource clean up, let's hope that all were properly copied out. - NOT_PRODUCT(free_strings();) + NOT_PRODUCT(clear_strings()); -#ifdef ASSERT - // Save allocation type to execute assert in ~ResourceObj() - // which is called after this destructor. assert(_default_oop_recorder.allocated_on_stack(), "should be embedded object"); - ResourceObj::allocation_type at = _default_oop_recorder.get_allocation_type(); - Copy::fill_to_bytes(this, sizeof(*this), badResourceValue); - ResourceObj::set_allocation_type((address)(&_default_oop_recorder), at); -#endif } void CodeBuffer::initialize_oop_recorder(OopRecorder* r) { @@ -715,8 +704,9 @@ void CodeBuffer::copy_code_to(CodeBlob* dest_blob) { relocate_code_to(&dest); - // transfer strings and comments from buffer to blob - NOT_PRODUCT(dest_blob->set_strings(_code_strings);) + // Share assembly remarks and debug strings with the blob. + NOT_PRODUCT(dest_blob->use_remarks(_asm_remarks)); + NOT_PRODUCT(dest_blob->use_strings(_dbg_strings)); // Done moving code bytes; were they the right size? assert((int)align_up(dest.total_content_size(), oopSize) == dest_blob->content_size(), "sanity"); @@ -989,221 +979,342 @@ void CodeBuffer::log_section_sizes(const char* name) { } #ifndef PRODUCT - -void CodeBuffer::block_comment(intptr_t offset, const char * comment) { +void CodeBuffer::block_comment(ptrdiff_t offset, const char* comment) { if (_collect_comments) { - _code_strings.add_comment(offset, comment); + const char* str = _asm_remarks.insert(offset, comment); + postcond(str != comment); } } const char* CodeBuffer::code_string(const char* str) { - return _code_strings.add_string(str); + const char* tmp = _dbg_strings.insert(str); + postcond(tmp != str); + return tmp; } -class CodeString: public CHeapObj { - private: - friend class CodeStrings; - const char * _string; - CodeString* _next; - CodeString* _prev; - intptr_t _offset; - - static long allocated_code_strings; - - ~CodeString() { - assert(_next == NULL && _prev == NULL, "wrong interface for freeing list"); - allocated_code_strings--; - log_trace(codestrings)("Freeing CodeString [%s] (%p)", _string, (void*)_string); - os::free((void*)_string); +void CodeBuffer::decode() { + ttyLocker ttyl; + Disassembler::decode(decode_begin(), insts_end(), tty NOT_PRODUCT(COMMA &asm_remarks())); + _decode_begin = insts_end(); +} + +void CodeSection::print(const char* name) { + csize_t locs_size = locs_end() - locs_start(); + tty->print_cr(" %7s.code = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d)", + name, p2i(start()), p2i(end()), p2i(limit()), size(), capacity()); + tty->print_cr(" %7s.locs = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d) point=%d", + name, p2i(locs_start()), p2i(locs_end()), p2i(locs_limit()), locs_size, locs_capacity(), locs_point_off()); + if (PrintRelocations) { + RelocIterator iter(this); + iter.print(); } +} - bool is_comment() const { return _offset >= 0; } +void CodeBuffer::print() { + if (this == NULL) { + tty->print_cr("NULL CodeBuffer pointer"); + return; + } + tty->print_cr("CodeBuffer:"); + for (int n = 0; n < (int)SECT_LIMIT; n++) { + // print each section + CodeSection* cs = code_section(n); + cs->print(code_section_name(n)); + } +} + +// ----- CHeapString ----------------------------------------------------------- + +class CHeapString : public CHeapObj { public: - CodeString(const char * string, intptr_t offset = -1) - : _next(NULL), _prev(NULL), _offset(offset) { - allocated_code_strings++; - _string = os::strdup(string, mtCode); - log_trace(codestrings)("Created CodeString [%s] (%p)", _string, (void*)_string); + CHeapString(const char* str) : _string(os::strdup(str)) {} + ~CHeapString() { + os::free((void*)_string); + _string = nullptr; } + const char* string() const { return _string; } + + private: + const char* _string; +}; - const char * string() const { return _string; } - intptr_t offset() const { assert(_offset >= 0, "offset for non comment?"); return _offset; } - CodeString* next() const { return _next; } +// ----- AsmRemarkCollection --------------------------------------------------- - void set_next(CodeString* next) { - _next = next; - if (next != NULL) { - next->_prev = this; - } +class AsmRemarkCollection : public CHeapObj { + public: + AsmRemarkCollection() : _ref_cnt(1), _remarks(nullptr), _next(nullptr) {} + ~AsmRemarkCollection() { + assert(is_empty(), "Must 'clear()' before deleting!"); + assert(_ref_cnt == 0, "No uses must remain when deleting!"); + } + AsmRemarkCollection* reuse() { + precond(_ref_cnt > 0); + return _ref_cnt++, this; } - CodeString* first_comment() { - if (is_comment()) { - return this; - } else { - return next_comment(); + const char* insert(uint offset, const char* remark); + const char* lookup(uint offset) const; + const char* next(uint offset) const; + + bool is_empty() const { return _remarks == nullptr; } + uint clear(); + + private: + struct Cell : CHeapString { + Cell(const char* remark, uint offset) : + CHeapString(remark), offset(offset), prev(nullptr), next(nullptr) {} + void push_back(Cell* cell) { + Cell* head = this; + Cell* tail = prev; + tail->next = cell; + cell->next = head; + cell->prev = tail; + prev = cell; } + uint offset; + Cell* prev; + Cell* next; + }; + uint _ref_cnt; + Cell* _remarks; + // Using a 'mutable' iteration pointer to allow 'const' on lookup/next (that + // does not change the state of the list per se), supportig a simplistic + // iteration scheme. + mutable Cell* _next; +}; + +// ----- DbgStringCollection --------------------------------------------------- + +class DbgStringCollection : public CHeapObj { + public: + DbgStringCollection() : _ref_cnt(1), _strings(nullptr) {} + ~DbgStringCollection() { + assert(is_empty(), "Must 'clear()' before deleting!"); + assert(_ref_cnt == 0, "No uses must remain when deleting!"); } - CodeString* next_comment() const { - CodeString* s = _next; - while (s != NULL && !s->is_comment()) { - s = s->_next; - } - return s; + DbgStringCollection* reuse() { + precond(_ref_cnt > 0); + return _ref_cnt++, this; } + + const char* insert(const char* str); + const char* lookup(const char* str) const; + + bool is_empty() const { return _strings == nullptr; } + uint clear(); + + private: + struct Cell : CHeapString { + Cell(const char* dbgstr) : + CHeapString(dbgstr), prev(nullptr), next(nullptr) {} + void push_back(Cell* cell) { + Cell* head = this; + Cell* tail = prev; + tail->next = cell; + cell->next = head; + cell->prev = tail; + prev = cell; + } + Cell* prev; + Cell* next; + }; + uint _ref_cnt; + Cell* _strings; }; -// For tracing statistics. Will use raw increment/decrement, so it might not be -// exact -long CodeString::allocated_code_strings = 0; +// ----- AsmRemarks ------------------------------------------------------------ +// +// Acting as interface to reference counted mapping [offset -> remark], where +// offset is a byte offset into an instruction stream (CodeBuffer, CodeBlob or +// other memory buffer) and remark is a string (comment). +// +AsmRemarks::AsmRemarks() : _remarks(new AsmRemarkCollection()) { + assert(_remarks != nullptr, "Allocation failure!"); +} -CodeString* CodeStrings::find(intptr_t offset) const { - CodeString* a = _strings->first_comment(); - while (a != NULL && a->offset() != offset) { - a = a->next_comment(); - } - return a; +AsmRemarks::~AsmRemarks() { + assert(_remarks == nullptr, "Must 'clear()' before deleting!"); } -// Convenience for add_comment. -CodeString* CodeStrings::find_last(intptr_t offset) const { - CodeString* a = _strings_last; - while (a != NULL && !(a->is_comment() && a->offset() == offset)) { - a = a->_prev; - } - return a; +const char* AsmRemarks::insert(uint offset, const char* remstr) { + precond(remstr != nullptr); + return _remarks->insert(offset, remstr); } -void CodeStrings::add_comment(intptr_t offset, const char * comment) { - check_valid(); - CodeString* c = new CodeString(comment, offset); - CodeString* inspos = (_strings == NULL) ? NULL : find_last(offset); +bool AsmRemarks::is_empty() const { + return _remarks->is_empty(); +} - if (inspos != NULL) { - // insert after already existing comments with same offset - c->set_next(inspos->next()); - inspos->set_next(c); - } else { - // no comments with such offset, yet. Insert before anything else. - c->set_next(_strings); - _strings = c; - } - if (c->next() == NULL) { - _strings_last = c; - } +void AsmRemarks::share(const AsmRemarks &src) { + precond(is_empty()); + clear(); + _remarks = src._remarks->reuse(); } -// Deep copy of CodeStrings for consistent memory management. -void CodeStrings::copy(CodeStrings& other) { - log_debug(codestrings)("Copying %d Codestring(s)", other.count()); - - other.check_valid(); - check_valid(); - assert(is_null(), "Cannot copy onto non-empty CodeStrings"); - CodeString* n = other._strings; - CodeString** ps = &_strings; - CodeString* prev = NULL; - while (n != NULL) { - if (n->is_comment()) { - *ps = new CodeString(n->string(), n->offset()); - } else { - *ps = new CodeString(n->string()); - } - (*ps)->_prev = prev; - prev = *ps; - ps = &((*ps)->_next); - n = n->next(); +void AsmRemarks::clear() { + if (_remarks->clear() == 0) { + delete _remarks; } + _remarks = nullptr; } -const char* CodeStrings::_prefix = " ;; "; // default: can be changed via set_prefix - -void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const { - check_valid(); - if (_strings != NULL) { - CodeString* c = find(offset); - while (c && c->offset() == offset) { - stream->bol(); - stream->print("%s", _prefix); - // Don't interpret as format strings since it could contain % - stream->print_raw(c->string()); - stream->bol(); // advance to next line only if string didn't contain a cr() at the end. - c = c->next_comment(); - } +uint AsmRemarks::print(uint offset, outputStream* strm) const { + uint count = 0; + const char* prefix = " ;; "; + const char* remstr = _remarks->lookup(offset); + while (remstr != nullptr) { + strm->bol(); + strm->print("%s", prefix); + // Don't interpret as format strings since it could contain '%'. + strm->print_raw(remstr); + // Advance to next line iff string didn't contain a cr() at the end. + strm->bol(); + remstr = _remarks->next(offset); + count++; } + return count; +} + +// ----- DbgStrings ------------------------------------------------------------ +// +// Acting as interface to reference counted collection of (debug) strings used +// in the code generated, and thus requiring a fixed address. +// +DbgStrings::DbgStrings() : _strings(new DbgStringCollection()) { + assert(_strings != nullptr, "Allocation failure!"); +} + +DbgStrings::~DbgStrings() { + assert(_strings == nullptr, "Must 'clear()' before deleting!"); +} + +const char* DbgStrings::insert(const char* dbgstr) { + const char* str = _strings->lookup(dbgstr); + return str != nullptr ? str : _strings->insert(dbgstr); +} + +bool DbgStrings::is_empty() const { + return _strings->is_empty(); +} + +void DbgStrings::share(const DbgStrings &src) { + precond(is_empty()); + _strings = src._strings->reuse(); } -int CodeStrings::count() const { - int i = 0; - CodeString* s = _strings; - while (s != NULL) { - i++; - s = s->_next; +void DbgStrings::clear() { + if (_strings->clear() == 0) { + delete _strings; } - return i; + _strings = nullptr; } -// Also sets is_null() -void CodeStrings::free() { - log_debug(codestrings)("Freeing %d out of approx. %ld CodeString(s), ", count(), CodeString::allocated_code_strings); - CodeString* n = _strings; - while (n) { - // unlink the node from the list saving a pointer to the next - CodeString* p = n->next(); - n->set_next(NULL); - if (p != NULL) { - assert(p->_prev == n, "missing prev link"); - p->_prev = NULL; - } - delete n; - n = p; +// ----- AsmRemarkCollection --------------------------------------------------- + +const char* AsmRemarkCollection::insert(uint offset, const char* remstr) { + precond(remstr != nullptr); + Cell* cell = new Cell { remstr, offset }; + if (is_empty()) { + cell->prev = cell; + cell->next = cell; + _remarks = cell; + } else { + _remarks->push_back(cell); } - set_null_and_invalidate(); + return cell->string(); } -const char* CodeStrings::add_string(const char * string) { - check_valid(); - CodeString* s = new CodeString(string); - s->set_next(_strings); - if (_strings == NULL) { - _strings_last = s; +const char* AsmRemarkCollection::lookup(uint offset) const { + _next = _remarks; + return next(offset); +} + +const char* AsmRemarkCollection::next(uint offset) const { + if (_next != nullptr) { + Cell* i = _next; + do { + if (i->offset == offset) { + _next = i->next == _remarks ? nullptr : i->next; + return i->string(); + } + i = i->next; + } while (i != _remarks); + _next = nullptr; } - _strings = s; - assert(s->string() != NULL, "should have a string"); - return s->string(); + return nullptr; } -void CodeBuffer::decode() { - ttyLocker ttyl; - Disassembler::decode(decode_begin(), insts_end(), tty NOT_PRODUCT(COMMA &strings())); - _decode_begin = insts_end(); +uint AsmRemarkCollection::clear() { + precond(_ref_cnt > 0); + if (--_ref_cnt > 0) { + return _ref_cnt; + } + if (!is_empty()) { + uint count = 0; + Cell* i = _remarks; + do { + Cell* next = i->next; + delete i; + i = next; + count++; + } while (i != _remarks); + + log_debug(codestrings)("Clear %u asm-remark%s.", count, count == 1 ? "" : "s"); + _remarks = nullptr; + } + return 0; // i.e. _ref_cnt == 0 } -void CodeSection::print(const char* name) { - csize_t locs_size = locs_end() - locs_start(); - tty->print_cr(" %7s.code = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d)", - name, p2i(start()), p2i(end()), p2i(limit()), size(), capacity()); - tty->print_cr(" %7s.locs = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d) point=%d", - name, p2i(locs_start()), p2i(locs_end()), p2i(locs_limit()), locs_size, locs_capacity(), locs_point_off()); - if (PrintRelocations) { - RelocIterator iter(this); - iter.print(); +// ----- DbgStringCollection --------------------------------------------------- + +const char* DbgStringCollection::insert(const char* dbgstr) { + precond(dbgstr != nullptr); + Cell* cell = new Cell { dbgstr }; + + if (is_empty()) { + cell->prev = cell; + cell->next = cell; + _strings = cell; + } else { + _strings->push_back(cell); } + return cell->string(); } -void CodeBuffer::print() { - if (this == NULL) { - tty->print_cr("NULL CodeBuffer pointer"); - return; +const char* DbgStringCollection::lookup(const char* dbgstr) const { + precond(dbgstr != nullptr); + if (_strings != nullptr) { + Cell* i = _strings; + do { + if (strcmp(i->string(), dbgstr) == 0) { + return i->string(); + } + i = i->next; + } while (i != _strings); } + return nullptr; +} - tty->print_cr("CodeBuffer:"); - for (int n = 0; n < (int)SECT_LIMIT; n++) { - // print each section - CodeSection* cs = code_section(n); - cs->print(code_section_name(n)); +uint DbgStringCollection::clear() { + precond(_ref_cnt > 0); + if (--_ref_cnt > 0) { + return _ref_cnt; + } + if (!is_empty()) { + uint count = 0; + Cell* i = _strings; + do { + Cell* next = i->next; + delete i; + i = next; + count++; + } while (i != _strings); + + log_debug(codestrings)("Clear %u dbg-string%s.", count, count == 1 ? "" : "s"); + _strings = nullptr; } + return 0; // i.e. _ref_cnt == 0 } -#endif // PRODUCT +#endif // not PRODUCT diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index 89dc70ae2d09e..773994a01af9e 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -31,7 +31,6 @@ #include "utilities/debug.hpp" #include "utilities/macros.hpp" -class CodeStrings; class PhaseCFG; class Compile; class BufferBlob; @@ -273,70 +272,75 @@ class CodeSection { #endif //PRODUCT }; -class CodeString; -class CodeStrings { -private: + #ifndef PRODUCT - CodeString* _strings; - CodeString* _strings_last; -#ifdef ASSERT - // Becomes true after copy-out, forbids further use. - bool _defunct; // Zero bit pattern is "valid", see memset call in decode_env::decode_env -#endif - static const char* _prefix; // defaults to " ;; " - CodeString* find(intptr_t offset) const; - CodeString* find_last(intptr_t offset) const; +class AsmRemarkCollection; +class DbgStringCollection; - void set_null_and_invalidate() { - _strings = NULL; - _strings_last = NULL; -#ifdef ASSERT - _defunct = true; -#endif - } -#endif +// The assumption made here is that most code remarks (or comments) added to +// the generated assembly code are unique, i.e. there is very little gain in +// trying to share the strings between the different offsets tracked in a +// buffer (or blob). -public: - CodeStrings() { -#ifndef PRODUCT - _strings = NULL; - _strings_last = NULL; -#ifdef ASSERT - _defunct = false; -#endif -#endif - } +class AsmRemarks { + public: + AsmRemarks(); + ~AsmRemarks(); -#ifndef PRODUCT - bool is_null() { -#ifdef ASSERT - return _strings == NULL; -#else - return true; -#endif - } + const char* insert(uint offset, const char* remstr); - const char* add_string(const char * string); + bool is_empty() const; - void add_comment(intptr_t offset, const char * comment); - void print_block_comment(outputStream* stream, intptr_t offset) const; - int count() const; - // COPY strings from other to this; leave other valid. - void copy(CodeStrings& other); - // FREE strings; invalidate this. - void free(); + void share(const AsmRemarks &src); + void clear(); + uint print(uint offset, outputStream* strm = tty) const; - // Guarantee that _strings are used at most once; assign and free invalidate a buffer. - inline void check_valid() const { - assert(!_defunct, "Use of invalid CodeStrings"); - } + // For testing purposes only. + const AsmRemarkCollection* ref() const { return _remarks; } - static void set_prefix(const char *prefix) { - _prefix = prefix; +private: + AsmRemarkCollection* _remarks; +}; + +// The assumption made here is that the number of debug strings (with a fixed +// address requirement) is a rather small set per compilation unit. + +class DbgStrings { + public: + DbgStrings(); + ~DbgStrings(); + + const char* insert(const char* dbgstr); + + bool is_empty() const; + + void share(const DbgStrings &src); + void clear(); + + // For testing purposes only. + const DbgStringCollection* ref() const { return _strings; } + +private: + DbgStringCollection* _strings; +}; +#endif // not PRODUCT + + +#ifdef ASSERT +#include "utilities/copy.hpp" + +class Scrubber { + public: + Scrubber(void* addr, size_t size) : _addr(addr), _size(size) {} + ~Scrubber() { + Copy::fill_to_bytes(_addr, _size, badResourceValue); } -#endif // !PRODUCT + private: + void* _addr; + size_t _size; }; +#endif // ASSERT // A CodeBuffer describes a memory space into which assembly // code is generated. This memory space usually occupies the @@ -362,7 +366,7 @@ class CodeStrings { // Instructions and data in one section can contain relocatable references to // addresses in a sibling section. -class CodeBuffer: public StackObj { +class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) { friend class CodeSection; friend class StubCodeGenerator; @@ -411,7 +415,8 @@ class CodeBuffer: public StackObj { address _last_insn; // used to merge consecutive memory barriers, loads or stores. #ifndef PRODUCT - CodeStrings _code_strings; + AsmRemarks _asm_remarks; + DbgStrings _dbg_strings; bool _collect_comments; // Indicate if we need to collect block comments at all. address _decode_begin; // start address for decode address decode_begin(); @@ -429,7 +434,6 @@ class CodeBuffer: public StackObj { #ifndef PRODUCT _decode_begin = NULL; - _code_strings = CodeStrings(); // Collect block comments, but restrict collection to cases where a disassembly is output. _collect_comments = ( PrintAssembly || PrintStubCode @@ -484,7 +488,9 @@ class CodeBuffer: public StackObj { public: // (1) code buffer referring to pre-allocated instruction memory - CodeBuffer(address code_start, csize_t code_size) { + CodeBuffer(address code_start, csize_t code_size) + DEBUG_ONLY(: Scrubber(this, sizeof(*this))) + { assert(code_start != NULL, "sanity"); initialize_misc("static buffer"); initialize(code_start, code_size); @@ -497,14 +503,18 @@ class CodeBuffer: public StackObj { // (3) code buffer allocating codeBlob memory for code & relocation // info but with lazy initialization. The name must be something // informative. - CodeBuffer(const char* name) { + CodeBuffer(const char* name) + DEBUG_ONLY(: Scrubber(this, sizeof(*this))) + { initialize_misc(name); } // (4) code buffer allocating codeBlob memory for code & relocation // info. The name must be something informative and code_size must // include both code and stubs sizes. - CodeBuffer(const char* name, csize_t code_size, csize_t locs_size) { + CodeBuffer(const char* name, csize_t code_size, csize_t locs_size) + DEBUG_ONLY(: Scrubber(this, sizeof(*this))) + { initialize_misc(name); initialize(code_size, locs_size); } @@ -634,12 +644,12 @@ class CodeBuffer: public StackObj { void clear_last_insn() { set_last_insn(NULL); } #ifndef PRODUCT - CodeStrings& strings() { return _code_strings; } + AsmRemarks &asm_remarks() { return _asm_remarks; } + DbgStrings &dbg_strings() { return _dbg_strings; } - void free_strings() { - if (!_code_strings.is_null()) { - _code_strings.free(); // sets _strings Null as a side-effect. - } + void clear_strings() { + _asm_remarks.clear(); + _dbg_strings.clear(); } #endif @@ -666,7 +676,7 @@ class CodeBuffer: public StackObj { } } - void block_comment(intptr_t offset, const char * comment) PRODUCT_RETURN; + void block_comment(ptrdiff_t offset, const char* comment) PRODUCT_RETURN; const char* code_string(const char* str) PRODUCT_RETURN_(return NULL;); // Log a little info about section usage in the CodeBuffer diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index 41a582f43ec1a..57990cdc53253 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -94,7 +94,6 @@ CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& la _oop_maps(oop_maps), _caller_must_gc_arguments(caller_must_gc_arguments), _name(name) - NOT_PRODUCT(COMMA _strings(CodeStrings())) { assert(is_aligned(layout.size(), oopSize), "unaligned size"); assert(is_aligned(layout.header_size(), oopSize), "unaligned size"); @@ -107,7 +106,7 @@ CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& la S390_ONLY(_ctable_offset = 0;) // avoid uninitialized fields } -CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments) : +CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, CodeBuffer* cb /*UNUSED*/, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments) : _type(type), _size(layout.size()), _header_size(layout.header_size()), @@ -122,7 +121,6 @@ CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& la _relocation_end(layout.relocation_end()), _caller_must_gc_arguments(caller_must_gc_arguments), _name(name) - NOT_PRODUCT(COMMA _strings(CodeStrings())) { assert(is_aligned(_size, oopSize), "unaligned size"); assert(is_aligned(_header_size, oopSize), "unaligned size"); @@ -164,7 +162,8 @@ RuntimeBlob::RuntimeBlob( void CodeBlob::flush() { FREE_C_HEAP_ARRAY(unsigned char, _oop_maps); _oop_maps = NULL; - NOT_PRODUCT(_strings.free();) + NOT_PRODUCT(_asm_remarks.clear()); + NOT_PRODUCT(_dbg_strings.clear()); } void CodeBlob::set_oop_maps(OopMapSet* p) { @@ -191,7 +190,8 @@ void RuntimeBlob::trace_new_stub(RuntimeBlob* stub, const char* name1, const cha tty->print_cr("- - - [BEGIN] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); tty->print_cr("Decoding %s " PTR_FORMAT " [" PTR_FORMAT ", " PTR_FORMAT "] (%d bytes)", stub_id, p2i(stub), p2i(stub->code_begin()), p2i(stub->code_end()), stub->code_size()); - Disassembler::decode(stub->code_begin(), stub->code_end(), tty); + Disassembler::decode(stub->code_begin(), stub->code_end(), tty + NOT_PRODUCT(COMMA &stub->asm_remarks())); if ((stub->oop_maps() != NULL) && AbstractDisassembler::show_structs()) { tty->print_cr("- - - [OOP MAPS]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); stub->oop_maps()->print(); diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index 104e04fba5339..3994fbfd42c74 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -112,15 +112,22 @@ class CodeBlob { const char* _name; S390_ONLY(int _ctable_offset;) - NOT_PRODUCT(CodeStrings _strings;) +#ifndef PRODUCT + AsmRemarks _asm_remarks; + DbgStrings _dbg_strings; + + ~CodeBlob() { + _asm_remarks.clear(); + _dbg_strings.clear(); + } +#endif // not PRODUCT CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments); CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments); public: // Only used by unit test. - CodeBlob() - : _type(compiler_none) {} + CodeBlob() : _type(compiler_none) {} // Returns the space needed for CodeBlob static unsigned int allocation_size(CodeBuffer* cb, int header_size); @@ -232,18 +239,21 @@ class CodeBlob { void dump_for_addr(address addr, outputStream* st, bool verbose) const; void print_code(); - // Print the comment associated with offset on stream, if there is one + // Print to stream, any comments associated with offset. virtual void print_block_comment(outputStream* stream, address block_begin) const { - #ifndef PRODUCT - intptr_t offset = (intptr_t)(block_begin - code_begin()); - _strings.print_block_comment(stream, offset); - #endif +#ifndef PRODUCT + ptrdiff_t offset = block_begin - code_begin(); + assert(offset >= 0, "Expecting non-negative offset!"); + _asm_remarks.print(uint(offset), stream); +#endif } #ifndef PRODUCT - void set_strings(CodeStrings& strings) { - _strings.copy(strings); - } + AsmRemarks &asm_remarks() { return _asm_remarks; } + DbgStrings &dbg_strings() { return _dbg_strings; } + + void use_remarks(AsmRemarks &remarks) { _asm_remarks.share(remarks); } + void use_strings(DbgStrings &strings) { _dbg_strings.share(strings); } #endif }; diff --git a/src/hotspot/share/code/icBuffer.hpp b/src/hotspot/share/code/icBuffer.hpp index eb45e043bf19e..cda634b42fe95 100644 --- a/src/hotspot/share/code/icBuffer.hpp +++ b/src/hotspot/share/code/icBuffer.hpp @@ -56,8 +56,7 @@ class ICStub: public Stub { protected: friend class ICStubInterface; // This will be called only by ICStubInterface - void initialize(int size, - CodeStrings strings) { _size = size; _ic_site = NULL; } + void initialize(int size) { _size = size; _ic_site = NULL; } void finalize(); // called when a method is removed // General info diff --git a/src/hotspot/share/code/stubs.cpp b/src/hotspot/share/code/stubs.cpp index 2c48ae424a355..d941f9c2073b4 100644 --- a/src/hotspot/share/code/stubs.cpp +++ b/src/hotspot/share/code/stubs.cpp @@ -109,8 +109,7 @@ Stub* StubQueue::stub_containing(address pc) const { Stub* StubQueue::request_committed(int code_size) { Stub* s = request(code_size); - CodeStrings strings; - if (s != NULL) commit(code_size, strings); + if (s != NULL) commit(code_size); return s; } @@ -127,8 +126,7 @@ Stub* StubQueue::request(int requested_code_size) { assert(_buffer_limit == _buffer_size, "buffer must be fully usable"); if (_queue_end + requested_size <= _buffer_size) { // code fits in at the end => nothing to do - CodeStrings strings; - stub_initialize(s, requested_size, strings); + stub_initialize(s, requested_size); return s; } else { // stub doesn't fit in at the queue end @@ -145,8 +143,7 @@ Stub* StubQueue::request(int requested_code_size) { // Queue: |XXX|.......|XXXXXXX|.......| // ^0 ^end ^begin ^limit ^size s = current_stub(); - CodeStrings strings; - stub_initialize(s, requested_size, strings); + stub_initialize(s, requested_size); return s; } // Not enough space left @@ -155,12 +152,12 @@ Stub* StubQueue::request(int requested_code_size) { } -void StubQueue::commit(int committed_code_size, CodeStrings& strings) { +void StubQueue::commit(int committed_code_size) { assert(committed_code_size > 0, "committed_code_size must be > 0"); int committed_size = align_up(stub_code_size_to_size(committed_code_size), CodeEntryAlignment); Stub* s = current_stub(); assert(committed_size <= stub_size(s), "committed size must not exceed requested size"); - stub_initialize(s, committed_size, strings); + stub_initialize(s, committed_size); _queue_end += committed_size; _number_of_stubs++; if (_mutex != NULL) _mutex->unlock(); diff --git a/src/hotspot/share/code/stubs.hpp b/src/hotspot/share/code/stubs.hpp index 60ca20679cc60..411695ef0ef0e 100644 --- a/src/hotspot/share/code/stubs.hpp +++ b/src/hotspot/share/code/stubs.hpp @@ -60,8 +60,7 @@ class Stub { public: // Initialization/finalization - void initialize(int size, - CodeStrings& strings) { ShouldNotCallThis(); } // called to initialize/specify the stub's size + void initialize(int size) { ShouldNotCallThis(); } // called to initialize/specify the stub's size void finalize() { ShouldNotCallThis(); } // called before the stub is deallocated // General info/converters @@ -94,8 +93,7 @@ class Stub { class StubInterface: public CHeapObj { public: // Initialization/finalization - virtual void initialize(Stub* self, int size, - CodeStrings& strings) = 0; // called after creation (called twice if allocated via (request, commit)) + virtual void initialize(Stub* self, int size) = 0; // called after creation (called twice if allocated via (request, commit)) virtual void finalize(Stub* self) = 0; // called before deallocation // General info/converters @@ -123,8 +121,7 @@ class StubInterface: public CHeapObj { \ public: \ /* Initialization/finalization */ \ - virtual void initialize(Stub* self, int size, \ - CodeStrings& strings) { cast(self)->initialize(size, strings); } \ + virtual void initialize(Stub* self, int size) { cast(self)->initialize(size); } \ virtual void finalize(Stub* self) { cast(self)->finalize(); } \ \ /* General info */ \ @@ -163,8 +160,7 @@ class StubQueue: public CHeapObj { Stub* current_stub() const { return stub_at(_queue_end); } // Stub functionality accessed via interface - void stub_initialize(Stub* s, int size, - CodeStrings& strings) { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size, strings); } + void stub_initialize(Stub* s, int size) { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size); } void stub_finalize(Stub* s) { _stub_interface->finalize(s); } int stub_size(Stub* s) const { return _stub_interface->size(s); } bool stub_contains(Stub* s, address pc) const { return _stub_interface->code_begin(s) <= pc && pc < _stub_interface->code_end(s); } @@ -191,8 +187,7 @@ class StubQueue: public CHeapObj { // Stub allocation (atomic transactions) Stub* request_committed(int code_size); // request a stub that provides exactly code_size space for code Stub* request(int requested_code_size); // request a stub with a (maximum) code space - locks the queue - void commit (int committed_code_size, - CodeStrings& strings); // commit the previously requested stub - unlocks the queue + void commit (int committed_code_size); // commit the previously requested stub - unlocks the queue // Stub deallocation void remove_first(); // remove the first stub in the queue diff --git a/src/hotspot/share/compiler/disassembler.cpp b/src/hotspot/share/compiler/disassembler.cpp index 4cc2f8781c336..c7ff3877ba87e 100644 --- a/src/hotspot/share/compiler/disassembler.cpp +++ b/src/hotspot/share/compiler/disassembler.cpp @@ -72,7 +72,10 @@ class decode_env { bool _print_help; bool _helpPrinted; static bool _optionsParsed; - NOT_PRODUCT(const CodeStrings* _strings;) +#ifndef PRODUCT + const AsmRemarks* _remarks; // Used with start/end range to provide code remarks. + ptrdiff_t _disp; // Adjustment to offset -> remark mapping. +#endif enum { tabspacing = 8 @@ -214,7 +217,8 @@ class decode_env { decode_env(nmethod* code, outputStream* output); // Constructor for a 'decode_env' to decode an arbitrary // piece of memory, hopefully containing code. - decode_env(address start, address end, outputStream* output, const CodeStrings* strings = NULL); + decode_env(address start, address end, outputStream* output + NOT_PRODUCT(COMMA const AsmRemarks* remarks = NULL COMMA ptrdiff_t disp = 0)); // Add 'original_start' argument which is the the original address // the instructions were located at (if this is not equal to 'start'). @@ -332,11 +336,11 @@ decode_env::decode_env(CodeBlob* code, outputStream* output) : _print_file_name(false), _print_help(false), _helpPrinted(false) - NOT_PRODUCT(COMMA _strings(NULL)) { - + NOT_PRODUCT(COMMA _remarks(nullptr)) + NOT_PRODUCT(COMMA _disp(0)) +{ memset(_option_buf, 0, sizeof(_option_buf)); process_options(_output); - } decode_env::decode_env(nmethod* code, outputStream* output) : @@ -354,15 +358,17 @@ decode_env::decode_env(nmethod* code, outputStream* output) : _print_file_name(false), _print_help(false), _helpPrinted(false) - NOT_PRODUCT(COMMA _strings(NULL)) { - + NOT_PRODUCT(COMMA _remarks(nullptr)) + NOT_PRODUCT(COMMA _disp(0)) +{ memset(_option_buf, 0, sizeof(_option_buf)); process_options(_output); } // Constructor for a 'decode_env' to decode a memory range [start, end) // of unknown origin, assuming it contains code. -decode_env::decode_env(address start, address end, outputStream* output, const CodeStrings* c) : +decode_env::decode_env(address start, address end, outputStream* output + NOT_PRODUCT(COMMA const AsmRemarks* remarks COMMA ptrdiff_t disp)) : _output(output ? output : tty), _codeBlob(NULL), _nm(NULL), @@ -377,8 +383,9 @@ decode_env::decode_env(address start, address end, outputStream* output, const C _print_file_name(false), _print_help(false), _helpPrinted(false) - NOT_PRODUCT(COMMA _strings(c)) { - + NOT_PRODUCT(COMMA _remarks(remarks)) + NOT_PRODUCT(COMMA _disp(disp)) +{ assert(start < end, "Range must have a positive size, [" PTR_FORMAT ".." PTR_FORMAT ").", p2i(start), p2i(end)); memset(_option_buf, 0, sizeof(_option_buf)); process_options(_output); @@ -645,15 +652,15 @@ void decode_env::print_insn_labels() { //---< Block comments for nmethod >--- // Outputs a bol() before and a cr() after, but only if a comment is printed. // Prints nmethod_section_label as well. - if (_nm != NULL) { + if (_nm != nullptr) { _nm->print_block_comment(st, p); } - if (_codeBlob != NULL) { + else if (_codeBlob != nullptr) { _codeBlob->print_block_comment(st, p); } #ifndef PRODUCT - if (_strings != NULL) { - _strings->print_block_comment(st, (intptr_t)(p - _start)); + else if (_remarks != nullptr) { + _remarks->print((p - _start) + _disp, st); } #endif } @@ -930,7 +937,8 @@ void Disassembler::decode(nmethod* nm, outputStream* st) { } // Decode a range, given as [start address, end address) -void Disassembler::decode(address start, address end, outputStream* st, const CodeStrings* c) { +void Disassembler::decode(address start, address end, outputStream* st + NOT_PRODUCT(COMMA const AsmRemarks* remarks COMMA ptrdiff_t disp)) { #if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY) //---< Test memory before decoding >--- if (!os::is_readable_range(start, end)) { @@ -943,22 +951,9 @@ void Disassembler::decode(address start, address end, outputStream* st, const Co if (is_abstract()) { AbstractDisassembler::decode_abstract(start, end, st, Assembler::instr_maxlen()); - return; - } - -// Don't do that fancy stuff. If we just have two addresses, live with it -// and treat the memory contents as "amorphic" piece of code. -#if 0 - CodeBlob* cb = CodeCache::find_blob_unsafe(start); - if (cb != NULL) { - // If we have an CodeBlob at hand, - // call the specialized decoder directly. - decode(cb, st, c); - } else -#endif - { + } else { // This seems to be just a chunk of memory. - decode_env env(start, end, st, c); + decode_env env(start, end, st NOT_PRODUCT(COMMA remarks COMMA disp)); env.output()->print_cr("--------------------------------------------------------------------------------"); env.decode_instructions(start, end); env.output()->print_cr("--------------------------------------------------------------------------------"); diff --git a/src/hotspot/share/compiler/disassembler.hpp b/src/hotspot/share/compiler/disassembler.hpp index 93228a565b4bf..57fc376b21853 100644 --- a/src/hotspot/share/compiler/disassembler.hpp +++ b/src/hotspot/share/compiler/disassembler.hpp @@ -99,11 +99,12 @@ class Disassembler : public AbstractDisassembler { } // Directly disassemble code blob. - static void decode(CodeBlob *cb, outputStream* st = NULL); + static void decode(CodeBlob* cb, outputStream* st = NULL); // Directly disassemble nmethod. static void decode(nmethod* nm, outputStream* st = NULL); // Disassemble an arbitrary memory range. - static void decode(address start, address end, outputStream* st = NULL, const CodeStrings* = NULL); + static void decode(address start, address end, outputStream* st = NULL + NOT_PRODUCT(COMMA const AsmRemarks* remarks = NULL COMMA ptrdiff_t disp = 0)); static void _hook(const char* file, int line, class MacroAssembler* masm); diff --git a/src/hotspot/share/interpreter/interpreter.cpp b/src/hotspot/share/interpreter/interpreter.cpp index 7805f39e18f07..1c8570516c4ed 100644 --- a/src/hotspot/share/interpreter/interpreter.cpp +++ b/src/hotspot/share/interpreter/interpreter.cpp @@ -47,18 +47,21 @@ # define __ _masm-> -//------------------------------------------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // Implementation of InterpreterCodelet void InterpreterCodelet::initialize(const char* description, Bytecodes::Code bytecode) { - _description = description; - _bytecode = bytecode; -} - - -void InterpreterCodelet::verify() { + _description = description; + _bytecode = bytecode; +#ifndef PRODUCT + AsmRemarks* arp = new(&_asm_remarks) AsmRemarks(); + DbgStrings* dsp = new(&_dbg_strings) DbgStrings(); + postcond(arp == &_asm_remarks); + postcond(dsp == &_dbg_strings); +#endif } +void InterpreterCodelet::verify() {} void InterpreterCodelet::print_on(outputStream* st) const { ttyLocker ttyl; @@ -75,7 +78,7 @@ void InterpreterCodelet::print_on(outputStream* st) const { if (PrintInterpreter) { st->cr(); - Disassembler::decode(code_begin(), code_end(), st DEBUG_ONLY(COMMA &_strings)); + Disassembler::decode(code_begin(), code_end(), st NOT_PRODUCT(COMMA &_asm_remarks)); } } @@ -104,9 +107,13 @@ CodeletMark::~CodeletMark() { // Commit Codelet. int committed_code_size = (*_masm)->code()->pure_insts_size(); - if (committed_code_size) { - CodeStrings cs NOT_PRODUCT(= (*_masm)->code()->strings()); - AbstractInterpreter::code()->commit(committed_code_size, cs); + if (committed_code_size > 0) { + // This is the ONE place where we pickup any assembly remarks and debug + // strings, and propagate these to the codelet. + NOT_PRODUCT(_clet->use_remarks((*_masm)->code()->asm_remarks())); + NOT_PRODUCT(_clet->use_strings((*_masm)->code()->dbg_strings())); + + AbstractInterpreter::code()->commit(committed_code_size); } // Make sure nobody can use _masm outside a CodeletMark lifespan. *_masm = NULL; diff --git a/src/hotspot/share/interpreter/interpreter.hpp b/src/hotspot/share/interpreter/interpreter.hpp index 2e1333b08b570..b639aa9759e3e 100644 --- a/src/hotspot/share/interpreter/interpreter.hpp +++ b/src/hotspot/share/interpreter/interpreter.hpp @@ -46,17 +46,15 @@ class InterpreterCodelet: public Stub { friend class VMStructs; friend class CodeCacheDumper; // possible extension [do not remove] private: - NOT_PRODUCT(CodeStrings _strings;) // Comments for annotating assembler output. const char* _description; // A description of the codelet, for debugging & printing int _size; // The codelet size in bytes Bytecodes::Code _bytecode; // Associated bytecode, if any + NOT_PRODUCT(AsmRemarks _asm_remarks;) // Comments for annotating assembler output. + NOT_PRODUCT(DbgStrings _dbg_strings;) // Debug strings used in generated code. public: // Initialization/finalization - void initialize(int size, - CodeStrings& strings) { _size = size; - NOT_PRODUCT(_strings = CodeStrings();) - NOT_PRODUCT(_strings.copy(strings);) } + void initialize(int size) { _size = size; } void finalize() { ShouldNotCallThis(); } // General info/converters @@ -79,6 +77,15 @@ class InterpreterCodelet: public Stub { int code_size() const { return code_end() - code_begin(); } const char* description() const { return _description; } Bytecodes::Code bytecode() const { return _bytecode; } +#ifndef PRODUCT + ~InterpreterCodelet() { + // InterpreterCodelets reside in the StubQueue and should not be deleted, + // nor are they ever finalized (see above). + ShouldNotCallThis(); + } + void use_remarks(AsmRemarks &remarks) { _asm_remarks.share(remarks); } + void use_strings(DbgStrings &strings) { _dbg_strings.share(strings); } +#endif }; // Define a prototype interface diff --git a/src/hotspot/share/interpreter/interpreterRuntime.cpp b/src/hotspot/share/interpreter/interpreterRuntime.cpp index d66ed24d86257..611ed66862264 100644 --- a/src/hotspot/share/interpreter/interpreterRuntime.cpp +++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp @@ -1345,7 +1345,8 @@ void SignatureHandlerLibrary::add(const methodHandle& method) { fingerprint, buffer.insts_size()); if (buffer.insts_size() > 0) { - Disassembler::decode(handler, handler + buffer.insts_size()); + Disassembler::decode(handler, handler + buffer.insts_size(), tty + NOT_PRODUCT(COMMA &buffer.asm_remarks())); } #ifndef PRODUCT address rh_begin = Interpreter::result_handler(method()->result_type()); diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index 9af4b513a9994..e4ff6fa9df425 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -2945,7 +2945,8 @@ AdapterHandlerEntry* AdapterHandlerLibrary::create_adapter(AdapterBlob*& new_ada if (Verbose || PrintStubCode) { address first_pc = entry->base_address(); if (first_pc != NULL) { - Disassembler::decode(first_pc, first_pc + insts_size); + Disassembler::decode(first_pc, first_pc + insts_size, tty + NOT_PRODUCT(COMMA &new_adapter->asm_remarks())); tty->cr(); } } diff --git a/src/hotspot/share/runtime/stubCodeGenerator.cpp b/src/hotspot/share/runtime/stubCodeGenerator.cpp index 965c8a9e575ec..fb546bc8ebee7 100644 --- a/src/hotspot/share/runtime/stubCodeGenerator.cpp +++ b/src/hotspot/share/runtime/stubCodeGenerator.cpp @@ -78,7 +78,8 @@ StubCodeGenerator::~StubCodeGenerator() { CodeBuffer* cbuf = _masm->code(); CodeBlob* blob = CodeCache::find_blob_unsafe(cbuf->insts()->start()); if (blob != NULL) { - blob->set_strings(cbuf->strings()); + blob->use_remarks(cbuf->asm_remarks()); + blob->use_strings(cbuf->dbg_strings()); } #endif } @@ -90,15 +91,15 @@ void StubCodeGenerator::stub_prolog(StubCodeDesc* cdesc) { void StubCodeGenerator::stub_epilog(StubCodeDesc* cdesc) { if (_print_code) { #ifndef PRODUCT - // Find the code strings in the outer CodeBuffer. - CodeBuffer *outer_cbuf = _masm->code_section()->outer(); - CodeStrings* cs = &outer_cbuf->strings(); + // Find the assembly code remarks in the outer CodeBuffer. + AsmRemarks* remarks = &_masm->code_section()->outer()->asm_remarks(); #endif ttyLocker ttyl; tty->print_cr("- - - [BEGIN] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); cdesc->print_on(tty); tty->cr(); - Disassembler::decode(cdesc->begin(), cdesc->end(), tty NOT_PRODUCT(COMMA cs)); + Disassembler::decode(cdesc->begin(), cdesc->end(), tty + NOT_PRODUCT(COMMA remarks COMMA cdesc->disp())); tty->print_cr("- - - [END] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); tty->cr(); } @@ -119,6 +120,11 @@ StubCodeMark::~StubCodeMark() { _cgen->assembler()->flush(); _cdesc->set_end(_cgen->assembler()->pc()); assert(StubCodeDesc::_list == _cdesc, "expected order on list"); +#ifndef PRODUCT + address base = _cgen->assembler()->code_section()->outer()->insts_begin(); + address head = _cdesc->begin(); + _cdesc->set_disp(uint(head - base)); +#endif _cgen->stub_epilog(_cdesc); Forte::register_stub(_cdesc->name(), _cdesc->begin(), _cdesc->end()); diff --git a/src/hotspot/share/runtime/stubCodeGenerator.hpp b/src/hotspot/share/runtime/stubCodeGenerator.hpp index dae1eccc6f9ac..061e2d0b71df6 100644 --- a/src/hotspot/share/runtime/stubCodeGenerator.hpp +++ b/src/hotspot/share/runtime/stubCodeGenerator.hpp @@ -38,19 +38,18 @@ class StubCodeDesc: public CHeapObj { private: - static StubCodeDesc* _list; // the list of all descriptors - static bool _frozen; // determines whether _list modifications are allowed + static StubCodeDesc* _list; // the list of all descriptors + static bool _frozen; // determines whether _list modifications are allowed - StubCodeDesc* _next; // the next element in the linked list - const char* _group; // the group to which the stub code belongs - const char* _name; // the name assigned to the stub code - address _begin; // points to the first byte of the stub code (included) - address _end; // points to the first byte after the stub code (excluded) + StubCodeDesc* _next; // the next element in the linked list + const char* _group; // the group to which the stub code belongs + const char* _name; // the name assigned to the stub code + address _begin; // points to the first byte of the stub code (included) + address _end; // points to the first byte after the stub code (excluded) + uint _disp; // Displacement relative base address in buffer. - void set_end(address end) { - assert(_begin <= end, "begin & end not properly ordered"); - _end = end; - } + friend class StubCodeMark; + friend class StubCodeGenerator; void set_begin(address begin) { assert(begin >= _begin, "begin may not decrease"); @@ -58,8 +57,12 @@ class StubCodeDesc: public CHeapObj { _begin = begin; } - friend class StubCodeMark; - friend class StubCodeGenerator; + void set_end(address end) { + assert(_begin <= end, "begin & end not properly ordered"); + _end = end; + } + + void set_disp(uint disp) { _disp = disp; } public: static StubCodeDesc* first() { return _list; } @@ -76,6 +79,7 @@ class StubCodeDesc: public CHeapObj { _name = name; _begin = begin; _end = end; + _disp = 0; _list = this; }; @@ -85,6 +89,7 @@ class StubCodeDesc: public CHeapObj { const char* name() const { return _name; } address begin() const { return _begin; } address end() const { return _end; } + uint disp() const { return _disp; } int size_in_bytes() const { return _end - _begin; } bool contains(address pc) const { return _begin <= pc && pc < _end; } void print_on(outputStream* st) const; diff --git a/test/hotspot/gtest/code/test_codestrings.cpp b/test/hotspot/gtest/code/test_codestrings.cpp new file mode 100644 index 0000000000000..fb45c36c5f231 --- /dev/null +++ b/test/hotspot/gtest/code/test_codestrings.cpp @@ -0,0 +1,263 @@ +/* + * 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. + */ + +#include "precompiled.hpp" + +#ifndef PRODUCT +#ifndef ZERO + +#include "asm/macroAssembler.inline.hpp" +#include "compiler/disassembler.hpp" +#include "memory/resourceArea.hpp" +#include "unittest.hpp" + +#include + +static const char* replace_addr_expr(const char* str) +{ + // Remove any address expression "0x0123456789abcdef" found in order to + // aid string comparison. Also remove any trailing printout from a padded + // buffer. + + std::basic_string tmp = std::regex_replace(str, std::regex("0x[0-9a-fA-F]+"), ""); + std::basic_string red = std::regex_replace(tmp, std::regex("\\s+:\\s+\\.inst\\t ; undefined"), ""); + + return os::strdup(red.c_str()); +} + +static const char* delete_header_line(const char* str) +{ + // Remove (second) header line in output, e.g.: + // Decoding CodeBlob, name: CodeStringTest, at [, ] 8 bytes\n + + std::basic_string red = std::regex_replace(str, std::regex("Decoding.+bytes\\n"), ""); + + return os::strdup(red.c_str()); +} + +static void asm_remarks_check(const AsmRemarks &rem1, + const AsmRemarks &rem2) +{ + ASSERT_EQ(rem1.ref(), rem2.ref()) << "Should share the same collection."; +} + +static void dbg_strings_check(const DbgStrings &dbg1, + const DbgStrings &dbg2) +{ + ASSERT_EQ(dbg1.ref(), dbg2.ref()) << "Should share the same collection."; +} + +static void disasm_string_check(CodeBuffer* cbuf, CodeBlob* blob) +{ + if (Disassembler::is_abstract()) + { + return; // No disassembler available (no comments will be used). + } + stringStream out1, out2; + + Disassembler::decode(cbuf->insts_begin(), cbuf->insts_end(), &out1, &cbuf->asm_remarks()); + Disassembler::decode(blob->code_begin(), blob->code_end(), &out2, &blob->asm_remarks()); + + EXPECT_STREQ(replace_addr_expr(out1.as_string()), + replace_addr_expr(out2.as_string())) + << "1. Output should be identical."; + + stringStream out3; + + Disassembler::decode(blob, &out3); + + EXPECT_STREQ(replace_addr_expr(out2.as_string()), + replace_addr_expr(delete_header_line(out3.as_string()))) + << "2. Output should be identical."; +} + +static void copy_and_compare(CodeBuffer* cbuf) +{ + bool remarks_empty = cbuf->asm_remarks().is_empty(); + bool strings_empty = cbuf->dbg_strings().is_empty(); + + BufferBlob* blob = BufferBlob::create("CodeBuffer Copy&Compare", cbuf); + + // 1. Check Assembly Remarks are shared by buffer and blob. + asm_remarks_check(cbuf->asm_remarks(), blob->asm_remarks()); + + // 2. Check Debug Strings are shared by buffer and blob. + dbg_strings_check(cbuf->dbg_strings(), blob->dbg_strings()); + + // 3. Check that the disassembly output matches. + disasm_string_check(cbuf, blob); + + BufferBlob::free(blob); + + ASSERT_EQ(remarks_empty, cbuf->asm_remarks().is_empty()) + << "Expecting property to be unchanged."; + ASSERT_EQ(strings_empty, cbuf->dbg_strings().is_empty()) + << "Expecting property to be unchanged."; +} + +static void code_buffer_test() +{ + constexpr int BUF_SZ = 256; + + ResourceMark rm; + CodeBuffer cbuf("CodeStringTest", BUF_SZ, BUF_SZ); + MacroAssembler as(&cbuf); + + ASSERT_TRUE(cbuf.asm_remarks().is_empty()); + ASSERT_TRUE(cbuf.dbg_strings().is_empty()); + + ASSERT_TRUE(cbuf.blob()->asm_remarks().is_empty()); + ASSERT_TRUE(cbuf.blob()->dbg_strings().is_empty()); + + int re, sz, n; + + re = cbuf.insts_remaining(); + + // 1. Generate a first entry. + as.block_comment("First block comment."); + as.nop(); + + sz = re - cbuf.insts_remaining(); + + ASSERT_TRUE(sz > 0); + + ASSERT_FALSE(cbuf.asm_remarks().is_empty()); + ASSERT_TRUE(cbuf.dbg_strings().is_empty()); + + ASSERT_TRUE(cbuf.blob()->asm_remarks().is_empty()); + ASSERT_TRUE(cbuf.blob()->dbg_strings().is_empty()); + + copy_and_compare(&cbuf); + + n = re/sz; + ASSERT_TRUE(n > 0); + + // 2. Generate additional entries without causing the buffer to expand. + for (unsigned i = 0; i < unsigned(n)/2; i++) + { + ASSERT_FALSE(cbuf.insts()->maybe_expand_to_ensure_remaining(sz)); + ASSERT_TRUE(cbuf.insts_remaining()/sz >= n/2); + + stringStream strm; + strm.print("Comment No. %d", i); + as.block_comment(strm.as_string()); + as.nop(); + } + ASSERT_FALSE(cbuf.asm_remarks().is_empty()); + + copy_and_compare(&cbuf); + + re = cbuf.insts_remaining(); + + // 3. Generate a single code with a debug string. + as.unimplemented("First debug string."); + + ASSERT_FALSE(cbuf.asm_remarks().is_empty()); + ASSERT_FALSE(cbuf.dbg_strings().is_empty()); + + sz = re - cbuf.insts_remaining(); + n = (re - sz)/sz; + ASSERT_TRUE(n > 0); + + // 4. Generate additional code with debug strings. + for (unsigned i = 0; i < unsigned(n); i++) + { + ASSERT_TRUE(cbuf.insts_remaining() >= sz); + + stringStream strm; + strm.print("Fixed address string No. %d", i); + as.unimplemented(strm.as_string()); + } + ASSERT_TRUE(cbuf.insts_remaining() >= 0); + + ASSERT_FALSE(cbuf.asm_remarks().is_empty()); + ASSERT_FALSE(cbuf.dbg_strings().is_empty()); + + ASSERT_TRUE(cbuf.blob()->asm_remarks().is_empty()); + ASSERT_TRUE(cbuf.blob()->dbg_strings().is_empty()); + + copy_and_compare(&cbuf); +} + +static void buffer_blob_test() +{ + constexpr int BUF_SZ = 256; + + ResourceMark rm; + BufferBlob* blob = BufferBlob::create("BufferBlob Test", BUF_SZ); + CodeBuffer cbuf(blob); + MacroAssembler as(&cbuf); + + ASSERT_FALSE(cbuf.insts()->has_locs()); + + // The x86-64 version of 'stop' will use relocation info. that will result + // in tainting the location start and limit if no location info. buffer is + // present. + static uint8_t s_loc_buf[BUF_SZ]; // Raw memory buffer used for relocInfo. + cbuf.insts()->initialize_shared_locs((relocInfo*)&s_loc_buf[0], BUF_SZ); + + int re = cbuf.insts_remaining(); + + as.block_comment("First block comment."); + as.nop(); + as.unimplemented("First debug string."); + + int sz = re - cbuf.insts_remaining(); + + ASSERT_TRUE(sz > 0); + constexpr int LIM_GEN = 51; // Limit number of entries generated. + + for (unsigned i = 0; i < LIM_GEN; i++) + { + if (cbuf.insts_remaining() < sz) break; + + stringStream strm1; + strm1.print("Comment No. %d", i); + as.block_comment(strm1.as_string()); + as.nop(); + + stringStream strm2; + strm2.print("Fixed address string No. %d", i); + as.unimplemented(strm2.as_string()); + } + ASSERT_TRUE(cbuf.insts_remaining() >= 0); + + ASSERT_FALSE(cbuf.asm_remarks().is_empty()); + ASSERT_FALSE(cbuf.dbg_strings().is_empty()); + + copy_and_compare(&cbuf); + + ASSERT_TRUE(blob->asm_remarks().is_empty()); + ASSERT_TRUE(blob->dbg_strings().is_empty()); + + BufferBlob::free(blob); +} + +TEST_VM(codestrings, validate) +{ + code_buffer_test(); + buffer_blob_test(); +} + +#endif // not ZERO +#endif // not PRODUCT From 4241313127be05704eeebcc6454120742cc93753 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Thu, 12 Jun 2025 16:21:01 +0000 Subject: [PATCH 309/846] 8354941: Build failure with glibc 2.42 due to uabs() name collision Reviewed-by: phh Backport-of: 38bb8adf4f632b08af15f2d8530b35f05f86a020 --- src/hotspot/cpu/aarch64/assembler_aarch64.cpp | 2 +- src/hotspot/cpu/aarch64/assembler_aarch64.hpp | 2 +- src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp | 2 +- src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp | 4 ++-- src/hotspot/cpu/riscv/assembler_riscv.hpp | 2 +- src/hotspot/cpu/riscv/stubGenerator_riscv.cpp | 4 ++-- src/hotspot/share/opto/mulnode.cpp | 4 ++-- src/hotspot/share/utilities/globalDefinitions.hpp | 8 ++++---- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.cpp b/src/hotspot/cpu/aarch64/assembler_aarch64.cpp index 0c503e0b7fddc..70a750f0043bb 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.cpp @@ -318,7 +318,7 @@ void Assembler::wrap_label(Label &L, prfop op, prefetch_insn insn) { bool Assembler::operand_valid_for_add_sub_immediate(int64_t imm) { bool shift = false; - uint64_t uimm = (uint64_t)uabs((jlong)imm); + uint64_t uimm = (uint64_t)g_uabs((jlong)imm); if (uimm < (1 << 12)) return true; if (uimm < (1 << 24) diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp index 5a8047bc2afdc..12fff1972bd90 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp @@ -858,7 +858,7 @@ class Assembler : public AbstractAssembler { static const uint64_t branch_range = NOT_DEBUG(128 * M) DEBUG_ONLY(2 * M); static bool reachable_from_branch_at(address branch, address target) { - return uabs(target - branch) < branch_range; + return g_uabs(target - branch) < branch_range; } // Unconditional branch (immediate) diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index 7abb2205414fd..c9a8db901e44a 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -2410,7 +2410,7 @@ void MacroAssembler::wrap_add_sub_imm_insn(Register Rd, Register Rn, uint64_t im if (fits) { (this->*insn1)(Rd, Rn, imm); } else { - if (uabs(imm) < (1 << 24)) { + if (g_uabs(imm) < (1 << 24)) { (this->*insn1)(Rd, Rn, imm & -(1 << 12)); (this->*insn1)(Rd, Rd, imm & ((1 << 12)-1)); } else { diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index c92f0cf05bd66..4920b7cb47c03 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -1042,7 +1042,7 @@ class StubGenerator: public StubCodeGenerator { void copy_memory_small(Register s, Register d, Register count, Register tmp, int step) { bool is_backwards = step < 0; - size_t granularity = uabs(step); + size_t granularity = g_uabs(step); int direction = is_backwards ? -1 : 1; int unit = wordSize * direction; @@ -1098,7 +1098,7 @@ class StubGenerator: public StubCodeGenerator { Register count, Register tmp, int step) { copy_direction direction = step < 0 ? copy_backwards : copy_forwards; bool is_backwards = step < 0; - unsigned int granularity = uabs(step); + unsigned int granularity = g_uabs(step); const Register t0 = r3, t1 = r4; // <= 80 (or 96 for SIMD) bytes do inline. Direction doesn't matter because we always diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp index 98c51e9883d96..31a8f59f80277 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp @@ -2779,7 +2779,7 @@ enum Nf { static const unsigned long branch_range = 1 * M; static bool reachable_from_branch_at(address branch, address target) { - return uabs(target - branch) < branch_range; + return g_uabs(target - branch) < branch_range; } // Decode the given instruction, checking if it's a 16-bit compressed diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index 7fe0392ea5c63..a0ebb34a54860 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -925,7 +925,7 @@ class StubGenerator: public StubCodeGenerator { void copy_memory_v(Register s, Register d, Register count, Register tmp, int step) { bool is_backward = step < 0; - int granularity = uabs(step); + int granularity = g_uabs(step); const Register src = x30, dst = x31, vl = x14, cnt = x15, tmp1 = x16, tmp2 = x17; assert_different_registers(s, d, cnt, vl, tmp, tmp1, tmp2); @@ -974,7 +974,7 @@ class StubGenerator: public StubCodeGenerator { } bool is_backwards = step < 0; - int granularity = uabs(step); + int granularity = g_uabs(step); const Register src = x30, dst = x31, cnt = x15, tmp3 = x16, tmp4 = x17, tmp5 = x14, tmp6 = x13; diff --git a/src/hotspot/share/opto/mulnode.cpp b/src/hotspot/share/opto/mulnode.cpp index 6d35fd8bf7b02..6eb47eb38bb92 100644 --- a/src/hotspot/share/opto/mulnode.cpp +++ b/src/hotspot/share/opto/mulnode.cpp @@ -242,7 +242,7 @@ Node *MulINode::Ideal(PhaseGVN *phase, bool can_reshape) { // Check for negative constant; if so negate the final result bool sign_flip = false; - unsigned int abs_con = uabs(con); + unsigned int abs_con = g_uabs(con); if (abs_con != (unsigned int)con) { sign_flip = true; } @@ -336,7 +336,7 @@ Node *MulLNode::Ideal(PhaseGVN *phase, bool can_reshape) { // Check for negative constant; if so negate the final result bool sign_flip = false; - julong abs_con = uabs(con); + julong abs_con = g_uabs(con); if (abs_con != (julong)con) { sign_flip = true; } diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp index 98d7fbc674c82..d5840b0c001ff 100644 --- a/src/hotspot/share/utilities/globalDefinitions.hpp +++ b/src/hotspot/share/utilities/globalDefinitions.hpp @@ -1064,7 +1064,7 @@ inline bool is_even(intx x) { return !is_odd(x); } // abs methods which cannot overflow and so are well-defined across // the entire domain of integer types. -static inline unsigned int uabs(unsigned int n) { +static inline unsigned int g_uabs(unsigned int n) { union { unsigned int result; int value; @@ -1073,7 +1073,7 @@ static inline unsigned int uabs(unsigned int n) { if (value < 0) result = 0-result; return result; } -static inline julong uabs(julong n) { +static inline julong g_uabs(julong n) { union { julong result; jlong value; @@ -1082,8 +1082,8 @@ static inline julong uabs(julong n) { if (value < 0) result = 0-result; return result; } -static inline julong uabs(jlong n) { return uabs((julong)n); } -static inline unsigned int uabs(int n) { return uabs((unsigned int)n); } +static inline julong g_uabs(jlong n) { return g_uabs((julong)n); } +static inline unsigned int g_uabs(int n) { return g_uabs((unsigned int)n); } // "to" should be greater than "from." inline intx byte_size(void* from, void* to) { From f7492dda384b814c5fceaea15a2fdf1a2a7bc617 Mon Sep 17 00:00:00 2001 From: Bara' Hasheesh Date: Fri, 13 Jun 2025 12:06:46 +0000 Subject: [PATCH 310/846] 8312475: org.jline.util.PumpReader signed byte problem Backport-of: bea2d48696ee2c213e475ca3aa3aa9c412b91089 --- .../share/classes/jdk/internal/org/jline/utils/PumpReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java index ce68fa5f84e9a..12e9795c6f51f 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java @@ -413,7 +413,7 @@ public int read() throws IOException { return EOF; } - return buffer.get(); + return buffer.get() & 0xFF; } private boolean readUsingBuffer() throws IOException { From 95fe05a32508fc2ac2eb235a236111e6b9a4eba7 Mon Sep 17 00:00:00 2001 From: Daniel Hu Date: Fri, 13 Jun 2025 14:44:00 +0000 Subject: [PATCH 311/846] 8136895: Writer not closed with disk full error, file resource leaked Backport-of: d55d7e8d87670043dd22ec6a3fb6cc49b39000cd --- .../classes/sun/nio/cs/StreamEncoder.java | 15 +--- .../CloseWriterOnFailedFlush.java | 86 ++++++++++++++++++ .../Channels/CloseWriterOnFailedFlush.java | 88 +++++++++++++++++++ test/jdk/sun/nio/cs/StreamEncoderClose.java | 18 ++-- 4 files changed, 190 insertions(+), 17 deletions(-) create mode 100644 test/jdk/java/io/OutputStreamWriter/CloseWriterOnFailedFlush.java create mode 100644 test/jdk/java/nio/channels/Channels/CloseWriterOnFailedFlush.java diff --git a/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java b/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java index 65cb25bb06d12..03ddeaa166dca 100644 --- a/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java +++ b/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java @@ -322,8 +322,8 @@ void implFlush() throws IOException { } void implClose() throws IOException { - flushLeftoverChar(null, true); - try { + try (ch; out) { + flushLeftoverChar(null, true); for (;;) { CoderResult cr = encoder.flush(bb); if (cr.isUnderflow()) @@ -338,15 +338,8 @@ void implClose() throws IOException { if (bb.position() > 0) writeBytes(); - if (ch != null) - ch.close(); - else { - try { - out.flush(); - } finally { - out.close(); - } - } + if (out != null) + out.flush(); } catch (IOException x) { encoder.reset(); throw x; diff --git a/test/jdk/java/io/OutputStreamWriter/CloseWriterOnFailedFlush.java b/test/jdk/java/io/OutputStreamWriter/CloseWriterOnFailedFlush.java new file mode 100644 index 0000000000000..b87362ca37610 --- /dev/null +++ b/test/jdk/java/io/OutputStreamWriter/CloseWriterOnFailedFlush.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 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. + */ + +/* @test + * @bug 8136895 + * @summary Verify stream closed after write error in StreamEncoder::implClose + */ + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.MalformedInputException; +import java.nio.charset.StandardCharsets; + +public class CloseWriterOnFailedFlush { + private static final String STR_IOE = "Test"; // IOException + private static final String STR_MIE = "\ud83c"; // MalformedInputException + + public static void main(String[] args) throws IOException { + boolean failed = false; + + for (String s : new String[] {STR_IOE, STR_MIE}) { + System.out.println("string: " + s); + ErroringOutputStream stream = new ErroringOutputStream(); + try (Writer writer = new OutputStreamWriter(stream, + StandardCharsets.UTF_8.newEncoder())) { + writer.write(s); + } catch (IOException ex) { + Class exClass = ex.getClass(); + if (s.equals(STR_IOE) && exClass != IOException.class || + s.equals(STR_MIE) && exClass != MalformedInputException.class) + throw ex; + } + + if (stream.isOpen()) { + System.err.println("Stream is STILL open"); + failed = true; + } else { + System.out.println("Stream is closed"); + } + } + + if (failed) + throw new RuntimeException("Test failed"); + } + + private static class ErroringOutputStream extends OutputStream { + private boolean open = true; + + @Override + public void write(int b) throws IOException { + throw new IOException(); + } + + public boolean isOpen() { + return open; + } + + @Override + public void close() throws IOException { + open = false; + System.out.println("Closing"); + } + } +} diff --git a/test/jdk/java/nio/channels/Channels/CloseWriterOnFailedFlush.java b/test/jdk/java/nio/channels/Channels/CloseWriterOnFailedFlush.java new file mode 100644 index 0000000000000..fc5b173086787 --- /dev/null +++ b/test/jdk/java/nio/channels/Channels/CloseWriterOnFailedFlush.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 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. + */ + +/* @test + * @bug 8136895 + * @summary Verify channel closed after write error in StreamEncoder::implClose + */ + +import java.io.IOException; +import java.io.Writer; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.WritableByteChannel; +import java.nio.charset.MalformedInputException; +import java.nio.charset.StandardCharsets; + +public class CloseWriterOnFailedFlush { + private static final String STR_IOE = "Test"; // IOException + private static final String STR_MIE = "\ud83c"; // MalformedInputException + + public static void main(String[] args) throws IOException { + boolean failed = false; + + for (String s : new String[] {STR_IOE, STR_MIE}) { + System.out.println("string: " + s); + ErroringByteChannel channel = new ErroringByteChannel(); + try (Writer writer = Channels.newWriter + (channel, StandardCharsets.UTF_8.newEncoder(), -1 )) { + writer.write(s); + } catch (IOException ex) { + Class exClass = ex.getClass(); + if (s.equals(STR_IOE) && exClass != IOException.class || + s.equals(STR_MIE) && exClass != MalformedInputException.class) + throw ex; + } + + if (channel.isOpen()) { + System.err.println("Channel is STILL open"); + failed = true; + } else { + System.out.println("Channel is closed"); + } + } + + if (failed) + throw new RuntimeException("Test failed"); + } + + private static class ErroringByteChannel implements WritableByteChannel { + private boolean open = true; + + @Override + public int write(ByteBuffer src) throws IOException { + throw new IOException(); + } + + @Override + public boolean isOpen() { + return open; + } + + @Override + public void close() { + open = false; + System.out.println("Closing"); + } + } +} diff --git a/test/jdk/sun/nio/cs/StreamEncoderClose.java b/test/jdk/sun/nio/cs/StreamEncoderClose.java index 68b4111fb4763..8e0d259536cfd 100644 --- a/test/jdk/sun/nio/cs/StreamEncoderClose.java +++ b/test/jdk/sun/nio/cs/StreamEncoderClose.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -31,6 +31,15 @@ import java.io.*; public class StreamEncoderClose { + private static void ck(String s, int actual, int expected) + throws IOException { + if (actual != expected) { + String msg = String.format("%s: actual (%d) != expected (%d)%n", + s, actual, expected); + throw new IOException(msg); + } + } + public static void main( String arg[] ) throws Exception { byte[] expected = {(byte)0x1b,(byte)0x24,(byte)0x42, (byte)0x30,(byte)0x6c, @@ -46,13 +55,10 @@ public static void main( String arg[] ) throws Exception { //double check, probably not necessary byte[] out = baos.toByteArray(); - if (out.length != expected.length) { - throw new IOException("Failed"); - } + ck("Lengths are unequal", out.length, expected.length); for (int i = 0; i < out.length; i++) { //System.out.printf("(byte)0x%x,", out[i] & 0xff); - if (out[i] != expected[i]) - throw new IOException("Failed"); + ck("Values are unequal", out[i], expected[i]); } } From 3ee18396f15167dab00d3af1d5a33a69de7b5a8c Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Mon, 16 Jun 2025 08:23:01 +0000 Subject: [PATCH 312/846] 8357793: [PPC64] VM crashes with -XX:-UseSIGTRAP -XX:-ImplicitNullChecks Reviewed-by: mbaesken Backport-of: fef4c29e5a296c0c689abb25183c243326607614 --- src/hotspot/cpu/ppc/interp_masm_ppc.hpp | 1 + src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp | 5 +++++ src/hotspot/cpu/ppc/methodHandles_ppc.cpp | 4 +++- src/hotspot/cpu/ppc/templateTable_ppc_64.cpp | 8 +++----- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/hotspot/cpu/ppc/interp_masm_ppc.hpp b/src/hotspot/cpu/ppc/interp_masm_ppc.hpp index f289b80815033..7ac6bc9e3f00d 100644 --- a/src/hotspot/cpu/ppc/interp_masm_ppc.hpp +++ b/src/hotspot/cpu/ppc/interp_masm_ppc.hpp @@ -38,6 +38,7 @@ class InterpreterMacroAssembler: public MacroAssembler { InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {} void null_check_throw(Register a, int offset, Register temp_reg); + void load_klass_check_null_throw(Register dst, Register src, Register temp_reg); void jump_to_entry(address entry, Register Rscratch); diff --git a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp index 6950b304d084c..8c07c6bef1463 100644 --- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp @@ -54,6 +54,11 @@ void InterpreterMacroAssembler::null_check_throw(Register a, int offset, Registe MacroAssembler::null_check_throw(a, offset, temp_reg, exception_entry); } +void InterpreterMacroAssembler::load_klass_check_null_throw(Register dst, Register src, Register temp_reg) { + null_check_throw(src, oopDesc::klass_offset_in_bytes(), temp_reg); + load_klass(dst, src); +} + void InterpreterMacroAssembler::jump_to_entry(address entry, Register Rscratch) { assert(entry, "Entry must have been generated by now"); if (is_within_range_of_b(entry, pc())) { diff --git a/src/hotspot/cpu/ppc/methodHandles_ppc.cpp b/src/hotspot/cpu/ppc/methodHandles_ppc.cpp index ff8ba4fc84e96..e592257dfcde2 100644 --- a/src/hotspot/cpu/ppc/methodHandles_ppc.cpp +++ b/src/hotspot/cpu/ppc/methodHandles_ppc.cpp @@ -348,7 +348,9 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm, ? -1 // enforce receiver null check : oopDesc::klass_offset_in_bytes(); // regular null-checking behavior - __ null_check_throw(receiver_reg, klass_offset, temp1, Interpreter::throw_NullPointerException_entry()); + address NullPointerException_entry = for_compiler_entry ? StubRoutines::throw_NullPointerException_at_call_entry() + : Interpreter::throw_NullPointerException_entry(); + __ null_check_throw(receiver_reg, klass_offset, temp1, NullPointerException_entry); if (iid != vmIntrinsics::_linkToSpecial || VerifyMethodHandles) { __ load_klass(temp1_recv_klass, receiver_reg); diff --git a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp index 5d33604489ec8..f54731237524f 100644 --- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp @@ -1040,7 +1040,7 @@ void TemplateTable::bastore() { // Need to check whether array is boolean or byte // since both types share the bastore bytecode. - __ load_klass(Rscratch, Rarray); + __ load_klass_check_null_throw(Rscratch, Rarray, Rscratch); __ lwz(Rscratch, in_bytes(Klass::layout_helper_offset()), Rscratch); int diffbit = exact_log2(Klass::layout_helper_boolean_diffbit()); __ testbitdi(CCR0, R0, Rscratch, diffbit); @@ -3440,8 +3440,7 @@ void TemplateTable::invokevirtual(int byte_no) { __ load_dispatch_table(Rtable_addr, Interpreter::invoke_return_entry_table()); __ sldi(Rret_type, Rret_type, LogBytesPerWord); __ ldx(Rret_addr, Rret_type, Rtable_addr); - __ null_check_throw(Rrecv, oopDesc::klass_offset_in_bytes(), R11_scratch1); - __ load_klass(Rrecv_klass, Rrecv); + __ load_klass_check_null_throw(Rrecv_klass, Rrecv, R11_scratch1); __ verify_klass_ptr(Rrecv_klass); __ profile_virtual_call(Rrecv_klass, R11_scratch1, R12_scratch2, false); @@ -3578,8 +3577,7 @@ void TemplateTable::invokeinterface(int byte_no) { // then regular interface method. // Get receiver klass - this is also a null check - __ null_check_throw(Rreceiver, oopDesc::klass_offset_in_bytes(), Rscratch2); - __ load_klass(Rrecv_klass, Rreceiver); + __ load_klass_check_null_throw(Rrecv_klass, Rreceiver, Rscratch2); // Check corner case object method. // Special case of invokeinterface called for virtual method of From 37b986700f5cdc95eaf31e0c6145fa3f6ca05cbf Mon Sep 17 00:00:00 2001 From: Paul Hohensee Date: Mon, 16 Jun 2025 11:20:50 +0000 Subject: [PATCH 313/846] 8335252: Reduce size of j.u.Formatter.Conversion#isValid Backport-of: 5d866bf17d96bd0f0e4545d7eee5912eda2e3a94 --- src/java.base/share/classes/java/util/Formatter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/java/util/Formatter.java b/src/java.base/share/classes/java/util/Formatter.java index 0436b7faf89b4..498a470363c60 100644 --- a/src/java.base/share/classes/java/util/Formatter.java +++ b/src/java.base/share/classes/java/util/Formatter.java @@ -4721,9 +4721,9 @@ static boolean isValid(char c) { DECIMAL_FLOAT, HEXADECIMAL_FLOAT, HEXADECIMAL_FLOAT_UPPER, - LINE_SEPARATOR, - PERCENT_SIGN -> true; - default -> false; + LINE_SEPARATOR -> true; + // Don't put PERCENT_SIGN inside switch, as that will make the method size exceed 325 and cannot be inlined. + default -> c == PERCENT_SIGN; }; } From 7b1be98df749e885cc8325ceacd41e427a05b6b4 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Tue, 17 Jun 2025 03:37:58 +0000 Subject: [PATCH 314/846] 8339561: The test/jdk/java/awt/Paint/ListRepaint.java may fail after JDK-8327401 Backport-of: 0844745e7bd954a96441365f8010741ec1c29dbf --- test/jdk/ProblemList.txt | 2 + .../MiscUndecorated/ActiveAWTWindowTest.java | 23 ++-- .../awt/List/KeyEventsTest/KeyEventsTest.java | 102 +++++++++--------- test/jdk/java/awt/Paint/ButtonRepaint.java | 30 +++--- test/jdk/java/awt/Paint/CheckboxRepaint.java | 29 ++--- test/jdk/java/awt/Paint/LabelRepaint.java | 24 +++-- test/jdk/java/awt/Paint/ListRepaint.java | 45 +++----- 7 files changed, 129 insertions(+), 126 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index f7d97e64c9491..6a6fa1e54e449 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -149,6 +149,8 @@ java/awt/EventQueue/PushPopDeadlock/PushPopDeadlock.java 8024034 generic-all java/awt/grab/EmbeddedFrameTest1/EmbeddedFrameTest1.java 7080150 macosx-all java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java 8168646 generic-all java/awt/KeyboardFocusmanager/TypeAhead/TestDialogTypeAhead.java 8198626 macosx-all +java/awt/List/KeyEventsTest/KeyEventsTest.java 8201307 linux-all +java/awt/Paint/ListRepaint.java 8201307 linux-all java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java 8049405 macosx-all java/awt/Mixing/AWT_Mixing/OpaqueOverlappingChoice.java 8048171 generic-all java/awt/Mixing/AWT_Mixing/JMenuBarOverlapping.java 8159451 linux-all,windows-all,macosx-all diff --git a/test/jdk/java/awt/Frame/MiscUndecorated/ActiveAWTWindowTest.java b/test/jdk/java/awt/Frame/MiscUndecorated/ActiveAWTWindowTest.java index 7aa5b8c5132eb..c7ec6c6d969f3 100644 --- a/test/jdk/java/awt/Frame/MiscUndecorated/ActiveAWTWindowTest.java +++ b/test/jdk/java/awt/Frame/MiscUndecorated/ActiveAWTWindowTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, 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 @@ -25,15 +25,24 @@ * @test * @key headful * @summary To check proper WINDOW_EVENTS are triggered when Frame gains or losses the focus - * @author Jitender(jitender.singh@eng.sun.com) area=AWT - * @author yan * @library /lib/client * @build ExtendedRobot * @run main ActiveAWTWindowTest */ -import java.awt.*; -import java.awt.event.*; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowFocusListener; public class ActiveAWTWindowTest { @@ -47,12 +56,12 @@ public class ActiveAWTWindowTest { private boolean passed = true; private final int delay = 150; - public static void main(String[] args) { + public static void main(String[] args) throws Exception { ActiveAWTWindowTest test = new ActiveAWTWindowTest(); try { test.doTest(); } finally { - EventQueue.invokeLater(() -> { + EventQueue.invokeAndWait(() -> { if (test.frame != null) { test.frame.dispose(); } diff --git a/test/jdk/java/awt/List/KeyEventsTest/KeyEventsTest.java b/test/jdk/java/awt/List/KeyEventsTest/KeyEventsTest.java index 919ea72a49490..b4c3e5e4f05cf 100644 --- a/test/jdk/java/awt/List/KeyEventsTest/KeyEventsTest.java +++ b/test/jdk/java/awt/List/KeyEventsTest/KeyEventsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, 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 @@ -22,9 +22,8 @@ */ import java.awt.BorderLayout; -import java.awt.EventQueue; -import java.awt.KeyboardFocusManager; import java.awt.Frame; +import java.awt.KeyboardFocusManager; import java.awt.List; import java.awt.Panel; import java.awt.Point; @@ -51,7 +50,7 @@ * @run main KeyEventsTest */ public class KeyEventsTest { - TestState currentState; + private volatile TestState currentState; final Object LOCK = new Object(); final int ACTION_TIMEOUT = 500; @@ -66,16 +65,14 @@ public static void main(final String[] args) throws Exception { r = new Robot(); KeyEventsTest app = new KeyEventsTest(); try { - EventQueue.invokeAndWait(app::initAndShowGui); + app.initAndShowGui(); r.waitForIdle(); r.delay(500); app.doTest(); } finally { - EventQueue.invokeAndWait(() -> { - if (app.keyFrame != null) { - app.keyFrame.dispose(); - } - }); + if (app.keyFrame != null) { + app.keyFrame.dispose(); + } } } @@ -184,52 +181,51 @@ private void test(TestState currentState) throws Exception { throw new RuntimeException("Test failed - list isn't focus owner."); } - EventQueue.invokeAndWait(() -> { - list.deselect(0); - list.deselect(1); - list.deselect(2); - list.deselect(3); - list.deselect(4); - list.deselect(5); - list.deselect(6); - list.deselect(7); - list.deselect(8); - - int selectIndex = 0; - int visibleIndex = 0; - - if (currentState.getScrollMoved()) { - if (currentState.getKeyID() == KeyEvent.VK_PAGE_UP || - currentState.getKeyID() == KeyEvent.VK_HOME) { - selectIndex = 8; - visibleIndex = 8; - } else if (currentState.getKeyID() == KeyEvent.VK_PAGE_DOWN || - currentState.getKeyID() == KeyEvent.VK_END) { + list.deselect(0); + list.deselect(1); + list.deselect(2); + list.deselect(3); + list.deselect(4); + list.deselect(5); + list.deselect(6); + list.deselect(7); + list.deselect(8); + + int selectIndex = 0; + int visibleIndex = 0; + + if (currentState.getScrollMoved()) { + if (currentState.getKeyID() == KeyEvent.VK_PAGE_UP || + currentState.getKeyID() == KeyEvent.VK_HOME) { + selectIndex = 8; + visibleIndex = 8; + } else if (currentState.getKeyID() == KeyEvent.VK_PAGE_DOWN || + currentState.getKeyID() == KeyEvent.VK_END) { + selectIndex = 0; + visibleIndex = 0; + } + } else { + if (currentState.getKeyID() == KeyEvent.VK_PAGE_UP || + currentState.getKeyID() == KeyEvent.VK_HOME) { + if (currentState.getSelectedMoved()) { + selectIndex = 1; + } else { selectIndex = 0; - visibleIndex = 0; } - } else { - if (currentState.getKeyID() == KeyEvent.VK_PAGE_UP || - currentState.getKeyID() == KeyEvent.VK_HOME) { - if (currentState.getSelectedMoved()) { - selectIndex = 1; - } else { - selectIndex = 0; - } - visibleIndex = 0; - } else if (currentState.getKeyID() == KeyEvent.VK_PAGE_DOWN || - currentState.getKeyID() == KeyEvent.VK_END) { - if (currentState.getSelectedMoved()) { - selectIndex = 7; - } else { - selectIndex = 8; - } - visibleIndex = 8; + visibleIndex = 0; + } else if (currentState.getKeyID() == KeyEvent.VK_PAGE_DOWN || + currentState.getKeyID() == KeyEvent.VK_END) { + if (currentState.getSelectedMoved()) { + selectIndex = 7; + } else { + selectIndex = 8; } + visibleIndex = 8; } - list.select(selectIndex); - list.makeVisible(visibleIndex); - }); + } + list.select(selectIndex); + list.makeVisible(visibleIndex); + r.delay(10); r.waitForIdle(); @@ -309,7 +305,7 @@ class TestState { private final boolean scrollMoved; private final int keyID; private final boolean template; - private boolean action; + private volatile boolean action; public TestState(boolean multiple, boolean selectedMoved, boolean scrollMoved, int keyID, boolean template){ this.multiple = multiple; diff --git a/test/jdk/java/awt/Paint/ButtonRepaint.java b/test/jdk/java/awt/Paint/ButtonRepaint.java index 77cd1a4649ddb..260e6c1097fd2 100644 --- a/test/jdk/java/awt/Paint/ButtonRepaint.java +++ b/test/jdk/java/awt/Paint/ButtonRepaint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 @@ -21,28 +21,32 @@ * questions. */ - -import java.awt.*; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; /** * @test * @key headful * @bug 7090424 - * @author Sergey Bylokhov */ public final class ButtonRepaint extends Button { public static void main(final String[] args) { for (int i = 0; i < 10; ++i) { - final Frame frame = new Frame(); - frame.setSize(300, 300); - frame.setLocationRelativeTo(null); - ButtonRepaint button = new ButtonRepaint(); - frame.add(button); - frame.setVisible(true); - sleep(); - button.test(); - frame.dispose(); + Frame frame = new Frame(); + try { + frame.setSize(300, 300); + frame.setLocationRelativeTo(null); + ButtonRepaint button = new ButtonRepaint(); + frame.add(button); + frame.setVisible(true); + sleep(); + button.test(); + } finally { + frame.dispose(); + } } } diff --git a/test/jdk/java/awt/Paint/CheckboxRepaint.java b/test/jdk/java/awt/Paint/CheckboxRepaint.java index 409c11f6f4d85..5522497dc2a6e 100644 --- a/test/jdk/java/awt/Paint/CheckboxRepaint.java +++ b/test/jdk/java/awt/Paint/CheckboxRepaint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 @@ -21,27 +21,32 @@ * questions. */ -import java.awt.*; +import java.awt.Checkbox; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; /** * @test * @key headful * @bug 7090424 - * @author Sergey Bylokhov */ public final class CheckboxRepaint extends Checkbox { public static void main(final String[] args) { for (int i = 0; i < 10; ++i) { - final Frame frame = new Frame(); - frame.setSize(300, 300); - frame.setLocationRelativeTo(null); - CheckboxRepaint checkbox = new CheckboxRepaint(); - frame.add(checkbox); - frame.setVisible(true); - sleep(); - checkbox.test(); - frame.dispose(); + Frame frame = new Frame(); + try { + frame.setSize(300, 300); + frame.setLocationRelativeTo(null); + CheckboxRepaint checkbox = new CheckboxRepaint(); + frame.add(checkbox); + frame.setVisible(true); + sleep(); + checkbox.test(); + } finally { + frame.dispose(); + } } } diff --git a/test/jdk/java/awt/Paint/LabelRepaint.java b/test/jdk/java/awt/Paint/LabelRepaint.java index 7131f6d4f0f52..56e096a2457a6 100644 --- a/test/jdk/java/awt/Paint/LabelRepaint.java +++ b/test/jdk/java/awt/Paint/LabelRepaint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 @@ -30,21 +30,23 @@ * @test * @key headful * @bug 7090424 - * @author Sergey Bylokhov */ public final class LabelRepaint extends Label { public static void main(final String[] args) { for (int i = 0; i < 10; ++i) { - final Frame frame = new Frame(); - frame.setSize(300, 300); - frame.setLocationRelativeTo(null); - LabelRepaint label = new LabelRepaint(); - frame.add(label); - frame.setVisible(true); - sleep(); - label.test(); - frame.dispose(); + Frame frame = new Frame(); + try { + frame.setSize(300, 300); + frame.setLocationRelativeTo(null); + LabelRepaint label = new LabelRepaint(); + frame.add(label); + frame.setVisible(true); + sleep(); + label.test(); + } finally { + frame.dispose(); + } } } diff --git a/test/jdk/java/awt/Paint/ListRepaint.java b/test/jdk/java/awt/Paint/ListRepaint.java index 08cf06d63f66a..a2d9c77a95b52 100644 --- a/test/jdk/java/awt/Paint/ListRepaint.java +++ b/test/jdk/java/awt/Paint/ListRepaint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 @@ -30,26 +30,27 @@ * @test * @key headful * @bug 7090424 - * @author Sergey Bylokhov */ public final class ListRepaint extends List { - static ListRepaint listRepaint; - static Frame frame; - - public static void main(final String[] args) throws Exception { + public static void main(final String[] args) { for (int i = 0; i < 10; ++i) { + Frame frame = new Frame(); try { - EventQueue.invokeLater(ListRepaint::createAndShowGUI); + frame.setSize(300, 300); + frame.setLocationRelativeTo(null); + ListRepaint list = new ListRepaint(); + list.add("1"); + list.add("2"); + list.add("3"); + list.add("4"); + list.select(0); + frame.add(list); + frame.setVisible(true); sleep(); - EventQueue.invokeAndWait(listRepaint::test); + list.test(); } finally { - EventQueue.invokeAndWait(() -> { - if (frame != null) { - frame.dispose(); - frame = null; - } - }); + frame.dispose(); } } } @@ -61,22 +62,6 @@ private static void sleep() { } } - static void createAndShowGUI() { - frame = new Frame(); - frame.setSize(300, 300); - frame.setLocationRelativeTo(null); - - listRepaint = new ListRepaint(); - listRepaint.add("1"); - listRepaint.add("2"); - listRepaint.add("3"); - listRepaint.add("4"); - listRepaint.select(0); - - frame.add(listRepaint); - frame.setVisible(true); - } - @Override public void paint(final Graphics g) { super.paint(g); From fca25f193b6d743e9fd9893106801b61941370af Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 17 Jun 2025 07:54:27 +0000 Subject: [PATCH 315/846] 8277969: HttpClient SelectorManager shuts down when custom Executor rejects a task Reviewed-by: rschmelter Backport-of: 5291ec8d56b0e89aa96c3d53d9dcf093480cf48f --- .../jdk/internal/net/http/Exchange.java | 1 - .../jdk/internal/net/http/ExchangeImpl.java | 23 +- .../internal/net/http/Http1AsyncReceiver.java | 5 +- .../jdk/internal/net/http/Http1Exchange.java | 114 ++++- .../jdk/internal/net/http/Http1Request.java | 12 +- .../jdk/internal/net/http/Http1Response.java | 164 ++----- .../internal/net/http/Http2ClientImpl.java | 18 +- .../internal/net/http/Http2Connection.java | 44 +- .../jdk/internal/net/http/HttpClientImpl.java | 399 +++++++++++++++-- .../jdk/internal/net/http/HttpConnection.java | 17 +- .../jdk/internal/net/http/MultiExchange.java | 7 +- .../net/http/PlainHttpConnection.java | 21 +- .../internal/net/http/ResponseContent.java | 25 +- .../net/http/ResponseSubscribers.java | 9 +- .../jdk/internal/net/http/SocketTube.java | 8 + .../classes/jdk/internal/net/http/Stream.java | 51 ++- .../common/HttpBodySubscriberWrapper.java | 174 ++++++++ .../net/http/common/OperationTrackers.java | 11 +- .../net/httpclient/AsyncExecutorShutdown.java | 417 ++++++++++++++++++ .../java/net/httpclient/ExecutorShutdown.java | 380 ++++++++++++++++ .../java/net/httpclient/ReferenceTracker.java | 100 ++++- .../test/lib/http2/Http2TestServer.java | 100 +++-- .../internal/net/http/ConnectionPoolTest.java | 12 +- .../internal/net/http/SSLEchoTubeTest.java | 6 +- 24 files changed, 1852 insertions(+), 266 deletions(-) create mode 100644 src/java.net.http/share/classes/jdk/internal/net/http/common/HttpBodySubscriberWrapper.java create mode 100644 test/jdk/java/net/httpclient/AsyncExecutorShutdown.java create mode 100644 test/jdk/java/net/httpclient/ExecutorShutdown.java diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java b/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java index 8c71795766c78..b1a1925a0a9fa 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java @@ -26,7 +26,6 @@ package jdk.internal.net.http; import java.io.IOException; -import java.lang.System.Logger.Level; import java.net.InetSocketAddress; import java.net.ProtocolException; import java.net.ProxySelector; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ExchangeImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/ExchangeImpl.java index 9f2a4008d1800..17d49c1aa6171 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ExchangeImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ExchangeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -26,11 +26,12 @@ package jdk.internal.net.http; import java.io.IOException; -import java.net.http.HttpClient; import java.net.http.HttpResponse; +import java.net.http.HttpResponse.ResponseInfo; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import jdk.internal.net.http.common.HttpBodySubscriberWrapper; import jdk.internal.net.http.common.Logger; import jdk.internal.net.http.common.MinimalFuture; import jdk.internal.net.http.common.Utils; @@ -66,7 +67,7 @@ final Exchange getExchange() { return exchange; } - HttpClient client() { + HttpClientImpl client() { return exchange.client(); } @@ -181,6 +182,22 @@ abstract CompletableFuture readBodyAsync(HttpResponse.BodyHandler handler, boolean returnConnectionToPool, Executor executor); + /** + * Creates and wraps an {@link HttpResponse.BodySubscriber} from a {@link + * HttpResponse.BodyHandler} for the given {@link ResponseInfo}. + * An {@code HttpBodySubscriberWrapper} wraps a response body subscriber and makes + * sure its completed/onError methods are called only once, and that its onSusbscribe + * is called before onError. This is useful when errors occur asynchronously, and + * most typically when the error occurs before the {@code BodySubscriber} has + * subscribed. + * @param handler a body handler + * @param response a response info + * @return a new {@code HttpBodySubscriberWrapper} to handle the response + */ + HttpBodySubscriberWrapper createResponseSubscriber(HttpResponse.BodyHandler handler, ResponseInfo response) { + return new HttpBodySubscriberWrapper<>(handler.apply(response)); + } + /** * Ignore/consume the body. */ diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1AsyncReceiver.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1AsyncReceiver.java index 115077da0d247..7a2d7107182ec 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1AsyncReceiver.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1AsyncReceiver.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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -497,7 +497,8 @@ void onReadError(Throwable ex) { final Throwable t = (recorded == null ? ex : recorded); if (debug.on()) debug.log("recorded " + t + "\n\t delegate: " + delegate - + "\t\t queue.isEmpty: " + queue.isEmpty(), ex); + + "\n\t queue.isEmpty: " + queue.isEmpty() + + "\n\tstopRequested: " + stopRequested, ex); if (Log.errors()) { Log.logError("HTTP/1 read subscriber recorded error: {0} - {1}", describe(), t); } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java index efe0ccfb79dff..2e32c5b828a02 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -27,10 +27,10 @@ import java.io.IOException; import java.net.InetSocketAddress; -import java.net.http.HttpClient; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandler; import java.net.http.HttpResponse.BodySubscriber; +import java.net.http.HttpResponse.ResponseInfo; import java.nio.ByteBuffer; import java.util.Objects; import java.util.concurrent.CompletableFuture; @@ -39,7 +39,9 @@ import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.Executor; import java.util.concurrent.Flow; + import jdk.internal.net.http.common.Demand; +import jdk.internal.net.http.common.HttpBodySubscriberWrapper; import jdk.internal.net.http.common.Log; import jdk.internal.net.http.common.FlowTube; import jdk.internal.net.http.common.Logger; @@ -47,7 +49,6 @@ import jdk.internal.net.http.common.MinimalFuture; import jdk.internal.net.http.common.Utils; import static java.net.http.HttpClient.Version.HTTP_1_1; -import static jdk.internal.net.http.common.Utils.wrapWithExtraDetail; /** * Encapsulates one HTTP/1.1 request/response exchange. @@ -78,7 +79,7 @@ class Http1Exchange extends ExchangeImpl { final ConcurrentLinkedDeque outgoing = new ConcurrentLinkedDeque<>(); /** The write publisher, responsible for writing the complete request ( both - * headers and body ( if any ). */ + * headers and body ( if any )). */ private final Http1Publisher writePublisher = new Http1Publisher(); /** Completed when the header have been published, or there is an error */ @@ -86,8 +87,10 @@ class Http1Exchange extends ExchangeImpl { /** Completed when the body has been published, or there is an error */ private final CompletableFuture> bodySentCF = new MinimalFuture<>(); - /** The subscriber to the request's body published. Maybe null. */ - private volatile Http1BodySubscriber bodySubscriber; + /** The subscriber to the request's body published. May be null. */ + private volatile Http1RequestBodySubscriber bodySubscriber; + /** The subscriber to the response's body received. May be null. */ + private volatile BodySubscriber responseSubscriber; enum State { INITIAL, HEADERS, @@ -117,12 +120,12 @@ public String toString() { * concrete implementations: {@link Http1Request.StreamSubscriber}, and * {@link Http1Request.FixedContentSubscriber}, for receiving chunked and * fixed length bodies, respectively. */ - static abstract class Http1BodySubscriber implements Flow.Subscriber { + abstract static class Http1RequestBodySubscriber implements Flow.Subscriber { final MinimalFuture whenSubscribed = new MinimalFuture<>(); private volatile Flow.Subscription subscription; volatile boolean complete; private final Logger debug; - Http1BodySubscriber(Logger debug) { + Http1RequestBodySubscriber(Logger debug) { assert debug != null; this.debug = debug; } @@ -159,8 +162,8 @@ final void cancelSubscription() { } } - static Http1BodySubscriber completeSubscriber(Logger debug) { - return new Http1BodySubscriber(debug) { + static Http1RequestBodySubscriber completeSubscriber(Logger debug) { + return new Http1RequestBodySubscriber(debug) { @Override public void onSubscribe(Flow.Subscription subscription) { error(); } @Override public void onNext(ByteBuffer item) { error(); } @Override public void onError(Throwable throwable) { error(); } @@ -173,6 +176,34 @@ private void error() { } } + /** + * The Http1AsyncReceiver ensures that all calls to + * the subscriber, including onSubscribe, occur sequentially. + * There could however be some race conditions that could happen + * in case of unexpected errors thrown at unexpected places, which + * may cause onError to be called multiple times. + * The Http1BodySubscriber will ensure that the user subscriber + * is actually completed only once - and only after it is + * subscribed. + * @param The type of response. + */ + static final class Http1ResponseBodySubscriber extends HttpBodySubscriberWrapper { + final Http1Exchange exchange; + Http1ResponseBodySubscriber(BodySubscriber userSubscriber, Http1Exchange exchange) { + super(userSubscriber); + this.exchange = exchange; + } + + @Override + protected void complete(Throwable t) { + try { + exchange.responseSubscriberCompleted(this); + } finally { + super.complete(t); + } + } + } + @Override public String toString() { return "HTTP/1.1 " + request.toString(); @@ -217,6 +248,28 @@ private void connectFlows(HttpConnection connection) { asyncReceiver.subscriber()); } + // The Http1ResponseBodySubscriber is registered with the HttpClient + // to ensure that it gets completed if the SelectorManager aborts due + // to unexpected exceptions. + void registerResponseSubscriber(Http1ResponseBodySubscriber subscriber) { + Throwable failed = null; + synchronized (lock) { + failed = this.failed; + if (failed == null) { + this.responseSubscriber = subscriber; + } + } + if (failed != null) { + subscriber.onError(failed); + } else { + client.registerSubscriber(subscriber); + } + } + + void responseSubscriberCompleted(HttpBodySubscriberWrapper subscriber) { + client.subscriberCompleted(subscriber); + } + @Override CompletableFuture> sendHeadersAsync() { // create the response before sending the request headers, so that @@ -321,12 +374,12 @@ CompletableFuture> sendBodyAsync() { if (debug.on()) debug.log("bodySubscriber is %s", bodySubscriber == null ? null : bodySubscriber.getClass()); if (bodySubscriber == null) { - bodySubscriber = Http1BodySubscriber.completeSubscriber(debug); - appendToOutgoing(Http1BodySubscriber.COMPLETED); + bodySubscriber = Http1RequestBodySubscriber.completeSubscriber(debug); + appendToOutgoing(Http1RequestBodySubscriber.COMPLETED); } else { // start bodySubscriber.whenSubscribed - .thenAccept((s) -> cancelIfFailed(s)) + .thenAccept(this::cancelIfFailed) .thenAccept((s) -> requestMoreBody()); } } catch (Throwable t) { @@ -370,15 +423,24 @@ CompletableFuture readBodyAsync(BodyHandler handler, boolean returnConnectionToPool, Executor executor) { - BodySubscriber bs = handler.apply(new ResponseInfoImpl(response.responseCode(), - response.responseHeaders(), - HTTP_1_1)); + var responseInfo = new ResponseInfoImpl(response.responseCode(), + response.responseHeaders(), HTTP_1_1); + BodySubscriber bs = createResponseSubscriber(handler, responseInfo); CompletableFuture bodyCF = response.readBody(bs, returnConnectionToPool, executor); return bodyCF; } + @Override + Http1ResponseBodySubscriber createResponseSubscriber(BodyHandler handler, ResponseInfo response) { + BodySubscriber subscriber = handler.apply(response); + Http1ResponseBodySubscriber bs = + new Http1ResponseBodySubscriber(subscriber, this); + registerResponseSubscriber(bs); + return bs; + } + @Override CompletableFuture ignoreBody() { return response.ignoreBody(executor); @@ -439,8 +501,10 @@ void onProtocolError(final IOException cause) { private void cancelImpl(Throwable cause) { LinkedList> toComplete = null; int count = 0; - Throwable error; + Throwable error = null; + BodySubscriber subscriber; synchronized (lock) { + subscriber = responseSubscriber; if ((error = failed) == null) { failed = error = cause; } @@ -473,6 +537,15 @@ private void cancelImpl(Throwable cause) { operations.clear(); } } + + // complete subscriber if needed + if (subscriber != null && error != null) { + var failure = error; + if (client.isSelectorThread()) { + executor.execute(() -> subscriber.onError(failure)); + } else subscriber.onError(failure); + } + try { Log.logError("Http1Exchange.cancel: count=" + count); if (toComplete != null) { @@ -607,7 +680,7 @@ private DataPair getOutgoing() { headersSentCF.completeAsync(() -> this, exec); break; case BODY: - if (dp.data == Http1BodySubscriber.COMPLETED) { + if (dp.data == Http1RequestBodySubscriber.COMPLETED) { synchronized (lock) { state = State.COMPLETING; } @@ -718,7 +791,7 @@ public void run() { writeScheduler.stop(); } else { List data = dp.data; - if (data == Http1BodySubscriber.COMPLETED) { + if (data == Http1RequestBodySubscriber.COMPLETED) { synchronized (lock) { assert state == State.COMPLETING : "Unexpected state:" + state; state = State.COMPLETED; @@ -763,7 +836,8 @@ public void cancel() { } } - HttpClient client() { + @Override + final HttpClientImpl client() { return client; } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java index b33763fce447e..d1d9daf70a985 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -38,7 +38,7 @@ import java.util.function.BiPredicate; import java.net.http.HttpHeaders; import java.net.http.HttpRequest; -import jdk.internal.net.http.Http1Exchange.Http1BodySubscriber; +import jdk.internal.net.http.Http1Exchange.Http1RequestBodySubscriber; import jdk.internal.net.http.common.HttpHeadersBuilder; import jdk.internal.net.http.common.Log; import jdk.internal.net.http.common.Logger; @@ -314,8 +314,8 @@ List headers() { return List.of(b); } - Http1BodySubscriber continueRequest() { - Http1BodySubscriber subscriber; + Http1RequestBodySubscriber continueRequest() { + Http1RequestBodySubscriber subscriber; if (streaming) { subscriber = new StreamSubscriber(); requestPublisher.subscribe(subscriber); @@ -329,7 +329,7 @@ Http1BodySubscriber continueRequest() { return subscriber; } - final class StreamSubscriber extends Http1BodySubscriber { + final class StreamSubscriber extends Http1RequestBodySubscriber { StreamSubscriber() { super(debug); } @@ -392,7 +392,7 @@ public void onComplete() { } } - final class FixedContentSubscriber extends Http1BodySubscriber { + final class FixedContentSubscriber extends Http1RequestBodySubscriber { private volatile long contentWritten; FixedContentSubscriber() { super(debug); } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java index 8090568c4e451..b642dc8177b98 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -27,13 +27,10 @@ import java.io.EOFException; import java.lang.System.Logger.Level; +import java.net.http.HttpResponse.BodySubscriber; import java.nio.ByteBuffer; -import java.util.List; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; import java.util.concurrent.Executor; -import java.util.concurrent.Flow; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; import java.util.function.Function; @@ -41,7 +38,6 @@ import java.net.http.HttpResponse; import jdk.internal.net.http.ResponseContent.BodyParser; import jdk.internal.net.http.ResponseContent.UnknownLengthBodyParser; -import jdk.internal.net.http.ResponseSubscribers.TrustedSubscriber; import jdk.internal.net.http.common.Log; import jdk.internal.net.http.common.Logger; import jdk.internal.net.http.common.MinimalFuture; @@ -74,7 +70,7 @@ class Http1Response { private final static int MAX_IGNORE = 1024; // Revisit: can we get rid of this? - static enum State {INITIAL, READING_HEADERS, READING_BODY, DONE} + enum State {INITIAL, READING_HEADERS, READING_BODY, DONE} private volatile State readProgress = State.INITIAL; final Logger debug = Utils.getDebugLogger(this::dbgString, Utils.DEBUG); @@ -123,7 +119,7 @@ private final class ClientRefCountTracker { // state & 0x02 != 0 => tryRelease called byte state; - public synchronized void acquire() { + public synchronized boolean acquire() { if (state == 0) { // increment the reference count on the HttpClientImpl // to prevent the SelectorManager thread from exiting @@ -132,11 +128,13 @@ public synchronized void acquire() { debug.log("Operation started: incrementing ref count for %s", client); client.reference(); state = 0x01; + return true; } else { if (debug.on()) debug.log("Operation ref count for %s is already %s", client, ((state & 0x2) == 0x2) ? "released." : "incremented!" ); assert (state & 0x01) == 0 : "reference count already incremented"; + return false; } } @@ -277,119 +275,6 @@ public void nullBody(HttpResponse resp, Throwable t) { } } - static final Flow.Subscription NOP = new Flow.Subscription() { - @Override - public void request(long n) { } - public void cancel() { } - }; - - /** - * The Http1AsyncReceiver ensures that all calls to - * the subscriber, including onSubscribe, occur sequentially. - * There could however be some race conditions that could happen - * in case of unexpected errors thrown at unexpected places, which - * may cause onError to be called multiple times. - * The Http1BodySubscriber will ensure that the user subscriber - * is actually completed only once - and only after it is - * subscribed. - * @param The type of response. - */ - final static class Http1BodySubscriber implements TrustedSubscriber { - final HttpResponse.BodySubscriber userSubscriber; - final AtomicBoolean completed = new AtomicBoolean(); - volatile Throwable withError; - volatile boolean subscribed; - Http1BodySubscriber(HttpResponse.BodySubscriber userSubscriber) { - this.userSubscriber = userSubscriber; - } - - @Override - public boolean needsExecutor() { - return TrustedSubscriber.needsExecutor(userSubscriber); - } - - // propagate the error to the user subscriber, even if not - // subscribed yet. - private void propagateError(Throwable t) { - assert t != null; - try { - // if unsubscribed at this point, it will not - // get subscribed later - so do it now and - // propagate the error - if (subscribed == false) { - subscribed = true; - userSubscriber.onSubscribe(NOP); - } - } finally { - // if onError throws then there is nothing to do - // here: let the caller deal with it by logging - // and closing the connection. - userSubscriber.onError(t); - } - } - - // complete the subscriber, either normally or exceptionally - // ensure that the subscriber is completed only once. - private void complete(Throwable t) { - if (completed.compareAndSet(false, true)) { - t = withError = Utils.getCompletionCause(t); - if (t == null) { - assert subscribed; - try { - userSubscriber.onComplete(); - } catch (Throwable x) { - // Simply propagate the error by calling - // onError on the user subscriber, and let the - // connection be reused since we should have received - // and parsed all the bytes when we reach here. - // If onError throws in turn, then we will simply - // let that new exception flow up to the caller - // and let it deal with it. - // (i.e: log and close the connection) - // Note that rethrowing here could introduce a - // race that might cause the next send() operation to - // fail as the connection has already been put back - // into the cache when we reach here. - propagateError(t = withError = Utils.getCompletionCause(x)); - } - } else { - propagateError(t); - } - } - } - - @Override - public CompletionStage getBody() { - return userSubscriber.getBody(); - } - - @Override - public void onSubscribe(Flow.Subscription subscription) { - if (!subscribed) { - subscribed = true; - userSubscriber.onSubscribe(subscription); - } else { - // could be already subscribed and completed - // if an unexpected error occurred before the actual - // subscription - though that's not supposed - // happen. - assert completed.get(); - } - } - @Override - public void onNext(List item) { - assert !completed.get(); - userSubscriber.onNext(item); - } - @Override - public void onError(Throwable throwable) { - complete(throwable); - } - @Override - public void onComplete() { - complete(null); - } - } public CompletableFuture readBody(HttpResponse.BodySubscriber p, boolean return2Cache, @@ -398,12 +283,13 @@ public CompletableFuture readBody(HttpResponse.BodySubscriber p, debug.log("readBody: return2Cache: " + return2Cache); if (request.isWebSocket() && return2Cache && connection != null) { debug.log("websocket connection will be returned to cache: " - + connection.getClass() + "/" + connection ); + + connection.getClass() + "/" + connection); } } assert !return2Cache || !request.isWebSocket(); this.return2Cache = return2Cache; - final Http1BodySubscriber subscriber = new Http1BodySubscriber<>(p); + final BodySubscriber subscriber = p; + final CompletableFuture cf = new MinimalFuture<>(); @@ -420,6 +306,7 @@ public CompletableFuture readBody(HttpResponse.BodySubscriber p, // tracker has been incremented. connection.client().reference(); executor.execute(() -> { + boolean acquired = false; try { content = new ResponseContent( connection, clen, headers, subscriber, @@ -433,7 +320,8 @@ public CompletableFuture readBody(HttpResponse.BodySubscriber p, // increment the reference count on the HttpClientImpl // to prevent the SelectorManager thread from exiting until // the body is fully read. - refCountTracker.acquire(); + acquired = refCountTracker.acquire(); + assert acquired == true; bodyParser = content.getBodyParser( (t) -> { try { @@ -457,7 +345,7 @@ public CompletableFuture readBody(HttpResponse.BodySubscriber p, assert bodyReaderCF != null : "parsing not started"; // Make sure to keep a reference to asyncReceiver from // within this - CompletableFuture trailingOp = bodyReaderCF.whenComplete((s,t) -> { + CompletableFuture trailingOp = bodyReaderCF.whenComplete((s, t) -> { t = Utils.getCompletionCause(t); try { if (t == null) { @@ -479,11 +367,12 @@ public CompletableFuture readBody(HttpResponse.BodySubscriber p, }); connection.addTrailingOperation(trailingOp); } catch (Throwable t) { - if (debug.on()) debug.log("Failed reading body: " + t); + if (debug.on()) debug.log("Failed reading body: " + t); try { subscriber.onError(t); cf.completeExceptionally(t); } finally { + if (acquired) refCountTracker.tryRelease(); asyncReceiver.onReadError(t); } } finally { @@ -492,6 +381,7 @@ public CompletableFuture readBody(HttpResponse.BodySubscriber p, }); ResponseSubscribers.getBodyAsync(executor, p, cf, (t) -> { + subscriber.onError(t); cf.completeExceptionally(t); asyncReceiver.setRetryOnError(false); asyncReceiver.onReadError(t); @@ -752,12 +642,14 @@ public final boolean tryAsyncReceive(ByteBuffer b) { @Override public final void onReadError(Throwable t) { - if (t instanceof EOFException && bodyParser != null && - bodyParser instanceof UnknownLengthBodyParser) { - ((UnknownLengthBodyParser)bodyParser).complete(); + BodyParser parser = bodyParser; + if (t instanceof EOFException && parser != null && + parser instanceof UnknownLengthBodyParser ulBodyParser) { + ulBodyParser.complete(); return; } t = wrapWithExtraDetail(t, parser::currentStateMessage); + parser.onError(t); Http1Response.this.onReadError(t); } @@ -824,6 +716,20 @@ public final void close(Throwable error) { cf.complete(State.READING_BODY); } } + if (error != null) { + // makes sure the parser gets the error + BodyParser parser = this.parser; + if (parser != null) { + if (debug.on()) { + debug.log("propagating error to parser: " + error); + } + parser.onError(error); + } else { + if (debug.on()) { + debug.log("no parser - error not propagated: " + error); + } + } + } } @Override diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java index 8da321ffab40a..339b5b469508f 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java @@ -57,6 +57,7 @@ class Http2ClientImpl { Utils.getDebugLogger("Http2ClientImpl"::toString, Utils.DEBUG); private final HttpClientImpl client; + private volatile boolean stopping; Http2ClientImpl(HttpClientImpl client) { this.client = client; @@ -163,6 +164,11 @@ boolean offerConnection(Http2Connection c) { String key = c.key(); synchronized(this) { + if (stopping) { + if (debug.on()) debug.log("stopping - closing connection: %s", c); + close(c); + return false; + } if (!c.isOpen()) { if (debug.on()) debug.log("skipping offered closed or closing connection: %s", c); @@ -207,16 +213,24 @@ void deleteConnection(Http2Connection c) { private EOFException STOPPED; void stop() { + synchronized (this) {stopping = true;} if (debug.on()) debug.log("stopping"); STOPPED = new EOFException("HTTP/2 client stopped"); STOPPED.setStackTrace(new StackTraceElement[0]); - connections.values().forEach(this::close); - connections.clear(); + do { + connections.values().forEach(this::close); + } while (!connections.isEmpty()); } private void close(Http2Connection h2c) { + // close all streams + try { h2c.closeAllStreams(); } catch (Throwable t) {} + // send GOAWAY try { h2c.close(); } catch (Throwable t) {} + // attempt graceful shutdown try { h2c.shutdown(STOPPED); } catch (Throwable t) {} + // double check and close any new streams + try { h2c.closeAllStreams(); } catch (Throwable t) {} } HttpClientImpl client() { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java index c1326789da06a..45b64315d65dc 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java @@ -1119,16 +1119,29 @@ synchronized void decrementStreamsCount(int streamid) { } } + // This method is called when the HTTP/2 client is being + // stopped. Do not call it from anywhere else. + void closeAllStreams() { + for (var streamId : streams.keySet()) { + // safe to call without locking - see Stream::deRegister + decrementStreamsCount(streamId); + closeStream(streamId); + } + } + void closeStream(int streamid) { if (debug.on()) debug.log("Closed stream %d", streamid); - boolean isClient = (streamid % 2) == 1; - Stream s = streams.remove(streamid); - if (s != null) { - // decrement the reference count on the HttpClientImpl - // to allow the SelectorManager thread to exit if no - // other operation is pending and the facade is no - // longer referenced. - client().streamUnreference(); + + Stream s; + synchronized (this) { + s = streams.remove(streamid); + if (s != null) { + // decrement the reference count on the HttpClientImpl + // to allow the SelectorManager thread to exit if no + // other operation is pending and the facade is no + // longer referenced. + client().streamUnreference(); + } } // ## Remove s != null. It is a hack for delayed cancellation,reset if (s != null && !(s instanceof Stream.PushedStream)) { @@ -1325,8 +1338,19 @@ void putStream(Stream stream, int streamid) { // increment the reference count on the HttpClientImpl // to prevent the SelectorManager thread from exiting until // the stream is closed. - client().streamReference(); - streams.put(streamid, stream); + synchronized (this) { + if (!closed) { + if (debug.on()) { + debug.log("Opened stream %d", streamid); + } + client().streamReference(); + streams.put(streamid, stream); + return; + } + } + if (debug.on()) debug.log("connection closed: closing stream %d", stream); + stream.cancel(); + } /** diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java index bb0dd914afb86..f30ba9d1e2e61 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java @@ -43,6 +43,7 @@ import java.nio.ByteBuffer; import java.nio.channels.CancelledKeyException; import java.nio.channels.ClosedChannelException; +import java.nio.channels.ClosedSelectorException; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; @@ -64,14 +65,19 @@ import java.util.Set; import java.util.TreeSet; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.CompletionException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiConsumer; import java.util.function.BooleanSupplier; import java.util.stream.Stream; import java.net.http.HttpClient; @@ -80,9 +86,12 @@ import java.net.http.HttpResponse.BodyHandler; import java.net.http.HttpResponse.PushPromiseHandler; import java.net.http.WebSocket; + import jdk.internal.net.http.common.BufferSupplier; +import jdk.internal.net.http.common.HttpBodySubscriberWrapper; import jdk.internal.net.http.common.Log; import jdk.internal.net.http.common.Logger; +import jdk.internal.net.http.common.MinimalFuture; import jdk.internal.net.http.common.Pair; import jdk.internal.net.http.common.Utils; import jdk.internal.net.http.common.OperationTrackers.Trackable; @@ -103,6 +112,7 @@ final class HttpClientImpl extends HttpClient implements Trackable { final Logger debugelapsed = Utils.getDebugLogger(this::dbgString, DEBUGELAPSED); final Logger debugtimeout = Utils.getDebugLogger(this::dbgString, DEBUGTIMEOUT); static final AtomicLong CLIENT_IDS = new AtomicLong(); + private final AtomicLong CONNECTION_IDS = new AtomicLong(); // Define the default factory as a static inner class // that embeds all the necessary logic to avoid @@ -141,24 +151,39 @@ public Thread newThread(Runnable r) { final static class DelegatingExecutor implements Executor { private final BooleanSupplier isInSelectorThread; private final Executor delegate; - DelegatingExecutor(BooleanSupplier isInSelectorThread, Executor delegate) { + private final BiConsumer errorHandler; + DelegatingExecutor(BooleanSupplier isInSelectorThread, + Executor delegate, + BiConsumer errorHandler) { this.isInSelectorThread = isInSelectorThread; this.delegate = delegate; + this.errorHandler = errorHandler; } Executor delegate() { return delegate; } + + @Override public void execute(Runnable command) { if (isInSelectorThread.getAsBoolean()) { - delegate.execute(command); + ensureExecutedAsync(command); } else { command.run(); } } + public void ensureExecutedAsync(Runnable command) { + try { + delegate.execute(command); + } catch (Throwable t) { + errorHandler.accept(command, t); + ASYNC_POOL.execute(command); + } + } + @SuppressWarnings("removal") private void shutdown() { if (delegate instanceof ExecutorService service) { @@ -170,7 +195,129 @@ private void shutdown() { new RuntimePermission("modifyThread")); } } + } + // We maintain a list of pending requests that will be aborted if ever + // the selector manager thread exists abnormally. + // The request, its id, and its completable future, are stored in a record-like + // PendingRequest object added to the pending requests set (pendingRequests). + // + // When the request's cf completes, either normally or abnormally, a dependent action + // will remove the PendingRequest object from the pending requests set. + // If the SelectorManager threads exits abnormally, all pending requests in the + // pending requests set will be completed exceptionally, in the ASYNC_POOL. + // + // HttpClientImpl::registerPending(id, req, cf, client) is called from sendAsync + // to register the pending request in the pending requests set before returning + // the completable future to the caller. + // + // HttpClientImpl::abortPendingRequests(client, Throwable reason) is called from + // the SelectorManager when a throwable is caught just before exiting. + // + // A dependent action is registered with the pending request's cf to make sure + // that the pending request will be removed from the pending requests set if, + // or after, the cf is completed. + // + private final Set pendingRequests; + // an id to ensure total order of pending request objects + private final AtomicLong pendingRequestId = new AtomicLong(); + private static final class PendingRequest implements Comparable { + final long id; + final HttpRequest request; + final CompletableFuture cf; + final HttpClientImpl client; + final MultiExchange mex; + Object ref; + private PendingRequest(long id, + HttpRequest request, + CompletableFuture cf, + MultiExchange mex, + HttpClientImpl client) { + this.id = id; + this.request = request; + this.cf = cf; + this.mex = mex; + this.client = client; + } + + public void abort(Throwable t) { + try { + if (client.isSelectorThread()) { + var done = cf.exceptionally((e) -> null); + ASYNC_POOL.execute(() -> completeExceptionally(t)); + // special case for when this method is called in the SelectorManager thread: + // we want to wait until all futures are completed before proceeding to + // shutdown. This ensures that the caller receive the actual `reason` + // and not something like "HTTP/2 client closed"... + done.join(); + } else { + cf.completeExceptionally(t); + } + } finally { + mex.cancel(Utils.getIOException(t)); + } + } + + private void completeExceptionally(Throwable t) { + if (client.debug.on()) { + client.debug.log("aborting %s with %s", this, t); + } + try { cf.completeExceptionally(t); } catch (Throwable e) { + client.debug.log("Failed to complete cf for [%s]: %s", this, e); + } + } + + + @Override + public int compareTo(PendingRequest o) { + if (o == null) return 1; + return Long.compare(id, o.id); + } + + public String toString() { + return id + ": " + request.toString(); + } + } + + static void registerPending(PendingRequest pending) { + // shortcut if cf is already completed: no need to go through the trouble of + // registering it + if (pending.cf.isDone()) return; + + var client = pending.client; + var cf = pending.cf; + var id = pending.id; + boolean added = client.pendingRequests.add(pending); + // this may immediately remove `pending` from the set is the cf is already completed + pending.ref = cf.whenComplete((r,t) -> client.pendingRequests.remove(pending)); + assert added : "request %d was already added".formatted(id); + // should not happen, unless the selector manager has already + // exited abnormally + if (client.selmgr.isClosed()) { + pending.abort(client.selmgr.selectorClosedException()); + } + } + + static void abortPendingRequests(HttpClientImpl client, Throwable reason) { + reason = Utils.getCompletionCause(reason); + if (client.debug.on()) { + var msg = reason instanceof RejectedExecutionException + ? reason.getClass() : reason; + client.debug.log("aborting pending requests due to: %s", msg); + } + closeSubscribers(client, reason); + var pendingRequests = client.pendingRequests; + while (!pendingRequests.isEmpty()) { + var pendings = pendingRequests.iterator(); + while (pendings.hasNext()) { + var pending = pendings.next(); + try { + pending.abort(reason); + } finally { + pendings.remove(); + } + } + } } private final CookieHandler cookieHandler; @@ -209,6 +356,11 @@ private void shutdown() { // have completed. private final WeakReference facadeRef; + private final ConcurrentSkipListSet openedConnections + = new ConcurrentSkipListSet<>(HttpConnection.COMPARE_BY_ID); + private final ConcurrentSkipListSet> subscribers + = new ConcurrentSkipListSet<>(HttpBodySubscriberWrapper.COMPARE_BY_ID); + // This counter keeps track of the number of operations pending // on the HttpClient. The SelectorManager thread will wait // until there are no longer any pending operations and the @@ -240,8 +392,11 @@ private void shutdown() { // the response has been fully received or the web socket is closed. private final AtomicLong pendingOperationCount = new AtomicLong(); private final AtomicLong pendingWebSocketCount = new AtomicLong(); + private final AtomicLong pendingHttpOperationsCount = new AtomicLong(); private final AtomicLong pendingHttpRequestCount = new AtomicLong(); private final AtomicLong pendingHttp2StreamCount = new AtomicLong(); + private final AtomicLong pendingTCPConnectionCount = new AtomicLong(); + private final AtomicBoolean isAlive = new AtomicBoolean(); /** A Set of, deadline first, ordered timeout events. */ private final TreeSet timeouts; @@ -295,7 +450,9 @@ private HttpClientImpl(HttpClientBuilderImpl builder, } else { isDefaultExecutor = false; } - delegatingExecutor = new DelegatingExecutor(this::isSelectorThread, ex); + pendingRequests = new ConcurrentSkipListSet<>(); + delegatingExecutor = new DelegatingExecutor(this::isSelectorThread, ex, + this::onSubmitFailure); facadeRef = new WeakReference<>(facadeFactory.createFacade(this)); client2 = new Http2ClientImpl(this); cookieHandler = builder.cookieHandler; @@ -334,6 +491,10 @@ private HttpClientImpl(HttpClientBuilderImpl builder, assert facadeRef.get() != null; } + void onSubmitFailure(Runnable command, Throwable failure) { + selmgr.abort(failure); + } + private void start() { selmgr.start(); } @@ -347,10 +508,48 @@ private void stop() { connections.stop(); // Clears HTTP/2 cache and close its connections. client2.stop(); + // make sure all subscribers are completed + closeSubscribers(); + // close TCP connection if any are still opened + openedConnections.forEach(this::closeConnection); // shutdown the executor if needed if (isDefaultExecutor) delegatingExecutor.shutdown(); } + private void closeSubscribers() { + if (subscribers.isEmpty()) return; + IOException io = selmgr.selectorClosedException(); + closeSubscribers(this, io); + } + + private static void closeSubscribers(HttpClientImpl client, Throwable t) { + client.subscribers.forEach(s -> s.onError(t)); + } + + public void registerSubscriber(HttpBodySubscriberWrapper subscriber) { + if (!selmgr.isClosed()) { + synchronized (selmgr) { + if (!selmgr.isClosed()) { + subscribers.add(subscriber); + return; + } + } + } + subscriber.onError(selmgr.selectorClosedException()); + } + + public void subscriberCompleted(HttpBodySubscriberWrapper subscriber) { + subscribers.remove(subscriber); + } + + private void closeConnection(HttpConnection conn) { + try { conn.close(); } catch (Throwable e) { + if (Log.channel()) { + Log.logChannel("Failed to close connection: " + e); + } + } + } + private static SSLParameters getDefaultParams(SSLContext ctx) { SSLParameters params = ctx.getDefaultSSLParameters(); return params; @@ -368,16 +567,46 @@ final HttpClientFacade facade() { return facadeRef.get(); } - // Increments the pendingOperationCount. - final long reference() { + public long newConnectionId() { + return CONNECTION_IDS.incrementAndGet(); + } + + // Increments the pendingTCPConnectionCount + public void connectionOpened(PlainHttpConnection plainHttpConnection) { + if (openedConnections.add(plainHttpConnection)) { + pendingTCPConnectionCount.incrementAndGet(); + } + } + + // Decrements the pendingTCPConnectionCount + public void connectionClosed(PlainHttpConnection plainHttpConnection) { + if (openedConnections.remove(plainHttpConnection)) { + pendingTCPConnectionCount.decrementAndGet(); + } + } + + // Increments the pendingHttpRequestCount and pendingOperationCount. + final long requestReference() { pendingHttpRequestCount.incrementAndGet(); + return reference(); + } + + // Decrements the pendingHttpRequestCount and pendingOperationCount. + final long requestUnreference() { + pendingHttpRequestCount.decrementAndGet(); + return unreference(); + } + + // Increments the pendingHttpOperationsCount and pendingOperationCount. + final long reference() { + pendingHttpOperationsCount.incrementAndGet(); return pendingOperationCount.incrementAndGet(); } - // Decrements the pendingOperationCount. + // Decrements the pendingHttpOperationsCount and pendingOperationCount. final long unreference() { final long count = pendingOperationCount.decrementAndGet(); - final long httpCount = pendingHttpRequestCount.decrementAndGet(); + final long httpCount = pendingHttpOperationsCount.decrementAndGet(); final long http2Count = pendingHttp2StreamCount.get(); final long webSocketCount = pendingWebSocketCount.get(); if (count == 0 && facade() == null) { @@ -390,17 +619,17 @@ final long unreference() { return count; } - // Increments the pendingOperationCount. + // Increments the pendingHttp2StreamCount and pendingOperationCount. final long streamReference() { pendingHttp2StreamCount.incrementAndGet(); return pendingOperationCount.incrementAndGet(); } - // Decrements the pendingOperationCount. + // Decrements the pendingHttp2StreamCount and pendingOperationCount. final long streamUnreference() { final long count = pendingOperationCount.decrementAndGet(); final long http2Count = pendingHttp2StreamCount.decrementAndGet(); - final long httpCount = pendingHttpRequestCount.get(); + final long httpCount = pendingHttpOperationsCount.get(); final long webSocketCount = pendingWebSocketCount.get(); if (count == 0 && facade() == null) { selmgr.wakeupSelector(); @@ -412,17 +641,17 @@ final long streamUnreference() { return count; } - // Increments the pendingOperationCount. + // Increments the pendingWebSocketCount and pendingOperationCount. final long webSocketOpen() { pendingWebSocketCount.incrementAndGet(); return pendingOperationCount.incrementAndGet(); } - // Decrements the pendingOperationCount. + // Decrements the pendingWebSocketCount and pendingOperationCount. final long webSocketClose() { final long count = pendingOperationCount.decrementAndGet(); final long webSocketCount = pendingWebSocketCount.decrementAndGet(); - final long httpCount = pendingHttpRequestCount.get(); + final long httpCount = pendingHttpOperationsCount.get(); final long http2Count = pendingHttp2StreamCount.get(); if (count == 0 && facade() == null) { selmgr.wakeupSelector(); @@ -435,28 +664,41 @@ final long webSocketClose() { } // Returns the pendingOperationCount. + // Incremented with any operation, whether it's HTTP/1.1, HTTP/2, or WebSocket final long referenceCount() { return pendingOperationCount.get(); } + // Trackers are used in test to verify that an instance of + // HttpClient has shutdown correctly, and that all operations + // have terminated. final static class HttpClientTracker implements Tracker { + final AtomicLong requestCount; final AtomicLong httpCount; final AtomicLong http2Count; final AtomicLong websocketCount; final AtomicLong operationsCount; + final AtomicLong connnectionsCount; final Reference reference; + final AtomicBoolean isAlive; final String name; - HttpClientTracker(AtomicLong http, + HttpClientTracker(AtomicLong request, + AtomicLong http, AtomicLong http2, AtomicLong ws, AtomicLong ops, + AtomicLong conns, Reference ref, + AtomicBoolean isAlive, String name) { + this.requestCount = request; this.httpCount = http; this.http2Count = http2; this.websocketCount = ws; this.operationsCount = ops; + this.connnectionsCount = conns; this.reference = ref; + this.isAlive = isAlive; this.name = name; } @Override @@ -464,6 +706,12 @@ public long getOutstandingOperations() { return operationsCount.get(); } @Override + public long getOutstandingHttpRequests() { + return requestCount.get(); + } + @Override + public long getOutstandingTcpConnections() { return connnectionsCount.get();} + @Override public long getOutstandingHttpOperations() { return httpCount.get(); } @@ -478,23 +726,29 @@ public boolean isFacadeReferenced() { return reference.get() != null; } @Override + public boolean isSelectorAlive() { return isAlive.get(); } + @Override public String getName() { return name; } } public Tracker getOperationsTracker() { - return new HttpClientTracker(pendingHttpRequestCount, + return new HttpClientTracker( + pendingHttpRequestCount, + pendingHttpOperationsCount, pendingHttp2StreamCount, pendingWebSocketCount, pendingOperationCount, + pendingTCPConnectionCount, facadeRef, + isAlive, dbgTag); } // Called by the SelectorManager thread to figure out whether it's time // to terminate. - final boolean isReferenced() { + boolean isReferenced() { HttpClient facade = facade(); return facade != null || referenceCount() > 0; } @@ -526,6 +780,14 @@ boolean isSelectorThread() { return Thread.currentThread() == selmgr; } + boolean isSelectorClosed() { + return selmgr.isClosed(); + } + + IOException selectorClosedException() { + return selmgr.selectorClosedException(); + } + Http2ClientImpl client2() { return client2; } @@ -622,6 +884,12 @@ private void debugCompleted(String tag, long startNanos, HttpRequest req) { Objects.requireNonNull(userRequest); Objects.requireNonNull(responseHandler); + // should not happen, unless the selector manager has + // exited abnormally + if (selmgr.isClosed()) { + return MinimalFuture.failedFuture(selmgr.selectorClosedException()); + } + AccessControlContext acc = null; if (System.getSecurityManager() != null) acc = AccessController.getContext(); @@ -631,8 +899,9 @@ private void debugCompleted(String tag, long startNanos, HttpRequest req) { if (requestImpl.method().equals("CONNECT")) throw new IllegalArgumentException("Unsupported method CONNECT"); + long id = pendingRequestId.incrementAndGet(); long start = DEBUGELAPSED ? System.nanoTime() : 0; - reference(); + requestReference(); try { if (debugelapsed.on()) debugelapsed.log("ClientImpl (async) send %s", userRequest); @@ -655,8 +924,8 @@ private void debugCompleted(String tag, long startNanos, HttpRequest req) { responseHandler, pushPromiseHandler, acc); - CompletableFuture> res = - mex.responseAsync(executor).whenComplete((b,t) -> unreference()); + CompletableFuture> mexCf = mex.responseAsync(executor); + CompletableFuture> res = mexCf.whenComplete((b,t) -> requestUnreference()); if (DEBUGELAPSED) { res = res.whenComplete( (b,t) -> debugCompleted("ClientImpl (async)", start, userRequest)); @@ -668,9 +937,14 @@ private void debugCompleted(String tag, long startNanos, HttpRequest req) { if (exchangeExecutor != null) { res = res.whenCompleteAsync((r, t) -> { /* do nothing */}, ASYNC_POOL); } + + // The mexCf is the Cf we need to abort if the SelectorManager thread + // is aborted. + PendingRequest pending = new PendingRequest(id, requestImpl, mexCf, mex, this); + registerPending(pending); return res; } catch(Throwable t) { - unreference(); + requestUnreference(); debugCompleted("ClientImpl (async)", start, userRequest); throw t; } @@ -710,8 +984,9 @@ private final static class SelectorManager extends Thread { private final List deregistrations; private final Logger debug; private final Logger debugtimeout; - HttpClientImpl owner; - ConnectionPool pool; + private final HttpClientImpl owner; + private final ConnectionPool pool; + private final AtomicReference errorRef = new AtomicReference<>(); SelectorManager(HttpClientImpl ref) throws IOException { super(null, null, @@ -726,13 +1001,22 @@ private final static class SelectorManager extends Thread { selector = Selector.open(); } + IOException selectorClosedException() { + var io = new IOException("selector manager closed"); + var cause = errorRef.get(); + if (cause != null) { + io.initCause(cause); + } + return io; + } + void eventUpdated(AsyncEvent e) throws ClosedChannelException { if (Thread.currentThread() == this) { SelectionKey key = e.channel().keyFor(selector); if (key != null && key.isValid()) { SelectorAttachment sa = (SelectorAttachment) key.attachment(); sa.register(e); - } else if (e.interestOps() != 0){ + } else if (e.interestOps() != 0) { // We don't care about paused events. // These are actually handled by // SelectorAttachment::resetInterestOps later on. @@ -749,6 +1033,7 @@ void eventUpdated(AsyncEvent e) throws ClosedChannelException { // This returns immediately. So caller not allowed to send/receive // on connection. synchronized void register(AsyncEvent e) { + if (closed) e.abort(selectorClosedException()); registrations.add(e); selector.wakeup(); } @@ -765,6 +1050,48 @@ void wakeupSelector() { selector.wakeup(); } + void abort(Throwable t) { + boolean closed = this.closed; + errorRef.compareAndSet(null, t); + if (debug.on()) { + debug.log("aborting selector manager(closed=%s): " + t, closed); + } + t = errorRef.get(); + boolean inSelectorThread = owner.isSelectorThread(); + if (!inSelectorThread) { + // abort anything pending, then close + abortPendingRequests(owner, t); + } + Set keys = new HashSet<>(); + Set toAbort = new HashSet<>(); + synchronized (this) { + if (closed = this.closed) return; + this.closed = true; + try { + keys.addAll(selector.keys()); + } catch (ClosedSelectorException ce) { + // OK - nothing to do... + } + toAbort.addAll(this.registrations); + toAbort.addAll(this.deregistrations); + this.registrations.clear(); + this.deregistrations.clear(); + } + // double check after closing + abortPendingRequests(owner, t); + + IOException io = toAbort.isEmpty() + ? null : selectorClosedException(); + for (AsyncEvent e : toAbort) { + try { + e.abort(io); + } catch (Throwable x) { + debug.log("Failed to abort event: " + x); + } + } + if (!inSelectorThread) selector.wakeup(); + } + synchronized void shutdown() { Log.logTrace("{0}: shutting down", getName()); if (debug.on()) debug.log("SelectorManager shutting down"); @@ -777,14 +1104,19 @@ synchronized void shutdown() { } } + boolean isClosed() { + return closed; + } + @Override public void run() { List> errorList = new ArrayList<>(); List readyList = new ArrayList<>(); List resetList = new ArrayList<>(); + owner.isAlive.set(true); try { if (Log.channel()) Log.logChannel(getName() + ": starting"); - while (!Thread.currentThread().isInterrupted()) { + while (!Thread.currentThread().isInterrupted() && !closed) { synchronized (this) { assert errorList.isEmpty(); assert readyList.isEmpty(); @@ -817,7 +1149,7 @@ public void run() { // may throw IOE if channel closed: that's OK sa.register(event); if (!chan.isOpen()) { - throw new IOException("Channel closed"); + throw new ClosedChannelException(); } } catch (IOException e) { Log.logTrace("{0}: {1}", getName(), e); @@ -936,7 +1268,8 @@ public void run() { selector.selectedKeys().clear(); // handle selected events - readyList.forEach((e) -> handleEvent(e, null)); + IOException ioe = closed ? selectorClosedException() : null; + readyList.forEach((e) -> handleEvent(e, ioe)); readyList.clear(); // handle errors (closed channels etc...) @@ -949,19 +1282,26 @@ public void run() { } } catch (Throwable e) { + errorRef.compareAndSet(null, e); if (!closed) { + closed = true; // set closed early so that new requests are rejected // This terminates thread. So, better just print stack trace String err = Utils.stackTrace(e); Log.logError("{0}: {1}: {2}", getName(), "HttpClientImpl shutting down due to fatal error", err); } + abortPendingRequests(owner, selectorClosedException()); if (debug.on()) debug.log("shutting down", e); if (Utils.ASSERTIONSENABLED && !debug.on()) { e.printStackTrace(System.err); // always print the stack } } finally { if (Log.channel()) Log.logChannel(getName() + ": stopping"); - shutdown(); + try { + shutdown(); + } finally { + owner.isAlive.set(false); + } } } @@ -978,7 +1318,10 @@ public void run() { /** Handles the given event. The given ioe may be null. */ void handleEvent(AsyncEvent event, IOException ioe) { - if (closed || ioe != null) { + if (ioe == null && closed) { + ioe = selectorClosedException(); + } + if (ioe != null) { event.abort(ioe); } else { event.handle(); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpConnection.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpConnection.java index 6f47a0bad6a4b..5234a25f94280 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpConnection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -31,10 +31,10 @@ import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.util.Arrays; +import java.util.Comparator; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; -import java.util.TreeMap; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.ConcurrentLinkedDeque; @@ -69,16 +69,29 @@ abstract class HttpConnection implements Closeable { final Logger debug = Utils.getDebugLogger(this::dbgString, Utils.DEBUG); final static Logger DEBUG_LOGGER = Utils.getDebugLogger( () -> "HttpConnection(SocketTube(?))", Utils.DEBUG); + public static final Comparator COMPARE_BY_ID + = Comparator.comparing(HttpConnection::id); /** The address this connection is connected to. Could be a server or a proxy. */ final InetSocketAddress address; private final HttpClientImpl client; private final TrailingOperations trailingOperations; + private final long id; HttpConnection(InetSocketAddress address, HttpClientImpl client) { this.address = address; this.client = client; trailingOperations = new TrailingOperations(); + this.id = newConnectionId(client); + } + + // This is overridden in tests + long newConnectionId(HttpClientImpl client) { + return client.newConnectionId(); + } + + private long id() { + return id; } private static final class TrailingOperations { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java b/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java index 1f6054dbe4470..92cd223a541c1 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -169,9 +169,10 @@ Duration getRemaining() { this.responseHandler = responseHandler; if (pushPromiseHandler != null) { + Executor ensureExecutedAsync = this.executor::ensureExecutedAsync; Executor executor = acc == null - ? this.executor.delegate() - : new PrivilegedExecutor(this.executor.delegate(), acc); + ? ensureExecutedAsync + : new PrivilegedExecutor(ensureExecutedAsync, acc); this.pushGroup = new PushGroup<>(pushPromiseHandler, request, executor); } else { pushGroup = null; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/PlainHttpConnection.java b/src/java.net.http/share/classes/jdk/internal/net/http/PlainHttpConnection.java index c09d862df4509..760ebcf586bc6 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/PlainHttpConnection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/PlainHttpConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -140,15 +140,18 @@ public void handle() { debug.log("ConnectEvent: connect finished: %s, cancelled: %s, Local addr: %s", finished, exchange.multi.requestCancelled(), chan.getLocalAddress()); assert finished || exchange.multi.requestCancelled() : "Expected channel to be connected"; + client().connectionOpened(PlainHttpConnection.this); // complete async since the event runs on the SelectorManager thread cf.completeAsync(() -> ConnectState.SUCCESS, client().theExecutor()); } catch (Throwable e) { if (canRetryConnect(e)) { unsuccessfulAttempts++; + // complete async since the event runs on the SelectorManager thread cf.completeAsync(() -> ConnectState.RETRY, client().theExecutor()); return; } Throwable t = Utils.toConnectException(e); + // complete async since the event runs on the SelectorManager thread client().theExecutor().execute( () -> cf.completeExceptionally(t)); close(); } @@ -156,6 +159,7 @@ public void handle() { @Override public void abort(IOException ioe) { + // complete async since the event runs on the SelectorManager thread client().theExecutor().execute( () -> cf.completeExceptionally(ioe)); close(); } @@ -188,6 +192,7 @@ public CompletableFuture connectAsync(Exchange exchange) { } if (finished) { if (debug.on()) debug.log("connect finished without blocking"); + client().connectionOpened(this); cf.complete(ConnectState.SUCCESS); } else { if (debug.on()) debug.log("registering connect event"); @@ -197,6 +202,9 @@ public CompletableFuture connectAsync(Exchange exchange) { } catch (Throwable throwable) { cf.completeExceptionally(Utils.toConnectException(throwable)); try { + if (Log.channel()) { + Log.logChannel("Closing connection: connect failed due to: " + throwable); + } close(); } catch (Exception x) { if (debug.on()) @@ -368,8 +376,15 @@ public void close() { debug.log("Closing channel: " + client().debugInterestOps(chan)); if (connectTimerEvent != null) client().cancelTimer(connectTimerEvent); - chan.close(); - tube.signalClosed(); + if (Log.channel()) { + Log.logChannel("Closing channel: " + chan); + } + try { + chan.close(); + tube.signalClosed(); + } finally { + client().connectionClosed(this); + } } catch (IOException e) { Log.logTrace("Closing resulted in " + e); } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseContent.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseContent.java index de1e67425059a..59f7a22a22ec2 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseContent.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseContent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -103,6 +103,7 @@ interface BodyParser extends Consumer { // A current-state message suitable for inclusion in an exception // detail message. String currentStateMessage(); + void onError(Throwable t); } // Returns a parser that will take care of parsing the received byte @@ -177,6 +178,12 @@ public void onSubscribe(AbstractSubscription sub) { pusher.onSubscribe(this.sub = sub); } + @Override + public void onError(Throwable t) { + closedExceptionally = t; + onComplete.accept(t); + } + @Override public String currentStateMessage() { return format("chunked transfer encoding, state: %s", state); @@ -476,6 +483,12 @@ public void onSubscribe(AbstractSubscription sub) { pusher.onSubscribe(this.sub = sub); } + @Override + public void onError(Throwable t) { + closedExceptionally = t; + onComplete.accept(t); + } + @Override public String currentStateMessage() { return format("http1_0 content, bytes received: %d", breceived); @@ -565,6 +578,16 @@ public void onSubscribe(AbstractSubscription sub) { } } + @Override + public void onError(Throwable t) { + if (contentLength != 0) { + closedExceptionally = t; + onComplete.accept(t); + } else { + onComplete.accept(null); + } + } + @Override public String currentStateMessage() { return format("fixed content-length: %d, bytes received: %d", diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java index c97a950c4ebc1..f9b546d485eaa 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -63,6 +63,7 @@ import jdk.internal.net.http.common.Logger; import jdk.internal.net.http.common.MinimalFuture; import jdk.internal.net.http.common.Utils; +import jdk.internal.net.http.HttpClientImpl.DelegatingExecutor; import static java.nio.charset.StandardCharsets.UTF_8; public class ResponseSubscribers { @@ -1144,8 +1145,8 @@ public static CompletableFuture getBodyAsync(Executor e, assert cf != null; if (TrustedSubscriber.needsExecutor(bs)) { - e = (e instanceof HttpClientImpl.DelegatingExecutor) - ? ((HttpClientImpl.DelegatingExecutor) e).delegate() : e; + e = (e instanceof DelegatingExecutor exec) + ? exec::ensureExecutedAsync : e; } e.execute(() -> { @@ -1158,12 +1159,14 @@ public static CompletableFuture getBodyAsync(Executor e, } }); } catch (Throwable t) { + // the errorHandler will complete the CF errorHandler.accept(t); } }); return cf; } catch (Throwable t) { + // the errorHandler will complete the CF errorHandler.accept(t); } return cf; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java b/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java index b0b5c373a90ec..dfbe9e6b3397b 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java @@ -341,6 +341,10 @@ public void onNext(List bufs) { void tryFlushCurrent(boolean inSelectorThread) { List bufs = current; if (bufs == null) return; + if (client.isSelectorClosed()) { + signalError(client.selectorClosedException()); + return; + } try { assert inSelectorThread == client.isSelectorThread() : "should " + (inSelectorThread ? "" : "not ") @@ -354,6 +358,10 @@ void tryFlushCurrent(boolean inSelectorThread) { if (remaining - written == 0) { current = null; if (writeDemand.tryDecrement()) { + if (client.isSelectorClosed()) { + signalError(client.selectorClosedException()); + return; + } Runnable requestMore = this::requestMore; if (inSelectorThread) { assert client.isSelectorThread(); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java index 0b9cf64d49050..f4b2600a599f0 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java @@ -32,6 +32,8 @@ import java.lang.invoke.VarHandle; import java.net.ProtocolException; import java.net.URI; +import java.net.http.HttpResponse.BodyHandler; +import java.net.http.HttpResponse.ResponseInfo; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; @@ -308,6 +310,9 @@ private boolean consumed(DataFrame df) { return endStream; } + // This method is called by Http2Connection::decrementStreamCount in order + // to make sure that the stream count is decremented only once for + // a given stream. boolean deRegister() { return DEREGISTERED.compareAndSet(this, false, true); } @@ -320,7 +325,8 @@ CompletableFuture readBodyAsync(HttpResponse.BodyHandler handler, try { Log.logTrace("Reading body on stream {0}", streamid); debug.log("Getting BodySubscriber for: " + response); - BodySubscriber bodySubscriber = handler.apply(new ResponseInfoImpl(response)); + Http2StreamResponseSubscriber bodySubscriber = + createResponseSubscriber(handler, new ResponseInfoImpl(response)); CompletableFuture cf = receiveData(bodySubscriber, executor); PushGroup pg = exchange.getPushGroup(); @@ -336,6 +342,25 @@ CompletableFuture readBodyAsync(HttpResponse.BodyHandler handler, } } + @Override + Http2StreamResponseSubscriber createResponseSubscriber(BodyHandler handler, ResponseInfo response) { + Http2StreamResponseSubscriber subscriber = + new Http2StreamResponseSubscriber<>(handler.apply(response)); + registerResponseSubscriber(subscriber); + return subscriber; + } + + // The Http2StreamResponseSubscriber is registered with the HttpClient + // to ensure that it gets completed if the SelectorManager aborts due + // to unexpected exceptions. + private void registerResponseSubscriber(Http2StreamResponseSubscriber subscriber) { + client().registerSubscriber(subscriber); + } + + private void subscriberCompleted(Http2StreamResponseSubscriber subscriber) { + client().subscriberCompleted(subscriber); + } + @Override public String toString() { return "streamid: " + streamid; @@ -393,10 +418,13 @@ CompletableFuture receiveData(BodySubscriber bodySubscriber, Executor exec if (isCanceled()) { Throwable t = getCancelCause(); responseBodyCF.completeExceptionally(t); - } else { - pendingResponseSubscriber = bodySubscriber; - sched.runOrSchedule(); // in case data waiting already to be processed } + + // ensure that the body subscriber will be subsribed and onError() is + // invoked + pendingResponseSubscriber = bodySubscriber; + sched.runOrSchedule(); // in case data waiting already to be processed, or error + return responseBodyCF; } @@ -1625,6 +1653,21 @@ public void onMaxHeaderListSizeReached(long size, int maxHeaderListSize) throws } } + final class Http2StreamResponseSubscriber extends HttpBodySubscriberWrapper { + Http2StreamResponseSubscriber(BodySubscriber subscriber) { + super(subscriber); + } + + @Override + protected void complete(Throwable t) { + try { + Stream.this.subscriberCompleted(this); + } finally { + super.complete(t); + } + } + } + private static final VarHandle STREAM_STATE; private static final VarHandle DEREGISTERED; static { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/HttpBodySubscriberWrapper.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/HttpBodySubscriberWrapper.java new file mode 100644 index 0000000000000..2f06e7c48ed3d --- /dev/null +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/HttpBodySubscriberWrapper.java @@ -0,0 +1,174 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.internal.net.http.common; + +import java.net.http.HttpResponse.BodySubscriber; +import java.nio.ByteBuffer; +import java.util.Comparator; +import java.util.List; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Flow; +import java.util.concurrent.Flow.Subscription; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; + +import jdk.internal.net.http.ResponseSubscribers.TrustedSubscriber; + +/** + * A class that wraps a user supplied {@link BodySubscriber}, but on + * which {@link #onError(Throwable)} can be invoked at any time, + * even before {@link #onSubscribe(Subscription)} has not been called + * yet. + * @param the type of the response body + */ +public class HttpBodySubscriberWrapper implements TrustedSubscriber { + + public static final Comparator> COMPARE_BY_ID + = Comparator.comparing(HttpBodySubscriberWrapper::id); + + + public static final Flow.Subscription NOP = new Flow.Subscription() { + @Override + public void request(long n) { } + public void cancel() { } + }; + + static final AtomicLong IDS = new AtomicLong(); + final long id = IDS.incrementAndGet(); + final BodySubscriber userSubscriber; + final AtomicBoolean completed = new AtomicBoolean(); + final AtomicBoolean subscribed = new AtomicBoolean(); + volatile Subscription subscription; + volatile Throwable withError; + public HttpBodySubscriberWrapper(BodySubscriber userSubscriber) { + this.userSubscriber = userSubscriber; + } + + final long id() { return id; } + + @Override + public boolean needsExecutor() { + return TrustedSubscriber.needsExecutor(userSubscriber); + } + + // propagate the error to the user subscriber, even if not + // subscribed yet. + private void propagateError(Throwable t) { + assert t != null; + try { + // if unsubscribed at this point, it will not + // get subscribed later - so do it now and + // propagate the error + // Race condition with onSubscribe: we need to wait until + // subscription is finished before calling onError; + synchronized (this) { + if (subscribed.compareAndSet(false, true)) { + userSubscriber.onSubscribe(NOP); + } + } + } finally { + // if onError throws then there is nothing to do + // here: let the caller deal with it by logging + // and closing the connection. + userSubscriber.onError(t); + } + } + + /** + * Complete the subscriber, either normally or exceptionally + * ensure that the subscriber is completed only once. + * @param t a throwable, or {@code null} + */ + protected void complete(Throwable t) { + if (completed.compareAndSet(false, true)) { + t = withError = Utils.getCompletionCause(t); + if (t == null) { + try { + assert subscribed.get(); + userSubscriber.onComplete(); + } catch (Throwable x) { + // Simply propagate the error by calling + // onError on the user subscriber, and let the + // connection be reused since we should have received + // and parsed all the bytes when we reach here. + // If onError throws in turn, then we will simply + // let that new exception flow up to the caller + // and let it deal with it. + // (i.e: log and close the connection) + // Note that rethrowing here could introduce a + // race that might cause the next send() operation to + // fail as the connection has already been put back + // into the cache when we reach here. + propagateError(t = withError = Utils.getCompletionCause(x)); + } + } else { + propagateError(t); + } + } + } + + @Override + public CompletionStage getBody() { + return userSubscriber.getBody(); + } + + @Override + public void onSubscribe(Flow.Subscription subscription) { + this.subscription = subscription; + // race condition with propagateError: we need to wait until + // subscription is finished before calling onError; + synchronized (this) { + if (subscribed.compareAndSet(false, true)) { + userSubscriber.onSubscribe(subscription); + } else { + // could be already subscribed and completed + // if an unexpected error occurred before the actual + // subscription - though that's not supposed + // happen. + assert completed.get(); + } + } + } + + @Override + public void onNext(List item) { + if (completed.get()) { + if (subscription != null) { + subscription.cancel(); + } + } else { + userSubscriber.onNext(item); + } + } + @Override + public void onError(Throwable throwable) { + complete(throwable); + } + @Override + public void onComplete() { + complete(null); + } +} diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/OperationTrackers.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/OperationTrackers.java index 0094d064532ad..e8a095cedef62 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/OperationTrackers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/OperationTrackers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 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 @@ -43,6 +43,10 @@ private OperationTrackers() { public interface Tracker { // The total number of outstanding operations long getOutstandingOperations(); + // The number of outstandanding requests: this is + // the number of CF returned by send/sendAsync which + // have not been completed. + long getOutstandingHttpRequests(); // The number of outstanding HTTP/1.1 operations. // A single HTTP/1.1 request may increment this counter // multiple times, so the value returned will be >= to @@ -53,11 +57,16 @@ public interface Tracker { long getOutstandingHttp2Streams(); // The number of active WebSockets long getOutstandingWebSocketOperations(); + // number of TCP connections still opened + long getOutstandingTcpConnections(); // Whether the facade returned to the // user is still referenced boolean isFacadeReferenced(); + // whether the Selector Manager thread is still running + boolean isSelectorAlive(); // The name of the object being tracked. String getName(); + } /** diff --git a/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java b/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java new file mode 100644 index 0000000000000..97037824a6a1f --- /dev/null +++ b/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java @@ -0,0 +1,417 @@ +/* + * Copyright (c) 2022, 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. + */ + +/* + * @test + * @bug 8277969 + * @summary Test for edge case where the executor is not accepting + * new tasks while the client is still running + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker + * @run testng/othervm + * -Djdk.internal.httpclient.debug=true + * -Djdk.httpclient.HttpClient.log=trace,headers,requests + * AsyncExecutorShutdown + */ +// -Djdk.internal.httpclient.debug=true + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UncheckedIOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpClient.Redirect; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandlers; +import java.nio.channels.ClosedChannelException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Function; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLHandshakeException; + +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsServer; +import jdk.test.lib.RandomFactory; +import jdk.test.lib.net.SimpleSSLContext; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import static java.lang.System.out; +import static java.net.http.HttpClient.Builder.NO_PROXY; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.fail; + +public class AsyncExecutorShutdown implements HttpServerAdapters { + + static { + HttpServerAdapters.enableServerLogging(); + } + static final Random RANDOM = RandomFactory.getRandom(); + + SSLContext sslContext; + HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ] + HttpTestServer httpsTestServer; // HTTPS/1.1 + HttpTestServer http2TestServer; // HTTP/2 ( h2c ) + HttpTestServer https2TestServer; // HTTP/2 ( h2 ) + String httpURI; + String httpsURI; + String http2URI; + String https2URI; + + static final String MESSAGE = "AsyncExecutorShutdown message body"; + static final int ITERATIONS = 3; + + @DataProvider(name = "positive") + public Object[][] positive() { + return new Object[][] { + { httpURI, }, + { httpsURI, }, + { http2URI, }, + { https2URI, }, + }; + } + + static final AtomicLong requestCounter = new AtomicLong(); + final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE; + + static Throwable getCause(Throwable t) { + while (t instanceof CompletionException || t instanceof ExecutionException) { + t = t.getCause(); + } + return t; + } + + static String readBody(InputStream in) { + try { + return new String(in.readAllBytes(), StandardCharsets.UTF_8); + } catch (IOException io) { + throw new UncheckedIOException(io); + } + } + + static void checkCause(String what, Throwable cause) { + Throwable t = cause; + Throwable accepted = null; + while (t != null) { + out.println(what + ": checking " + t); + if (t instanceof RejectedExecutionException) { + out.println(what + ": Got expected RejectedExecutionException in cause: " + t); + return; + } else if (t instanceof ClosedChannelException) { + out.println(what + ": Accepting ClosedChannelException as a valid cause: " + t); + accepted = t; + } + t = t.getCause(); + } + if (accepted != null) { + out.println(what + ": Didn't find expected RejectedExecutionException, " + + "but accepting " + accepted.getClass().getSimpleName() + + " as a valid cause: " + accepted); + return; + } + throw new AssertionError(what + ": Unexpected exception: " + cause, cause); + } + + @Test(dataProvider = "positive") + void testConcurrent(String uriString) throws Exception { + out.printf("%n---- starting (%s) ----%n", uriString); + ExecutorService executorService = Executors.newCachedThreadPool(); + ExecutorService readerService = Executors.newCachedThreadPool(); + HttpClient client = HttpClient.newBuilder() + .proxy(NO_PROXY) + .followRedirects(Redirect.ALWAYS) + .executor(executorService) + .sslContext(sslContext) + .build(); + TRACKER.track(client); + assert client.executor().isPresent(); + + int step = RANDOM.nextInt(ITERATIONS); + try { + List> bodies = new ArrayList<>(); + for (int i = 0; i < ITERATIONS; i++) { + URI uri = URI.create(uriString + "/concurrent/iteration-" + i); + HttpRequest request = HttpRequest.newBuilder(uri) + .header("X-uuid", "uuid-" + requestCounter.incrementAndGet()) + .build(); + out.printf("Iteration %d request: %s%n", i, request.uri()); + CompletableFuture> responseCF; + CompletableFuture bodyCF; + final int si = i; + try { + responseCF = client.sendAsync(request, BodyHandlers.ofInputStream()) + .thenApply((response) -> { + out.println(si + ": Got response: " + response); + assertEquals(response.statusCode(), 200); + return response; + }); + bodyCF = responseCF.thenApplyAsync(HttpResponse::body, readerService) + .thenApply(AsyncExecutorShutdown::readBody) + .thenApply((s) -> { assertEquals(s, MESSAGE); return s;}); + } catch (RejectedExecutionException x) { + out.println(i + ": Got expected exception: " + x); + continue; + } + long sleep = RANDOM.nextLong(5); + if (sleep > 0) { + out.printf("%d: sleeping %d ms%n", i, sleep); + Thread.sleep(sleep); + } + if (i == step) { + out.printf("%d: shutting down executor now%n", i, sleep); + executorService.shutdownNow(); + } + var cf = bodyCF.exceptionally((t) -> { + Throwable cause = getCause(t); + out.println(si + ": Got expected exception: " + cause); + if (UncheckedIOException.class.isAssignableFrom(cause.getClass())) { + if (cause.getCause() != null) { + out.println(si + ": Got expected exception: " + cause); + cause = cause.getCause(); + } + } + checkCause(String.valueOf(si), cause); + return null; + }); + bodies.add(cf); + } + CompletableFuture.allOf(bodies.toArray(new CompletableFuture[0])).get(); + } finally { + client = null; + executorService.awaitTermination(2000, TimeUnit.MILLISECONDS); + readerService.shutdown(); + readerService.awaitTermination(2000, TimeUnit.MILLISECONDS); + } + } + + @Test(dataProvider = "positive") + void testSequential(String uriString) throws Exception { + out.printf("%n---- starting (%s) ----%n", uriString); + ExecutorService executorService = Executors.newCachedThreadPool(); + ExecutorService readerService = Executors.newCachedThreadPool(); + HttpClient client = HttpClient.newBuilder() + .proxy(NO_PROXY) + .followRedirects(Redirect.ALWAYS) + .executor(executorService) + .sslContext(sslContext) + .build(); + TRACKER.track(client); + assert client.executor().isPresent(); + + int step = RANDOM.nextInt(ITERATIONS); + out.printf("will shutdown executor in step %d%n", step); + try { + for (int i = 0; i < ITERATIONS; i++) { + URI uri = URI.create(uriString + "/sequential/iteration-" + i); + HttpRequest request = HttpRequest.newBuilder(uri) + .header("X-uuid", "uuid-" + requestCounter.incrementAndGet()) + .build(); + out.printf("Iteration %d request: %s%n", i, request.uri()); + final int si = i; + CompletableFuture> responseCF; + CompletableFuture bodyCF; + try { + responseCF = client.sendAsync(request, BodyHandlers.ofInputStream()) + .thenApply((response) -> { + out.println(si + ": Got response: " + response); + assertEquals(response.statusCode(), 200); + return response; + }); + bodyCF = responseCF.thenApplyAsync(HttpResponse::body, readerService) + .thenApply(AsyncExecutorShutdown::readBody) + .thenApply((s) -> {assertEquals(s, MESSAGE); return s;}) + .thenApply((s) -> {out.println(si + ": Got body: " + s); return s;}); + } catch (RejectedExecutionException x) { + out.println(i + ": Got expected exception: " + x); + continue; + } + long sleep = RANDOM.nextLong(5); + if (sleep > 0) { + out.printf("%d: sleeping %d ms%n", i, sleep); + Thread.sleep(sleep); + } + if (i == step) { + out.printf("%d: shutting down executor now%n", i, sleep); + executorService.shutdownNow(); + } + bodyCF.handle((r,t) -> { + if (t != null) { + try { + Throwable cause = getCause(t); + out.println(si + ": Got expected exception: " + cause); + if (UncheckedIOException.class.isAssignableFrom(cause.getClass())) { + if (cause.getCause() != null) { + out.println(si + ": Got expected exception: " + cause); + cause = cause.getCause(); + } + } + checkCause(String.valueOf(si), cause); + } catch (Throwable ase) { + return CompletableFuture.failedFuture(ase); + } + return CompletableFuture.completedFuture(null); + } else { + return CompletableFuture.completedFuture(r); + } + }).thenCompose((c) -> c).get(); + } + } finally { + client = null; + executorService.awaitTermination(2000, TimeUnit.MILLISECONDS); + readerService.shutdown(); + readerService.awaitTermination(2000, TimeUnit.MILLISECONDS); + } + } + + // -- Infrastructure + + @BeforeTest + public void setup() throws Exception { + out.println("\n**** Setup ****\n"); + sslContext = new SimpleSSLContext().get(); + if (sslContext == null) + throw new AssertionError("Unexpected null sslContext"); + + InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); + + httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer.addHandler(new ServerRequestHandler(), "/http1/exec/"); + httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/exec/retry"; + HttpsServer httpsServer = HttpsServer.create(sa, 0); + httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer.addHandler(new ServerRequestHandler(),"/https1/exec/"); + httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/exec/retry"; + + http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer.addHandler(new ServerRequestHandler(), "/http2/exec/"); + http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/exec/retry"; + https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer.addHandler(new ServerRequestHandler(), "/https2/exec/"); + https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/exec/retry"; + + httpTestServer.start(); + httpsTestServer.start(); + http2TestServer.start(); + https2TestServer.start(); + } + + @AfterTest + public void teardown() throws Exception { + Thread.sleep(100); + AssertionError fail = TRACKER.checkShutdown(5000); + try { + httpTestServer.stop(); + httpsTestServer.stop(); + http2TestServer.stop(); + https2TestServer.stop(); + } finally { + if (fail != null) throw fail; + } + } + + static class ServerRequestHandler implements HttpTestHandler { + ConcurrentHashMap closedRequests = new ConcurrentHashMap<>(); + + @java.lang.Override + public void handle(HttpTestExchange t) throws IOException { + out.println("ServerRequestHandler for: " + t.getRequestURI()); + + List uuids = t.getRequestHeaders().get("X-uuid"); + if (uuids == null || uuids.size() != 1) { + readAllRequestData(t); + try (OutputStream os = t.getResponseBody()) { + String msg = "Incorrect uuid header values:[" + uuids + "]"; + (new RuntimeException(msg)).printStackTrace(); + t.sendResponseHeaders(500, -1); + os.write(msg.getBytes(UTF_8)); + } + return; + } + + String uuid = uuids.get(0); + // retrying + if (closedRequests.putIfAbsent(uuid, t.getRequestURI().toString()) == null) { + if (t.getExchangeVersion() == HttpClient.Version.HTTP_1_1) { + // Throwing an exception here only causes a retry + // with HTTP_1_1 - where it forces the server to close + // the connection. + // For HTTP/2 then throwing an IOE would cause the server + // to close the stream, and throwing anything else would + // cause it to close the connection, but neither would + // cause the client to retry. + // So we simply do not try to retry with HTTP/2. + out.println("Server will close connection, client will retry: " + + t.getRequestURI().toString()); + throw new IOException("Closing on first request"); + } + } + + // not retrying + readAllRequestData(t); + try (OutputStream os = t.getResponseBody()) { + byte[] bytes = MESSAGE.getBytes(UTF_8); + t.sendResponseHeaders(200, bytes.length); + for (int i=0; i>> responses = new ArrayList<>(); + for (int i = 0; i < ITERATIONS; i++) { + URI uri = URI.create(uriString + "/concurrent/iteration-" + i); + HttpRequest request = HttpRequest.newBuilder(uri) + .header("X-uuid", "uuid-" + requestCounter.incrementAndGet()) + .build(); + out.printf("Iteration %d request: %s%n", i, request.uri()); + CompletableFuture> responseCF; + try { + responseCF = client.sendAsync(request, BodyHandlers.ofString()); + } catch (RejectedExecutionException x) { + out.println(i + ": Got expected exception: " + x); + continue; + } + long sleep = RANDOM.nextLong(5); + if (sleep > 0) { + out.printf("%d: sleeping %d ms%n", i, sleep); + Thread.sleep(sleep); + } + if (i == step) { + out.printf("%d: shutting down executor now%n", i, sleep); + executorService.shutdownNow(); + } + final int si = i; + var cf = responseCF.thenApply((response) -> { + out.println(si + ": Got response: " + response); + out.println(si + ": Got body Path: " + response.body()); + assertEquals(response.statusCode(), 200); + assertEquals(response.body(), MESSAGE); + return response; + }).exceptionally((t) -> { + Throwable cause = getCause(t); + out.println(si + ": Got expected exception: " + cause); + checkCause(String.valueOf(si), cause); + return null; + }); + responses.add(cf); + } + CompletableFuture.allOf(responses.toArray(new CompletableFuture[0])).get(); + } finally { + client = null; + executorService.awaitTermination(2000, TimeUnit.MILLISECONDS); + } + } + + @Test(dataProvider = "positive") + void testSequential(String uriString) throws Exception { + out.printf("%n---- starting (%s) ----%n", uriString); + ExecutorService executorService = Executors.newCachedThreadPool(); + HttpClient client = HttpClient.newBuilder() + .proxy(NO_PROXY) + .followRedirects(Redirect.ALWAYS) + .executor(executorService) + .sslContext(sslContext) + .build(); + TRACKER.track(client); + assert client.executor().isPresent(); + + int step = RANDOM.nextInt(ITERATIONS); + out.printf("will shutdown executor in step %d%n", step); + try { + for (int i = 0; i < ITERATIONS; i++) { + URI uri = URI.create(uriString + "/sequential/iteration-" + i); + HttpRequest request = HttpRequest.newBuilder(uri) + .header("X-uuid", "uuid-" + requestCounter.incrementAndGet()) + .build(); + out.printf("Iteration %d request: %s%n", i, request.uri()); + CompletableFuture> responseCF; + try { + responseCF = client.sendAsync(request, BodyHandlers.ofString()); + } catch (RejectedExecutionException x) { + out.println(i + ": Got expected exception: " + x); + continue; + } + long sleep = RANDOM.nextLong(5); + if (sleep > 0) { + out.printf("%d: sleeping %d ms%n", i, sleep); + Thread.sleep(sleep); + } + if (i == step) { + out.printf("%d: shutting down executor now%n", i, sleep); + executorService.shutdownNow(); + } + final int si = i; + responseCF.thenApply((response) -> { + out.println(si + ": Got response: " + response); + out.println(si + ": Got body Path: " + response.body()); + assertEquals(response.statusCode(), 200); + assertEquals(response.body(), MESSAGE); + return response; + }).handle((r,t) -> { + if (t != null) { + try { + Throwable cause = getCause(t); + out.println(si + ": Got expected exception: " + cause); + checkCause(String.valueOf(si), cause); + } catch (Throwable ase) { + return CompletableFuture.failedFuture(ase); + } + return CompletableFuture.completedFuture(null); + } else { + return CompletableFuture.completedFuture(r); + } + }).thenCompose((c) -> c).get(); + } + } finally { + client = null; + executorService.awaitTermination(2000, TimeUnit.MILLISECONDS); + } + } + + // -- Infrastructure + + @BeforeTest + public void setup() throws Exception { + out.println("\n**** Setup ****\n"); + sslContext = new SimpleSSLContext().get(); + if (sslContext == null) + throw new AssertionError("Unexpected null sslContext"); + + InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); + + httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer.addHandler(new ServerRequestHandler(), "/http1/exec/"); + httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/exec/retry"; + HttpsServer httpsServer = HttpsServer.create(sa, 0); + httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer.addHandler(new ServerRequestHandler(),"/https1/exec/"); + httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/exec/retry"; + + http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer.addHandler(new ServerRequestHandler(), "/http2/exec/"); + http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/exec/retry"; + https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer.addHandler(new ServerRequestHandler(), "/https2/exec/"); + https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/exec/retry"; + + httpTestServer.start(); + httpsTestServer.start(); + http2TestServer.start(); + https2TestServer.start(); + } + + @AfterTest + public void teardown() throws Exception { + Thread.sleep(100); + AssertionError fail = TRACKER.check(5000); + try { + httpTestServer.stop(); + httpsTestServer.stop(); + http2TestServer.stop(); + https2TestServer.stop(); + } finally { + if (fail != null) throw fail; + } + } + + static class ServerRequestHandler implements HttpTestHandler { + ConcurrentHashMap closedRequests = new ConcurrentHashMap<>(); + + @java.lang.Override + public void handle(HttpTestExchange t) throws IOException { + out.println("ServerRequestHandler for: " + t.getRequestURI()); + + List uuids = t.getRequestHeaders().get("X-uuid"); + if (uuids == null || uuids.size() != 1) { + readAllRequestData(t); + try (OutputStream os = t.getResponseBody()) { + String msg = "Incorrect uuid header values:[" + uuids + "]"; + (new RuntimeException(msg)).printStackTrace(); + t.sendResponseHeaders(500, -1); + os.write(msg.getBytes(UTF_8)); + } + return; + } + + String uuid = uuids.get(0); + // retrying + if (closedRequests.putIfAbsent(uuid, t.getRequestURI().toString()) == null) { + if (t.getExchangeVersion() == HttpClient.Version.HTTP_1_1) { + // Throwing an exception here only causes a retry + // with HTTP_1_1 - where it forces the server to close + // the connection. + // For HTTP/2 then throwing an IOE would cause the server + // to close the stream, and throwing anything else would + // cause it to close the connection, but neither would + // cause the client to retry. + // So we simply do not try to retry with HTTP/2. + out.println("Server will close connection, client will retry: " + + t.getRequestURI().toString()); + throw new IOException("Closing on first request"); + } + } + + // not retrying + readAllRequestData(t); + try (OutputStream os = t.getResponseBody()) { + byte[] bytes = MESSAGE.getBytes(UTF_8); + t.sendResponseHeaders(200, bytes.length); + for (int i=0; i t.getOutstandingHttpOperations() > 0); + } + + public StringBuilder diagnose(StringBuilder warnings, Predicate hasOutstanding) { for (Tracker tracker : TRACKERS) { - checkOutstandingOperations(warnings, tracker); + checkOutstandingOperations(warnings, tracker, hasOutstanding); } return warnings; } @@ -76,22 +84,54 @@ public long getOutstandingClientCount() { } public AssertionError check(long graceDelayMs) { + return check(graceDelayMs, + (t) -> t.getOutstandingHttpOperations() > 0, + "outstanding operations", true); + } + + private void printThreads(String why, PrintStream out) { + out.println(why); + Arrays.stream(ManagementFactory.getThreadMXBean() + .dumpAllThreads(true, true)) + .forEach(out::println); + } + + public AssertionError check(long graceDelayMs, + Predicate hasOutstanding, + String description, + boolean printThreads) { AssertionError fail = null; - if (hasOutstandingOperations()) { - try { - Thread.sleep(graceDelayMs); - } catch (InterruptedException x) { - // OK - } - StringBuilder warnings = diagnose(new StringBuilder()); + graceDelayMs = Math.max(graceDelayMs, 100); + long delay = Math.min(graceDelayMs, 500); + var count = delay > 0 ? graceDelayMs / delay : 1; + for (int i = 0; i < count; i++) { + if (TRACKERS.stream().anyMatch(hasOutstanding)) { + System.gc(); + try { + System.out.println("Waiting for HTTP operations to terminate..."); + Thread.sleep(Math.min(graceDelayMs, Math.max(delay, 1))); + } catch (InterruptedException x) { + // OK + } + } else break; + } + if (TRACKERS.stream().anyMatch(hasOutstanding)) { + StringBuilder warnings = diagnose(new StringBuilder(), hasOutstanding); addSummary(warnings); - if (hasOutstandingOperations()) { + if (TRACKERS.stream().anyMatch(hasOutstanding)) { fail = new AssertionError(warnings.toString()); } } else { - System.out.println("PASSED: No outstanding operations found in " + System.out.println("PASSED: No " + description + " found in " + getTrackedClientCount() + " clients"); } + if (fail != null) { + Predicate isAlive = Tracker::isSelectorAlive; + if (printThreads && TRACKERS.stream().anyMatch(isAlive)) { + printThreads("Some selector manager threads are still alive: ", System.out); + printThreads("Some selector manager threads are still alive: ", System.err); + } + } return fail; } @@ -108,23 +148,49 @@ private void addSummary(StringBuilder warning) { .append(" operations still pending out of ") .append(tracked) .append(" tracked clients."); - System.out.println(warning.toString().substring(pos)); - System.err.println(warning.toString().substring(pos)); + System.out.println(warning.substring(pos)); + System.err.println(warning.substring(pos)); } - private static void checkOutstandingOperations(StringBuilder warning, Tracker tracker) { - if (tracker.getOutstandingOperations() > 0) { + private static void checkOutstandingOperations(StringBuilder warning, + Tracker tracker, + Predicate hasOutsanding) { + if (hasOutsanding.test(tracker)) { if (warning.length() > 0) warning.append("\n"); int pos = warning.length(); warning.append("WARNING: tracker for " + tracker.getName() + " has outstanding operations:"); + warning.append("\n\tPending HTTP Requests: " + tracker.getOutstandingHttpRequests()); warning.append("\n\tPending HTTP/1.1 operations: " + tracker.getOutstandingHttpOperations()); warning.append("\n\tPending HTTP/2 streams: " + tracker.getOutstandingHttp2Streams()); warning.append("\n\tPending WebSocket operations: " + tracker.getOutstandingWebSocketOperations()); + warning.append("\n\tPending TCP connections: " + tracker.getOutstandingTcpConnections()); warning.append("\n\tTotal pending operations: " + tracker.getOutstandingOperations()); warning.append("\n\tFacade referenced: " + tracker.isFacadeReferenced()); - System.out.println(warning.toString().substring(pos)); - System.err.println(warning.toString().substring(pos)); + warning.append("\n\tSelector alive: " + tracker.isSelectorAlive()); + System.out.println(warning.substring(pos)); + System.err.println(warning.substring(pos)); } } + private boolean isSelectorManager(Thread t) { + String name = t.getName(); + if (name == null) return false; + return name.contains("SelectorManager"); + } + + // This is a slightly more permissive check than the default checks, + // it only verifies that all CFs returned by send/sendAsync have been + // completed, and that all opened channels have been closed, and that + // the selector manager thread has exited. + // It doesn't check that all refcounts have reached 0. + // This is typically useful to only check that resources have been released. + public AssertionError checkShutdown(long graceDelayMs) { + Predicate isAlive = Tracker::isSelectorAlive; + Predicate hasPendingRequests = (t) -> t.getOutstandingHttpRequests() > 0; + Predicate hasPendingConnections = (t) -> t.getOutstandingTcpConnections() > 0; + AssertionError failed = check(graceDelayMs, + isAlive.or(hasPendingRequests).or(hasPendingConnections), + "outstanding unclosed resources", true); + return failed; + } } diff --git a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServer.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServer.java index fd900f956c8eb..297373761c99c 100644 --- a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServer.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServer.java @@ -26,17 +26,16 @@ import java.io.IOException; import java.net.*; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; import javax.net.ServerSocketFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLServerSocket; -import javax.net.ssl.SSLServerSocketFactory; -import javax.net.ssl.SNIServerName; import jdk.internal.net.http.frame.ErrorFrame; /** @@ -47,16 +46,19 @@ * obtained from the supplied ExecutorService. */ public class Http2TestServer implements AutoCloseable { + static final AtomicLong IDS = new AtomicLong(); + final long id = IDS.incrementAndGet(); final ServerSocket server; final boolean supportsHTTP11; volatile boolean secure; final ExecutorService exec; - volatile boolean stopping = false; + private volatile boolean stopping = false; final Map handlers; final SSLContext sslContext; final String serverName; - final HashMap connections; + final Set connections; final Properties properties; + final String name; private static ThreadFactory defaultThreadFac = (Runnable r) -> { @@ -177,6 +179,7 @@ public Http2TestServer(InetAddress localAddr, boolean supportsHTTP11) throws Exception { + this.name = "TestServer(%d)".formatted(id); this.serverName = serverName; this.supportsHTTP11 = supportsHTTP11; if (secure) { @@ -193,7 +196,7 @@ public Http2TestServer(InetAddress localAddr, this.exec = exec == null ? getDefaultExecutor() : exec; this.handlers = Collections.synchronizedMap(new HashMap<>()); this.properties = properties == null ? new Properties() : properties; - this.connections = new HashMap<>(); + this.connections = ConcurrentHashMap.newKeySet(); } /** @@ -232,7 +235,7 @@ Http2Handler getHandlerFor(String path) { Http2Handler handler = href.get(); if (handler == null) throw new RuntimeException("No handler found for path " + path); - System.err.println("Using handler for: " + bestMatch.get()); + System.err.println(name + ": Using handler for: " + bestMatch.get()); return handler; } @@ -246,8 +249,8 @@ final ServerSocket initPlaintext(int port, int backlog) throws Exception { public synchronized void stop() { // TODO: clean shutdown GoAway stopping = true; - System.err.printf("Server stopping %d connections\n", connections.size()); - for (Http2TestServerConnection connection : connections.values()) { + System.err.printf("%s: stopping %d connections\n", name, connections.size()); + for (Http2TestServerConnection connection : connections) { connection.close(ErrorFrame.NO_ERROR); } try { @@ -284,11 +287,56 @@ public String serverName() { private synchronized void putConnection(InetSocketAddress addr, Http2TestServerConnection c) { if (!stopping) - connections.put(addr, c); + connections.add(c); } private synchronized void removeConnection(InetSocketAddress addr, Http2TestServerConnection c) { - connections.remove(addr, c); + connections.remove(c); + } + + record AcceptedConnection(Http2TestServer server, + Socket socket) { + void startConnection() { + String name = server.name; + Http2TestServerConnection c = null; + InetSocketAddress addr = null; + try { + addr = (InetSocketAddress) socket.getRemoteSocketAddress(); + System.err.println(name + ": creating connection"); + c = server.createConnection(server, socket, server.exchangeSupplier); + server.putConnection(addr, c); + System.err.println(name + ": starting connection"); + c.run(); + System.err.println(name + ": connection started"); + } catch (Throwable e) { + boolean stopping = server.stopping; + if (!stopping) { + System.err.println(name + ": unexpected exception: " + e); + e.printStackTrace(); + } + // we should not reach here, but if we do + // the connection might not have been closed + // and if so then the client might wait + // forever. + if (c != null) { + server.removeConnection(addr, c); + } + try { + if (c != null) c.close(ErrorFrame.PROTOCOL_ERROR); + } catch (Exception x) { + if (!stopping) + System.err.println(name + ": failed to close connection: " + e); + } finally { + try { + socket.close(); + } catch (IOException x) { + if (!stopping) + System.err.println(name + ": failed to close socket: " + e); + } + } + System.err.println(name + ": failed to start connection: " + e); + } + } } /** @@ -298,38 +346,37 @@ public void start() { exec.submit(() -> { try { while (!stopping) { + System.err.println(name + ": accepting connections"); Socket socket = server.accept(); - Http2TestServerConnection c = null; - InetSocketAddress addr = null; + System.err.println(name + ": connection accepted"); try { - addr = (InetSocketAddress) socket.getRemoteSocketAddress(); - c = createConnection(this, socket, exchangeSupplier); - putConnection(addr, c); - c.run(); + var accepted = new AcceptedConnection(this, socket); + exec.submit(accepted::startConnection); } catch (Throwable e) { + if (!stopping) { + System.err.println(name + ": unexpected exception: " + e); + e.printStackTrace(); + } // we should not reach here, but if we do // the connection might not have been closed // and if so then the client might wait // forever. - if (c != null) { - removeConnection(addr, c); - c.close(ErrorFrame.PROTOCOL_ERROR); - } else { - socket.close(); - } - System.err.println("TestServer: start exception: " + e); + System.err.println(name + ": start exception: " + e); } + System.err.println(name + ": stopping is: " + stopping); } } catch (SecurityException se) { - System.err.println("TestServer: terminating, caught " + se); + System.err.println(name + ": terminating, caught " + se); se.printStackTrace(); stopping = true; try { server.close(); } catch (IOException ioe) { /* ignore */} } catch (Throwable e) { if (!stopping) { - System.err.println("TestServer: terminating, caught " + e); + System.err.println(name + ": terminating, caught " + e); e.printStackTrace(); } + } finally { + System.err.println(name + ": finished"); } }); } @@ -343,6 +390,7 @@ protected Http2TestServerConnection createConnection(Http2TestServer http2TestSe @Override public void close() throws Exception { + System.err.println(name + ": closing"); stop(); } } diff --git a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/ConnectionPoolTest.java b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/ConnectionPoolTest.java index 7d900f30cbf3c..991f30093296b 100644 --- a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/ConnectionPoolTest.java +++ b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/ConnectionPoolTest.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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.Flow; +import java.util.concurrent.atomic.AtomicLong; import java.util.stream.IntStream; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -62,7 +63,6 @@ * connection deadlines and purges the right connections * from the cache. * @bug 8187044 8187111 8221395 - * @author danielfuchs */ public class ConnectionPoolTest { @@ -441,6 +441,8 @@ protected void implConfigureBlocking(boolean block) throws IOException { // Emulates an HttpConnection that has a strong reference to its HttpClient. static class HttpConnectionStub extends HttpConnection { + static final AtomicLong IDS = new AtomicLong(); + public HttpConnectionStub( HttpClient client, InetSocketAddress address, @@ -473,6 +475,12 @@ public HttpConnectionStub( final SocketChannel channel; volatile boolean closed, finished; + // Called from within super constructor + @Override + long newConnectionId(HttpClientImpl client) { + return IDS.incrementAndGet(); + } + // Used for testing closeOrReturnToPool. void finish(boolean finished) { this.finished = finished; } void reopen() { closed = finished = false;} diff --git a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLEchoTubeTest.java b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLEchoTubeTest.java index 82bc48f19cbcd..2884b74eee5d9 100644 --- a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLEchoTubeTest.java +++ b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLEchoTubeTest.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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -299,12 +299,12 @@ private void requestMore() { Flow.Subscription s = subscription; if (s == null || cancelled.get()) return; long unfulfilled = queue.size() + --requested; - if (unfulfilled <= maxQueueSize/2) { + if (unfulfilled <= maxQueueSize / 2) { long req = maxQueueSize - unfulfilled; requested += req; s.request(req); System.out.printf("EchoTube request: %s [requested:%s, queue:%s, unfulfilled:%s]%n", - req, requested-req, queue.size(), unfulfilled ); + req, requested - req, queue.size(), unfulfilled); } } From 89770f2e4954592566f3104c8135eaeb434139f1 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 17 Jun 2025 07:55:40 +0000 Subject: [PATCH 316/846] 8285032: vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy008/ fails with "eventSet.suspendPolicy() != policyExpected" Backport-of: 5c0934931b097baf76c1f6a25f0c0b73af45ffc3 --- .../suspendPolicy/suspendpolicy008.java | 17 ++++++------ .../nsk/share/jdi/EventFilters.java | 6 ++++- .../vmTestbase/nsk/share/jdi/JDIBase.java | 26 +++++++++++++------ 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy008.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy008.java index 7690717a2cac4..3dbc1458ce952 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy008.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy008.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -247,8 +247,8 @@ private void testRun() getEventSet(); cpRequest.disable(); - ClassPrepareEvent event = (ClassPrepareEvent) eventIterator.next(); - debuggeeClass = event.referenceType(); + ClassPrepareEvent cpEvent = (ClassPrepareEvent) eventIterator.next(); + debuggeeClass = cpEvent.referenceType(); if (!debuggeeClass.name().equals(debuggeeName)) throw new JDITestRuntimeException("** Unexpected ClassName for ClassPrepareEvent **"); @@ -371,13 +371,14 @@ private void testRun() } mainThread.resume(); - getEventSet(); + getEventSetForThreadStartDeath("thread" + i); - if ( !(eventIterator.nextEvent() instanceof ThreadStartEvent)) { - log3("ERROR: new event is not ThreadStartEvent"); + Event event = eventIterator.nextEvent(); + if (!(event instanceof ThreadStartEvent)) { + log3("ERROR: new event is not ThreadStartEvent: " + event); testExitCode = FAILED; } else { - log2("......got : instanceof ThreadStartEvent"); + log2("......got : instanceof ThreadStartEvent: " + event); policy = eventSet.suspendPolicy(); if (policy != policyExpected[i]) { log3("ERROR: eventSet.suspendPolicy() != policyExpected"); @@ -418,8 +419,6 @@ private ThreadStartRequest settingThreadStartRequest(int suspendPolicy, throws JDITestRuntimeException { try { ThreadStartRequest tsr = eventRManager.createThreadStartRequest(); -// tsr.addThreadFilter(mainThread); - tsr.addCountFilter(1); tsr.setSuspendPolicy(suspendPolicy); tsr.putProperty("number", property); return tsr; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/EventFilters.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/EventFilters.java index 8dbae59e8e434..ef24e59387787 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/EventFilters.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/EventFilters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -337,6 +337,10 @@ public static boolean filtered(Event event) { if (event.toString().contains("JFR request timer")) return true; + // Filter out any carrier thread that starts while running the test. + if (event.toString().contains("ForkJoinPool")) + return true; + return false; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIBase.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIBase.java index d20a084a6322d..795ac24afca4b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIBase.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -165,18 +165,21 @@ protected void getEventSetForThreadStartDeath(String threadName) throws JDITestR Event event = eventIterator.nextEvent(); if (event instanceof ThreadStartEvent evt) { if (evt.thread().name().equals(threadName)) { + log2("Got ThreadStartEvent for '" + evt.thread().name()); break; } log2("Got ThreadStartEvent for '" + evt.thread().name() + "' instead of '" + threadName + "', skipping"); } else if (event instanceof ThreadDeathEvent evt) { if (evt.thread().name().equals(threadName)) { + log2("Got ThreadDeathEvent for '" + evt.thread().name()); break; } log2("Got ThreadDeathEvent for '" + evt.thread().name() + "' instead of '" + threadName + "', skipping"); } else { // not ThreadStartEvent nor ThreadDeathEvent + log2("Did't get ThreadStartEvent or ThreadDeathEvent: " + event); break; } eventSet.resume(); @@ -188,15 +191,22 @@ protected void getEventSetForThreadStartDeath(String threadName) throws JDITestR protected void breakpointForCommunication() throws JDITestRuntimeException { log2("breakpointForCommunication"); - getEventSet(); + while (true) { + getEventSet(); - Event event = eventIterator.nextEvent(); - if (event instanceof BreakpointEvent) { - bpEvent = (BreakpointEvent) event; - return; - } + Event event = eventIterator.nextEvent(); + if (event instanceof BreakpointEvent) { + bpEvent = (BreakpointEvent) event; + return; + } - throw new JDITestRuntimeException("** event '" + event + "' IS NOT a breakpoint **"); + if (EventFilters.filtered(event)) { + // We filter out spurious ThreadStartEvents + continue; + } + + throw new JDITestRuntimeException("** event '" + event + "' IS NOT a breakpoint **"); + } } // Similar to breakpointForCommunication, but skips Locatable events from unexpected locations. From 2a83c8773f3fbcf54f5ab34942f560dbd2fec6e5 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 17 Jun 2025 08:05:13 +0000 Subject: [PATCH 317/846] 8286194: ExecutorShutdown test fails intermittently Backport-of: 04df8b74379c9de7b20931fea1642f82569d3a2d --- .../jdk/internal/net/http/Http1Exchange.java | 27 +++++-- .../jdk/internal/net/http/Http1Request.java | 2 + .../internal/net/http/Http2Connection.java | 12 +-- .../jdk/internal/net/http/HttpClientImpl.java | 38 +++++---- .../net/http/common/SSLFlowDelegate.java | 3 +- .../net/http/common/SubscriberWrapper.java | 4 +- .../java/net/httpclient/ReferenceTracker.java | 77 +++++++++++++++++++ 7 files changed, 135 insertions(+), 28 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java index 2e32c5b828a02..4b7d55c3b3466 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java @@ -148,13 +148,26 @@ final boolean isSubscribed() { } final void setSubscription(Flow.Subscription subscription) { - this.subscription = subscription; - whenSubscribed.complete(subscription); + Flow.Subscription sub; + synchronized (this) { + if ((sub = this.subscription) == null) { + this.subscription = sub = subscription; + } + } + if (sub == subscription) { + whenSubscribed.complete(subscription); + } else subscription.cancel(); } final void cancelSubscription() { try { - subscription.cancel(); + Flow.Subscription sub; + synchronized (this) { + if ((sub = this.subscription) == null) { + this.subscription = sub = HttpBodySubscriberWrapper.NOP; + } + } + sub.cancel(); } catch(Throwable t) { String msg = "Ignoring exception raised when canceling BodyPublisher subscription"; if (debug.on()) debug.log("%s: %s", msg, t); @@ -779,9 +792,10 @@ public void run() { return; } - if (debug.on()) debug.log(() -> "hasOutgoing = " + hasOutgoing()); + if (debug.on()) debug.log(() -> "hasOutgoing = " + hasOutgoing() + ", demand = " + demand.get()); while (hasOutgoing() && demand.tryDecrement()) { DataPair dp = getOutgoing(); + if (debug.on()) debug.log("outgoing: " + dp); if (dp == null) break; @@ -803,7 +817,10 @@ public void run() { // The next Subscriber will eventually take over. } else { - if (checkRequestCancelled()) return; + if (checkRequestCancelled()) { + if (debug.on()) debug.log("Request cancelled!"); + return; + } if (debug.on()) debug.log("onNext with " + Utils.remaining(data) + " bytes"); subscriber.onNext(data); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java index d1d9daf70a985..84c0bd7ea0ecf 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java @@ -338,6 +338,7 @@ public void onSubscribe(Flow.Subscription subscription) { if (isSubscribed()) { Throwable t = new IllegalStateException("already subscribed"); http1Exchange.appendToOutgoing(t); + subscription.cancel(); } else { setSubscription(subscription); } @@ -402,6 +403,7 @@ public void onSubscribe(Flow.Subscription subscription) { if (isSubscribed()) { Throwable t = new IllegalStateException("already subscribed"); http1Exchange.appendToOutgoing(t); + subscription.cancel(); } else { setSubscription(subscription); } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java index 45b64315d65dc..819c72de6632c 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java @@ -704,11 +704,13 @@ final int maxConcurrentServerInitiatedStreams() { void close() { Log.logTrace("Closing HTTP/2 connection: to {0}", connection.address()); - GoAwayFrame f = new GoAwayFrame(0, - ErrorFrame.NO_ERROR, - "Requested by user".getBytes(UTF_8)); - // TODO: set last stream. For now zero ok. - sendFrame(f); + if (connection.channel().isOpen()) { + GoAwayFrame f = new GoAwayFrame(0, + ErrorFrame.NO_ERROR, + "Requested by user".getBytes(UTF_8)); + // TODO: set last stream. For now zero ok. + sendFrame(f); + } } long count; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java index f30ba9d1e2e61..eb3584cc881c2 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java @@ -1032,18 +1032,21 @@ void eventUpdated(AsyncEvent e) throws ClosedChannelException { // This returns immediately. So caller not allowed to send/receive // on connection. - synchronized void register(AsyncEvent e) { - if (closed) e.abort(selectorClosedException()); - registrations.add(e); - selector.wakeup(); - } - - synchronized void cancel(SocketChannel e) { - SelectionKey key = e.keyFor(selector); - if (key != null) { - key.cancel(); + void register(AsyncEvent e) { + var closed = this.closed; + if (!closed) { + synchronized (this) { + closed = this.closed; + if (!closed) { + registrations.add(e); + } + } + } + if (closed) { + e.abort(selectorClosedException()); + } else { + selector.wakeup(); } - selector.wakeup(); } void wakeupSelector() { @@ -1092,12 +1095,15 @@ void abort(Throwable t) { if (!inSelectorThread) selector.wakeup(); } - synchronized void shutdown() { - Log.logTrace("{0}: shutting down", getName()); - if (debug.on()) debug.log("SelectorManager shutting down"); - closed = true; + // Only called by the selector manager thread + private void shutdown() { try { - selector.close(); + synchronized (this) { + Log.logTrace("{0}: shutting down", getName()); + if (debug.on()) debug.log("SelectorManager shutting down"); + closed = true; + selector.close(); + } } catch (IOException ignored) { } finally { owner.stop(); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java index aefae6507dc30..e64e4034a1ba1 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -795,6 +795,7 @@ private void processData() { + hsTriggered() + ", needWrap:" + needWrap()); while (Utils.synchronizedRemaining(writeList) > 0 || hsTriggered() || needWrap()) { + if (scheduler.isStopped()) return; ByteBuffer[] outbufs = writeList.toArray(Utils.EMPTY_BB_ARRAY); EngineResult result = wrapBuffers(outbufs); if (debugw.on()) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/SubscriberWrapper.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/SubscriberWrapper.java index 7c7772cc08530..43fbc2a1e460e 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/SubscriberWrapper.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/SubscriberWrapper.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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -344,6 +344,7 @@ final boolean hasNoOutputData() { } void upstreamWindowUpdate() { + if (pushScheduler.isStopped()) return; long downstreamQueueSize = outputQ.size(); long upstreamWindowSize = upstreamWindow.get(); long n = upstreamWindowUpdate(upstreamWindowSize, downstreamQueueSize); @@ -379,6 +380,7 @@ public void onNext(List item) { } private void upstreamRequest(long n) { + if (pushScheduler.isStopped()) return; if (debug.on()) debug.log("requesting %d", n); upstreamWindow.getAndAdd(n); upstreamSubscription.request(n); diff --git a/test/jdk/java/net/httpclient/ReferenceTracker.java b/test/jdk/java/net/httpclient/ReferenceTracker.java index 3af8033f622c7..df26c0f790529 100644 --- a/test/jdk/java/net/httpclient/ReferenceTracker.java +++ b/test/jdk/java/net/httpclient/ReferenceTracker.java @@ -25,7 +25,10 @@ import jdk.internal.net.http.common.OperationTrackers.Tracker; import java.io.PrintStream; +import java.lang.management.LockInfo; import java.lang.management.ManagementFactory; +import java.lang.management.MonitorInfo; +import java.lang.management.ThreadInfo; import java.net.http.HttpClient; import java.util.Arrays; import java.util.concurrent.ConcurrentLinkedQueue; @@ -89,10 +92,84 @@ public AssertionError check(long graceDelayMs) { "outstanding operations", true); } + // This method is copied from ThreadInfo::toString, but removes the + // limit on the stack trace depth (8 frames max) that ThreadInfo::toString + // forcefully implement. We want to print all frames for better diagnosis. + private static String toString(ThreadInfo info) { + StringBuilder sb = new StringBuilder("\"" + info.getThreadName() + "\"" + + (info.isDaemon() ? " daemon" : "") + + " prio=" + info.getPriority() + + " Id=" + info.getThreadId() + " " + + info.getThreadState()); + if (info.getLockName() != null) { + sb.append(" on " + info.getLockName()); + } + if (info.getLockOwnerName() != null) { + sb.append(" owned by \"" + info.getLockOwnerName() + + "\" Id=" + info.getLockOwnerId()); + } + if (info.isSuspended()) { + sb.append(" (suspended)"); + } + if (info.isInNative()) { + sb.append(" (in native)"); + } + sb.append('\n'); + int i = 0; + var stackTrace = info.getStackTrace(); + for (; i < stackTrace.length ; i++) { + StackTraceElement ste = stackTrace[i]; + sb.append("\tat " + ste.toString()); + sb.append('\n'); + if (i == 0 && info.getLockInfo() != null) { + Thread.State ts = info.getThreadState(); + switch (ts) { + case BLOCKED: + sb.append("\t- blocked on " + info.getLockInfo()); + sb.append('\n'); + break; + case WAITING: + sb.append("\t- waiting on " + info.getLockInfo()); + sb.append('\n'); + break; + case TIMED_WAITING: + sb.append("\t- waiting on " + info.getLockInfo()); + sb.append('\n'); + break; + default: + } + } + + for (MonitorInfo mi : info.getLockedMonitors()) { + if (mi.getLockedStackDepth() == i) { + sb.append("\t- locked " + mi); + sb.append('\n'); + } + } + } + if (i < stackTrace.length) { + sb.append("\t..."); + sb.append('\n'); + } + + LockInfo[] locks = info.getLockedSynchronizers(); + if (locks.length > 0) { + sb.append("\n\tNumber of locked synchronizers = " + locks.length); + sb.append('\n'); + for (LockInfo li : locks) { + sb.append("\t- " + li); + sb.append('\n'); + } + } + sb.append('\n'); + return sb.toString(); + } + private void printThreads(String why, PrintStream out) { out.println(why); Arrays.stream(ManagementFactory.getThreadMXBean() .dumpAllThreads(true, true)) + .map(ReferenceTracker::toString) .forEach(out::println); } From 2e40718823b869e9d49b5756b52cb16e7f5923a5 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 17 Jun 2025 08:06:39 +0000 Subject: [PATCH 318/846] 8298514: vmTestbase/nsk/jdi/EventRequestManager/threadDeathRequests/thrdeathreq002/TestDescription.java fails with usage tracker Backport-of: a120764cc4636b3b0cd128d43de148bdc3f4513b --- .../threadDeathRequests/thrdeathreq002.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/threadDeathRequests/thrdeathreq002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/threadDeathRequests/thrdeathreq002.java index ac3ab653fa928..d725958ff6516 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/threadDeathRequests/thrdeathreq002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/threadDeathRequests/thrdeathreq002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -266,7 +266,7 @@ private void testRun() for (int i = 0; ; i++) { vm.resume(); - breakpointForCommunication(); + breakpointForCommunication(debuggeeName); int instruction = ((IntegerValue) (debuggeeClass.getValue(debuggeeClass.fieldByName("instruction")))).value(); From df3ea97e3556fe813a69981aa261d3e44ec66496 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 17 Jun 2025 08:08:12 +0000 Subject: [PATCH 319/846] 8167252: Some of Charset.availableCharsets() does not contain itself Backport-of: 3eeb681a0de87baa12b6eac5966e7f707b76c8bf --- .../share/classes/sun/nio/cs/Unicode.java | 8 +++++- .../sun/nio/cs/ext/EUC_JP_Open.java.template | 5 ++-- .../classes/sun/nio/cs/ext/JISAutoDetect.java | 3 ++- .../java/nio/charset/Charset/Contains.java | 27 +++++++++++++++++-- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/java.base/share/classes/sun/nio/cs/Unicode.java b/src/java.base/share/classes/sun/nio/cs/Unicode.java index fa97b6f36f5f1..aac77a13ffb98 100644 --- a/src/java.base/share/classes/sun/nio/cs/Unicode.java +++ b/src/java.base/share/classes/sun/nio/cs/Unicode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -45,6 +45,12 @@ public boolean contains(Charset cs) { || (cs instanceof UTF_16BE) || (cs instanceof UTF_16LE) || (cs instanceof UTF_16LE_BOM) + || (cs instanceof CESU_8) + || (cs instanceof UTF_32) + || (cs instanceof UTF_32BE) + || (cs instanceof UTF_32BE_BOM) + || (cs instanceof UTF_32LE) + || (cs instanceof UTF_32LE_BOM) || (cs.name().equals("GBK")) || (cs.name().equals("GB18030")) || (cs.name().equals("ISO-8859-2")) diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_JP_Open.java.template b/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_JP_Open.java.template index 9c86e7ac71988..bc9139cbc7081 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_JP_Open.java.template +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_JP_Open.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -51,7 +51,8 @@ public class EUC_JP_Open public boolean contains(Charset cs) { return ((cs.name().equals("US-ASCII")) || (cs instanceof JIS_X_0201) - || (cs instanceof EUC_JP)); + || (cs instanceof EUC_JP) + || (cs instanceof EUC_JP_Open)); } public CharsetDecoder newDecoder() { diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/JISAutoDetect.java b/src/jdk.charsets/share/classes/sun/nio/cs/ext/JISAutoDetect.java index b043ca09d74e9..85519b499817e 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/JISAutoDetect.java +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/JISAutoDetect.java @@ -60,7 +60,8 @@ public boolean contains(Charset cs) { return ((cs.name().equals("US-ASCII")) || (cs instanceof SJIS) || (cs instanceof EUC_JP) - || (cs instanceof ISO2022_JP)); + || (cs instanceof ISO2022_JP) + || (cs instanceof JISAutoDetect)); } public boolean canEncode() { diff --git a/test/jdk/java/nio/charset/Charset/Contains.java b/test/jdk/java/nio/charset/Charset/Contains.java index 302809830887a..0e5cf63723196 100644 --- a/test/jdk/java/nio/charset/Charset/Contains.java +++ b/test/jdk/java/nio/charset/Charset/Contains.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -23,7 +23,7 @@ /* @test * @summary Unit test for charset containment - * @bug 6798572 + * @bug 6798572 8167252 * @modules jdk.charsets */ @@ -93,6 +93,8 @@ public static void main(String[] args) throws Exception { ck(cp1252, cp1252, true); checkUTF(); + + containsSelfTest(); } static void checkUTF() throws Exception { @@ -103,6 +105,27 @@ static void checkUTF() throws Exception { true); } + /** + * Tests the assertion in the contains() method: "Every charset contains itself." + */ + static void containsSelfTest() { + boolean failed = false; + + for (var entry : Charset.availableCharsets().entrySet()) { + Charset charset = entry.getValue(); + boolean contains = charset.contains(charset); + + System.out.println("Charset(" + charset.name() + ").contains(Charset(" + charset.name() + + ")) returns " + contains); + if (!contains) { + failed = true; + } + } + if (failed) { + throw new RuntimeException("Charset.contains(itself) returns false for some charsets"); + } + } + static String[] utfNames = {"utf-16", "utf-8", "utf-16le", From 49027ee5af77f3f2580c04759a8e37986b108deb Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 17 Jun 2025 08:09:29 +0000 Subject: [PATCH 320/846] 8295210: IR framework should not whitelist -XX:-UseTLAB Backport-of: 31dcda5d67c90ecd571b0a943bcedc0bfe3f1fba --- test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java | 1 - 1 file changed, 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java index 424399682dd63..24f6615eb8301 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java @@ -110,7 +110,6 @@ public class TestFramework { "Trace", "Print", "Verify", - "TLAB", "UseNewCode", "Xmn", "Xms", From 35325584ecf40cee0b8ef9096e45035347df88b0 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 17 Jun 2025 08:11:02 +0000 Subject: [PATCH 321/846] 8334394: Race condition in Class::protectionDomain Backport-of: c3226aaeb810521257e961be5763552c86ee5651 --- .../share/classes/java/lang/Class.java | 36 +++++---- .../java/lang/Class/ProtectionDomainRace.java | 80 +++++++++++++++++++ 2 files changed, 99 insertions(+), 17 deletions(-) create mode 100644 test/jdk/java/lang/Class/ProtectionDomainRace.java diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index 61cbc42243c78..aceba5dd9f09a 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -53,7 +53,9 @@ import java.lang.constant.Constable; import java.net.URL; import java.security.AccessController; +import java.security.Permissions; import java.security.PrivilegedAction; +import java.security.ProtectionDomain; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -2966,10 +2968,6 @@ private boolean isOpenToCaller(String name, Class caller) { return true; } - - /** protection domain returned when the internal domain is null */ - private static java.security.ProtectionDomain allPermDomain; - /** * Returns the {@code ProtectionDomain} of this class. If there is a * security manager installed, this method first calls the security @@ -2990,7 +2988,7 @@ private boolean isOpenToCaller(String name, Class caller) { * @see java.lang.RuntimePermission * @since 1.2 */ - public java.security.ProtectionDomain getProtectionDomain() { + public ProtectionDomain getProtectionDomain() { @SuppressWarnings("removal") SecurityManager sm = System.getSecurityManager(); if (sm != null) { @@ -2999,26 +2997,30 @@ public java.security.ProtectionDomain getProtectionDomain() { return protectionDomain(); } + /** Holder for the protection domain returned when the internal domain is null */ + private static class Holder { + private static final ProtectionDomain allPermDomain; + static { + Permissions perms = new Permissions(); + perms.add(SecurityConstants.ALL_PERMISSION); + allPermDomain = new ProtectionDomain(null, perms); + } + } + // package-private - java.security.ProtectionDomain protectionDomain() { - java.security.ProtectionDomain pd = getProtectionDomain0(); + ProtectionDomain protectionDomain() { + ProtectionDomain pd = getProtectionDomain0(); if (pd == null) { - if (allPermDomain == null) { - java.security.Permissions perms = - new java.security.Permissions(); - perms.add(SecurityConstants.ALL_PERMISSION); - allPermDomain = - new java.security.ProtectionDomain(null, perms); - } - pd = allPermDomain; + return Holder.allPermDomain; + } else { + return pd; } - return pd; } /** * Returns the ProtectionDomain of this class. */ - private native java.security.ProtectionDomain getProtectionDomain0(); + private native ProtectionDomain getProtectionDomain0(); /* * Return the Virtual Machine's Class object for the named diff --git a/test/jdk/java/lang/Class/ProtectionDomainRace.java b/test/jdk/java/lang/Class/ProtectionDomainRace.java new file mode 100644 index 0000000000000..52b45d7ab105f --- /dev/null +++ b/test/jdk/java/lang/Class/ProtectionDomainRace.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 8334394 + * @summary ensure there is no race condition in Class::protectionDomain + * @run main/othervm ProtectionDomainRace + */ +import javax.security.auth.Subject; +import java.security.PrivilegedAction; + +/** + * Without the code fix, this test would fail with + * java.lang.AssertionError: sun.security.util.ResourcesMgr (PD) + * at java.base/java.lang.invoke.MethodHandleImpl$BindCaller.checkInjectedInvoker(MethodHandleImpl.java:1209) + * at java.base/java.lang.invoke.MethodHandleImpl$BindCaller.makeInjectedInvoker(MethodHandleImpl.java:1110) + * at java.base/java.lang.invoke.MethodHandleImpl$BindCaller$1.computeValue(MethodHandleImpl.java:1117) + * at java.base/java.lang.invoke.MethodHandleImpl$BindCaller$1.computeValue(MethodHandleImpl.java:1114) + * at java.base/java.lang.ClassValue.getFromHashMap(ClassValue.java:229) + * at java.base/java.lang.ClassValue.getFromBackup(ClassValue.java:211) + * at java.base/java.lang.ClassValue.get(ClassValue.java:117) + * at java.base/java.lang.invoke.MethodHandleImpl$BindCaller.bindCallerWithInjectedInvoker(MethodHandleImpl.java:1089) + * at java.base/java.lang.invoke.MethodHandleImpl$BindCaller.bindCaller(MethodHandleImpl.java:1077) + * at java.base/java.lang.invoke.MethodHandleImpl.bindCaller(MethodHandleImpl.java:1032) + * at java.base/java.lang.invoke.MethodHandles$Lookup.maybeBindCaller(MethodHandles.java:4149) + * at java.base/java.lang.invoke.MethodHandles$Lookup.getDirectMethodCommon(MethodHandles.java:4133) + * at java.base/java.lang.invoke.MethodHandles$Lookup.getDirectMethodNoSecurityManager(MethodHandles.java:4077) + * at java.base/java.lang.invoke.MethodHandles$Lookup.getDirectMethodForConstant(MethodHandles.java:4326) + * at java.base/java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:4274) + * at java.base/java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:628) + * at java.base/sun.security.util.ResourcesMgr.getBundle(ResourcesMgr.java:54) + * at java.base/sun.security.util.ResourcesMgr.getString(ResourcesMgr.java:40) + * at java.base/javax.security.auth.Subject.doAs(Subject.java:517) + * ... + * as the Class::protectionDomain might assign different objects to the (original) allPermDomain field. + */ +public class ProtectionDomainRace { + private static volatile Throwable failed = null; + public static void main(String[] args) throws Throwable { + PrivilegedAction pa = () -> null; + Thread[] threads = new Thread[100]; + for (int i = 0; i < 100; i++) { + threads[i] = new Thread(() -> { + try { + Subject.doAs(null, pa); + } catch (Throwable t) { + failed = t; + } + }); + threads[i].start(); + } + for (int i = 0; i < 100; i++) { + threads[i].join(); + } + if (failed != null) { + throw failed; + } + } +} From c2bd339c4af3782b04001b3617720a411e614b8b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 17 Jun 2025 08:12:29 +0000 Subject: [PATCH 322/846] 8332551: Test vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001/TestDescription.java timed out Backport-of: 7ea773056433c467dbd321a0a063f4789552ef89 --- .../MemoryNotificationInfo/from/from001.java | 91 ++++++++++++------- .../from/from001/TestDescription.java | 11 ++- 2 files changed, 67 insertions(+), 35 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001.java index b6ca1c84e9c4c..6e50e6998cdd5 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import java.util.List; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; import nsk.share.*; import nsk.share.gc.Algorithms; import nsk.share.gc.Memory; @@ -39,6 +40,7 @@ public class from001 { private static boolean testFailed = false; + private static final int MAX_TRIES = 6; // limit attempts to receive Notification data public static void main(String[] args) { @@ -62,8 +64,8 @@ public static void main(String[] args) { log.display("null CompositeData check passed."); - // 2. Check CompositeData that doest not represnt - // MemoryNotificationInfo - IllegalArgumentException must be thrown + // 2. Check CompositeData that does not represent MemoryNotificationInfo + // throws IllegalArgumentException ObjectName mbeanObjectName = null; CompositeData cdata = null; @@ -85,12 +87,13 @@ public static void main(String[] args) { testFailed = true; } catch (IllegalArgumentException e) { - // Expected: CompositeData doest not represnt MemoryNotificationInfo + // Expected: CompositeData does not represent MemoryNotificationInfo } - log.display("check for CompositeData doest not represnt MemoryNotificationInfo passed."); + log.display("check that CompositeData does not represent MemoryNotificationInfo passed."); - // 3. Check correct CompositeData + // 3. Check correct CompositeData usage: + // First try to provoke a Notification on a MemoryPool. Object poolObject = null; try { mbeanObjectName = new ObjectName(ManagementFactory.MEMORY_MXBEAN_NAME); @@ -123,7 +126,11 @@ public static void main(String[] args) { throw new TestFailure("TEST FAILED. See log."); } - // eat memory just to emmit notification + if (poolObject == null) { + throw new TestFailure("No memory pool found to test."); + } + + // eat memory just to emit notification Stresser stresser = new Stresser(args) { @Override @@ -133,41 +140,57 @@ public boolean continueExecution() { } }; stresser.start(0);// we use timeout, not iterations - GarbageUtils.eatMemory(stresser); - - boolean messageNotRecieved = true; - while(messageNotRecieved) { + int oomCount = GarbageUtils.eatMemory(stresser); + log.display("eatMemory returns OOM count: " + oomCount); + + // Check for the message. Poll on queue to avoid waiting forver on failure. + // Notification is known to fail, very rarely, with -Xcomp where the allocations + // do not affect the monitored pool. Possibly a timing issue, where the "eatMemory" + // is done before Notification/threshold processing happens. + // The Notification is quite immediate, other than that problem. + boolean messageReceived = false; + int tries = 0; + while (!messageReceived && ++tries < MAX_TRIES) { try { - from001Listener.queue.take(); - messageNotRecieved = false; + Object r = from001Listener.queue.poll(10000, TimeUnit.MILLISECONDS); + if (r == null) { + log.display("poll for Notification data returns null..."); + continue; + } else { + messageReceived = true; + break; + } } catch (InterruptedException e) { - messageNotRecieved = true; + // ignored, continue } } + // If we got a Notification, test that the CompositeData can create a MemoryNotificationInfo + if (!messageReceived) { + throw new TestFailure("No Notification received."); + } result = MemoryNotificationInfo.from(from001Listener.data.get()); try { - ObjectName poolObjectName = new ObjectName(monitor.getName(poolObject)); - ObjectName resultObjectName = new ObjectName( - ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE + - ",name=" + result.getPoolName()); - - log.display("poolObjectName : " + poolObjectName + - " resultObjectName : " + resultObjectName); - - if (!poolObjectName.equals(resultObjectName)) { - log.complain("FAILURE 3."); - log.complain("Wrong pool name : " + resultObjectName + - ", expected : " + poolObjectName); - testFailed = true; - } + ObjectName poolObjectName = new ObjectName(monitor.getName(poolObject)); + ObjectName resultObjectName = new ObjectName( + ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE + + ",name=" + result.getPoolName()); + + log.display("poolObjectName : " + poolObjectName + + " resultObjectName : " + resultObjectName); + + if (!poolObjectName.equals(resultObjectName)) { + log.complain("FAILURE 3."); + log.complain("Wrong pool name : " + resultObjectName + + ", expected : " + poolObjectName); + testFailed = true; + } } catch (Exception e) { log.complain("Unexpected exception " + e); e.printStackTrace(log.getOutStream()); testFailed = true; } - if (testFailed) { throw new TestFailure("TEST FAILED. See log."); } @@ -183,9 +206,13 @@ class from001Listener implements NotificationListener { static SynchronousQueue queue = new SynchronousQueue(); public void handleNotification(Notification notification, Object handback) { - if (data.get() != null) + if (data.get() != null) { + System.out.println("handleNotification: ignoring"); return; - data.set((CompositeData) notification.getUserData()); + } + System.out.println("handleNotification: getting data"); + CompositeData d = (CompositeData) notification.getUserData(); + data.set(d); boolean messageNotSent = true; while(messageNotSent){ @@ -193,7 +220,7 @@ public void handleNotification(Notification notification, Object handback) { queue.put(new Object()); messageNotSent = false; } catch(InterruptedException e) { - messageNotSent = true; + // ignore, retry } } } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001/TestDescription.java index 3630a3dd36d05..629672b2e9176 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,15 +34,20 @@ * MemoryNotificationInfo.from(CompositeData) * returns correct results: * 1. null, if CompositeData is null; - * 2. trows IllegalArgumentException, if CompositeData doest not represnt + * 2. throws IllegalArgumentException, if CompositeData does not represent * MemoryNotificationInfo; - * 3. correct MemoryNotificationInfo object, if CompositeData is correst (i.e + * 3. correct MemoryNotificationInfo object, if CompositeData is correct, i.e * all attributes of the CompositeData must have correct values: pool name, * count; init, used, committed, max (from MemoryUsage). * COMMENT * Updated according to: * 5024531 Fix MBeans design flaw that restricts to use JMX CompositeData * + * Avoid running with -Xcomp due to rare failure where the MemoryPool does not + * increase in usage and send Notification. Likely the timing changes so "eatMemory" + * completes before Notification/threshold processing. + * + * @requires vm.compMode != "Xcomp" * @library /vmTestbase * /test/lib * @run main/othervm From e29909141cd0312b7d696cf2c57ebe561ac31f4b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 17 Jun 2025 08:14:02 +0000 Subject: [PATCH 323/846] 8340389: vmTestbase/gc/gctests/PhantomReference/phantom001/TestDescription.java Test exit code: 97 with -Xcomp UseAVX=3 Backport-of: d6f8b465e47d40220bdba6bf7502de90ee9fa7f7 --- .../gc/gctests/PhantomReference/phantom001/phantom001.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom001/phantom001.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom001/phantom001.java index d45adbf4efd1a..9f5fc94221ede 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom001/phantom001.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/PhantomReference/phantom001/phantom001.java @@ -177,14 +177,15 @@ public void run() { // If referent is finalizable, provoke GCs and wait for finalization. if (type.equals("class")) { progress("Waiting for finalization: " + type); + WhiteBox.getWhiteBox().fullGC(); for (int checks = 0; !finalized && !shouldTerminate(); ++checks) { - // There are scenarios where one WB.fillGC() isn't enough, - // but 10 iterations really ought to be sufficient. + // Wait for up to 10 iterations that the finalizer has been run, + // this ought to be sufficient. Full GCs and other threads might + // starve out the finalizer thread, requiring more waiting. if (checks > 10) { fail("Waiting for finalization: " + type); return; } - WhiteBox.getWhiteBox().fullGC(); // Give some time for finalizer to run. try { Thread.sleep(checks * 100); From 81874f35484448772c181e40f6cb972525ff3b11 Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Tue, 17 Jun 2025 16:26:35 +0000 Subject: [PATCH 324/846] 8342330: C2: "node pinned on loop exit test?" assert failure Backport-of: 004aaea76db091569aa88eeb6b08db3408f288cd --- src/hotspot/share/opto/loopopts.cpp | 9 ++- .../TestSunkRangeFromPreLoopRCE.java | 81 +++++++++++++++++++ 2 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/rangechecks/TestSunkRangeFromPreLoopRCE.java diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp index 880dbff8307b6..e57f87b843750 100644 --- a/src/hotspot/share/opto/loopopts.cpp +++ b/src/hotspot/share/opto/loopopts.cpp @@ -1717,10 +1717,11 @@ bool PhaseIdealLoop::ctrl_of_use_out_of_loop(const Node* n, Node* n_ctrl, IdealL // Sinking a node from a pre loop to its main loop pins the node between the pre and main loops. If that node is input // to a check that's eliminated by range check elimination, it becomes input to an expression that feeds into the exit // test of the pre loop above the point in the graph where it's pinned. - if (n_loop->_head->is_CountedLoop() && n_loop->_head->as_CountedLoop()->is_pre_loop() && - u_loop->_head->is_CountedLoop() && u_loop->_head->as_CountedLoop()->is_main_loop() && - n_loop->_next == get_loop(u_loop->_head->as_CountedLoop()->skip_strip_mined())) { - return false; + if (n_loop->_head->is_CountedLoop() && n_loop->_head->as_CountedLoop()->is_pre_loop()) { + CountedLoopNode* pre_loop = n_loop->_head->as_CountedLoop(); + if (is_dominator(pre_loop->loopexit(), ctrl)) { + return false; + } } return true; } diff --git a/test/hotspot/jtreg/compiler/rangechecks/TestSunkRangeFromPreLoopRCE.java b/test/hotspot/jtreg/compiler/rangechecks/TestSunkRangeFromPreLoopRCE.java new file mode 100644 index 0000000000000..4e788df035ed6 --- /dev/null +++ b/test/hotspot/jtreg/compiler/rangechecks/TestSunkRangeFromPreLoopRCE.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024, Red Hat, Inc. 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 8342330 + * @summary C2: "node pinned on loop exit test?" assert failure + * @requires vm.flavor == "server" + * + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:-TieredCompilation + * -XX:-UseLoopPredicate -XX:LoopMaxUnroll=0 TestSunkRangeFromPreLoopRCE + * + */ + + +import java.util.Arrays; + +public class TestSunkRangeFromPreLoopRCE { + private static int[] array = new int[1000]; + private static A objectField = new A(42); + + public static void main(String[] args) { + boolean[] allTrue = new boolean[1000]; + Arrays.fill(allTrue, true); + boolean[] allFalse = new boolean[1000]; + for (int i = 0; i < 20_000; i++) { + test1(array.length/4, allTrue, 1, 0); + test1(array.length/4, allFalse, 1, 0); + } + } + + private static int test1(int stop, boolean[] flags, int otherScale, int x) { + int scale; + for (scale = 0; scale < 4; scale++) { + for (int i = 0; i < 10; i++) { + + } + } + if (array == null) { + } + int v = 0; + for (int i = 0; i < stop; i++) { + v += array[i]; + v += array[scale * i]; + if (i * scale + (objectField.intField + 1) == x) { + } + v += (scale - 4) * (x-objectField.intField); + if (flags[i]) { + return (x-objectField.intField); + } + } + return v; + } + + private static class A { + A(int field) { + intField = field; + } + public int intField; + } +} From 5dab2277926bc83ed9875c381dfe0e5c6b429cb8 Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Tue, 17 Jun 2025 18:40:13 +0000 Subject: [PATCH 325/846] 8330106: C2: VectorInsertNode::make() shouldn't call ConINode::make() directly Backport-of: bde3fc0c03c87d1f2605ae6bb84c33fadb7aa865 --- src/hotspot/share/opto/vectorIntrinsics.cpp | 2 +- src/hotspot/share/opto/vectornode.cpp | 4 ++-- src/hotspot/share/opto/vectornode.hpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/opto/vectorIntrinsics.cpp b/src/hotspot/share/opto/vectorIntrinsics.cpp index c4a99ed8f6d5f..7e52e1ebc510c 100644 --- a/src/hotspot/share/opto/vectorIntrinsics.cpp +++ b/src/hotspot/share/opto/vectorIntrinsics.cpp @@ -1813,7 +1813,7 @@ bool LibraryCallKit::inline_vector_insert() { default: fatal("%s", type2name(elem_bt)); break; } - Node* operation = gvn().transform(VectorInsertNode::make(opd, insert_val, idx->get_con())); + Node* operation = gvn().transform(VectorInsertNode::make(opd, insert_val, idx->get_con(), gvn())); Node* vbox = box_vector(operation, vbox_type, elem_bt, num_elem); set_result(vbox); diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp index b9ef5abd75a67..bd4b2b10fe2a7 100644 --- a/src/hotspot/share/opto/vectornode.cpp +++ b/src/hotspot/share/opto/vectornode.cpp @@ -1252,9 +1252,9 @@ Node* VectorReinterpretNode::Identity(PhaseGVN *phase) { return this; } -Node* VectorInsertNode::make(Node* vec, Node* new_val, int position) { +Node* VectorInsertNode::make(Node* vec, Node* new_val, int position, PhaseGVN& gvn) { assert(position < (int)vec->bottom_type()->is_vect()->length(), "pos in range"); - ConINode* pos = ConINode::make(position); + ConINode* pos = gvn.intcon(position); return new VectorInsertNode(vec, new_val, pos, vec->bottom_type()->is_vect()); } diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index ccb5fd88bf6a1..d1d30f36ac2a6 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -1398,7 +1398,7 @@ class VectorInsertNode : public VectorNode { virtual int Opcode() const; uint pos() const { return in(3)->get_int(); } - static Node* make(Node* vec, Node* new_val, int position); + static Node* make(Node* vec, Node* new_val, int position, PhaseGVN& gvn); }; class VectorBoxNode : public Node { From dab6b01b2f94aa793d9c4909e1d4e82ac349c012 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Wed, 18 Jun 2025 06:23:27 +0000 Subject: [PATCH 326/846] 8359272: Several vmTestbase/compact tests timed out on large memory machine Backport-of: eb727dcb51963add7966a9d86b08520a003af0ca --- .../gc/compact/Compact_InternedStrings/TestDescription.java | 4 +++- .../TestDescription.java | 4 +++- .../gc/compact/Compact_Strings_ArrayOf/TestDescription.java | 4 +++- .../gc/compact/Humongous_InternedStrings/TestDescription.java | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Compact_InternedStrings/TestDescription.java b/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Compact_InternedStrings/TestDescription.java index 8d28df3c4576d..657cb68edc7dd 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Compact_InternedStrings/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Compact_InternedStrings/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, 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,9 +34,11 @@ * This testcase uses interned strings for both first and second phases * and multiple threads. * + * @requires os.maxMemory > 3G * @library /vmTestbase * /test/lib * @run main/othervm + * -Xmx2G * -XX:-UseGCOverheadLimit * vm.gc.compact.Compact * -gp interned(randomString) diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Compact_InternedStrings_NonbranchyTree/TestDescription.java b/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Compact_InternedStrings_NonbranchyTree/TestDescription.java index 1aaeb2fc84d87..b0771871a56f9 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Compact_InternedStrings_NonbranchyTree/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Compact_InternedStrings_NonbranchyTree/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, 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,9 +34,11 @@ * This testcase uses interned strings for first phase, * random arrays for second phases and multiple threads. * + * @requires os.maxMemory > 3G * @library /vmTestbase * /test/lib * @run main/othervm + * -Xmx2G * -XX:-UseGCOverheadLimit * vm.gc.compact.Compact * -gp interned(randomString) diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Compact_Strings_ArrayOf/TestDescription.java b/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Compact_Strings_ArrayOf/TestDescription.java index f54f006d4aa44..ea942c7be07cb 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Compact_Strings_ArrayOf/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Compact_Strings_ArrayOf/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, 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,9 +34,11 @@ * This testcase uses random strings for first phase, array of * random strings for second phase and multiple threads. * + * @requires os.maxMemory > 3G * @library /vmTestbase * /test/lib * @run main/othervm + * -Xmx2G * -XX:-UseGCOverheadLimit * vm.gc.compact.Compact * -gp randomString diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Humongous_InternedStrings/TestDescription.java b/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Humongous_InternedStrings/TestDescription.java index b155c081eea9e..41c2b0ae4d04d 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Humongous_InternedStrings/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/vm/gc/compact/Humongous_InternedStrings/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, 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,9 +34,11 @@ * This testcase uses interned strings for both first and second phases * and multiple threads. * + * @requires os.maxMemory > 3G * @library /vmTestbase * /test/lib * @run main/othervm + * -Xmx2G * -XX:-UseGCOverheadLimit * vm.gc.compact.Compact * -gp interned(randomString) From 7b3000f85104ab1c9a7ca15b51d2728682a4f205 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 08:30:41 +0000 Subject: [PATCH 327/846] 8298907: nsk JDI tests pass if the debuggee failed to launch Backport-of: a91143cc93fe3810ecca4b04c9f81c1b967db0ed --- .../nsk/jdi/BooleanType/_itself_/booleantype001.java | 4 ++-- .../addInstanceFilter/instancefilter002.java | 4 ++-- .../addInstanceFilter/instancefilter003.java | 4 ++-- .../BreakpointRequest/addThreadFilter/threadfilter002.java | 4 ++-- .../BreakpointRequest/addThreadFilter/threadfilter003.java | 4 ++-- .../nsk/jdi/BreakpointRequest/location/location001.java | 4 ++-- .../vmTestbase/nsk/jdi/ByteType/_itself_/bytetype001.java | 4 ++-- .../vmTestbase/nsk/jdi/CharType/_itself_/chartype001.java | 4 ++-- .../definedClasses/definedclasses001.java | 4 ++-- .../visibleClasses/visibleclasses001.java | 4 ++-- .../addClassExclusionFilter/filter003.java | 4 ++-- .../ClassPrepareRequest/addClassFilter_rt/filter_rt002.java | 4 ++-- .../jdi/ClassPrepareRequest/addClassFilter_s/filter_s002.java | 4 ++-- .../vmTestbase/nsk/jdi/DoubleType/_itself_/doubletype001.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/Event/request/request001.java | 4 ++-- .../nsk/jdi/EventIterator/nextEvent/nextevent001.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004.java | 4 ++-- .../vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004.java | 4 ++-- .../jdi/EventRequest/addCountFilter/addcountfilter001.java | 4 ++-- .../vmTestbase/nsk/jdi/EventRequest/disable/disable001.java | 4 ++-- .../vmTestbase/nsk/jdi/EventRequest/disable/disable002.java | 4 ++-- .../vmTestbase/nsk/jdi/EventRequest/enable/enable001.java | 4 ++-- .../vmTestbase/nsk/jdi/EventRequest/enable/enable002.java | 4 ++-- .../nsk/jdi/EventRequest/getProperty/getproperty001.java | 4 ++-- .../nsk/jdi/EventRequest/isEnabled/isenabled001.java | 4 ++-- .../nsk/jdi/EventRequest/putProperty/putproperty001.java | 4 ++-- .../nsk/jdi/EventRequest/setEnabled/setenabled001.java | 4 ++-- .../nsk/jdi/EventRequest/setEnabled/setenabled002.java | 4 ++-- .../nsk/jdi/EventRequest/setEnabled/setenabled003.java | 4 ++-- .../EventRequest/setSuspendPolicy/setsuspendpolicy001.java | 4 ++-- .../nsk/jdi/EventRequest/suspendPolicy/suspendpolicy001.java | 4 ++-- .../accessWatchpointRequests/accwtchpreq002.java | 4 ++-- .../EventRequestManager/breakpointRequests/breakpreq002.java | 4 ++-- .../classPrepareRequests/clsprepreq002.java | 4 ++-- .../EventRequestManager/classUnloadRequests/clsunlreq002.java | 4 ++-- .../createAccessWatchpointRequest/craccwtchpreq003.java | 4 ++-- .../createBreakpointRequest/crbreakpreq003.java | 4 ++-- .../createClassPrepareRequest/cpreg001.java | 4 ++-- .../createClassUnloadRequest/cureg001.java | 4 ++-- .../createExceptionRequest/crexreq009.java | 4 ++-- .../createExceptionRequest/crexreq010.java | 4 ++-- .../createMethodEntryRequest/menreg001.java | 4 ++-- .../createMethodExitRequest/mexreg001.java | 4 ++-- .../createModificationWatchpointRequest/crmodwtchpreq003.java | 4 ++-- .../EventRequestManager/createStepRequest/crstepreq002.java | 4 ++-- .../createThreadDeathRequest/tdreg001.java | 4 ++-- .../createThreadStartRequest/tsreg001.java | 4 ++-- .../EventRequestManager/createVMDeathRequest/vmdreg001.java | 4 ++-- .../deleteAllBreakpoints/delallbreakp002.java | 4 ++-- .../EventRequestManager/deleteEventRequest/delevtreq002.java | 4 ++-- .../deleteEventRequests/delevtreqs002.java | 4 ++-- .../jdi/EventRequestManager/exceptionRequests/excreq002.java | 4 ++-- .../methodEntryRequests/methentreq002.java | 4 ++-- .../methodExitRequests/methexitreq002.java | 4 ++-- .../modificationWatchpointRequests/modwtchpreq002.java | 4 ++-- .../nsk/jdi/EventRequestManager/stepRequests/stepreq002.java | 4 ++-- .../threadDeathRequests/thrdeathreq002.java | 4 ++-- .../threadStartRequests/thrstartreq002.java | 4 ++-- .../EventRequestManager/vmDeathRequests/vmdeathreq001.java | 4 ++-- .../nsk/jdi/EventSet/eventIterator/eventiterator001.java | 4 ++-- .../nsk/jdi/EventSet/eventIterator/eventiterator002.java | 4 ++-- .../nsk/jdi/EventSet/eventIterator/eventiterator003.java | 4 ++-- .../nsk/jdi/EventSet/eventIterator/eventiterator004.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume002.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume003.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume004.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume005.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume006.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume007.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume010.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume011.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume012.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume013.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy001.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy002.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy003.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy004.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy005.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy006.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy007.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy008.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy009.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy010.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy011.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy012.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy013.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy014.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy015.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy016.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy017.java | 4 ++-- .../nsk/jdi/EventSet/suspendPolicy/suspendpolicy018.java | 4 ++-- .../ExceptionRequest/addClassExclusionFilter/filter002.java | 4 ++-- .../jdi/ExceptionRequest/addClassFilter_rt/filter_rt002.java | 4 ++-- .../jdi/ExceptionRequest/addClassFilter_s/filter_s002.java | 4 ++-- .../ExceptionRequest/addInstanceFilter/instancefilter002.java | 4 ++-- .../ExceptionRequest/addInstanceFilter/instancefilter003.java | 4 ++-- .../jdi/ExceptionRequest/addThreadFilter/threadfilter002.java | 4 ++-- .../jdi/ExceptionRequest/addThreadFilter/threadfilter003.java | 4 ++-- .../nsk/jdi/ExceptionRequest/exception/exception001.java | 4 ++-- .../jdi/ExceptionRequest/notifyCaught/notifycaught001.java | 4 ++-- .../ExceptionRequest/notifyUncaught/notifyuncaught001.java | 4 ++-- .../vmTestbase/nsk/jdi/FloatType/_itself_/floattype001.java | 4 ++-- .../nsk/jdi/IntegerType/_itself_/integertype001.java | 4 ++-- .../vmTestbase/nsk/jdi/LocatableEvent/thread/thread001.java | 4 ++-- .../vmTestbase/nsk/jdi/LongType/_itself_/longtype001.java | 4 ++-- .../vmTestbase/nsk/jdi/Method/isObsolete/isobsolete001.java | 4 ++-- .../vmTestbase/nsk/jdi/Method/isObsolete/isobsolete002.java | 4 ++-- .../MethodEntryRequest/addClassExclusionFilter/filter002.java | 4 ++-- .../MethodEntryRequest/addClassFilter_rt/filter_rt002.java | 4 ++-- .../jdi/MethodEntryRequest/addClassFilter_s/filter_s002.java | 4 ++-- .../addInstanceFilter/instancefilter002.java | 4 ++-- .../addInstanceFilter/instancefilter003.java | 4 ++-- .../MethodEntryRequest/addThreadFilter/threadfilter002.java | 4 ++-- .../MethodEntryRequest/addThreadFilter/threadfilter003.java | 4 ++-- .../MethodExitRequest/addClassExclusionFilter/filter002.java | 4 ++-- .../jdi/MethodExitRequest/addClassFilter_rt/filter_rt002.java | 4 ++-- .../jdi/MethodExitRequest/addClassFilter_s/filter_s002.java | 4 ++-- .../addInstanceFilter/instancefilter002.java | 4 ++-- .../addInstanceFilter/instancefilter003.java | 4 ++-- .../MethodExitRequest/addThreadFilter/threadfilter002.java | 4 ++-- .../MethodExitRequest/addThreadFilter/threadfilter003.java | 4 ++-- .../jdi/ModificationWatchpointEvent/_itself_/mwevent001.java | 4 ++-- .../disableCollection/disablecollection002.java | 4 ++-- .../PathSearchingVirtualMachine/classPath/classpath001.java | 4 ++-- .../nsk/jdi/PrimitiveType/_itself_/primitivetype001.java | 4 ++-- .../nsk/jdi/ReferenceType/classLoader/classloader001.java | 4 ++-- .../nsk/jdi/ReferenceType/getValue/getvalue001.java | 4 ++-- .../nsk/jdi/ReferenceType/getValue/getvalue002.java | 4 ++-- .../nsk/jdi/ReferenceType/getValue/getvalue003.java | 4 ++-- .../nsk/jdi/ReferenceType/getValues/getvalues001.java | 4 ++-- .../nsk/jdi/ReferenceType/isStatic/isstatic001.java | 4 ++-- .../nsk/jdi/ReferenceType/isStatic/isstatic002.java | 4 ++-- .../vmTestbase/nsk/jdi/ShortType/_itself_/shorttype001.java | 4 ++-- .../jdi/StepRequest/addClassExclusionFilter/filter002.java | 4 ++-- .../nsk/jdi/StepRequest/addClassFilter_rt/filter_rt002.java | 4 ++-- .../nsk/jdi/StepRequest/addClassFilter_s/filter_s002.java | 4 ++-- .../jdi/StepRequest/addInstanceFilter/instancefilter002.java | 4 ++-- .../jdi/StepRequest/addInstanceFilter/instancefilter003.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth001.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth002.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth003.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/StepRequest/size/size001.java | 4 ++-- .../jtreg/vmTestbase/nsk/jdi/StepRequest/size/size002.java | 4 ++-- .../vmTestbase/nsk/jdi/StepRequest/thread/thread001.java | 4 ++-- .../addThreadFilter/addthreadfilter001.java | 4 ++-- .../addThreadFilter/addthreadfilter002.java | 4 ++-- .../addThreadFilter/addthreadfilter003.java | 4 ++-- .../addThreadFilter/addthreadfilter005.java | 4 ++-- .../nsk/jdi/ThreadReference/popFrames/popframes001.java | 4 ++-- .../nsk/jdi/ThreadReference/popFrames/popframes002.java | 4 ++-- .../nsk/jdi/ThreadReference/popFrames/popframes003.java | 4 ++-- .../nsk/jdi/ThreadReference/popFrames/popframes004.java | 4 ++-- .../nsk/jdi/ThreadReference/popFrames/popframes005.java | 4 ++-- .../addThreadFilter/addthreadfilter001.java | 4 ++-- .../addThreadFilter/addthreadfilter002.java | 4 ++-- .../addThreadFilter/addthreadfilter003.java | 4 ++-- .../addThreadFilter/addthreadfilter005.java | 4 ++-- .../vmTestbase/nsk/jdi/VMDeathEvent/_itself_/vmdeath002.java | 4 ++-- .../vmTestbase/nsk/jdi/VMDeathEvent/_itself_/vmdeath003.java | 4 ++-- .../nsk/jdi/VirtualMachine/canAddMethod/canaddmethod001.java | 4 ++-- .../nsk/jdi/VirtualMachine/canPopFrames/canpopframes001.java | 4 ++-- .../canRedefineClasses/canredefineclasses001.java | 4 ++-- .../VirtualMachine/canRequestVMDeathEvent/canreqvmdev001.java | 4 ++-- .../canUnrestrictedlyRedefineClasses/curc001.java | 4 ++-- .../canUseInstanceFilters/canusefilters001.java | 4 ++-- .../VirtualMachine/canWatchFieldAccess/canwatchaccess001.java | 4 ++-- .../canWatchFieldModification/canwatchmod001.java | 4 ++-- .../VirtualMachine/redefineClasses/redefineclasses001.java | 4 ++-- .../vmTestbase/nsk/jdi/VoidType/_itself_/voidtype001.java | 4 ++-- .../WatchpointRequest/addClassExclusionFilter/filter003.java | 4 ++-- .../WatchpointRequest/addClassExclusionFilter/filter004.java | 4 ++-- .../jdi/WatchpointRequest/addClassFilter_rt/filter_rt003.java | 4 ++-- .../jdi/WatchpointRequest/addClassFilter_rt/filter_rt004.java | 4 ++-- .../jdi/WatchpointRequest/addClassFilter_s/filter_s003.java | 4 ++-- .../jdi/WatchpointRequest/addClassFilter_s/filter_s004.java | 4 ++-- .../addInstanceFilter/instancefilter003.java | 4 ++-- .../addInstanceFilter/instancefilter004.java | 4 ++-- .../addInstanceFilter/instancefilter005.java | 4 ++-- .../addInstanceFilter/instancefilter006.java | 4 ++-- .../WatchpointRequest/addThreadFilter/addthreadfilter003.java | 4 ++-- .../WatchpointRequest/addThreadFilter/addthreadfilter004.java | 4 ++-- .../WatchpointRequest/addThreadFilter/addthreadfilter005.java | 4 ++-- .../WatchpointRequest/addThreadFilter/addthreadfilter006.java | 4 ++-- .../vmTestbase/nsk/jdi/WatchpointRequest/field/field001.java | 4 ++-- .../vmTestbase/nsk/jdi/WatchpointRequest/field/field002.java | 4 ++-- test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIBase.java | 4 ++-- 186 files changed, 372 insertions(+), 372 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/BooleanType/_itself_/booleantype001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/BooleanType/_itself_/booleantype001.java index a2fbc2b89bbd7..0a3ee9c54fe52 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/BooleanType/_itself_/booleantype001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/BooleanType/_itself_/booleantype001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -89,7 +89,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addInstanceFilter/instancefilter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addInstanceFilter/instancefilter002.java index a4b54bd831a1c..38cfa8b7c826f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addInstanceFilter/instancefilter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addInstanceFilter/instancefilter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addInstanceFilter/instancefilter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addInstanceFilter/instancefilter003.java index 0ca023a47b326..4e59735afdb7a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addInstanceFilter/instancefilter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addInstanceFilter/instancefilter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -93,7 +93,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addThreadFilter/threadfilter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addThreadFilter/threadfilter002.java index 34de029d726b9..b1b588adf11f1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addThreadFilter/threadfilter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addThreadFilter/threadfilter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -99,7 +99,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addThreadFilter/threadfilter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addThreadFilter/threadfilter003.java index 9fabd5cf9496b..5c20571ec0aeb 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addThreadFilter/threadfilter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/addThreadFilter/threadfilter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -99,7 +99,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/location/location001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/location/location001.java index d3ac2eb9c6a4b..413ec6022e5e6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/location/location001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/BreakpointRequest/location/location001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ByteType/_itself_/bytetype001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ByteType/_itself_/bytetype001.java index 8be846c734e51..532e6b0cc7478 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ByteType/_itself_/bytetype001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ByteType/_itself_/bytetype001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -89,7 +89,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/CharType/_itself_/chartype001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/CharType/_itself_/chartype001.java index ad07d11b5bb95..a69b4dedae7fe 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/CharType/_itself_/chartype001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/CharType/_itself_/chartype001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -89,7 +89,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassLoaderReference/definedClasses/definedclasses001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassLoaderReference/definedClasses/definedclasses001.java index ce0d4a10e2955..7a36464198b43 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassLoaderReference/definedClasses/definedclasses001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassLoaderReference/definedClasses/definedclasses001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassLoaderReference/visibleClasses/visibleclasses001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassLoaderReference/visibleClasses/visibleclasses001.java index bfcc7121611f5..2d5ba8a584ad6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassLoaderReference/visibleClasses/visibleclasses001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassLoaderReference/visibleClasses/visibleclasses001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -102,7 +102,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareRequest/addClassExclusionFilter/filter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareRequest/addClassExclusionFilter/filter003.java index e747d251434b4..b15e41de7a8eb 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareRequest/addClassExclusionFilter/filter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareRequest/addClassExclusionFilter/filter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareRequest/addClassFilter_rt/filter_rt002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareRequest/addClassFilter_rt/filter_rt002.java index 0b8d0866e29e6..68ce219eabd47 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareRequest/addClassFilter_rt/filter_rt002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareRequest/addClassFilter_rt/filter_rt002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -96,7 +96,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareRequest/addClassFilter_s/filter_s002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareRequest/addClassFilter_s/filter_s002.java index c0461a73e9630..2e1b0af494c3f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareRequest/addClassFilter_s/filter_s002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareRequest/addClassFilter_s/filter_s002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/DoubleType/_itself_/doubletype001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/DoubleType/_itself_/doubletype001.java index 328656766b560..254ac5045ce19 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/DoubleType/_itself_/doubletype001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/DoubleType/_itself_/doubletype001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -89,7 +89,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/request/request001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/request/request001.java index 795c37a22c37b..9895ce98faf2b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/request/request001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/request/request001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -111,7 +111,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventIterator/nextEvent/nextevent001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventIterator/nextEvent/nextevent001.java index bde47821ac668..860be46422b38 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventIterator/nextEvent/nextevent001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventIterator/nextEvent/nextevent001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -111,7 +111,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004.java index fc32b09c7aa67..48370081d74b5 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -90,7 +90,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004.java index 85b6259d9ddb7..8ecf265485493 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -85,7 +85,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/addCountFilter/addcountfilter001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/addCountFilter/addcountfilter001.java index 1eeae0e345663..404947071ce2c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/addCountFilter/addcountfilter001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/addCountFilter/addcountfilter001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/disable/disable001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/disable/disable001.java index 566f634cf9d11..d17d5aaba2e85 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/disable/disable001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/disable/disable001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -105,7 +105,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } //-------------------------------------------------- log procedures diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/disable/disable002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/disable/disable002.java index 6de71120957ab..ac62694e13f13 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/disable/disable002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/disable/disable002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/enable/enable001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/enable/enable001.java index c93d79344fd20..589e15cd30525 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/enable/enable001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/enable/enable001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/enable/enable002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/enable/enable002.java index 5d216a654ef98..fbab0d27c62a5 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/enable/enable002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/enable/enable002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -93,7 +93,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/getProperty/getproperty001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/getProperty/getproperty001.java index 8c2467af249fd..291b33fea10ac 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/getProperty/getproperty001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/getProperty/getproperty001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/isEnabled/isenabled001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/isEnabled/isenabled001.java index e0ba70c9bb6d0..a634df78b3b72 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/isEnabled/isenabled001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/isEnabled/isenabled001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/putProperty/putproperty001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/putProperty/putproperty001.java index 3c29d9216a89e..93d4fdae605b1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/putProperty/putproperty001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/putProperty/putproperty001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setEnabled/setenabled001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setEnabled/setenabled001.java index e0cb8ca82b93b..91002312cd8f3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setEnabled/setenabled001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setEnabled/setenabled001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -91,7 +91,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setEnabled/setenabled002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setEnabled/setenabled002.java index 7974b0076667d..5c9ef8ac9b95e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setEnabled/setenabled002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setEnabled/setenabled002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setEnabled/setenabled003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setEnabled/setenabled003.java index 799c253cc8643..5218654cbf17f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setEnabled/setenabled003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setEnabled/setenabled003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setSuspendPolicy/setsuspendpolicy001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setSuspendPolicy/setsuspendpolicy001.java index 90ad166b9df92..f58aced259baf 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setSuspendPolicy/setsuspendpolicy001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/setSuspendPolicy/setsuspendpolicy001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -96,7 +96,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/suspendPolicy/suspendpolicy001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/suspendPolicy/suspendpolicy001.java index 9c5cff3963c79..88cb33232d240 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/suspendPolicy/suspendpolicy001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequest/suspendPolicy/suspendpolicy001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -91,7 +91,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/accessWatchpointRequests/accwtchpreq002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/accessWatchpointRequests/accwtchpreq002.java index 63c671fe789ea..5f71b2444ff3d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/accessWatchpointRequests/accwtchpreq002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/accessWatchpointRequests/accwtchpreq002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } private String debuggeeName = diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/breakpointRequests/breakpreq002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/breakpointRequests/breakpreq002.java index 1e9660c8964f9..20bc83dc77a0d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/breakpointRequests/breakpreq002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/breakpointRequests/breakpreq002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/classPrepareRequests/clsprepreq002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/classPrepareRequests/clsprepreq002.java index df26bc95d2c3e..b04c00ed66536 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/classPrepareRequests/clsprepreq002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/classPrepareRequests/clsprepreq002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/classUnloadRequests/clsunlreq002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/classUnloadRequests/clsunlreq002.java index f2a5d602cef41..911d7913720f4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/classUnloadRequests/clsunlreq002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/classUnloadRequests/clsunlreq002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createAccessWatchpointRequest/craccwtchpreq003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createAccessWatchpointRequest/craccwtchpreq003.java index 17369a0647131..62084b0753c2e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createAccessWatchpointRequest/craccwtchpreq003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createAccessWatchpointRequest/craccwtchpreq003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createBreakpointRequest/crbreakpreq003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createBreakpointRequest/crbreakpreq003.java index 42ebb25299db7..60e2efc4194f5 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createBreakpointRequest/crbreakpreq003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createBreakpointRequest/crbreakpreq003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createClassPrepareRequest/cpreg001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createClassPrepareRequest/cpreg001.java index 07a88d62c0363..3ae793cb46d21 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createClassPrepareRequest/cpreg001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createClassPrepareRequest/cpreg001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -90,7 +90,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createClassUnloadRequest/cureg001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createClassUnloadRequest/cureg001.java index d808931ce0e95..706308240e3e8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createClassUnloadRequest/cureg001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createClassUnloadRequest/cureg001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -90,7 +90,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createExceptionRequest/crexreq009.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createExceptionRequest/crexreq009.java index f4c582102005e..e720efa0595a8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createExceptionRequest/crexreq009.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createExceptionRequest/crexreq009.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -93,7 +93,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createExceptionRequest/crexreq010.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createExceptionRequest/crexreq010.java index f6f9e0b710b06..e3cccc2a0e752 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createExceptionRequest/crexreq010.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createExceptionRequest/crexreq010.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createMethodEntryRequest/menreg001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createMethodEntryRequest/menreg001.java index 7a9ee65e6fe7b..f176e4e3a12e6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createMethodEntryRequest/menreg001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createMethodEntryRequest/menreg001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -90,7 +90,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createMethodExitRequest/mexreg001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createMethodExitRequest/mexreg001.java index 3035fc9aadd8c..6f9f01cfe452f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createMethodExitRequest/mexreg001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createMethodExitRequest/mexreg001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -90,7 +90,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createModificationWatchpointRequest/crmodwtchpreq003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createModificationWatchpointRequest/crmodwtchpreq003.java index 3e2f9a479bfbc..7a2019232d025 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createModificationWatchpointRequest/crmodwtchpreq003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createModificationWatchpointRequest/crmodwtchpreq003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq002.java index dfa75241c9212..55a72a6951a93 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createThreadDeathRequest/tdreg001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createThreadDeathRequest/tdreg001.java index 6b14e96024240..93a4fd4c507ce 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createThreadDeathRequest/tdreg001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createThreadDeathRequest/tdreg001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -90,7 +90,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createThreadStartRequest/tsreg001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createThreadStartRequest/tsreg001.java index 3bb3b75b595e9..63e1c2b5b22ab 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createThreadStartRequest/tsreg001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createThreadStartRequest/tsreg001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -90,7 +90,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createVMDeathRequest/vmdreg001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createVMDeathRequest/vmdreg001.java index 5c1b71388ea18..03ca620d431c9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createVMDeathRequest/vmdreg001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createVMDeathRequest/vmdreg001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/deleteAllBreakpoints/delallbreakp002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/deleteAllBreakpoints/delallbreakp002.java index 968e88adbd65b..8799579c5cb91 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/deleteAllBreakpoints/delallbreakp002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/deleteAllBreakpoints/delallbreakp002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -91,7 +91,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/deleteEventRequest/delevtreq002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/deleteEventRequest/delevtreq002.java index 30aae28e622c1..38a3623a697ca 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/deleteEventRequest/delevtreq002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/deleteEventRequest/delevtreq002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -97,7 +97,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/deleteEventRequests/delevtreqs002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/deleteEventRequests/delevtreqs002.java index bc63f49ce8e87..efcdbfd84acc4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/deleteEventRequests/delevtreqs002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/deleteEventRequests/delevtreqs002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/exceptionRequests/excreq002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/exceptionRequests/excreq002.java index 9b4172106b965..93cbd6aea57d3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/exceptionRequests/excreq002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/exceptionRequests/excreq002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/methodEntryRequests/methentreq002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/methodEntryRequests/methentreq002.java index 6b6fd054412bb..ffe30fbf73906 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/methodEntryRequests/methentreq002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/methodEntryRequests/methentreq002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/methodExitRequests/methexitreq002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/methodExitRequests/methexitreq002.java index 616b058b7d591..7ac37682ab977 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/methodExitRequests/methexitreq002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/methodExitRequests/methexitreq002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/modificationWatchpointRequests/modwtchpreq002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/modificationWatchpointRequests/modwtchpreq002.java index a88563a92b564..130ebfdad69b3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/modificationWatchpointRequests/modwtchpreq002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/modificationWatchpointRequests/modwtchpreq002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/stepRequests/stepreq002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/stepRequests/stepreq002.java index 2905cb0236f91..c55c96d9e652c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/stepRequests/stepreq002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/stepRequests/stepreq002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/threadDeathRequests/thrdeathreq002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/threadDeathRequests/thrdeathreq002.java index d725958ff6516..ca79baf854958 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/threadDeathRequests/thrdeathreq002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/threadDeathRequests/thrdeathreq002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/threadStartRequests/thrstartreq002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/threadStartRequests/thrstartreq002.java index c830df6a369df..df1bceeba1729 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/threadStartRequests/thrstartreq002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/threadStartRequests/thrstartreq002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/vmDeathRequests/vmdeathreq001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/vmDeathRequests/vmdeathreq001.java index af502883a9d5b..4772c770ff93c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/vmDeathRequests/vmdeathreq001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/vmDeathRequests/vmdeathreq001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -92,7 +92,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator001.java index d1f715df88024..8f151c7d48375 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -87,7 +87,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator002.java index a4be961309b66..cf317355206c0 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -93,7 +93,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator003.java index 3dc70e632f941..8178e6e26e28b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -90,7 +90,7 @@ public static int run(String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator004.java index 5e060095cce05..79c1063765f71 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/eventIterator/eventiterator004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -81,7 +81,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume002.java index e3417621fd8bb..a2920fc6e84c2 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -101,7 +101,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume003.java index 176a87b490b57..0026577befb36 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -101,7 +101,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume004.java index a37a4b222cf40..3757e7dab479e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -101,7 +101,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume005.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume005.java index 84f96cf33453c..e72ac3f2956e8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume005.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -101,7 +101,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume006.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume006.java index 53e35df25eb63..3919bac23f044 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume006.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume006.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -101,7 +101,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume007.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume007.java index 05d07e7933a3e..5ca1b3be36db6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume007.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume007.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -101,7 +101,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume010.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume010.java index 707704f21d216..daa904f75dac9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume010.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume010.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -101,7 +101,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume011.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume011.java index 0aa593f038e53..0898ce7ed553b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume011.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume011.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -85,7 +85,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume012.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume012.java index 2f84e7fe6bc80..3b9ed63ca8d30 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume012.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume012.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -86,7 +86,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume013.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume013.java index 0cd4f25e91918..d9fab2da5730f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume013.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume013.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -86,7 +86,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy001.java index 9de1fcfecf43b..04dfaca5bc4b3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -99,7 +99,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy002.java index fa550ccbf96c2..4bb8b6a19e926 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -97,7 +97,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy003.java index c990fce716f44..34ec4db572330 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -97,7 +97,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy004.java index 763befc2b2984..c8158e56551c6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -97,7 +97,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy005.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy005.java index 896e48ad48845..b57038634dfe7 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy005.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -97,7 +97,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy006.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy006.java index e1006ed04a50d..b7778abcef145 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy006.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy006.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -96,7 +96,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy007.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy007.java index 12c3a10e208da..da60e2c670ca9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy007.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy007.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -96,7 +96,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy008.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy008.java index 3dbc1458ce952..e0257fcac501a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy008.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy008.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -96,7 +96,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy009.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy009.java index d7a1bbc783339..8a31bd57faa02 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy009.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy009.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -96,7 +96,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy010.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy010.java index 682c5062492aa..f7b2fd4cae99b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy010.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy010.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy011.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy011.java index 772169efb21c6..04c32dbbd169b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy011.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy011.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy012.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy012.java index 554faa833a92b..a52f70705ef8d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy012.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy012.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy013.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy013.java index 147cc80db8287..9576413d0124a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy013.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy013.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy014.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy014.java index e2b94fb620ec5..2796d77dc155d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy014.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy014.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy015.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy015.java index 071e339d7f99d..58143790d413e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy015.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy015.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy016.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy016.java index 9fc708b9c534f..2f185dbd5d6db 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy016.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy016.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } private String debuggeeName = diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy017.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy017.java index 94ba9b6e5a4a1..1142912336253 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy017.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy017.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy018.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy018.java index e2d4d7da79a98..ba80a93cba07f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy018.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/suspendPolicy/suspendpolicy018.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } //-------------------------------------------------- log procedures diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addClassExclusionFilter/filter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addClassExclusionFilter/filter002.java index dbb738b906671..0a9e953887017 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addClassExclusionFilter/filter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addClassExclusionFilter/filter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -97,7 +97,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addClassFilter_rt/filter_rt002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addClassFilter_rt/filter_rt002.java index 981d57ca002cf..a5b24ee05bf7e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addClassFilter_rt/filter_rt002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addClassFilter_rt/filter_rt002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addClassFilter_s/filter_s002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addClassFilter_s/filter_s002.java index e4c53f8014dea..96524657b785e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addClassFilter_s/filter_s002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addClassFilter_s/filter_s002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addInstanceFilter/instancefilter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addInstanceFilter/instancefilter002.java index 5ae15dad45b72..ff49eb67f49c7 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addInstanceFilter/instancefilter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addInstanceFilter/instancefilter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addInstanceFilter/instancefilter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addInstanceFilter/instancefilter003.java index a7d7bbe29f797..37a85bd173dbc 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addInstanceFilter/instancefilter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addInstanceFilter/instancefilter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -93,7 +93,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addThreadFilter/threadfilter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addThreadFilter/threadfilter002.java index ece923ee2ad3e..ed1d16c8572ed 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addThreadFilter/threadfilter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addThreadFilter/threadfilter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -100,7 +100,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addThreadFilter/threadfilter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addThreadFilter/threadfilter003.java index 80d8ecd457e0a..43d4629d2e0bb 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addThreadFilter/threadfilter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/addThreadFilter/threadfilter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -100,7 +100,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/exception/exception001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/exception/exception001.java index c9091734db5a2..ca7731a3463e3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/exception/exception001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/exception/exception001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/notifyCaught/notifycaught001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/notifyCaught/notifycaught001.java index ea2615dfc0638..7e7eca7fbdc09 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/notifyCaught/notifycaught001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/notifyCaught/notifycaught001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -93,7 +93,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/notifyUncaught/notifyuncaught001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/notifyUncaught/notifyuncaught001.java index d4aacc05bc5b5..9287c1da1e882 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/notifyUncaught/notifyuncaught001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionRequest/notifyUncaught/notifyuncaught001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -93,7 +93,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/FloatType/_itself_/floattype001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/FloatType/_itself_/floattype001.java index 8e0bb5716ac9b..e9fad24935326 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/FloatType/_itself_/floattype001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/FloatType/_itself_/floattype001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -89,7 +89,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/IntegerType/_itself_/integertype001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/IntegerType/_itself_/integertype001.java index f49e1da055a51..218497f62da27 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/IntegerType/_itself_/integertype001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/IntegerType/_itself_/integertype001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -89,7 +89,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/LocatableEvent/thread/thread001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/LocatableEvent/thread/thread001.java index 3688fbcc8df75..1225b24893c25 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/LocatableEvent/thread/thread001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/LocatableEvent/thread/thread001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -101,7 +101,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/LongType/_itself_/longtype001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/LongType/_itself_/longtype001.java index 9854f1eedbd28..27b594756618a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/LongType/_itself_/longtype001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/LongType/_itself_/longtype001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -89,7 +89,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/Method/isObsolete/isobsolete001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/Method/isObsolete/isobsolete001.java index 2869667740de0..c45c87e0b1aaf 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/Method/isObsolete/isobsolete001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/Method/isObsolete/isobsolete001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -97,7 +97,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/Method/isObsolete/isobsolete002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/Method/isObsolete/isobsolete002.java index 098065a1d9e3e..464b43c3ff50e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/Method/isObsolete/isobsolete002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/Method/isObsolete/isobsolete002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addClassExclusionFilter/filter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addClassExclusionFilter/filter002.java index 0806e7f21e52e..b9fd6955d677f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addClassExclusionFilter/filter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addClassExclusionFilter/filter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -97,7 +97,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addClassFilter_rt/filter_rt002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addClassFilter_rt/filter_rt002.java index 81f651e58539e..a230fa1695155 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addClassFilter_rt/filter_rt002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addClassFilter_rt/filter_rt002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addClassFilter_s/filter_s002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addClassFilter_s/filter_s002.java index a02d4d1f83b49..e7a99c2bc7060 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addClassFilter_s/filter_s002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addClassFilter_s/filter_s002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -97,7 +97,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addInstanceFilter/instancefilter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addInstanceFilter/instancefilter002.java index 904db070d359d..32043b084940e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addInstanceFilter/instancefilter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addInstanceFilter/instancefilter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addInstanceFilter/instancefilter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addInstanceFilter/instancefilter003.java index c2ba325aeff4f..23e6e61f7389f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addInstanceFilter/instancefilter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addInstanceFilter/instancefilter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } //-------------------------------------------------- log procedures diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addThreadFilter/threadfilter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addThreadFilter/threadfilter002.java index 9f55fe518d0fd..baead18cfc0c1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addThreadFilter/threadfilter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addThreadFilter/threadfilter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -100,7 +100,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addThreadFilter/threadfilter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addThreadFilter/threadfilter003.java index eb150be88ff26..0b5d97ef01258 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addThreadFilter/threadfilter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodEntryRequest/addThreadFilter/threadfilter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -100,7 +100,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addClassExclusionFilter/filter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addClassExclusionFilter/filter002.java index 4a4e5dfcfcdba..84d05550a6483 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addClassExclusionFilter/filter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addClassExclusionFilter/filter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -97,7 +97,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addClassFilter_rt/filter_rt002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addClassFilter_rt/filter_rt002.java index 367f7aa7bf31c..f96b53a71ff30 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addClassFilter_rt/filter_rt002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addClassFilter_rt/filter_rt002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addClassFilter_s/filter_s002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addClassFilter_s/filter_s002.java index d34d006f53226..5c8cf1067ea33 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addClassFilter_s/filter_s002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addClassFilter_s/filter_s002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -97,7 +97,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addInstanceFilter/instancefilter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addInstanceFilter/instancefilter002.java index b20a88171cabe..cab4734e3d0c1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addInstanceFilter/instancefilter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addInstanceFilter/instancefilter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addInstanceFilter/instancefilter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addInstanceFilter/instancefilter003.java index 2e1fcb3f8ca39..517257f03e0cd 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addInstanceFilter/instancefilter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addInstanceFilter/instancefilter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addThreadFilter/threadfilter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addThreadFilter/threadfilter002.java index 173e621e50ad6..63f21d6556bc8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addThreadFilter/threadfilter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addThreadFilter/threadfilter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -99,7 +99,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addThreadFilter/threadfilter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addThreadFilter/threadfilter003.java index aeea727ca1789..175410b01f046 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addThreadFilter/threadfilter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/MethodExitRequest/addThreadFilter/threadfilter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -99,7 +99,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ModificationWatchpointEvent/_itself_/mwevent001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ModificationWatchpointEvent/_itself_/mwevent001.java index c208bb22b244f..6a192280ec360 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ModificationWatchpointEvent/_itself_/mwevent001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ModificationWatchpointEvent/_itself_/mwevent001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/disableCollection/disablecollection002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/disableCollection/disablecollection002.java index 9f8bb31a612a1..732b1e0a06fd9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/disableCollection/disablecollection002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/disableCollection/disablecollection002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -113,7 +113,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/PathSearchingVirtualMachine/classPath/classpath001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/PathSearchingVirtualMachine/classPath/classpath001.java index c78762a6e2fc8..fbc29a47de236 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/PathSearchingVirtualMachine/classPath/classpath001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/PathSearchingVirtualMachine/classPath/classpath001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/PrimitiveType/_itself_/primitivetype001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/PrimitiveType/_itself_/primitivetype001.java index 70e3794805556..fa13f624406c1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/PrimitiveType/_itself_/primitivetype001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/PrimitiveType/_itself_/primitivetype001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -88,7 +88,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/classLoader/classloader001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/classLoader/classloader001.java index b74b73bfb044b..101e006b90ca1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/classLoader/classloader001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/classLoader/classloader001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -79,7 +79,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValue/getvalue001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValue/getvalue001.java index fdbe0a5b5f354..e2e80abfbd0f6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValue/getvalue001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValue/getvalue001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -79,7 +79,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValue/getvalue002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValue/getvalue002.java index b7a541994972c..d3a2cbab4b25e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValue/getvalue002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValue/getvalue002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -78,7 +78,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValue/getvalue003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValue/getvalue003.java index cb01b136beeb2..7e1795fc76e43 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValue/getvalue003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValue/getvalue003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -78,7 +78,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValues/getvalues001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValues/getvalues001.java index a538815e6a17f..8403ab055470e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValues/getvalues001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/getValues/getvalues001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -82,7 +82,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/isStatic/isstatic001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/isStatic/isstatic001.java index 370e99fef7e6e..f73be251211e9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/isStatic/isstatic001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/isStatic/isstatic001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/isStatic/isstatic002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/isStatic/isstatic002.java index 8eba67bae64fb..0749021269ecb 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/isStatic/isstatic002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/isStatic/isstatic002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ShortType/_itself_/shorttype001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ShortType/_itself_/shorttype001.java index 7c800a58ffe05..141b618178971 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ShortType/_itself_/shorttype001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ShortType/_itself_/shorttype001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -89,7 +89,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addClassExclusionFilter/filter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addClassExclusionFilter/filter002.java index 0f1666fe29b43..5fa87598c6b78 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addClassExclusionFilter/filter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addClassExclusionFilter/filter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -96,7 +96,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addClassFilter_rt/filter_rt002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addClassFilter_rt/filter_rt002.java index ff014d431412d..80af7131dd73f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addClassFilter_rt/filter_rt002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addClassFilter_rt/filter_rt002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addClassFilter_s/filter_s002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addClassFilter_s/filter_s002.java index 4a49575e987dd..2d4c12c906ab8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addClassFilter_s/filter_s002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addClassFilter_s/filter_s002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addInstanceFilter/instancefilter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addInstanceFilter/instancefilter002.java index 066206c521417..cc03f52940756 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addInstanceFilter/instancefilter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addInstanceFilter/instancefilter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addInstanceFilter/instancefilter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addInstanceFilter/instancefilter003.java index b764fa9fee694..4446fcdcdc8f6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addInstanceFilter/instancefilter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/addInstanceFilter/instancefilter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth001.java index 12004bad5dfd7..249b6ee05fe90 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth002.java index dffd96e01998b..a3de24fb3d768 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth003.java index 6e050f7a0d8b1..b7281d524fb48 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/depth/depth003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/size/size001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/size/size001.java index 5585a49132815..6959aa2fed4e1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/size/size001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/size/size001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/size/size002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/size/size002.java index 9bb533b87246a..e25c3d9abd4d9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/size/size002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/size/size002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/thread/thread001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/thread/thread001.java index aaa8737d70c97..d0207238eb886 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/thread/thread001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StepRequest/thread/thread001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter001.java index 5dc0293b84862..7a5744f06c1d5 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter002.java index 56617b9f3004e..c14c28b9e9221 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -91,7 +91,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter003.java index 268726deeb6a3..0196795398cfd 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -102,7 +102,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter005.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter005.java index aad3c9cc4e320..f9003f4ba07a0 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadDeathRequest/addThreadFilter/addthreadfilter005.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -102,7 +102,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes001.java index 7e5b21d5d3633..51f51da29efbf 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -107,7 +107,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes002.java index b37bf4c6b188c..4f75c90b312f9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -99,7 +99,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes003.java index 455030b9a006e..f4a7fb4e38053 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes004.java index a372af1b8d5e8..7ca95a46c6511 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -97,7 +97,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes005.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes005.java index 09abeb54d5e84..7d221fb4db0f2 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes005.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -101,7 +101,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter001.java index da06b4fbb8190..3cc2cc9e321b5 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter002.java index be78eb12c0688..5ff5b8e835486 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -104,7 +104,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } //-------------------------------------------------- log procedures diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter003.java index 2ecb416a506c1..ccdadd2e4b594 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -102,7 +102,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter005.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter005.java index 36adefde262dc..d43e0257d7e0c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter005.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VMDeathEvent/_itself_/vmdeath002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VMDeathEvent/_itself_/vmdeath002.java index 00ed1e16a8e46..292df10b3e4d9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VMDeathEvent/_itself_/vmdeath002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VMDeathEvent/_itself_/vmdeath002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -80,7 +80,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VMDeathEvent/_itself_/vmdeath003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VMDeathEvent/_itself_/vmdeath003.java index 03a82a5a4a9a0..146f207bdc51e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VMDeathEvent/_itself_/vmdeath003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VMDeathEvent/_itself_/vmdeath003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -86,7 +86,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canAddMethod/canaddmethod001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canAddMethod/canaddmethod001.java index 715d918350568..ea2fa8462ac49 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canAddMethod/canaddmethod001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canAddMethod/canaddmethod001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -76,7 +76,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canPopFrames/canpopframes001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canPopFrames/canpopframes001.java index 8d5a131b6bab1..c16772d3ea333 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canPopFrames/canpopframes001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canPopFrames/canpopframes001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -76,7 +76,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canRedefineClasses/canredefineclasses001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canRedefineClasses/canredefineclasses001.java index d0d66e9554f32..73a501bfc6041 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canRedefineClasses/canredefineclasses001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canRedefineClasses/canredefineclasses001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -76,7 +76,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canRequestVMDeathEvent/canreqvmdev001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canRequestVMDeathEvent/canreqvmdev001.java index 0fca1d9739602..20c1b88e7513b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canRequestVMDeathEvent/canreqvmdev001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canRequestVMDeathEvent/canreqvmdev001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -76,7 +76,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canUnrestrictedlyRedefineClasses/curc001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canUnrestrictedlyRedefineClasses/curc001.java index 2fe87528dfc6b..950f13ca2ff49 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canUnrestrictedlyRedefineClasses/curc001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canUnrestrictedlyRedefineClasses/curc001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -76,7 +76,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canUseInstanceFilters/canusefilters001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canUseInstanceFilters/canusefilters001.java index 7ee8bc91ad9bc..ea8c4f55f67ec 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canUseInstanceFilters/canusefilters001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canUseInstanceFilters/canusefilters001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -76,7 +76,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canWatchFieldAccess/canwatchaccess001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canWatchFieldAccess/canwatchaccess001.java index 22ecbe109f691..a168056f423fa 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canWatchFieldAccess/canwatchaccess001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canWatchFieldAccess/canwatchaccess001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -87,7 +87,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canWatchFieldModification/canwatchmod001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canWatchFieldModification/canwatchmod001.java index 2b622584b60fc..a543024cea9cf 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canWatchFieldModification/canwatchmod001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/canWatchFieldModification/canwatchmod001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -88,7 +88,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses001.java index c8339ae4df171..30b39ac78f611 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -110,7 +110,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VoidType/_itself_/voidtype001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VoidType/_itself_/voidtype001.java index 505d6bd0f9673..be8765be809d9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VoidType/_itself_/voidtype001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VoidType/_itself_/voidtype001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -88,7 +88,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassExclusionFilter/filter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassExclusionFilter/filter003.java index ffd2e94985850..35465295ad51b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassExclusionFilter/filter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassExclusionFilter/filter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassExclusionFilter/filter004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassExclusionFilter/filter004.java index 8922042f1ddcb..c75f99d163801 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassExclusionFilter/filter004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassExclusionFilter/filter004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_rt/filter_rt003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_rt/filter_rt003.java index fab20a4862bd9..bc1eb909e2a88 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_rt/filter_rt003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_rt/filter_rt003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_rt/filter_rt004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_rt/filter_rt004.java index b00a463fcc7d3..69267ff95c2e4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_rt/filter_rt004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_rt/filter_rt004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_s/filter_s003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_s/filter_s003.java index 48e82775a7a9c..a17ec910620d4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_s/filter_s003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_s/filter_s003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_s/filter_s004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_s/filter_s004.java index e4d4a3cb77ed2..3598282d17653 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_s/filter_s004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addClassFilter_s/filter_s004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -98,7 +98,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter003.java index 278b468ead394..6c9eaaf618916 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -99,7 +99,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter004.java index c64d02f19997f..20348cec785ee 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -99,7 +99,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter005.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter005.java index 025f39cb34f22..07b368a73da5b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter005.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter006.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter006.java index d8f7a272d76fc..a03a1c041ba5c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter006.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addInstanceFilter/instancefilter006.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -95,7 +95,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter003.java index 7b9cf915e061a..717a26cef3ef4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -102,7 +102,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter004.java index 8b6ac6bdda6f0..2bf0958a17e5e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -102,7 +102,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter005.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter005.java index 3c9b5eae570b9..085082e6764cf 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter005.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -102,7 +102,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter006.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter006.java index a939d2f100fb4..5679dcf58312c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter006.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/addThreadFilter/addthreadfilter006.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -102,7 +102,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/field/field001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/field/field001.java index 8c0bd6848271c..52f7cb0d87c17 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/field/field001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/field/field001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -93,7 +93,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/field/field002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/field/field002.java index b795cb9495a42..4081b4bd98834 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/field/field002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/WatchpointRequest/field/field002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,7 +94,7 @@ public static int run (String argv[], PrintStream out) { if (exitCode != PASSED) { System.out.println("TEST FAILED"); } - return testExitCode; + return exitCode; } // ************************************************ test parameters diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIBase.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIBase.java index 795ac24afca4b..bc722844afdea 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIBase.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -76,7 +76,7 @@ public final void log3(String message) { protected ArgumentHandler argsHandler; protected VirtualMachine vm; protected ReferenceType debuggeeClass; - protected static int testExitCode = PASSED; + protected int testExitCode = PASSED; protected long waitTime; // used by tests with breakpoint communication From ef585a56f07f72d88c41d6e407c96fdfbd564cea Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 08:32:40 +0000 Subject: [PATCH 328/846] 8320858: Move jpackage tests to tier3 Reviewed-by: phh Backport-of: e44d4b24ed794957c47c140ab6f15544efa2b278 --- test/jdk/TEST.groups | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/test/jdk/TEST.groups b/test/jdk/TEST.groups index 38014cbcb323c..4a308842b4054 100644 --- a/test/jdk/TEST.groups +++ b/test/jdk/TEST.groups @@ -84,10 +84,12 @@ tier2_part3 = \ tier3 = \ :build \ :jdk_vector \ + -:jdk_vector_sanity \ :jdk_rmi \ :jdk_svc \ - -:jdk_svc_sanity \ - -:svc_tools + -:jdk_svc_sanity \ + -:svc_tools \ + :jdk_jpackage # Everything not in other tiers tier4 = \ @@ -278,10 +280,11 @@ jdk_launcher = \ sun/tools # -# Tool (and tool API) tests are split into core and svc groups +# Tool (and tool API) tests are mostly split into core and svc groups # core_tools = \ tools \ + -tools/jpackage \ jdk/internal/jrtfs \ sun/tools/jrunscript @@ -293,11 +296,15 @@ svc_tools = \ jdk_tools = \ :core_tools \ - :svc_tools + :svc_tools \ + :jdk_jpackage jdk_jfr = \ jdk/jfr +jdk_jpackage = \ + tools/jpackage + # # Catch-all for other areas with a small number of tests # From aeb2d2d0ce17da3aa7d49679beb4da2dd6f341ad Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 08:34:24 +0000 Subject: [PATCH 329/846] 8313083: Print 'rss' and 'cache' as part of the container information Backport-of: c96cbe481c86800b76e220374b24b6671984adb7 --- src/hotspot/os/linux/cgroupSubsystem_linux.hpp | 2 ++ src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp | 11 +++++++++++ src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp | 2 ++ src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp | 12 ++++++++++++ src/hotspot/os/linux/cgroupV2Subsystem_linux.hpp | 2 ++ src/hotspot/os/linux/osContainer_linux.cpp | 10 ++++++++++ src/hotspot/os/linux/osContainer_linux.hpp | 2 ++ src/hotspot/os/linux/os_linux.cpp | 2 ++ test/hotspot/jtreg/containers/docker/TestMisc.java | 4 +++- 9 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/hotspot/os/linux/cgroupSubsystem_linux.hpp b/src/hotspot/os/linux/cgroupSubsystem_linux.hpp index 721e49bf1fcc8..c7f34fa65c0b0 100644 --- a/src/hotspot/os/linux/cgroupSubsystem_linux.hpp +++ b/src/hotspot/os/linux/cgroupSubsystem_linux.hpp @@ -266,6 +266,8 @@ class CgroupSubsystem: public CHeapObj { virtual jlong memory_and_swap_limit_in_bytes() = 0; virtual jlong memory_soft_limit_in_bytes() = 0; virtual jlong memory_max_usage_in_bytes() = 0; + virtual jlong rss_usage_in_bytes() = 0; + virtual jlong cache_usage_in_bytes() = 0; virtual char * cpu_cpuset_cpus() = 0; virtual char * cpu_cpuset_memory_nodes() = 0; diff --git a/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp index 0c4a67c484e0f..bbe800c3a9e46 100644 --- a/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp @@ -214,6 +214,17 @@ jlong CgroupV1Subsystem::memory_max_usage_in_bytes() { return memmaxusage; } +jlong CgroupV1Subsystem::rss_usage_in_bytes() { + GET_CONTAINER_INFO_LINE(julong, _memory->controller(), "/memory.stat", + "rss", JULONG_FORMAT, JULONG_FORMAT, rss); + return rss; +} + +jlong CgroupV1Subsystem::cache_usage_in_bytes() { + GET_CONTAINER_INFO_LINE(julong, _memory->controller(), "/memory.stat", + "cache", JULONG_FORMAT, JULONG_FORMAT, cache); + return cache; +} jlong CgroupV1Subsystem::kernel_memory_usage_in_bytes() { GET_CONTAINER_INFO(jlong, _memory->controller(), "/memory.kmem.usage_in_bytes", diff --git a/src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp b/src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp index f0ac338957a11..9eb1dd2594e6f 100644 --- a/src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp +++ b/src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp @@ -79,6 +79,8 @@ class CgroupV1Subsystem: public CgroupSubsystem { jlong memory_soft_limit_in_bytes(); jlong memory_usage_in_bytes(); jlong memory_max_usage_in_bytes(); + jlong rss_usage_in_bytes(); + jlong cache_usage_in_bytes(); jlong kernel_memory_usage_in_bytes(); jlong kernel_memory_limit_in_bytes(); diff --git a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp index fb08eac1c2210..e8928a579d38c 100644 --- a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp @@ -139,6 +139,18 @@ jlong CgroupV2Subsystem::memory_max_usage_in_bytes() { return OSCONTAINER_ERROR; // not supported } +jlong CgroupV2Subsystem::rss_usage_in_bytes() { + GET_CONTAINER_INFO_LINE(julong, _memory->controller(), "/memory.stat", + "anon", JULONG_FORMAT, JULONG_FORMAT, rss); + return rss; +} + +jlong CgroupV2Subsystem::cache_usage_in_bytes() { + GET_CONTAINER_INFO_LINE(julong, _memory->controller(), "/memory.stat", + "file", JULONG_FORMAT, JULONG_FORMAT, cache); + return cache; +} + char* CgroupV2Subsystem::mem_soft_limit_val() { GET_CONTAINER_INFO_CPTR(cptr, _unified, "/memory.low", "Memory Soft Limit is: %s", "%1023s", mem_soft_limit_str, 1024); diff --git a/src/hotspot/os/linux/cgroupV2Subsystem_linux.hpp b/src/hotspot/os/linux/cgroupV2Subsystem_linux.hpp index bda5872bbbcaa..fe794b2fb9b34 100644 --- a/src/hotspot/os/linux/cgroupV2Subsystem_linux.hpp +++ b/src/hotspot/os/linux/cgroupV2Subsystem_linux.hpp @@ -78,6 +78,8 @@ class CgroupV2Subsystem: public CgroupSubsystem { jlong memory_soft_limit_in_bytes(); jlong memory_usage_in_bytes(); jlong memory_max_usage_in_bytes(); + jlong rss_usage_in_bytes(); + jlong cache_usage_in_bytes(); char * cpu_cpuset_cpus(); char * cpu_cpuset_memory_nodes(); diff --git a/src/hotspot/os/linux/osContainer_linux.cpp b/src/hotspot/os/linux/osContainer_linux.cpp index 88a9289b93972..ceca8038fc4b3 100644 --- a/src/hotspot/os/linux/osContainer_linux.cpp +++ b/src/hotspot/os/linux/osContainer_linux.cpp @@ -91,6 +91,16 @@ jlong OSContainer::memory_max_usage_in_bytes() { return cgroup_subsystem->memory_max_usage_in_bytes(); } +jlong OSContainer::rss_usage_in_bytes() { + assert(cgroup_subsystem != nullptr, "cgroup subsystem not available"); + return cgroup_subsystem->rss_usage_in_bytes(); +} + +jlong OSContainer::cache_usage_in_bytes() { + assert(cgroup_subsystem != nullptr, "cgroup subsystem not available"); + return cgroup_subsystem->cache_usage_in_bytes(); +} + void OSContainer::print_version_specific_info(outputStream* st) { assert(cgroup_subsystem != NULL, "cgroup subsystem not available"); cgroup_subsystem->print_version_specific_info(st); diff --git a/src/hotspot/os/linux/osContainer_linux.hpp b/src/hotspot/os/linux/osContainer_linux.hpp index ecf9dc5459a0f..35575135fc5bd 100644 --- a/src/hotspot/os/linux/osContainer_linux.hpp +++ b/src/hotspot/os/linux/osContainer_linux.hpp @@ -55,6 +55,8 @@ class OSContainer: AllStatic { static jlong memory_soft_limit_in_bytes(); static jlong memory_usage_in_bytes(); static jlong memory_max_usage_in_bytes(); + static jlong rss_usage_in_bytes(); + static jlong cache_usage_in_bytes(); static int active_processor_count(); diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 7c951cee51cf7..3d242348168a2 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -2387,6 +2387,8 @@ bool os::Linux::print_container_info(outputStream* st) { OSContainer::print_container_helper(st, OSContainer::memory_soft_limit_in_bytes(), "memory_soft_limit_in_bytes"); OSContainer::print_container_helper(st, OSContainer::memory_usage_in_bytes(), "memory_usage_in_bytes"); OSContainer::print_container_helper(st, OSContainer::memory_max_usage_in_bytes(), "memory_max_usage_in_bytes"); + OSContainer::print_container_helper(st, OSContainer::rss_usage_in_bytes(), "rss_usage_in_bytes"); + OSContainer::print_container_helper(st, OSContainer::cache_usage_in_bytes(), "cache_usage_in_bytes"); OSContainer::print_version_specific_info(st); diff --git a/test/hotspot/jtreg/containers/docker/TestMisc.java b/test/hotspot/jtreg/containers/docker/TestMisc.java index fbea62f81f8d5..5b7f96112b901 100644 --- a/test/hotspot/jtreg/containers/docker/TestMisc.java +++ b/test/hotspot/jtreg/containers/docker/TestMisc.java @@ -117,7 +117,9 @@ private static void checkContainerInfo(OutputAnalyzer out) throws Exception { "Maximum Memory Usage", "memory_max_usage_in_bytes", "maximum number of tasks", - "current number of tasks" + "current number of tasks", + "rss_usage_in_bytes", + "cache_usage_in_bytes" }; for (String s : expectedToContain) { From bab117d992deaf068a1e0aa7b1f18f802bed8975 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 08:36:08 +0000 Subject: [PATCH 330/846] 8327750: Convert javax/swing/JFileChooser/FileFilterDescription/FileFilterDescription.java applet test to main Backport-of: 78beb031c75d2435c3543a0edc2335b92e115858 --- .../FileFilterDescription.html | 40 --------------- .../FileFilterDescription.java | 49 ++++++++++++------- 2 files changed, 31 insertions(+), 58 deletions(-) delete mode 100644 test/jdk/javax/swing/JFileChooser/FileFilterDescription/FileFilterDescription.html diff --git a/test/jdk/javax/swing/JFileChooser/FileFilterDescription/FileFilterDescription.html b/test/jdk/javax/swing/JFileChooser/FileFilterDescription/FileFilterDescription.html deleted file mode 100644 index 99133770bffd7..0000000000000 --- a/test/jdk/javax/swing/JFileChooser/FileFilterDescription/FileFilterDescription.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - -Follow the instructions below. -1) Check that current filter in the opened JFileChooser is a "CustomFileFilter". -2) Close the JFileChooser. -3) Test will repeat steps 1 - 2 for all supported look and feels. -4) If it's true for all look and feels then the test passed, otherwise it failed. - - diff --git a/test/jdk/javax/swing/JFileChooser/FileFilterDescription/FileFilterDescription.java b/test/jdk/javax/swing/JFileChooser/FileFilterDescription/FileFilterDescription.java index 2bca535fe8d0c..9da801d6af749 100644 --- a/test/jdk/javax/swing/JFileChooser/FileFilterDescription/FileFilterDescription.java +++ b/test/jdk/javax/swing/JFileChooser/FileFilterDescription/FileFilterDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,44 +21,57 @@ * questions. */ -import java.applet.Applet; import java.io.File; - +import java.awt.BorderLayout; import javax.swing.JFileChooser; +import javax.swing.JFrame; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.filechooser.FileFilter; -public final class FileFilterDescription extends Applet { +/* + * @test + * @bug 8029536 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual FileFilterDescription + */ +public final class FileFilterDescription { - @Override - public void init() { - } - - @Override - public void start() { - try { - test(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } + private static final String INSTRUCTIONS = """ + 1) Check that current filter in the opened JFileChooser is a "CustomFileFilter". + 2) Close the JFileChooser. + 3) Test will repeat steps 1 - 2 for all supported look and feels. + 4) If it's true for all look and feels then click Pass else click Fail. """; + public static void main(String[] args) throws Exception { + PassFailJFrame passFailJFrame = PassFailJFrame.builder() + .title("JFileChooser Filefilter Instructions") + .instructions(INSTRUCTIONS) + .rows(10) + .columns(35) + .position(PassFailJFrame.Position.TOP_LEFT_CORNER) + .build(); - public static void test() throws Exception { final UIManager.LookAndFeelInfo[] infos = UIManager .getInstalledLookAndFeels(); for (final UIManager.LookAndFeelInfo info : infos) { SwingUtilities.invokeAndWait(() -> { - final JFileChooser chooser = new JFileChooser(); setLookAndFeel(info); + JFrame frame = new JFrame("JFileChooser FileFilter test"); + final JFileChooser chooser = new JFileChooser(); chooser.setAcceptAllFileFilterUsed(false); chooser.setFileFilter(new CustomFileFilter()); SwingUtilities.updateComponentTreeUI(chooser); + frame.add(chooser, BorderLayout.CENTER); + frame.pack(); + PassFailJFrame.addTestWindow(frame); + PassFailJFrame.positionTestWindow(frame, PassFailJFrame.Position.TOP_LEFT_CORNER); chooser.showDialog(null, "Open"); }); } + passFailJFrame.awaitAndCheck(); } private static void setLookAndFeel(final UIManager.LookAndFeelInfo info) { From f58e11ece516b1df3b900d05e2c661ef2b760480 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 08:50:17 +0000 Subject: [PATCH 331/846] 8327751: Convert javax/swing/JInternalFrame/6726866/bug6726866.java applet test to main Backport-of: cfd9209e03176bd8e02acd74b51a16f3113fbd21 --- .../JInternalFrame/6726866/bug6726866.html | 30 --------------- .../JInternalFrame/6726866/bug6726866.java | 37 ++++++++++++++----- 2 files changed, 27 insertions(+), 40 deletions(-) delete mode 100644 test/jdk/javax/swing/JInternalFrame/6726866/bug6726866.html diff --git a/test/jdk/javax/swing/JInternalFrame/6726866/bug6726866.html b/test/jdk/javax/swing/JInternalFrame/6726866/bug6726866.html deleted file mode 100644 index 0db8864e8d8cd..0000000000000 --- a/test/jdk/javax/swing/JInternalFrame/6726866/bug6726866.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - -Drag the internal frame inside the green undecorated window, -if you can drag it the test passes, otherwise fails. - - diff --git a/test/jdk/javax/swing/JInternalFrame/6726866/bug6726866.java b/test/jdk/javax/swing/JInternalFrame/6726866/bug6726866.java index d56f10d39ef12..88b890d7b2ca2 100644 --- a/test/jdk/javax/swing/JInternalFrame/6726866/bug6726866.java +++ b/test/jdk/javax/swing/JInternalFrame/6726866/bug6726866.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,11 +21,14 @@ * questions. */ -/* @test - @bug 6726866 8186617 - @summary Repainting artifacts when resizing or dragging JInternalFrames in +/* + * @test + * @bug 6726866 8186617 + * @summary Repainting artifacts when resizing or dragging JInternalFrames in non-opaque toplevel - @run applet/manual=yesno bug6726866.html + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug6726866 */ import java.awt.Color; @@ -36,10 +39,26 @@ import javax.swing.JFrame; import javax.swing.JInternalFrame; import javax.swing.JLabel; +import javax.swing.SwingUtilities; + +public class bug6726866 { -public class bug6726866 extends JApplet { + private static final String INSTRUCTIONS = """ + Drag the internal frame inside the green undecorated window, + if you can drag it the test passes, otherwise fails. """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("JInternalFrame Instructions") + .instructions(INSTRUCTIONS) + .rows(5) + .columns(35) + .testUI(bug6726866::createUI) + .build() + .awaitAndCheck(); + } - public void init() { + private static JFrame createUI() { JFrame frame = new JFrame("bug6726866"); frame.setUndecorated(true); setWindowNonOpaque(frame); @@ -53,10 +72,8 @@ public void init() { desktop.add(iFrame); frame.add(desktop); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(400, 400); - frame.setVisible(true); - frame.toFront(); + return frame; } public static void setWindowNonOpaque(Window window) { From ef807233a1e5072ceace79dd2791e006fb324741 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 08:54:19 +0000 Subject: [PATCH 332/846] 8327872: Convert javax/swing/JToolTip/4644444/bug4644444.java applet test to main Backport-of: a4a5196351a3c8ce45e2e36d27842194cbfcc5ff --- .../swing/JToolTip/4644444/bug4644444.html | 44 --- .../swing/JToolTip/4644444/bug4644444.java | 354 ------------------ test/jdk/javax/swing/JToolTip/bug4644444.java | 63 ++++ 3 files changed, 63 insertions(+), 398 deletions(-) delete mode 100644 test/jdk/javax/swing/JToolTip/4644444/bug4644444.html delete mode 100644 test/jdk/javax/swing/JToolTip/4644444/bug4644444.java create mode 100644 test/jdk/javax/swing/JToolTip/bug4644444.java diff --git a/test/jdk/javax/swing/JToolTip/4644444/bug4644444.html b/test/jdk/javax/swing/JToolTip/4644444/bug4644444.html deleted file mode 100644 index b7e9bcb03fe85..0000000000000 --- a/test/jdk/javax/swing/JToolTip/4644444/bug4644444.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - bug4644444 - - - -

    bug4644444
    Bug ID: 4644444

    - -

    See the dialog box (usually in upper left corner) for instructions

    - - - - diff --git a/test/jdk/javax/swing/JToolTip/4644444/bug4644444.java b/test/jdk/javax/swing/JToolTip/4644444/bug4644444.java deleted file mode 100644 index 124c565a9cbd6..0000000000000 --- a/test/jdk/javax/swing/JToolTip/4644444/bug4644444.java +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.awt.*; -import javax.swing.*; -import java.awt.event.*; - -/* - * test - * @bug 4644444 8076246 -*/ - -public class bug4644444 extends JApplet { - - JPanel panel; - JButton button; - - public bug4644444() throws Exception { - java.awt.EventQueue.invokeLater( () -> { - panel = new JPanel(); - button = new JButton("whooo"); - button.setToolTipText("Somthing really long 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890"); - panel.add(button); - getContentPane().add(panel); - }); - } - - public void init() { - String[][] instructionsSet = - { - { - " Note : Incase of Assertion failure,user can enter", - " remarks by pressing 'Assertion Fail Remarks ' button", - " ", - " You would see a testframe with a Button", - " ", - " ON ALL PLATFORMS", - "1. Move the mouse on the button, ", - " so that the tooltip attached to it comes up ", - "2. Tool tip should get adjusted it-self to show ", - " its full length of text. ", - "3. If tooltip text gets cut, ", - " press 'Assertion Fail' else press 'Assertion Pass'", - "4. Similarly, move the applet to different locations of the screen, ", - " & see if tooltip works properly everywhere. " - } - }; - - String[] exceptionsSet = - { - "JToolTip is shown partially when placed very close to screen boundaries", - }; - - Sysout.setInstructionsWithExceptions(instructionsSet,exceptionsSet); - - } - - public void start (){} - - public void destroy(){ - if(Sysout.failStatus()) { - String failMsg = Sysout.getFailureMessages(); - failMsg = failMsg.replace('\n',' '); - throw new RuntimeException(failMsg); - }// End destroy - } -} - - -/**************************************************** - Standard Test Machinery - DO NOT modify anything below -- it's a standard - chunk of code whose purpose is to make user - interaction uniform, and thereby make it simpler - to read and understand someone else's test. - ****************************************************/ - -/** - This is part of the standard test machinery. - It creates a dialog (with the instructions), and is the interface - for sending text messages to the user. - To print the instructions, send an array of strings to Sysout.createDialog - WithInstructions method. Put one line of instructions per array entry. - To display a message for the tester to see, simply call Sysout.println - with the string to be displayed. - This mimics System.out.println but works within the test harness as well - as standalone. - */ - -class Sysout - { - private static TestDialog dialog; - - public static void createDialogWithInstructions( String[] instructions ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - dialog.printInstructions( instructions ); - dialog.show(); - println( "Any messages for the tester will display here." ); - } - - public static void createDialog( ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - String[] defInstr = { "Instructions will appear here. ", "" } ; - dialog.printInstructions( defInstr ); - dialog.show(); - println( "Any messages for the tester will display here." ); - } - - - public static void printInstructions( String[] instructions ) - { - dialog.printInstructions( instructions ); - } - - - public static void println( String messageIn ) - { - dialog.displayMessage( messageIn ); - } - - public static void setInstructionsWithExceptions(String instructionsSet[][], - String exceptionsSet[]) { - createDialogWithInstructions(instructionsSet[0]); - dialog.setInstructions(instructionsSet); - dialog.setExceptionMessages(exceptionsSet); - } - - public static String getFailureMessages() { - return dialog.failureMessages; - } - - public static boolean failStatus() { - return dialog.failStatus; - } - - }// Sysout class - -/** - This is part of the standard test machinery. It provides a place for the - test instructions to be displayed, and a place for interactive messages - to the user to be displayed. - To have the test instructions displayed, see Sysout. - To have a message to the user be displayed, see Sysout. - Do not call anything in this dialog directly. - */ -class TestDialog extends Dialog - { - - TextArea instructionsText; - TextArea messageText; - int maxStringLength = 70; - - Panel assertPanel; - Button assertPass,assertFail,remarks; - HandleAssert handleAssert; - boolean failStatus=false; - int instructionCounter=0; - String instructions[][]; - int exceptionCounter=0; - String exceptionMessages[]; - String failureMessages="
    "; - String remarksMessage=null; - RemarksDialog remarksDialog; - - //DO NOT call this directly, go through Sysout - public TestDialog( Frame frame, String name ) - { - super( frame, name ); - int scrollBoth = TextArea.SCROLLBARS_BOTH; - instructionsText = new TextArea( "", 14, maxStringLength, scrollBoth ); - add( "North", instructionsText ); - - messageText = new TextArea( "", 3, maxStringLength, scrollBoth ); - add("Center", messageText); - - assertPanel = new Panel(new FlowLayout()); - assertPass=new Button("Assertion Pass"); - assertPass.setName("Assertion Pass"); - assertFail=new Button("Assertion Fail"); - assertFail.setName("Assertion Fail"); - remarks = new Button("Assertion Fail Remarks"); - remarks.setEnabled(false); - remarks.setName("Assertion Remarks"); - assertPanel.add(assertPass); - assertPanel.add(assertFail); - assertPanel.add(remarks); - handleAssert = new HandleAssert(); - assertPass.addActionListener(handleAssert); - assertFail.addActionListener(handleAssert); - remarks.addActionListener(handleAssert); - add("South",assertPanel); - pack(); - - show(); - }// TestDialog() - - //DO NOT call this directly, go through Sysout - public void printInstructions( String[] instructions ) - { - //Clear out any current instructions - instructionsText.setText( "" ); - - //Go down array of instruction strings - - String printStr, remainingStr; - for( int i=0; i < instructions.length; i++ ) - { - //chop up each into pieces maxSringLength long - remainingStr = instructions[ i ]; - while( remainingStr.length() > 0 ) - { - //if longer than max then chop off first max chars to print - if( remainingStr.length() >= maxStringLength ) - { - //Try to chop on a word boundary - int posOfSpace = remainingStr. - lastIndexOf( ' ', maxStringLength - 1 ); - - if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; - - printStr = remainingStr.substring( 0, posOfSpace + 1 ); - remainingStr = remainingStr.substring( posOfSpace + 1 ); - } - //else just print - else - { - printStr = remainingStr; - remainingStr = ""; - } - - instructionsText.append( printStr + "\n" ); - - }// while - - }// for - - }//printInstructions() - - //DO NOT call this directly, go through Sysout - public void displayMessage( String messageIn ) - { - messageText.append( messageIn + "\n" ); - } - - public void emptyMessage() { - messageText.setText(""); - } - - public void setInstructions(String insStr[][]) { - instructions=insStr; - } - - public void setExceptionMessages(String exceptionMessages[]) { - this.exceptionMessages=exceptionMessages; - } - - class HandleAssert implements ActionListener { - public void actionPerformed(ActionEvent ae) { - if(ae.getSource()==remarks) { - remarksDialog = new RemarksDialog(TestDialog.this, - "Assertion Remarks Dialog",true); - remarks.setEnabled(false); - if(remarksMessage!=null) - failureMessages+=". User Remarks : "+remarksMessage; - } - else { - if(instructionCounter"+ - exceptionMessages[exceptionCounter]; - } - } - exceptionCounter++; - } - } - } - - class RemarksDialog extends Dialog implements ActionListener{ - Panel rootPanel,remarksPanel; - TextArea textarea; - Button addRemarks,cancelRemarks; - public RemarksDialog(Dialog owner,String title,boolean modal) { - super(owner,title,modal); - rootPanel = new Panel(new BorderLayout()); - remarksPanel = new Panel(new FlowLayout()); - textarea = new TextArea(5,30); - addRemarks=new Button("Add Remarks"); - addRemarks.addActionListener(this); - cancelRemarks = new Button("Cancel Remarks"); - cancelRemarks.addActionListener(this); - remarksPanel.add(addRemarks); - remarksPanel.add(cancelRemarks); - rootPanel.add(textarea,"Center"); - rootPanel.add(remarksPanel,"South"); - add(rootPanel); - setBounds(150,150,400,200); - setVisible(true); - } - - public void actionPerformed(ActionEvent ae) { - remarksMessage=null; - if(ae.getSource()==addRemarks) { - String msg = textarea.getText().trim(); - if (msg.length()>0) - remarksMessage=msg; - } - dispose(); - } - - } - -}// TestDialog class diff --git a/test/jdk/javax/swing/JToolTip/bug4644444.java b/test/jdk/javax/swing/JToolTip/bug4644444.java new file mode 100644 index 0000000000000..2921ecf0da5cc --- /dev/null +++ b/test/jdk/javax/swing/JToolTip/bug4644444.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.swing.JButton; +import javax.swing.JFrame; + +/* + * @test + * @bug 4644444 8076246 + * @summary JToolTip is shown improperly when placed very close to screen boundaries + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4644444 + */ + +public class bug4644444 { + + private static final String INSTRUCTIONS = """ + 1. Move the mouse on the button, so that the tooltip is visible. + 2. Tooltip should get adjusted itself to show its full length of text. + 3. Similarly, move the frame to different locations of the screen + & see if tooltip works properly everywhere. + 4. Press 'Pass' if tooltip text is fully visible else press 'Fail'. """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("JToolTip Instructions") + .instructions(INSTRUCTIONS) + .testUI(bug4644444::createUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createUI() { + JFrame frame = new JFrame("bug4644444"); + JButton button = new JButton("Button"); + button.setToolTipText("Something really long 1234567890 1234567890 " + + "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890"); + frame.getContentPane().add(button); + frame.setSize(200, 80); + return frame; + } +} From c708567b94b5be9787ab80cce8540761b88d2300 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 08:55:40 +0000 Subject: [PATCH 333/846] 8327752: Convert javax/swing/JOptionPane/4174551/bug4174551.java applet to main Backport-of: 7858138ad212bb4dec0b30e7235b72fe74cdb960 --- .../swing/JOptionPane/4174551/bug4174551.html | 36 --------- .../swing/JOptionPane/4174551/bug4174551.java | 52 ------------- .../javax/swing/JOptionPane/bug4174551.java | 78 +++++++++++++++++++ 3 files changed, 78 insertions(+), 88 deletions(-) delete mode 100644 test/jdk/javax/swing/JOptionPane/4174551/bug4174551.html delete mode 100644 test/jdk/javax/swing/JOptionPane/4174551/bug4174551.java create mode 100644 test/jdk/javax/swing/JOptionPane/bug4174551.java diff --git a/test/jdk/javax/swing/JOptionPane/4174551/bug4174551.html b/test/jdk/javax/swing/JOptionPane/4174551/bug4174551.html deleted file mode 100644 index ca7bac5dac5c8..0000000000000 --- a/test/jdk/javax/swing/JOptionPane/4174551/bug4174551.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - Message Dialog should pop up - with a button font size 10 - and message font size 24. - - It should be true even on OS X. - If it is not so press "Fail" else press "Pass". - - - - - diff --git a/test/jdk/javax/swing/JOptionPane/4174551/bug4174551.java b/test/jdk/javax/swing/JOptionPane/4174551/bug4174551.java deleted file mode 100644 index fd20840867afe..0000000000000 --- a/test/jdk/javax/swing/JOptionPane/4174551/bug4174551.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 4174551 - * @summary JOptionPane should allow custom buttons - * @author Xhipra Tyagi(xhipra.tyagi@india.sun.com) area=Swing - * @run applet/manual=yesno bug4174551.html - */ -import java.awt.Font; -import javax.swing.JApplet; -import javax.swing.UIManager; -import javax.swing.JOptionPane; - -public class bug4174551 extends JApplet { - - public void init() { - try { - java.awt.EventQueue.invokeLater( () -> { - UIManager.getDefaults().put("OptionPane.buttonFont", new Font("Dialog", Font.PLAIN, 10)); - UIManager.getDefaults().put("OptionPane.messageFont", new Font("Dialog", Font.PLAIN, 24)); - JOptionPane.showMessageDialog(null, "HI 24!"); - - System.out.println(UIManager.getDefaults().get("OptionPane.buttonFont")); - System.out.println(UIManager.getDefaults().get("OptionPane.messageFont")); - }); - }catch(Exception ex) { - ex.printStackTrace(); - } - } -} diff --git a/test/jdk/javax/swing/JOptionPane/bug4174551.java b/test/jdk/javax/swing/JOptionPane/bug4174551.java new file mode 100644 index 0000000000000..f65f95192b7e2 --- /dev/null +++ b/test/jdk/javax/swing/JOptionPane/bug4174551.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4174551 + * @summary JOptionPane should allow custom buttons + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4174551 + */ +import java.awt.FlowLayout; +import java.awt.Font; +import javax.swing.JDialog; +import javax.swing.JOptionPane; +import javax.swing.UIManager; + +public class bug4174551 { + private static final String INSTRUCTIONS = """ + Two Message Dialog should pop up side-by-side + one with a custom message font size 24 with message "HI 24" + and another with default optionpane message font size with message "HI default" + If custom message font size is not more than default message fontsize + AND + custom message buttonfont size is more than default message buttonfont size + press "Fail" else press "Pass". """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .title("JOptionPane Instructions") + .instructions(INSTRUCTIONS) + .rows(8) + .columns(40) + .testUI(bug4174551::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JDialog createTestUI() { + JOptionPane defaultPane = new JOptionPane(); + defaultPane.setMessage("HI default"); + defaultPane.setMessageType(JOptionPane.INFORMATION_MESSAGE); + UIManager.getDefaults().put("OptionPane.buttonFont", new Font("Dialog", Font.PLAIN, 10)); + UIManager.getDefaults().put("OptionPane.messageFont", new Font("Dialog", Font.PLAIN, 24)); + JOptionPane optionPane = new JOptionPane(); + optionPane.setMessage("HI 24!"); + optionPane.setMessageType(JOptionPane.INFORMATION_MESSAGE); + JDialog dialog = new JDialog(); + dialog.setLayout(new FlowLayout()); + dialog.add(optionPane); + dialog.add(defaultPane); + dialog.pack(); + + System.out.println(UIManager.getDefaults().get("OptionPane.buttonFont")); + System.out.println(UIManager.getDefaults().get("OptionPane.messageFont")); + return dialog; + } +} From b1a6a79a1fabfb8b81c2e2f92505d5fb139b41c9 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 08:57:07 +0000 Subject: [PATCH 334/846] 8327754: Convert javax/swing/JPopupMenu/7160604/bug7160604.java applet to main Backport-of: 628e7702746ed4cc899d9727432b64c701533eb3 --- .../swing/JPopupMenu/7160604/bug7160604.html | 30 ----- .../swing/JPopupMenu/7160604/bug7160604.java | 95 --------------- .../javax/swing/JPopupMenu/bug7160604.java | 112 ++++++++++++++++++ 3 files changed, 112 insertions(+), 125 deletions(-) delete mode 100644 test/jdk/javax/swing/JPopupMenu/7160604/bug7160604.html delete mode 100644 test/jdk/javax/swing/JPopupMenu/7160604/bug7160604.java create mode 100644 test/jdk/javax/swing/JPopupMenu/bug7160604.java diff --git a/test/jdk/javax/swing/JPopupMenu/7160604/bug7160604.html b/test/jdk/javax/swing/JPopupMenu/7160604/bug7160604.html deleted file mode 100644 index d1356c3f6d59c..0000000000000 --- a/test/jdk/javax/swing/JPopupMenu/7160604/bug7160604.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - -Click on the top-bar and combo-box more than once. -Make sure popup menu and drop-down list have a border and their items are drawn properly. - - diff --git a/test/jdk/javax/swing/JPopupMenu/7160604/bug7160604.java b/test/jdk/javax/swing/JPopupMenu/7160604/bug7160604.java deleted file mode 100644 index cf73ba608f7cf..0000000000000 --- a/test/jdk/javax/swing/JPopupMenu/7160604/bug7160604.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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 7160604 - @summary Using non-opaque windows - popups are initially not painted correctly - @author Oleg Pekhovskiy - @run applet/manual=yesno bug7160604.html -*/ - -import javax.swing.AbstractAction; -import javax.swing.BorderFactory; -import javax.swing.JApplet; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JMenuItem; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JWindow; -import javax.swing.SwingUtilities; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import static java.awt.GraphicsDevice.WindowTranslucency.*; - -public class bug7160604 extends JApplet { - - public void init() { - SwingUtilities.invokeLater(() -> { - if (!GraphicsEnvironment - .getLocalGraphicsEnvironment() - .getDefaultScreenDevice() - .isWindowTranslucencySupported(PERPIXEL_TRANSLUCENT)) { - // Tested translucency is not supported. Test passed - return; - } - - final JWindow window = new JWindow(); - window.setLocation(200, 200); - window.setSize(300, 300); - - final JLabel label = new JLabel("...click to invoke JPopupMenu"); - label.setOpaque(true); - final JPanel contentPane = new JPanel(new BorderLayout()); - contentPane.setBorder(BorderFactory.createLineBorder(Color.RED)); - window.setContentPane(contentPane); - contentPane.add(label, BorderLayout.NORTH); - - final JComboBox comboBox = new JComboBox(new Object[]{"1", "2", "3", "4"}); - contentPane.add(comboBox, BorderLayout.SOUTH); - - final JPopupMenu jPopupMenu = new JPopupMenu(); - - jPopupMenu.add("string"); - jPopupMenu.add(new AbstractAction("action") { - @Override - public void actionPerformed(final ActionEvent e) { - } - }); - jPopupMenu.add(new JLabel("label")); - jPopupMenu.add(new JMenuItem("MenuItem")); - label.addMouseListener(new MouseAdapter() { - @Override - public void mouseReleased(final MouseEvent e) { - jPopupMenu.show(label, 0, 0); - } - }); - - window.setBackground(new Color(0, 0, 0, 0)); - - window.setVisible(true); - }); - } -} diff --git a/test/jdk/javax/swing/JPopupMenu/bug7160604.java b/test/jdk/javax/swing/JPopupMenu/bug7160604.java new file mode 100644 index 0000000000000..591817b75c909 --- /dev/null +++ b/test/jdk/javax/swing/JPopupMenu/bug7160604.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 7160604 + * @summary Using non-opaque windows - popups are initially not painted correctly + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug7160604 +*/ +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.GraphicsEnvironment; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import static java.awt.GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT; +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JWindow; +import javax.swing.SwingUtilities; + +public class bug7160604 { + + private static final String INSTRUCTIONS = """ + Click on the top-bar and combo-box at the bottom more than once. + Check top-bar popup menu and combo-box drop-down list have a border + and their items are drawn properly. + If yes, Click Pass else click Fail."""; + + public static void main(String[] args) throws Exception { + if (!GraphicsEnvironment + .getLocalGraphicsEnvironment() + .getDefaultScreenDevice() + .isWindowTranslucencySupported(PERPIXEL_TRANSLUCENT)) { + // Tested translucency is not supported. Test passed + return; + } + PassFailJFrame.builder() + .title("PopupMenu Instructions") + .instructions(INSTRUCTIONS) + .rows(5) + .columns(35) + .testUI(bug7160604::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JWindow createTestUI() { + + final JWindow window = new JWindow(); + window.setLocation(200, 200); + window.setSize(300, 300); + + final JLabel label = new JLabel("...click to invoke JPopupMenu"); + label.setOpaque(true); + final JPanel contentPane = new JPanel(new BorderLayout()); + contentPane.setBorder(BorderFactory.createLineBorder(Color.RED)); + window.setContentPane(contentPane); + contentPane.add(label, BorderLayout.NORTH); + + final JComboBox comboBox = new JComboBox(new Object[]{"1", "2", "3", "4"}); + contentPane.add(comboBox, BorderLayout.SOUTH); + + final JPopupMenu jPopupMenu = new JPopupMenu(); + + jPopupMenu.add("string"); + jPopupMenu.add(new AbstractAction("action") { + @Override + public void actionPerformed(final ActionEvent e) { + } + }); + jPopupMenu.add(new JLabel("label")); + jPopupMenu.add(new JMenuItem("MenuItem")); + label.addMouseListener(new MouseAdapter() { + @Override + public void mouseReleased(final MouseEvent e) { + jPopupMenu.show(label, 0, 0); + } + }); + + window.setBackground(new Color(0, 0, 0, 0)); + + return window; + } +} From 1d892a7d4cc8a908f9b426cba55ca4e78ec49725 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 08:58:30 +0000 Subject: [PATCH 335/846] 8327755: Convert javax/swing/JScrollBar/8039464/Test8039464.java applet to main Backport-of: 98e4b753e8d7fbbf651c866901734d4f6a7d1680 --- .../swing/JScrollBar/8039464/Test8039464.html | 32 ------------- .../JScrollBar/{8039464 => }/Test8039464.java | 45 ++++++++++--------- 2 files changed, 24 insertions(+), 53 deletions(-) delete mode 100644 test/jdk/javax/swing/JScrollBar/8039464/Test8039464.html rename test/jdk/javax/swing/JScrollBar/{8039464 => }/Test8039464.java (74%) diff --git a/test/jdk/javax/swing/JScrollBar/8039464/Test8039464.html b/test/jdk/javax/swing/JScrollBar/8039464/Test8039464.html deleted file mode 100644 index a473b819d1c3a..0000000000000 --- a/test/jdk/javax/swing/JScrollBar/8039464/Test8039464.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - -Choose the variable applet size and try to resize the applet. -The test passes the thumb is painted correctly. - - - - - diff --git a/test/jdk/javax/swing/JScrollBar/8039464/Test8039464.java b/test/jdk/javax/swing/JScrollBar/Test8039464.java similarity index 74% rename from test/jdk/javax/swing/JScrollBar/8039464/Test8039464.java rename to test/jdk/javax/swing/JScrollBar/Test8039464.java index 44bb33abd948c..780d5e9db7740 100644 --- a/test/jdk/javax/swing/JScrollBar/8039464/Test8039464.java +++ b/test/jdk/javax/swing/JScrollBar/Test8039464.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ import java.awt.GridBagConstraints; import java.awt.GridBagLayout; -import javax.swing.JApplet; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollBar; @@ -37,11 +36,16 @@ * @test * @bug 8039464 * @summary Tests enabling/disabling of titled border's caption - * @author Sergey Malenkov - * @run applet/manual=yesno Test8039464.html + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual Test8039464 */ -public class Test8039464 extends JApplet { +public class Test8039464 { + private static final String INSTRUCTIONS = """ + If the scrollbar thumb is painted correctly in system lookandfeel + click Pass else click Fail. """; + static { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); @@ -50,11 +54,6 @@ public class Test8039464 extends JApplet { } } - @Override - public void init() { - init(this); - } - private static void init(Container container) { container.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); @@ -77,16 +76,20 @@ private static void init(Container container) { } public static void main(String[] args) throws Exception { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - JFrame frame = new JFrame("8039464"); - init(frame); - frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - frame.pack(); - frame.setLocationRelativeTo(null); - frame.setVisible(true); - } - }); + PassFailJFrame.builder() + .title("JScrollBar Instructions") + .instructions(INSTRUCTIONS) + .rows(5) + .columns(35) + .testUI(Test8039464::createTestUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createTestUI() { + JFrame frame = new JFrame("8039464"); + init(frame); + frame.pack(); + return frame; } } From 84ccc1605850717318f149c08ead8adbb8d8bbfb Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 08:59:54 +0000 Subject: [PATCH 336/846] 8327874: Convert javax/swing/JTree/4314199/bug4314199.java applet test to main Backport-of: 49ce85fae9f06d05367c94615532f6ff87952c79 --- .../javax/swing/JTree/4314199/bug4314199.html | 31 --------- .../swing/JTree/{4314199 => }/bug4314199.java | 69 ++++++++++--------- 2 files changed, 38 insertions(+), 62 deletions(-) delete mode 100644 test/jdk/javax/swing/JTree/4314199/bug4314199.html rename test/jdk/javax/swing/JTree/{4314199 => }/bug4314199.java (58%) diff --git a/test/jdk/javax/swing/JTree/4314199/bug4314199.html b/test/jdk/javax/swing/JTree/4314199/bug4314199.html deleted file mode 100644 index 1ce22cbeac303..0000000000000 --- a/test/jdk/javax/swing/JTree/4314199/bug4314199.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - -Select the last tree node (marked "Here") and click on the menu. -Look at the vertical line connecting nodes "Bug" and "Here". If -this line disappears when the menu drops down, test fails. - - - diff --git a/test/jdk/javax/swing/JTree/4314199/bug4314199.java b/test/jdk/javax/swing/JTree/bug4314199.java similarity index 58% rename from test/jdk/javax/swing/JTree/4314199/bug4314199.java rename to test/jdk/javax/swing/JTree/bug4314199.java index ecf0dabb3429a..8dd38830d0f68 100644 --- a/test/jdk/javax/swing/JTree/4314199/bug4314199.java +++ b/test/jdk/javax/swing/JTree/bug4314199.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,42 +26,44 @@ * @test * @bug 4314199 * @summary Tests that JTree repaints correctly in a container with a JMenu - * @author Peter Zhelezniakov - * @run applet/manual=yesno bug4314199.html + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual bug4314199 */ -import javax.swing.*; -import javax.swing.tree.*; +import java.awt.BorderLayout; +import javax.swing.Box; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JTree; +import javax.swing.UIManager; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; -public class bug4314199 extends JApplet { +public class bug4314199 { - public void init() { + private static final String INSTRUCTIONS = """ + Select the last tree node (marked "Here") and click on the "Menu". + Look at the vertical line connecting nodes "Bug" and "Here". + If the connecting line does not disappear when the "Menu" drops down, + press 'Pass' else 'Fail'. """; - try { - UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); - SwingUtilities.invokeAndWait(new Runnable() { - - public void run() { - createAndShowGUI(); - } - }); - } catch (final Exception e) { - SwingUtilities.invokeLater(new Runnable() { - - public void run() { - createAndShowMessage("Test fails because of exception: " - + e.getMessage()); - } - }); - } + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + PassFailJFrame.builder() + .title("JTree Instructions") + .instructions(INSTRUCTIONS) + .rows(6) + .splitUI(bug4314199::createAndShowGUI) + .build() + .awaitAndCheck(); } - private void createAndShowMessage(String message) { - getContentPane().add(new JLabel(message)); - } - - private void createAndShowGUI() { + private static JPanel createAndShowGUI() { JMenuBar mb = new JMenuBar(); // needed to exactly align left edge of menu and angled line of tree @@ -71,7 +73,6 @@ private void createAndShowGUI() { JMenuItem mi = new JMenuItem("MenuItem"); mn.add(mi); mb.add(mn); - setJMenuBar(mb); DefaultMutableTreeNode n1 = new DefaultMutableTreeNode("Root"); DefaultMutableTreeNode n2 = new DefaultMutableTreeNode("Duke"); @@ -87,6 +88,12 @@ private void createAndShowGUI() { JTree tree = new JTree(new DefaultTreeModel(n1)); tree.putClientProperty("JTree.lineStyle", "Angled"); tree.expandPath(new TreePath(new Object[]{n1, n2, n3})); - setContentPane(tree); + + JPanel p = new JPanel(); + p.setLayout(new BorderLayout()); + p.setSize(200, 200); + p.add(mb, BorderLayout.NORTH); + p.add(tree); + return p; } } From 739cb0308522fd3aae1c7c05e66c7d32498f2c8e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 09:32:54 +0000 Subject: [PATCH 337/846] 8327969: Convert javax/swing/border/Test6910490.java applet test to main Backport-of: 759cc675915c551cc1d6899eedb95900752f2703 --- test/jdk/javax/swing/border/Test6910490.html | 32 ----------------- test/jdk/javax/swing/border/Test6910490.java | 36 +++++++++++++++----- 2 files changed, 27 insertions(+), 41 deletions(-) delete mode 100644 test/jdk/javax/swing/border/Test6910490.html diff --git a/test/jdk/javax/swing/border/Test6910490.html b/test/jdk/javax/swing/border/Test6910490.html deleted file mode 100644 index 5cc40cefc397c..0000000000000 --- a/test/jdk/javax/swing/border/Test6910490.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - -If the border is painted over scroll bars then test fails. -Otherwise test passes. - - - - - diff --git a/test/jdk/javax/swing/border/Test6910490.java b/test/jdk/javax/swing/border/Test6910490.java index 78dd3dfb872f3..f42e4fe0dd23a 100644 --- a/test/jdk/javax/swing/border/Test6910490.java +++ b/test/jdk/javax/swing/border/Test6910490.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,8 @@ import java.awt.Graphics; import java.awt.Insets; import javax.swing.Icon; -import javax.swing.JApplet; import javax.swing.JButton; +import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.border.MatteBorder; @@ -37,22 +37,40 @@ * @test * @bug 6910490 * @summary Tests a matte border around a component inside a scroll pane. - * @author Sergey Malenkov - * @run applet/manual=yesno Test6910490.html + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual Test6910490 */ -public class Test6910490 extends JApplet implements Icon { +public class Test6910490 implements Icon { + public static void main(String[] args) throws Exception { + String testInstructions = """ + If the border is painted over scroll bars then test fails. + Otherwise test passes."""; + Test6910490 obj = new Test6910490(); + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(testInstructions) + .rows(3) + .columns(35) + .testUI(obj.initializeTest()) + .build() + .awaitAndCheck(); + } - @Override - public void init() { + public JFrame initializeTest() { Insets insets = new Insets(10, 10, 10, 10); - Dimension size = new Dimension(getWidth() / 2, getHeight()); + JFrame frame = new JFrame("Matte Border Test"); + frame.setSize(600, 300); + Dimension size = new Dimension(frame.getWidth() / 2, frame.getHeight()); JSplitPane pane = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, create("Color", size, new MatteBorder(insets, RED)), create("Icon", size, new MatteBorder(insets, this))); + pane.setDividerLocation(size.width - pane.getDividerSize() / 2); - add(pane); + frame.add(pane); + return frame; } private JScrollPane create(String name, Dimension size, MatteBorder border) { From 1e301d3f35ed4db52136f84e5c6ef4744e488c49 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 09:33:59 +0000 Subject: [PATCH 338/846] 8332494: java/util/zip/EntryCount64k.java failing with java.lang.RuntimeException: '\\A\\Z' missing from stderr Backport-of: f5ab7dff402a3152f5d5736cc6521b4be617eccf --- test/jdk/java/util/zip/EntryCount64k.java | 2 +- .../jdk/test/lib/process/OutputAnalyzer.java | 22 +++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/test/jdk/java/util/zip/EntryCount64k.java b/test/jdk/java/util/zip/EntryCount64k.java index 2dac7643de2a7..d8c46d2236433 100644 --- a/test/jdk/java/util/zip/EntryCount64k.java +++ b/test/jdk/java/util/zip/EntryCount64k.java @@ -163,6 +163,6 @@ static void checkCanRead(File zipFile, int entryCount) throws Throwable { OutputAnalyzer a = ProcessTools.executeTestJava("-jar", zipFile.getName()); a.shouldHaveExitValue(0); a.stdoutShouldMatch("\\AMain\\Z"); - a.stderrShouldMatch("\\A\\Z"); + a.stderrShouldMatchIgnoreDeprecatedWarnings("\\A\\Z"); } } diff --git a/test/lib/jdk/test/lib/process/OutputAnalyzer.java b/test/lib/jdk/test/lib/process/OutputAnalyzer.java index 8f9ebde24262d..5ea90a1c6db9c 100644 --- a/test/lib/jdk/test/lib/process/OutputAnalyzer.java +++ b/test/lib/jdk/test/lib/process/OutputAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -641,7 +641,7 @@ public OutputAnalyzer shouldBeEmptyIgnoreVMWarnings() { /** * Verify that the stderr contents of output buffer matches the pattern, - * after filtering out the Hotespot warning messages + * after filtering out the Hotspot warning messages * * @param pattern * @throws RuntimeException If the pattern was not found @@ -657,6 +657,24 @@ public OutputAnalyzer stderrShouldMatchIgnoreVMWarnings(String pattern) { return this; } + /** + * Verify that the stderr contents of output buffer matches the pattern, + * after filtering out the Hotspot deprecation warning messages + * + * @param pattern + * @throws RuntimeException If the pattern was not found + */ + public OutputAnalyzer stderrShouldMatchIgnoreDeprecatedWarnings(String pattern) { + String stderr = getStderr().replaceAll(deprecatedmsg + "\\R", ""); + Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); + if (!matcher.find()) { + reportDiagnosticSummary(); + throw new RuntimeException("'" + pattern + + "' missing from stderr"); + } + return this; + } + /** * Returns the contents of the output buffer (stdout and stderr), without those * JVM warning msgs, as list of strings. Output is split by newlines. From 11fe8f048775fab0d21db8b9f43ce48727485823 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 09:36:17 +0000 Subject: [PATCH 339/846] 8332252: Clean up vmTestbase/vm/share Reviewed-by: mdoerr Backport-of: a81e1bf1e1a6f00280b9be987c03fe20915fd52c --- .../gc/gctests/LoadUnloadGC/LoadUnloadGC.java | 6 +- .../LoadUnloadGC}/MemoryPoolFinder.java | 6 +- .../metaspace/gc/HighWaterMarkTest.java | 3 +- .../share}/HeapOOMEException.java | 2 +- .../TriggerUnloadingByFillingMetaspace.java | 2 +- .../share}/TriggerUnloadingHelper.java | 2 +- .../share}/TriggerUnloadingWithWhiteBox.java | 2 +- .../staticReferences/StaticReferences.java | 8 +- .../common/PerformChecksHelper.java | 6 +- .../common/StressHierarchyBaseClass.java | 9 +- .../hotswap/HS203/hs203t004/hs203t004.java | 11 +- .../complog/share/LogCompilationTest.java | 3 +- .../complog/share}/ProcessExecutor.java | 13 +- .../complog/share}/StreamListener.java | 2 +- .../complog/share}/StreamLogger.java | 2 +- .../complog/share}/StreamReader.java | 2 +- .../hiddenloader/func/findByName/Test.java | 4 +- .../share/StressClassLoadingTest.java | 23 +- .../stress/byteMutation/Test.java | 4 +- .../hiddenloader/stress/oome/heap/Test.java | 4 +- .../stress/oome/metaspace/Test.java | 4 +- .../stress/parallelLoad/Test.java | 4 +- .../indy/stress/gc/lotsOfCallSites/Test.java | 8 +- .../vm/mlvm/share/CustomClassLoaders.java | 4 +- .../vm/{ => mlvm}/share/FileUtils.java | 2 +- .../vm/mlvm/share/MlvmTestExecutor.java | 21 +- .../vm/share/CommentedFileReader.java | 119 ----------- .../vmTestbase/vm/share/ProcessUtils.cpp | 201 ------------------ .../vmTestbase/vm/share/ProcessUtils.java | 65 +----- .../jtreg/vmTestbase/vm/share/RandomEx.java | 92 -------- .../vmTestbase/vm/share/StringUtils.java | 89 -------- .../vmTestbase/vm/share/UnsafeAccess.java | 42 ---- .../vm/share/VMRuntimeEnvUtils.java | 108 ---------- .../monitoring/data/MemoryManagerData.java | 61 ------ .../share/monitoring/data/MemoryPoolData.java | 59 ----- .../monitoring/data/MemoryUsageData.java | 82 ------- .../vm/share/process/CmdExecutor.java | 63 ------ .../vm/share/process/MessageInput.java | 37 ---- .../vm/share/process/MessageOutput.java | 29 --- .../vm/share/process/ProcessHandler.java | 102 --------- .../vm/share/process/StreamMessageInput.java | 187 ---------------- .../vm/share/process/StreamMessageOutput.java | 56 ----- .../AbstractClassFileTransformer.java | 44 ---- .../share/transform/AnnotationAppender.java | 62 ------ .../transform/TransformingClassLoader.java | 61 ------ 45 files changed, 74 insertions(+), 1642 deletions(-) rename test/hotspot/jtreg/vmTestbase/{vm/share/monitoring => gc/gctests/LoadUnloadGC}/MemoryPoolFinder.java (95%) rename test/hotspot/jtreg/vmTestbase/{vm/share/gc => metaspace/share}/HeapOOMEException.java (98%) rename test/hotspot/jtreg/vmTestbase/{vm/share/gc => metaspace/share}/TriggerUnloadingByFillingMetaspace.java (98%) rename test/hotspot/jtreg/vmTestbase/{vm/share/gc => metaspace/share}/TriggerUnloadingHelper.java (97%) rename test/hotspot/jtreg/vmTestbase/{vm/share/gc => metaspace/share}/TriggerUnloadingWithWhiteBox.java (98%) rename test/hotspot/jtreg/vmTestbase/vm/{share/process => compiler/complog/share}/ProcessExecutor.java (96%) rename test/hotspot/jtreg/vmTestbase/vm/{share/process => compiler/complog/share}/StreamListener.java (97%) rename test/hotspot/jtreg/vmTestbase/vm/{share/process => compiler/complog/share}/StreamLogger.java (98%) rename test/hotspot/jtreg/vmTestbase/vm/{share/process => compiler/complog/share}/StreamReader.java (99%) rename test/hotspot/jtreg/vmTestbase/vm/{ => mlvm}/share/FileUtils.java (99%) delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/CommentedFileReader.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/RandomEx.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/StringUtils.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/UnsafeAccess.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/VMRuntimeEnvUtils.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/monitoring/data/MemoryManagerData.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/monitoring/data/MemoryPoolData.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/monitoring/data/MemoryUsageData.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/process/CmdExecutor.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/process/MessageInput.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/process/MessageOutput.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/process/ProcessHandler.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/process/StreamMessageInput.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/process/StreamMessageOutput.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/transform/AbstractClassFileTransformer.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/transform/AnnotationAppender.java delete mode 100644 test/hotspot/jtreg/vmTestbase/vm/share/transform/TransformingClassLoader.java diff --git a/test/hotspot/jtreg/vmTestbase/gc/gctests/LoadUnloadGC/LoadUnloadGC.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/LoadUnloadGC/LoadUnloadGC.java index edd65b81145d6..53b7daab5ae47 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/gctests/LoadUnloadGC/LoadUnloadGC.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/LoadUnloadGC/LoadUnloadGC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,12 +47,8 @@ package gc.gctests.LoadUnloadGC; -import nsk.share.test.*; import nsk.share.gc.*; import nsk.share.classload.ClassPathNonDelegatingClassLoader; -import vm.share.monitoring.MemoryPoolFinder; - -import java.io.*; import java.util.*; import java.lang.management.MemoryPoolMXBean; diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/monitoring/MemoryPoolFinder.java b/test/hotspot/jtreg/vmTestbase/gc/gctests/LoadUnloadGC/MemoryPoolFinder.java similarity index 95% rename from test/hotspot/jtreg/vmTestbase/vm/share/monitoring/MemoryPoolFinder.java rename to test/hotspot/jtreg/vmTestbase/gc/gctests/LoadUnloadGC/MemoryPoolFinder.java index ca68beffca641..f7f5e19bd16f5 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/share/monitoring/MemoryPoolFinder.java +++ b/test/hotspot/jtreg/vmTestbase/gc/gctests/LoadUnloadGC/MemoryPoolFinder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,11 +20,11 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package vm.share.monitoring; +package gc.gctests.LoadUnloadGC; import java.lang.management.*; -public enum MemoryPoolFinder { +enum MemoryPoolFinder { CODE_CACHE, EDEN_SPACE, SURVIVOR_SPACE, diff --git a/test/hotspot/jtreg/vmTestbase/metaspace/gc/HighWaterMarkTest.java b/test/hotspot/jtreg/vmTestbase/metaspace/gc/HighWaterMarkTest.java index 2b717d46c6578..21a3cb1dd5604 100644 --- a/test/hotspot/jtreg/vmTestbase/metaspace/gc/HighWaterMarkTest.java +++ b/test/hotspot/jtreg/vmTestbase/metaspace/gc/HighWaterMarkTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,6 @@ package metaspace.gc; import java.util.Arrays; -import vm.share.VMRuntimeEnvUtils; /** * Test metaspace ergonomic. diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/gc/HeapOOMEException.java b/test/hotspot/jtreg/vmTestbase/metaspace/share/HeapOOMEException.java similarity index 98% rename from test/hotspot/jtreg/vmTestbase/vm/share/gc/HeapOOMEException.java rename to test/hotspot/jtreg/vmTestbase/metaspace/share/HeapOOMEException.java index 534df351169b2..493189a58c71e 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/share/gc/HeapOOMEException.java +++ b/test/hotspot/jtreg/vmTestbase/metaspace/share/HeapOOMEException.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package vm.share.gc; +package metaspace.share; /** * This class is used to distinguish between OOME in metaspace and OOME in heap when triggering class unloading. diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/gc/TriggerUnloadingByFillingMetaspace.java b/test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingByFillingMetaspace.java similarity index 98% rename from test/hotspot/jtreg/vmTestbase/vm/share/gc/TriggerUnloadingByFillingMetaspace.java rename to test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingByFillingMetaspace.java index e3f9caf9533e2..217abc25c96aa 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/share/gc/TriggerUnloadingByFillingMetaspace.java +++ b/test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingByFillingMetaspace.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package vm.share.gc; +package metaspace.share; import nsk.share.test.ExecutionController; import nsk.share.gc.gp.classload.GeneratedClassProducer; diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/gc/TriggerUnloadingHelper.java b/test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingHelper.java similarity index 97% rename from test/hotspot/jtreg/vmTestbase/vm/share/gc/TriggerUnloadingHelper.java rename to test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingHelper.java index b6458f5865e9c..7c9e4bec1a615 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/share/gc/TriggerUnloadingHelper.java +++ b/test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingHelper.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package vm.share.gc; +package metaspace.share; import nsk.share.test.ExecutionController; diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/gc/TriggerUnloadingWithWhiteBox.java b/test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingWithWhiteBox.java similarity index 98% rename from test/hotspot/jtreg/vmTestbase/vm/share/gc/TriggerUnloadingWithWhiteBox.java rename to test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingWithWhiteBox.java index dfe4bb73acbae..678e9551fa750 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/share/gc/TriggerUnloadingWithWhiteBox.java +++ b/test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingWithWhiteBox.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package vm.share.gc; +package metaspace.share; import jdk.test.whitebox.WhiteBox; diff --git a/test/hotspot/jtreg/vmTestbase/metaspace/staticReferences/StaticReferences.java b/test/hotspot/jtreg/vmTestbase/metaspace/staticReferences/StaticReferences.java index 1edf70d3a8c54..7ea901abe06f1 100644 --- a/test/hotspot/jtreg/vmTestbase/metaspace/staticReferences/StaticReferences.java +++ b/test/hotspot/jtreg/vmTestbase/metaspace/staticReferences/StaticReferences.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,14 +53,14 @@ import java.util.Map; import java.util.Random; -import jdk.test.lib.compiler.InMemoryJavaCompiler; +import metaspace.share.TriggerUnloadingHelper; +import metaspace.share.TriggerUnloadingWithWhiteBox; import nsk.share.gc.GCTestBase; import nsk.share.test.ExecutionController; import nsk.share.test.Stresser; import nsk.share.test.TestBase; import nsk.share.test.Tests; -import vm.share.gc.TriggerUnloadingHelper; -import vm.share.gc.TriggerUnloadingWithWhiteBox; +import jdk.test.lib.compiler.InMemoryJavaCompiler; /** * Test checks that static fields will be initialized in new loaded class. Test performs in loop the following routine: diff --git a/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/PerformChecksHelper.java b/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/PerformChecksHelper.java index 476dceb395de3..3d57bfb6ea9ee 100644 --- a/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/PerformChecksHelper.java +++ b/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/PerformChecksHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,13 +28,13 @@ import java.lang.reflect.Proxy; import java.util.List; +import jdk.test.whitebox.WhiteBox; +import metaspace.share.TriggerUnloadingHelper; import metaspace.stressHierarchy.common.classloader.tree.Node; import metaspace.stressHierarchy.common.classloader.tree.Tree; import metaspace.stressHierarchy.common.exceptions.ClassNotUnloadedException; import metaspace.stressHierarchy.common.exceptions.TimeIsOverException; import nsk.share.test.ExecutionController; -import jdk.test.whitebox.WhiteBox; -import vm.share.gc.TriggerUnloadingHelper; public class PerformChecksHelper { diff --git a/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/StressHierarchyBaseClass.java b/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/StressHierarchyBaseClass.java index 61a19baf98e36..20fcdabb13cf2 100644 --- a/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/StressHierarchyBaseClass.java +++ b/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/StressHierarchyBaseClass.java @@ -24,11 +24,10 @@ import java.net.MalformedURLException; -import vm.share.gc.HeapOOMEException; -import vm.share.gc.TriggerUnloadingByFillingMetaspace; -import vm.share.gc.TriggerUnloadingHelper; -import vm.share.gc.TriggerUnloadingWithWhiteBox; - +import metaspace.share.HeapOOMEException; +import metaspace.share.TriggerUnloadingByFillingMetaspace; +import metaspace.share.TriggerUnloadingHelper; +import metaspace.share.TriggerUnloadingWithWhiteBox; import metaspace.stressHierarchy.common.classloader.tree.Node; import metaspace.stressHierarchy.common.classloader.tree.Tree; import metaspace.stressHierarchy.common.exceptions.TimeIsOverException; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/hotswap/HS203/hs203t004/hs203t004.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/hotswap/HS203/hs203t004/hs203t004.java index a694698e2a39d..f9f1aa8a2706f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/hotswap/HS203/hs203t004/hs203t004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/hotswap/HS203/hs203t004/hs203t004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,8 +56,6 @@ package nsk.jvmti.scenarios.hotswap.HS203.hs203t004; -import vm.share.VMRuntimeEnvUtils; -import nsk.share.Consts; import nsk.share.jvmti.RedefineAgent; public class hs203t004 extends RedefineAgent { @@ -68,13 +66,6 @@ public hs203t004(String[] arg) { public static void main(String[] arg) { arg = nsk.share.jvmti.JVMTITest.commonInit(arg); - - if (!VMRuntimeEnvUtils.isJITEnabled()) { - System.out.println("WARNING: test isn't valid if JIT compilation is disabled"); - System.out.println("Exiting with 'PASSED' status"); - System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_PASSED); - } - hs203t004 hsCase = new hs203t004(arg); System.exit(hsCase.runAgent()); } diff --git a/test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/LogCompilationTest.java b/test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/LogCompilationTest.java index 0d24be9a16da7..0a069d272c004 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/LogCompilationTest.java +++ b/test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/LogCompilationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ import nsk.share.log.LogSupport; import vm.share.options.Option; import vm.share.options.OptionSupport; -import vm.share.process.ProcessExecutor; import java.io.File; import java.io.FileNotFoundException; diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/process/ProcessExecutor.java b/test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/ProcessExecutor.java similarity index 96% rename from test/hotspot/jtreg/vmTestbase/vm/share/process/ProcessExecutor.java rename to test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/ProcessExecutor.java index 0d9a0e0632961..9ab0a781d1f89 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/share/process/ProcessExecutor.java +++ b/test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/ProcessExecutor.java @@ -20,23 +20,16 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package vm.share.process; +package vm.compiler.complog.share; import nsk.share.TestBug; import nsk.share.TestFailure; import nsk.share.log.Log; -import vm.share.ProcessUtils; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.BufferedReader; import java.io.OutputStream; import java.io.PrintStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; import java.io.IOException; import java.util.*; -import java.lang.reflect.Field; public class ProcessExecutor { private static long CLEANUP_TIMEOUT = 60000; @@ -138,8 +131,8 @@ public int waitFor(long timeout) { return -1; } - public int getPid() { - return ProcessUtils.getPid(process); + public long getPid() { + return process.pid(); } public OutputStream getStdIn() { diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/process/StreamListener.java b/test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/StreamListener.java similarity index 97% rename from test/hotspot/jtreg/vmTestbase/vm/share/process/StreamListener.java rename to test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/StreamListener.java index 26c542f9bd003..c2d4e58c5bda8 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/share/process/StreamListener.java +++ b/test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/StreamListener.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package vm.share.process; +package vm.compiler.complog.share; /* * StreamListener listens on events from BufferedInputStream. diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/process/StreamLogger.java b/test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/StreamLogger.java similarity index 98% rename from test/hotspot/jtreg/vmTestbase/vm/share/process/StreamLogger.java rename to test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/StreamLogger.java index 5162e4010ff22..690f0bbfbfc50 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/share/process/StreamLogger.java +++ b/test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/StreamLogger.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package vm.share.process; +package vm.compiler.complog.share; import nsk.share.log.Log; diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/process/StreamReader.java b/test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/StreamReader.java similarity index 99% rename from test/hotspot/jtreg/vmTestbase/vm/share/process/StreamReader.java rename to test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/StreamReader.java index a8f56318da5b2..d983ae1aebea3 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/share/process/StreamReader.java +++ b/test/hotspot/jtreg/vmTestbase/vm/compiler/complog/share/StreamReader.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package vm.share.process; +package vm.compiler.complog.share; import java.io.InputStream; import java.io.InputStreamReader; diff --git a/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/func/findByName/Test.java b/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/func/findByName/Test.java index f891b980f8261..f78c9221dd503 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/func/findByName/Test.java +++ b/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/func/findByName/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ import vm.mlvm.hiddenloader.share.HiddenkTestee01; import vm.mlvm.share.MlvmTest; -import vm.share.FileUtils; +import vm.mlvm.share.FileUtils; public class Test extends MlvmTest { private static final Class PARENT = HiddenkTestee01.class; diff --git a/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/share/StressClassLoadingTest.java b/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/share/StressClassLoadingTest.java index edb91743c44e9..b269d7aa57ff6 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/share/StressClassLoadingTest.java +++ b/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/share/StressClassLoadingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,24 +23,25 @@ package vm.mlvm.hiddenloader.share; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodHandles.Lookup; + import java.io.File; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicBoolean; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; + import nsk.share.test.Stresser; -import vm.share.options.Option; -import vm.share.options.OptionSupport; -import vm.share.options.IgnoreUnknownArgumentsHandler; import vm.mlvm.share.Env; import vm.mlvm.share.MlvmTest; import vm.mlvm.share.CustomClassLoaders; -import vm.share.FileUtils; -import vm.share.UnsafeAccess; +import vm.mlvm.share.FileUtils; +import vm.share.options.Option; +import vm.share.options.OptionSupport; +import vm.share.options.IgnoreUnknownArgumentsHandler; /** * Does stress-testing of class loading subsystem. @@ -164,7 +165,7 @@ public void run() { c = CustomClassLoaders.makeClassBytesLoader(classBytes, className) .loadClass(className); } - UnsafeAccess.unsafe.ensureClassInitialized(c); + MethodHandles.lookup().ensureInitialized(c); } catch (Throwable e) { Env.traceVerbose(e, "parser caught exception"); } diff --git a/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/byteMutation/Test.java b/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/byteMutation/Test.java index e6a3e8a890d74..e9a49e119c887 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/byteMutation/Test.java +++ b/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/byteMutation/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ import vm.mlvm.hiddenloader.share.HiddenkTestee01; import vm.mlvm.hiddenloader.share.StressClassLoadingTest; -import vm.share.FileUtils; +import vm.mlvm.share.FileUtils; import vm.share.options.Option; /** diff --git a/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/oome/heap/Test.java b/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/oome/heap/Test.java index ea59685dfd3df..47de77729305d 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/oome/heap/Test.java +++ b/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/oome/heap/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ import vm.mlvm.share.MlvmOOMTest; import vm.mlvm.share.MlvmTestExecutor; import vm.mlvm.share.Env; -import vm.share.FileUtils; +import vm.mlvm.share.FileUtils; /** * This test loads a class using defineHiddenClass, creates instances diff --git a/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/oome/metaspace/Test.java b/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/oome/metaspace/Test.java index 85bb7c6167fff..886e2e3d52585 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/oome/metaspace/Test.java +++ b/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/oome/metaspace/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ import vm.mlvm.share.MlvmOOMTest; import vm.mlvm.share.MlvmTestExecutor; import vm.mlvm.share.Env; -import vm.share.FileUtils; +import vm.mlvm.share.FileUtils; /** * This test loads classes using defineHiddenClass and stores them, diff --git a/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/parallelLoad/Test.java b/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/parallelLoad/Test.java index fa4dbf3f4eb19..b3e433df95758 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/parallelLoad/Test.java +++ b/test/hotspot/jtreg/vmTestbase/vm/mlvm/hiddenloader/stress/parallelLoad/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ import vm.mlvm.hiddenloader.share.HiddenkTestee01; import vm.mlvm.share.MlvmTestExecutor; import vm.mlvm.share.MultiThreadedTest; -import vm.share.FileUtils; +import vm.mlvm.share.FileUtils; /** * Verifies that loading classes in parallel from several threads using diff --git a/test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/stress/gc/lotsOfCallSites/Test.java b/test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/stress/gc/lotsOfCallSites/Test.java index beb77041fdb18..6f2c82923b21e 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/stress/gc/lotsOfCallSites/Test.java +++ b/test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/stress/gc/lotsOfCallSites/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,15 +47,11 @@ package vm.mlvm.indy.stress.gc.lotsOfCallSites; import java.lang.invoke.CallSite; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodType; import java.lang.ref.PhantomReference; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; import java.lang.management.MemoryMXBean; import java.lang.management.MemoryPoolMXBean; import java.lang.management.ManagementFactory; @@ -67,8 +63,8 @@ import nsk.share.test.Stresser; import vm.mlvm.share.CustomClassLoaders; import vm.mlvm.share.Env; +import vm.mlvm.share.FileUtils; import vm.mlvm.share.MlvmTest; -import vm.share.FileUtils; import vm.share.options.Option; /** diff --git a/test/hotspot/jtreg/vmTestbase/vm/mlvm/share/CustomClassLoaders.java b/test/hotspot/jtreg/vmTestbase/vm/mlvm/share/CustomClassLoaders.java index 9596f7b1eab38..6be720088ac56 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/mlvm/share/CustomClassLoaders.java +++ b/test/hotspot/jtreg/vmTestbase/vm/mlvm/share/CustomClassLoaders.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ import java.io.IOException; -import vm.share.FileUtils; - public class CustomClassLoaders { public static ClassLoader makeClassBytesLoader(final byte[] classBytes, diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/FileUtils.java b/test/hotspot/jtreg/vmTestbase/vm/mlvm/share/FileUtils.java similarity index 99% rename from test/hotspot/jtreg/vmTestbase/vm/share/FileUtils.java rename to test/hotspot/jtreg/vmTestbase/vm/mlvm/share/FileUtils.java index 1652e75beafa8..c749551e85b1f 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/share/FileUtils.java +++ b/test/hotspot/jtreg/vmTestbase/vm/mlvm/share/FileUtils.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package vm.share; +package vm.mlvm.share; import java.io.File; import java.io.FileInputStream; diff --git a/test/hotspot/jtreg/vmTestbase/vm/mlvm/share/MlvmTestExecutor.java b/test/hotspot/jtreg/vmTestbase/vm/mlvm/share/MlvmTestExecutor.java index 581f8a905712b..dc32f30112d87 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/mlvm/share/MlvmTestExecutor.java +++ b/test/hotspot/jtreg/vmTestbase/vm/mlvm/share/MlvmTestExecutor.java @@ -23,12 +23,16 @@ package vm.mlvm.share; +import java.io.File; +import java.io.IOException; +import java.lang.management.ManagementFactory; import java.lang.reflect.Constructor; import java.util.List; +import com.sun.management.HotSpotDiagnosticMXBean; + import nsk.share.Consts; import nsk.share.ArgumentParser; -import vm.share.ProcessUtils; import vm.share.options.IgnoreUnknownArgumentsHandler; import vm.share.options.OptionSupport; @@ -262,10 +266,23 @@ public static void launch(Class testClass, Object[] constructorArgs) { } } + private static void dumpHeapWithHotspotDiagnosticMXBean(String fileName) throws IOException { + System.err.println("Dumping heap to " + fileName); + + File f = new File(fileName); + if (f.exists()) + f.delete(); + + HotSpotDiagnosticMXBean b = ManagementFactory.getPlatformMXBeans( + com.sun.management.HotSpotDiagnosticMXBean.class).get(0); + b.dumpHeap(fileName, false); + } + + private static void optionallyDumpHeap() { try { if (MlvmTest.getHeapDumpAfter()) { - ProcessUtils.dumpHeapWithHotspotDiagnosticMXBean(HEAP_DUMP_FILENAME); + dumpHeapWithHotspotDiagnosticMXBean(HEAP_DUMP_FILENAME); } } catch (Exception e) { Env.traceNormal(e, "Error dumping heap: "); diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/CommentedFileReader.java b/test/hotspot/jtreg/vmTestbase/vm/share/CommentedFileReader.java deleted file mode 100644 index 019d237482c71..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/CommentedFileReader.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 vm.share; - -import java.io.*; -import java.util.LinkedList; - -/** - * Utility class intended to read file line by line and skip comments. - */ -public class CommentedFileReader { - - /** - * Type of comments that should be removed from file. - */ - public static enum CommentStyle { - /** - * Comments started with #. - */ - BASH, - /** - * Comments started with //. - */ - JAVA - } - - /** - * Get lines from specified file and filter out comments. - * Only comments in BASH style will be filtered out. - * - * @param path to file that should be readed - * @return filtered lines from file - */ - public static String[] readFile(String path) throws IOException { - return readFile(new File(path), CommentStyle.BASH); - } - - /** - * Get lines from specified file and filter out comments. - * Only comments in BASH style will be filtered out. - * - * @param file that should be readed - * @return filtered lines from file - */ - public static String[] readFile(File file) throws IOException { - return readFile(file, CommentStyle.BASH); - } - - /** - * Get lines from specified file without comments. - * - * @param path to file that should be readed - * @param commentStyle describes what strings will be treated as comments - * @return filtered lines from file - */ - public static String[] readFile(String path, CommentStyle commentStyle) throws IOException { - return readFile(new File(path), commentStyle); - } - - /** - * Get lines from specified file without comments. - * - * @param file that should be readed - * @param commentStyle describes what strings will be treated as comments - * @return filtered lines from file - */ - public static String[] readFile(File file, CommentStyle commentStyle) throws IOException { - LinkedList entries = new LinkedList(); - BufferedReader reader = new BufferedReader(new FileReader(file)); - String commentBeginning; - - switch (commentStyle) { - case BASH: - commentBeginning = "#"; - break; - case JAVA: - commentBeginning = "//"; - break; - default: - throw new IllegalArgumentException("Unknown comment style"); - } - - while (true) { - String entry = reader.readLine(); - if (entry == null) { - break; - } - - entry = entry.replaceAll(commentBeginning + ".*", "").trim(); - - if (entry.length() > 0) { - entries.add(entry); - } - } - - return entries.toArray(new String[entries.size()]); - } - -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/ProcessUtils.cpp b/test/hotspot/jtreg/vmTestbase/vm/share/ProcessUtils.cpp index 0388af34e741b..0898d1f611c5a 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/share/ProcessUtils.cpp +++ b/test/hotspot/jtreg/vmTestbase/vm/share/ProcessUtils.cpp @@ -21,12 +21,8 @@ * questions. */ #include "jni.h" -#include "native_thread.h" #ifdef _WIN32 #include -#include -#include -#include #else /* _WIN32 */ #include #include @@ -35,40 +31,6 @@ extern "C" { -/* - * Class: vm_share_ProcessUtils - * Method: sendSignal - * Signature: ()Z - */ -JNIEXPORT jboolean JNICALL Java_vm_share_ProcessUtils_sendSignal -(JNIEnv *env, jclass klass, jint signalNum) { -#ifdef _WIN32 -/* TODO TODO TODO - int dw; - LPVOID lpMsgBuf; - if (!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0)) { - dw = GetLastError(); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - dw, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, - NULL - ); - printf("%s\n", (LPTSTR)lpMsgBuf); - LocalFree(lpMsgBuf); - return JNI_FALSE; - } - */ - return JNI_TRUE; -#else /* _WIN32 */ - if (kill(getpid(), signalNum) < 0) - return JNI_FALSE; - return JNI_TRUE; -#endif /* _WIN32 */ -} - /* * Class: vm_share_ProcessUtils * Method: sendCtrlBreak @@ -101,167 +63,4 @@ JNIEXPORT jboolean JNICALL Java_vm_share_ProcessUtils_sendCtrlBreak #endif /* _WIN32 */ } -#ifdef _WIN32 -static BOOL (WINAPI *_MiniDumpWriteDump) (HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION, - PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION); -void reportLastError(const char *msg) { - long errcode = GetLastError(); - if (errcode != 0) { - DWORD len = 0; - char *buf; - size_t n = (size_t)FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, - errcode, - 0, - (LPSTR) &buf, - (DWORD)len, - NULL); - if (n > 3) { - /* Drop final '.', CR, LF */ - if (buf[n - 1] == '\n') n--; - if (buf[n - 1] == '\r') n--; - if (buf[n - 1] == '.') n--; - buf[n] = '\0'; - } - printf("%s: %s\n", msg, buf); - LocalFree(buf); - } -} - -#endif /* _WIN32 */ - -jboolean doDumpCore() { -#ifdef _WIN32 - char path[MAX_PATH]; - DWORD size; - DWORD pathLen = (DWORD) sizeof(path); - HINSTANCE dbghelp; - MINIDUMP_EXCEPTION_INFORMATION* pmei; - - HANDLE hProcess = GetCurrentProcess(); - DWORD processId = GetCurrentProcessId(); - HANDLE dumpFile; - MINIDUMP_TYPE dumpType; - static const char* cwd; - static const char* name = "DBGHELP.DLL"; - - printf("# TEST: creating Windows minidump...\n"); - size = GetSystemDirectory(path, pathLen); - if (size > 0) { - strcat(path, "\\"); - strcat(path, name); - dbghelp = LoadLibrary(path); - if (dbghelp == NULL) - reportLastError("Load DBGHELP.DLL from system directory"); - } else { - printf("GetSystemDirectory returned 0\n"); - } - - // try Windows directory - if (dbghelp == NULL) { - size = GetWindowsDirectory(path, pathLen); - if (size > 6) { - strcat(path, "\\"); - strcat(path, name); - dbghelp = LoadLibrary(path); - if (dbghelp == NULL) { - reportLastError("Load DBGHELP.DLL from Windows directory"); - } - } - } - if (dbghelp == NULL) { - printf("Failed to load DBGHELP.DLL\n"); - return JNI_FALSE; - } - - _MiniDumpWriteDump = - (BOOL(WINAPI *)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION, - PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION)) - GetProcAddress(dbghelp, "MiniDumpWriteDump"); - - if (_MiniDumpWriteDump == NULL) { - printf("Failed to find MiniDumpWriteDump() in module dbghelp.dll"); - return JNI_FALSE; - } - dumpType = (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithHandleData); - - // Older versions of dbghelp.h doesn't contain all the dumptypes we want, dbghelp.h with - // API_VERSION_NUMBER 11 or higher contains the ones we want though -#if API_VERSION_NUMBER >= 11 - dumpType = (MINIDUMP_TYPE)(dumpType | MiniDumpWithFullMemoryInfo | MiniDumpWithThreadInfo | - MiniDumpWithUnloadedModules); -#endif - - dumpFile = CreateFile("core.mdmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - - if (dumpFile == INVALID_HANDLE_VALUE) { - reportLastError("Failed to create file for dumping"); - return JNI_FALSE; - } - pmei = NULL; - - - // Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all - // the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then. - if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == FALSE && - _MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == FALSE) { - reportLastError("Call to MiniDumpWriteDump() failed"); - return JNI_FALSE; - } - - CloseHandle(dumpFile); - printf("# TEST: minidump created\n"); - // Emulate Unix behaviour - exit process. - ExitProcess(137); - - return JNI_TRUE; -#else /* _WIN32 */ - if (kill(getpid(), SIGSEGV) < 0) - return JNI_FALSE; - return JNI_TRUE; -#endif /* _WIN32 */ - -} - -/* - * Class: vm_share_ProcessUtils - * Method: dumpCore - * Signature: ()Z - */ -JNIEXPORT jboolean JNICALL Java_vm_share_ProcessUtils_dumpCore - (JNIEnv *env, jclass klass) -{ - return doDumpCore(); -} - -/* - * Class: vm_share_ProcessUtils - * Method: getPid - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_vm_share_ProcessUtils_getPid - (JNIEnv *env, jclass klass) { -#ifdef _WIN32 - return _getpid(); -#else /* _WIN32 */ - return getpid(); -#endif /* _WIN32 */ -} - - -/* - * Class: vm_share_ProcessUtils - * Method: getPid - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_vm_share_ProcessUtils_getWindowsPid - (JNIEnv *env, jclass klass, jlong handle) { -#ifdef _WIN32 - return GetProcessId((HANDLE) handle); -#else /* _WIN32 */ - return -1; -#endif /* _WIN32 */ -} - } diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/ProcessUtils.java b/test/hotspot/jtreg/vmTestbase/vm/share/ProcessUtils.java index 2e9174452fdd3..3595428d98c25 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/share/ProcessUtils.java +++ b/test/hotspot/jtreg/vmTestbase/vm/share/ProcessUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,67 +46,4 @@ private ProcessUtils() {} * @return true if it was successful */ public static native boolean sendCtrlBreak(); - - /** - * Send any signal to java process on Unix. It currently does nothing on Windows. - * - * @return true if it was successful - */ - public static native boolean sendSignal(int signalNum); - - /** - * Force java process to dump core. - * - * This is done by sending SIGSEGV on unix systems. - * - * @return true if it was successful, false if not (for example on Windows) - */ - public static native boolean dumpCore(); - - /** - * Get PID of java process. - * - * @return PID - */ - public static native int getPid(); - - public static int getPid(Process process) { - Throwable exception; - try { - Field pidField = process.getClass().getDeclaredField("pid"); - pidField.setAccessible(true); - return ((Integer) pidField.get(process)).intValue(); - } catch (NoSuchFieldException e) { - exception = e; - } catch (IllegalAccessException e) { - exception = e; - } - // Try to get Windows handle - try { - Field handleField = process.getClass().getDeclaredField("handle"); - handleField.setAccessible(true); - long handle = ((Long) handleField.get(process)).longValue(); - return getWindowsPid(handle); - } catch (NoSuchFieldException e) { - exception = e; - } catch (IllegalAccessException e) { - exception = e; - } - throw new TestBug("Unable to determine pid from process class " + process.getClass(), exception); - } - - private static native int getWindowsPid(long handle); - - @SuppressWarnings("restriction") - public static void dumpHeapWithHotspotDiagnosticMXBean(String fileName) throws IOException { - System.err.println("Dumping heap to " + fileName); - - File f = new File(fileName); - if (f.exists()) - f.delete(); - - HotSpotDiagnosticMXBean b = ManagementFactory.getPlatformMXBeans( - com.sun.management.HotSpotDiagnosticMXBean.class).get(0); - b.dumpHeap(fileName, false); - } } diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/RandomEx.java b/test/hotspot/jtreg/vmTestbase/vm/share/RandomEx.java deleted file mode 100644 index 8abcfb1ba80e4..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/RandomEx.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2013, 2020, 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 vm.share; - -import java.util.HashMap; -import java.util.Map; -import java.util.Random; -import java.util.function.Predicate; -import java.util.function.Supplier; - -import jdk.test.lib.Utils; - -public class RandomEx extends Random { - private final Map, Supplier> map = new HashMap<>(); - - { - map.put(Boolean.class, this::nextBoolean); - map.put(boolean.class, this::nextBoolean); - map.put(Byte.class, this::nextByte); - map.put(byte.class, this::nextByte); - map.put(Short.class, this::nextShort); - map.put(short.class, this::nextShort); - map.put(Character.class, this::nextChar); - map.put(char.class, this::nextChar); - map.put(Integer.class, this::nextInt); - map.put(int.class, this::nextInt); - map.put(Long.class, this::nextLong); - map.put(long.class, this::nextLong); - map.put(Float.class, this::nextFloat); - map.put(float.class, this::nextFloat); - map.put(Double.class, this::nextDouble); - map.put(double.class, this::nextDouble); - } - - public RandomEx() { - super(Utils.getRandomInstance().nextLong()); - } - - public RandomEx(long seed) { - super(seed); - } - - public byte nextByte() { - return (byte) next(Byte.SIZE); - } - - public short nextShort() { - return (short) next(Short.SIZE); - } - - public char nextChar() { - return (char) next(Character.SIZE); - } - - public T next(Predicate p, T dummy) { - T result; - do { - result = next(dummy); - } while (!p.test(result)); - return result; - } - - @SuppressWarnings("unchecked") - public T next(T dummy) { - Supplier supplier = map.get(dummy.getClass()); - if (supplier == null) { - throw new IllegalArgumentException("supplier for <" + - dummy.getClass() + ">is not found"); - } - return (T) supplier.get(); - } -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/StringUtils.java b/test/hotspot/jtreg/vmTestbase/vm/share/StringUtils.java deleted file mode 100644 index 5643953869331..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/StringUtils.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2012, 2018, 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 vm.share; - -import java.io.ByteArrayOutputStream; -import java.util.Random; -import java.util.function.Predicate; - -public class StringUtils { - - public static byte[] binaryReplace(final byte[] src, String search, - String replacement) { - if (search.length() == 0) - return src; - - int nReplaced = 0; - - try { - final byte[] bSrch = search.getBytes("ASCII"); - final byte[] bRepl = replacement.getBytes("ASCII"); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - searching: for (int i = 0; i < src.length; i++) { - if (src[i] == bSrch[0]) { - replacing: do { - for (int ii = 1; ii < Math.min(bSrch.length, - src.length - i); ii++) - if (src[i + ii] != bSrch[ii]) - break replacing; - - out.write(bRepl); - i += bSrch.length - 1; - nReplaced++; - continue searching; - } while (false); - } - - out.write(src[i]); - } - - return out.toByteArray(); - - } finally { - out.close(); - } - } catch (Exception e) { - RuntimeException t = new RuntimeException("Test internal error"); - t.initCause(e); - throw t; - } - } - - public static String generateString(Random rng, int length, - Predicate predicate) { - if (length <= 0) { - throw new IllegalArgumentException("length <= 0"); - } - StringBuilder builder = new StringBuilder(length); - for (int i = 0; i < length; ++i) { - char tmp; - do { - tmp = (char) rng.nextInt(Character.MAX_VALUE); - } while (!predicate.test(tmp)); - builder.append(tmp); - } - return builder.toString(); - } -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/UnsafeAccess.java b/test/hotspot/jtreg/vmTestbase/vm/share/UnsafeAccess.java deleted file mode 100644 index 79a0a7392deff..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/UnsafeAccess.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2012, 2018, 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 vm.share; - -import java.lang.reflect.Field; - -import jdk.internal.misc.Unsafe; - -@SuppressWarnings("restriction") -public class UnsafeAccess { - public static Unsafe unsafe; - - static { - try { - unsafe = Unsafe.getUnsafe(); - } catch ( Exception e ) { - e.printStackTrace(); - } - } - - -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/VMRuntimeEnvUtils.java b/test/hotspot/jtreg/vmTestbase/vm/share/VMRuntimeEnvUtils.java deleted file mode 100644 index 85cab7a06db7a..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/VMRuntimeEnvUtils.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2008, 2018, 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 vm.share; - -import com.sun.management.HotSpotDiagnosticMXBean; -import com.sun.management.VMOption; - -import java.lang.management.ManagementFactory; -import java.util.Objects; - -public class VMRuntimeEnvUtils { - private static HotSpotDiagnosticMXBean DIAGNOSTIC_BEAN - = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); - - private VMRuntimeEnvUtils() { - } - - public static boolean isJITEnabled() { - boolean isJITEnabled = ManagementFactory.getCompilationMXBean() != null; - - return isJITEnabled; - } - - /** - * Returns value of VM option. - * - * @param name option's name - * @return value of option or {@code null}, if option doesn't exist - * @throws NullPointerException if name is null - * @see HotSpotDiagnosticMXBean#getVMOption(String) - */ - public static String getVMOption(String name) { - Objects.requireNonNull(name); - VMOption tmp; - try { - tmp = DIAGNOSTIC_BEAN.getVMOption(name); - } catch (IllegalArgumentException e) { - tmp = null; - } - return (tmp == null ? null : tmp.getValue()); - } - - /** - * Returns value of VM option or default value. - * - * @param name option's name - * @param defaultValue default value - * @return value of option or {@code defaultValue}, if option doesn't exist - * @throws NullPointerException if name is null - * @see #getVMOption(String) - */ - public static String getVMOption(String name, String defaultValue) { - String result = getVMOption(name); - return result == null ? defaultValue : result; - } - - /** - * Returns if a boolean VM option is enabled or not. - * - * @param name option's name - * @return true iff enabled - * @throws IllegalArgumentException if naming non-boolean or non-existing option - */ - public static boolean isVMOptionEnabled(String name) { - String isSet = getVMOption(name, "error"); - if (isSet.equals("true")) { - return true; - } else if (isSet.equals("false")) { - return false; - } - throw new IllegalArgumentException(name + " is not a boolean option."); - } - - /** - * Sets a specified value for VM option of given name. - * - * @param name option's name - * @param value new value - * @throws NullPointerException if name is null - * @throws IllegalArgumentException if new value is invalid or if vm option - * is not writable. - * @see HotSpotDiagnosticMXBean#setVMOption(String, String) - */ - public static void setVMOption(String name, String value) { - Objects.requireNonNull(name); - DIAGNOSTIC_BEAN.setVMOption(name, value); - } -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/monitoring/data/MemoryManagerData.java b/test/hotspot/jtreg/vmTestbase/vm/share/monitoring/data/MemoryManagerData.java deleted file mode 100644 index ec58d3d43eb81..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/monitoring/data/MemoryManagerData.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2009, 2018, 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 vm.share.monitoring.data; - -import java.lang.management.*; -import javax.management.*; -import java.io.Serializable; - -public class MemoryManagerData implements MemoryManagerMXBean, Serializable { - private String[] memoryPoolNames; - private String name; - private boolean valid; - - public MemoryManagerData(String[] memoryPoolNames, String name, boolean valid) { - this.memoryPoolNames = memoryPoolNames; - this.name = name; - this.valid = valid; - } - - public MemoryManagerData(MemoryManagerMXBean memoryManager) { - this.memoryPoolNames = memoryManager.getMemoryPoolNames(); - this.name = memoryManager.getName(); - this.valid = memoryManager.isValid(); - } - - public String[] getMemoryPoolNames() { - return memoryPoolNames; - } - - public String getName() { - return name; - } - - public boolean isValid() { - return valid; - } - - public ObjectName getObjectName() { - return null; - } -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/monitoring/data/MemoryPoolData.java b/test/hotspot/jtreg/vmTestbase/vm/share/monitoring/data/MemoryPoolData.java deleted file mode 100644 index cf2221bf13602..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/monitoring/data/MemoryPoolData.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2009, 2018, 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 vm.share.monitoring.data; - -import java.lang.management.MemoryPoolMXBean; -import java.io.Serializable; - -public class MemoryPoolData implements Serializable { - private String name; - private boolean valid; - private MemoryUsageData usage; - - public MemoryPoolData(String name, boolean valid, MemoryUsageData usage) { - this.name = name; - this.valid = valid; - } - - public MemoryPoolData(MemoryPoolMXBean memoryManager) { - this.name = memoryManager.getName(); - this.valid = memoryManager.isValid(); - this.usage = new MemoryUsageData(memoryManager.getUsage()); - } - - public String getName() { - return name; - } - - public boolean hasName(String name) { - return this.name.equals(name); - } - - public boolean isValid() { - return valid; - } - - public MemoryUsageData getUsage() { - return usage; - } -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/monitoring/data/MemoryUsageData.java b/test/hotspot/jtreg/vmTestbase/vm/share/monitoring/data/MemoryUsageData.java deleted file mode 100644 index 60b9fababe0ce..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/monitoring/data/MemoryUsageData.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2009, 2018, 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 vm.share.monitoring.data; - -import java.io.Serializable; -import java.lang.management.MemoryUsage; -import nsk.share.log.Log; - -public class MemoryUsageData implements Serializable { - private long init; - private long used; - private long committed; - private long max; - - public MemoryUsageData(long init, long used, long committed, long max) { - this.init = init; - this.used = used; - this.committed = committed; - this.max = max; - } - - public MemoryUsageData(MemoryUsage usage) { - this.init = usage.getInit(); - this.used = usage.getUsed(); - this.committed = usage.getCommitted(); - this.max = usage.getMax(); - } - - public MemoryUsageData(MemoryUsageData usage, MemoryUsageData usage1) { - this.init = usage.getInit() + usage1.getInit(); - this.used = usage.getUsed() + usage1.getUsed(); - this.committed = usage.getCommitted() + usage1.getCommitted(); - this.max = usage.getMax() + usage1.getMax(); - } - - public long getInit() { - return init; - } - - public long getUsed() { - return used; - } - - public long getMax() { - return max; - } - - public long getFree() { - return committed - used; - } - - public long getCommitted() { - return committed; - } - - public void log(Log log) { - log.info(" Init: " + init); - log.info(" Used: " + used); - log.info(" Committed: " + committed); - log.info(" Max: " + max); - } -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/process/CmdExecutor.java b/test/hotspot/jtreg/vmTestbase/vm/share/process/CmdExecutor.java deleted file mode 100644 index bea1bd8282bbb..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/process/CmdExecutor.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2013, 2018, 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 vm.share.process; - -import java.io.IOException; -import java.util.Collection; - -public class CmdExecutor extends ProcessExecutor { - private final StringBuilder cmd = new StringBuilder(); - @Override - public void clearArgs() { - cmd.setLength(0); - } - - @Override - public void addArg(String arg) { - cmd.append(" " + arg); - } - - @Override - public void addArgs(String[] args) { - for (String arg : args) { - addArg(arg); - } - } - - @Override - public void addArgs(Collection args) { - for (String arg : args) { - addArg(arg); - } - } - - @Override - protected Process createProcess() throws IOException { - return Runtime.getRuntime().exec(cmd.toString()); - } - - @Override - public String toString() { - return cmd.toString(); - } -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/process/MessageInput.java b/test/hotspot/jtreg/vmTestbase/vm/share/process/MessageInput.java deleted file mode 100644 index d684d88f54373..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/process/MessageInput.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2011, 2018, 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 vm.share.process; - -import java.util.List; - -public interface MessageInput { - public boolean waitForStart(long timeout) throws InterruptedException; - public boolean waitForMessage(long timeout) throws InterruptedException; - public boolean waitForMessage(String msg, long timeout) throws InterruptedException; - public String getMessage(); - public List getMessages(); - public List getMessages(int to); - public List getMessages(int from, int to); - public boolean waitForFinish(long timeout) throws InterruptedException; - public void reset(); -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/process/MessageOutput.java b/test/hotspot/jtreg/vmTestbase/vm/share/process/MessageOutput.java deleted file mode 100644 index 3a0b4549c4855..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/process/MessageOutput.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2011, 2018, 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 vm.share.process; - -public interface MessageOutput { - public void start(); - public void send(String msg); - public void finish(); -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/process/ProcessHandler.java b/test/hotspot/jtreg/vmTestbase/vm/share/process/ProcessHandler.java deleted file mode 100644 index 4ca3b191993f5..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/process/ProcessHandler.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2011, 2018, 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 vm.share.process; - -import java.util.List; - -public class ProcessHandler implements MessageInput, MessageOutput { - private StreamMessageInput stdout = new StreamMessageInput(); - private StreamMessageInput stderr = new StreamMessageInput(); - private StreamMessageOutput stdin = new StreamMessageOutput(); - - public ProcessHandler() { - } - - public ProcessHandler(ProcessExecutor exec) { - bind(exec); - } - - public void bind(ProcessExecutor exec) { - exec.addStdOutListener(stdout.createListener()); - exec.addStdErrListener(stderr.createListener()); - exec.start(); - stdin.bind(exec.getStdIn()); - } - - public boolean waitForStart(long timeout) throws InterruptedException { - return stdout.waitForStart(timeout) && stderr.waitForStart(timeout); - } - - public boolean waitForMessage(long timeout) throws InterruptedException { - return stdout.waitForMessage(timeout); - } - - public boolean waitForMessage(String msg, long timeout) throws InterruptedException { - return stdout.waitForMessage(msg, timeout); - } - - public String getMessage() { - return stdout.getMessage(); - } - - public List getMessages() { - return stdout.getMessages(); - } - - public List getMessages(int to) { - return stdout.getMessages(to); - } - - public List getMessages(int from, int to) { - return stdout.getMessages(from, to); - } - - public boolean waitForStdErrMessage(String msg, long timeout) throws InterruptedException { - return stderr.waitForMessage(msg, timeout); - } - - public String getStdErrMessage() { - return stderr.getMessage(); - } - - public boolean waitForFinish(long timeout) throws InterruptedException { - return stdout.waitForFinish(timeout) && stderr.waitForFinish(timeout); - } - - public void start() { - stdin.start(); - } - - public void send(String msg) { - stdin.send(msg); - } - - public void finish() { - stdin.finish(); - } - - public void reset() { - stdout.reset(); - stderr.reset(); - } -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/process/StreamMessageInput.java b/test/hotspot/jtreg/vmTestbase/vm/share/process/StreamMessageInput.java deleted file mode 100644 index 03d9ec6bd3e69..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/process/StreamMessageInput.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2011, 2018, 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 vm.share.process; - -import java.util.List; -import java.util.ArrayList; -import nsk.share.TestBug; - -public class StreamMessageInput implements MessageInput { - private Object sync = new Object(); - private List lines = new ArrayList(); - private int position = 0; - private volatile boolean active = false; - private volatile Throwable exception; - - public StreamMessageInput() { - } - - public StreamMessageInput(StreamReader sd) { - bind(sd); - } - - public StreamListener createListener() { - return new Listener(); - } - - public void bind(StreamReader sd) { - sd.addListener(createListener()); - } - - public boolean isActive() { - return active; - } - - public boolean isException() { - return exception != null; - } - - public Throwable getException() { - return exception; - } - - public boolean waitForStart(long timeout) throws InterruptedException { - long startTime = System.currentTimeMillis(); - long curTime = startTime; - synchronized (sync) { - while (!active && curTime - startTime < timeout) { - sync.wait(curTime - startTime); - curTime = System.currentTimeMillis(); - } - } - return active; - } - - public boolean waitForFinish(long timeout) throws InterruptedException { - long startTime = System.currentTimeMillis(); - long curTime = startTime; - synchronized (sync) { - while (active && curTime - startTime < timeout) { - sync.wait(curTime - startTime); - curTime = System.currentTimeMillis(); - } - } - return !active; - } - - public boolean waitForMessage(String msg, long timeout) throws InterruptedException { - long startTime = System.currentTimeMillis(); - long curTime = startTime; - int n = position; - synchronized (sync) { - while (curTime - startTime < timeout) { - while (n < lines.size()) { - // System.out.println("Check: " + lines.get(n)); - if (msg == null || lines.get(n++).contains(msg)) { - return true; - } - } - sync.wait(timeout - (curTime - startTime)); - curTime = System.currentTimeMillis(); - } - return false; - } - } - - public boolean waitForMessage(long timeout) throws InterruptedException { - return waitForMessage(null, timeout); - } - - public String getMessage() { - if (position < lines.size()) - return lines.get(position++); - else - return null; - } - - public String getMessage(int index) { - return lines.get(index); - } - - public int getPosition() { - return position; - } - - public void setPosition(int position) { - this.position = position; - } - - public int getMessageCount() { - return lines.size(); - } - - public List getMessages() { - return getMessages(position, lines.size()); - } - - public List getMessages(int to) { - return getMessages(position, to); - } - - public List getMessages(int from, int to) { - synchronized (sync) { - if (to < 0) - to = lines.size() + to; - position = Math.max(position, to); - return new ArrayList(lines.subList(from, to)); - } - } - - public void reset() { - synchronized (sync) { - position = lines.size(); - } - } - - private class Listener implements StreamListener { - @Override - public void onStart() { - synchronized (sync) { - active = true; - sync.notifyAll(); - } - } - - @Override - public void onRead(String line) { - //System.out.println("onRead: " + line); - synchronized (sync) { - lines.add(line); - sync.notifyAll(); - } - } - - @Override - public void onFinish() { - synchronized (sync) { - active = false; - sync.notifyAll(); - } - } - - @Override - public void onException(Throwable e) { - exception = e; - } - } -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/process/StreamMessageOutput.java b/test/hotspot/jtreg/vmTestbase/vm/share/process/StreamMessageOutput.java deleted file mode 100644 index 473ccc071f9a3..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/process/StreamMessageOutput.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2011, 2018, 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 vm.share.process; - -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.IOException; -import nsk.share.TestFailure; - -public class StreamMessageOutput implements MessageOutput { - private OutputStream out; - private PrintStream pout; - - public StreamMessageOutput() { - } - - public StreamMessageOutput(OutputStream out) { - bind(out); - } - - public void bind(OutputStream out) { - this.out = out; - this.pout = new PrintStream(out, true); // Autoflush is important - } - - public void start() { - } - - public void send(String msg) { - pout.println(msg); - } - - public void finish() { - pout.close(); - } -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/transform/AbstractClassFileTransformer.java b/test/hotspot/jtreg/vmTestbase/vm/share/transform/AbstractClassFileTransformer.java deleted file mode 100644 index 95906789fda31..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/transform/AbstractClassFileTransformer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2013, 2018, 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 vm.share.transform; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.IllegalClassFormatException; -import java.security.ProtectionDomain; - -public abstract class AbstractClassFileTransformer - implements ClassFileTransformer { - protected abstract boolean shouldBeTransformed(String name); - - protected abstract byte[] transformClass(byte[] bytes); - - @Override - public byte[] transform(ClassLoader loader, String className, - Class classBeingRedefined, ProtectionDomain protectionDomain, - byte[] classfileBuffer) throws IllegalClassFormatException { - if (shouldBeTransformed(className)) { - return transformClass(classfileBuffer); - } - return null; - } -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/transform/AnnotationAppender.java b/test/hotspot/jtreg/vmTestbase/vm/share/transform/AnnotationAppender.java deleted file mode 100644 index b3891fec5e411..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/transform/AnnotationAppender.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013, 2018, 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 vm.share.transform; - -import jdk.internal.org.objectweb.asm.AnnotationVisitor; - -public abstract class AnnotationAppender { - private final String desc; - private final boolean visible; - private boolean annotationPresent; - - public AnnotationAppender(String desc, boolean visible) { - this.desc = desc; - this.visible = visible; - } - - public void checkAnnotation(String desc, boolean isVisible) { - annotationPresent |= visible == isVisible && this.desc.equals(desc); - } - - public void addAnnotation(VisitAnnotation func) { - if (shouldAdd()) { - AnnotationVisitor av = func.visit(desc, true); - if (av != null) { - postCreate(av); - av.visitEnd(); - annotationPresent = true; - } - } - } - - protected boolean shouldAdd() { - return !annotationPresent; - } - - protected abstract void postCreate(AnnotationVisitor av); - - @FunctionalInterface - public static interface VisitAnnotation { - AnnotationVisitor visit(String desc, boolean visible); - } -} diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/transform/TransformingClassLoader.java b/test/hotspot/jtreg/vmTestbase/vm/share/transform/TransformingClassLoader.java deleted file mode 100644 index 5ce3dd02eb655..0000000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/share/transform/TransformingClassLoader.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2013, 2018, 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 vm.share.transform; - -import vm.share.FileUtils; - -public class TransformingClassLoader extends ClassLoader { - private final AbstractClassFileTransformer transformer; - - protected TransformingClassLoader(ClassLoader parent, - AbstractClassFileTransformer transformer) { - super(parent); - this.transformer = transformer; - } - - @Override - protected Class loadClass(String name, boolean resolve) - throws ClassNotFoundException { - if (!transformer.shouldBeTransformed(name)) { - return super.loadClass(name, resolve); - } - synchronized (getClassLoadingLock(name)) { - // First, check if the class has already been loaded - Class c = findLoadedClass(name); - if (c == null) { - try { - byte[] bytes = FileUtils.readClass(name); - bytes = transformer.transformClass(bytes); - c = defineClass(name, bytes, 0, bytes.length); - } catch (Exception e) { - e.printStackTrace(); - return super.loadClass(name, resolve); - } - } - if (resolve) { - resolveClass(c); - } - return c; - } - } -} From c5ac2ed97269ddfeb7c56074a5f90dc7446b1fdb Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 09:37:13 +0000 Subject: [PATCH 340/846] 8345566: Deproblemlist test/jdk/javax/swing/JComboBox/6559152/bug6559152.java Backport-of: 7ee84d8f7096ccfc4666d5bff78e7e5ac6d614bd --- test/jdk/javax/swing/JComboBox/6559152/bug6559152.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/jdk/javax/swing/JComboBox/6559152/bug6559152.java b/test/jdk/javax/swing/JComboBox/6559152/bug6559152.java index 5540bb306148c..c0747f8b1e47d 100644 --- a/test/jdk/javax/swing/JComboBox/6559152/bug6559152.java +++ b/test/jdk/javax/swing/JComboBox/6559152/bug6559152.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,8 +48,8 @@ public class bug6559152 { private static JFrame frame; private static JComboBox cb; private static Robot robot; - private static Point p = null; - private static Dimension d; + private static volatile Point p = null; + private static volatile Dimension d; public static void main(String[] args) throws Exception { robot = new Robot(); @@ -84,7 +84,7 @@ static void blockTillDisplayed(JComponent comp) throws Exception { } private static void setupUI() { - frame = new JFrame(); + frame = new JFrame("bug6559152"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); DefaultTableModel model = new DefaultTableModel(1, 1); From bf62af0a72ab258d401a66c2f885a8dbf6d1f986 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 09:40:57 +0000 Subject: [PATCH 341/846] 8346871: Improve robustness of java/util/zip/EntryCount64k.java test Backport-of: 24c5ff7ba58cb7cf93df07f81484cd8fae60e31e --- test/jdk/java/util/zip/EntryCount64k.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/jdk/java/util/zip/EntryCount64k.java b/test/jdk/java/util/zip/EntryCount64k.java index d8c46d2236433..8830a87ea647b 100644 --- a/test/jdk/java/util/zip/EntryCount64k.java +++ b/test/jdk/java/util/zip/EntryCount64k.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2013 Google Inc. All rights reserved. + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,9 +48,12 @@ import jdk.test.lib.process.ProcessTools; public class EntryCount64k { + + private static final String MAIN_CLASS_MSG = "foo bar hello world Main"; + public static class Main { public static void main(String[] args) { - System.out.print("Main"); + System.out.println(MAIN_CLASS_MSG); } } @@ -162,7 +166,10 @@ static void checkCanRead(File zipFile, int entryCount) throws Throwable { // Check java -jar OutputAnalyzer a = ProcessTools.executeTestJava("-jar", zipFile.getName()); a.shouldHaveExitValue(0); - a.stdoutShouldMatch("\\AMain\\Z"); + // expect the message from the application on stdout + a.stdoutContains(MAIN_CLASS_MSG); + // nothing is expected on stderr (apart from any probable deprecation + // warnings from the launcher/JVM) a.stderrShouldMatchIgnoreDeprecatedWarnings("\\A\\Z"); } } From 7b1096d771ba8d79bac8de6920eacd26df408e7b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 09:41:53 +0000 Subject: [PATCH 342/846] 8345767: javax/swing/JSplitPane/4164779/JSplitPaneKeyboardNavigationTest.java fails in ubuntu22.04 Backport-of: 8de0622c3a5c9e01e79659ef0b43b1b01dfa5cf6 --- .../JSplitPaneKeyboardNavigationTest.java | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/test/jdk/javax/swing/JSplitPane/4164779/JSplitPaneKeyboardNavigationTest.java b/test/jdk/javax/swing/JSplitPane/4164779/JSplitPaneKeyboardNavigationTest.java index ced7410bf0664..4f0857944aa4a 100644 --- a/test/jdk/javax/swing/JSplitPane/4164779/JSplitPaneKeyboardNavigationTest.java +++ b/test/jdk/javax/swing/JSplitPane/4164779/JSplitPaneKeyboardNavigationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,7 +64,7 @@ public class JSplitPaneKeyboardNavigationTest { public static void main(String[] s) throws Exception { robot = new Robot(); robot.setAutoWaitForIdle(true); - robot.setAutoDelay(200); + robot.setAutoDelay(100); List lafs = Arrays.stream(getInstalledLookAndFeels()) .map(LookAndFeelInfo::getClassName) .collect(Collectors.toList()); @@ -81,10 +81,13 @@ public static void main(String[] s) throws Exception { continue; } robot.waitForIdle(); + robot.delay(1000); // Press Right button 1 and move focus to it. pressButton(rightButton1); hitKeys(KeyEvent.VK_F6); + robot.waitForIdle(); + robot.delay(100); // Verifier1 - Verifies that, F6 transfers focus to the right/bottom side of the splitpane if (isFocusOwner(rightButton2)) { @@ -98,9 +101,12 @@ public static void main(String[] s) throws Exception { // Press Right button 2 and move focus to it. pressButton(rightButton2); hitKeys(KeyEvent.VK_F6); + robot.waitForIdle(); + robot.delay(100); // Verifier2 - Verifies that, F6 transfers focus to the left side of the parent splitpane, - // if the right/bottom side of splitpane already has focus, and it is contained within another splitpane + // if the right/bottom side of splitpane already has focus, + // and it is contained within another splitpane if (isFocusOwner(leftButton)) { System.out.println("Verifier 2 passed"); } else { @@ -112,6 +118,9 @@ public static void main(String[] s) throws Exception { // Press Left button and move focus to it. pressButton(leftButton); hitKeys(KeyEvent.VK_CONTROL, KeyEvent.VK_TAB); + robot.waitForIdle(); + robot.delay(100); + // Verifier3 - Verifies that, CTRL-TAB navigates forward outside the JSplitPane if (isFocusOwner(bottomButton)) { System.out.println("Verifier 3 passed"); @@ -124,6 +133,8 @@ public static void main(String[] s) throws Exception { // Press Left button and move focus to it. pressButton(leftButton); hitKeys(KeyEvent.VK_CONTROL, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); + robot.waitForIdle(); + robot.delay(100); // Verifier4 - Verifies that, CTRL-SHIFT-TAB navigates backward outside the JSplitPane if (isFocusOwner(topButton)) { @@ -137,7 +148,8 @@ public static void main(String[] s) throws Exception { if (failedVerifiers.toString().isEmpty()) { System.out.println("Test passed, All verifiers succeeded for " + laf); } else { - throw new RuntimeException("Test failed, verifiers " + failedVerifiers.toString() + " failed for " + laf); + throw new RuntimeException("Test failed, verifiers " + + failedVerifiers.toString() + " failed for " + laf); } } finally { SwingUtilities.invokeAndWait(JSplitPaneKeyboardNavigationTest::disposeFrame); @@ -159,13 +171,14 @@ private static void pressButton(JButton button) throws Exception { loc.set(button.getLocationOnScreen()); }); final Point buttonLoc = loc.get(); - robot.mouseMove(buttonLoc.x + 8, buttonLoc.y + 8); + robot.mouseMove(buttonLoc.x + button.getWidth() / 2, + buttonLoc.y + button.getHeight() / 2); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); } public static void createUI() { - frame = new JFrame(); + frame = new JFrame("JSplitPaneKeyboardNavigationTest"); panel = new JPanel(); panel.setLayout(new BorderLayout()); leftButton = new JButton("Left Button"); @@ -175,13 +188,14 @@ public static void createUI() { bottomButton = new JButton("Bottom Button"); panel.add(topButton, BorderLayout.NORTH); panel.add(bottomButton, BorderLayout.SOUTH); - final JSplitPane splitPane2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, rightButton1, rightButton2); - final JSplitPane splitPane1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, leftButton, splitPane2); + final JSplitPane splitPane2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, + true, rightButton1, rightButton2); + final JSplitPane splitPane1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, + true, leftButton, splitPane2); panel.add(splitPane1, BorderLayout.CENTER); frame.setContentPane(panel); frame.setSize(200, 200); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - frame.pack(); frame.setAlwaysOnTop(true); frame.setLocationRelativeTo(null); frame.setVisible(true); @@ -213,7 +227,6 @@ private static boolean setLookAndFeel(String lafName) { private static void disposeFrame() { if (frame != null) { frame.dispose(); - frame = null; } } From 6b156585e70a639930f6965c0b3871de8b1a874b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 23 Jun 2025 12:40:12 +0000 Subject: [PATCH 343/846] 8288746: HttpClient resources could be reclaimed more eagerly Reviewed-by: rschmelter Backport-of: f3f078846feae66d3504d50081353f74bd4891d7 --- src/java.base/share/classes/module-info.java | 1 + .../share/lib/security/default.policy | 1 + .../internal/net/http/HttpClientFacade.java | 12 +- .../jdk/internal/net/http/HttpClientImpl.java | 12 +- .../net/httpclient/AsFileDownloadTest.java | 108 +++++++++++------- .../java/net/httpclient/DigestEchoClient.java | 14 ++- .../java/net/httpclient/ReferenceTracker.java | 6 +- .../httpclient/ResponseBodyBeforeError.java | 100 ++++++++++------ 8 files changed, 169 insertions(+), 85 deletions(-) diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index fad70bdc058b9..8f1ecae3ed1ed 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -226,6 +226,7 @@ jdk.jfr; exports jdk.internal.ref to java.desktop, + java.net.http, jdk.incubator.foreign; exports jdk.internal.reflect to java.logging, diff --git a/src/java.base/share/lib/security/default.policy b/src/java.base/share/lib/security/default.policy index 4e3c326cb2f4d..9bd5dd53bd3b6 100644 --- a/src/java.base/share/lib/security/default.policy +++ b/src/java.base/share/lib/security/default.policy @@ -19,6 +19,7 @@ grant codeBase "jrt:/java.net.http" { permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util"; permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc"; + permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.ref"; permission java.lang.RuntimePermission "modifyThread"; permission java.net.SocketPermission "*","connect,resolve"; permission java.net.URLPermission "http:*","*:*"; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientFacade.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientFacade.java index 431a625315553..7edef3ee58d2a 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientFacade.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientFacade.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -26,6 +26,7 @@ package jdk.internal.net.http; import java.io.IOException; +import java.lang.ref.Cleaner; import java.lang.ref.Reference; import java.net.Authenticator; import java.net.CookieHandler; @@ -44,13 +45,20 @@ import java.net.http.WebSocket; import jdk.internal.net.http.common.OperationTrackers.Trackable; import jdk.internal.net.http.common.OperationTrackers.Tracker; +import jdk.internal.ref.CleanerFactory; /** * An HttpClientFacade is a simple class that wraps an HttpClient implementation * and delegates everything to its implementation delegate. + * @implSpec + * Though the facade strongly reference its implementation, the + * implementation MUST NOT strongly reference the facade. + * It MAY use weak references if needed. */ public final class HttpClientFacade extends HttpClient implements Trackable { + static final Cleaner cleaner = CleanerFactory.cleaner(); + final HttpClientImpl impl; /** @@ -58,6 +66,8 @@ public final class HttpClientFacade extends HttpClient implements Trackable { */ HttpClientFacade(HttpClientImpl impl) { this.impl = impl; + // wakeup the impl when the facade is gc'ed + cleaner.register(this, impl::facadeCleanup); } @Override // for tests diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java index eb3584cc881c2..d444ec775d06c 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java @@ -491,6 +491,13 @@ private HttpClientImpl(HttpClientBuilderImpl builder, assert facadeRef.get() != null; } + // called when the facade is GC'ed. + // Just wakes up the selector to cleanup... + void facadeCleanup() { + SelectorManager selmgr = this.selmgr; + if (selmgr != null) selmgr.wakeupSelector(); + } + void onSubmitFailure(Runnable command, Throwable failure) { selmgr.abort(failure); } @@ -723,7 +730,7 @@ public long getOutstandingWebSocketOperations() { } @Override public boolean isFacadeReferenced() { - return reference.get() != null; + return !reference.refersTo(null); } @Override public boolean isSelectorAlive() { return isAlive.get(); } @@ -749,8 +756,7 @@ public Tracker getOperationsTracker() { // Called by the SelectorManager thread to figure out whether it's time // to terminate. boolean isReferenced() { - HttpClient facade = facade(); - return facade != null || referenceCount() > 0; + return !facadeRef.refersTo(null) || referenceCount() > 0; } /** diff --git a/test/jdk/java/net/httpclient/AsFileDownloadTest.java b/test/jdk/java/net/httpclient/AsFileDownloadTest.java index 72131bfa03c07..d191c8f4d4ad0 100644 --- a/test/jdk/java/net/httpclient/AsFileDownloadTest.java +++ b/test/jdk/java/net/httpclient/AsFileDownloadTest.java @@ -29,6 +29,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.UncheckedIOException; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.URI; @@ -77,7 +79,6 @@ * @run testng/othervm AsFileDownloadTest * @run testng/othervm/java.security.policy=AsFileDownloadTest.policy AsFileDownloadTest */ - public class AsFileDownloadTest { SSLContext sslContext; @@ -89,6 +90,7 @@ public class AsFileDownloadTest { String httpsURI; String http2URI; String https2URI; + final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE; Path tempDir; @@ -164,37 +166,49 @@ void test(String uriString, String contentDispositionValue, String expectedFilen { out.printf("test(%s, %s, %s): starting", uriString, contentDispositionValue, expectedFilename); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); + TRACKER.track(client); + ReferenceQueue queue = new ReferenceQueue<>(); + WeakReference ref = new WeakReference<>(client, queue); + try { + URI uri = URI.create(uriString); + HttpRequest request = HttpRequest.newBuilder(uri) + .POST(BodyPublishers.ofString("May the luck of the Irish be with you!")) + .build(); - URI uri = URI.create(uriString); - HttpRequest request = HttpRequest.newBuilder(uri) - .POST(BodyPublishers.ofString("May the luck of the Irish be with you!")) - .build(); - - BodyHandler bh = ofFileDownload(tempDir.resolve(uri.getPath().substring(1)), - CREATE, TRUNCATE_EXISTING, WRITE); - HttpResponse response = client.send(request, bh); - - Path body = response.body(); - out.println("Got response: " + response); - out.println("Got body Path: " + body); - String fileContents = new String(Files.readAllBytes(response.body()), UTF_8); - out.println("Got body: " + fileContents); - - assertEquals(response.statusCode(),200); - assertEquals(body.getFileName().toString(), expectedFilename); - assertTrue(response.headers().firstValue("Content-Disposition").isPresent()); - assertEquals(response.headers().firstValue("Content-Disposition").get(), - contentDispositionValue); - assertEquals(fileContents, "May the luck of the Irish be with you!"); - - if (!body.toAbsolutePath().startsWith(tempDir.toAbsolutePath())) { - System.out.println("Tempdir = " + tempDir.toAbsolutePath()); - System.out.println("body = " + body.toAbsolutePath()); - throw new AssertionError("body in wrong location"); + BodyHandler bh = ofFileDownload(tempDir.resolve(uri.getPath().substring(1)), + CREATE, TRUNCATE_EXISTING, WRITE); + HttpResponse response = client.send(request, bh); + Path body = response.body(); + out.println("Got response: " + response); + out.println("Got body Path: " + body); + String fileContents = new String(Files.readAllBytes(response.body()), UTF_8); + out.println("Got body: " + fileContents); + + assertEquals(response.statusCode(), 200); + assertEquals(body.getFileName().toString(), expectedFilename); + assertTrue(response.headers().firstValue("Content-Disposition").isPresent()); + assertEquals(response.headers().firstValue("Content-Disposition").get(), + contentDispositionValue); + assertEquals(fileContents, "May the luck of the Irish be with you!"); + + if (!body.toAbsolutePath().startsWith(tempDir.toAbsolutePath())) { + System.out.println("Tempdir = " + tempDir.toAbsolutePath()); + System.out.println("body = " + body.toAbsolutePath()); + throw new AssertionError("body in wrong location"); + } + // additional checks unrelated to file download + caseInsensitivityOfHeaders(request.headers()); + caseInsensitivityOfHeaders(response.headers()); + } finally { + client = null; + System.gc(); + while (!ref.refersTo(null)) { + System.gc(); + if (queue.remove(100) == ref) break; + } + AssertionError failed = TRACKER.checkShutdown(1000); + if (failed != null) throw failed; } - // additional checks unrelated to file download - caseInsensitivityOfHeaders(request.headers()); - caseInsensitivityOfHeaders(response.headers()); } // --- Negative @@ -246,18 +260,32 @@ void negativeTest(String uriString, String contentDispositionValue) { out.printf("negativeTest(%s, %s): starting", uriString, contentDispositionValue); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); + TRACKER.track(client); + ReferenceQueue queue = new ReferenceQueue<>(); + WeakReference ref = new WeakReference<>(client, queue); - URI uri = URI.create(uriString); - HttpRequest request = HttpRequest.newBuilder(uri) - .POST(BodyPublishers.ofString("Does not matter")) - .build(); - - BodyHandler bh = ofFileDownload(tempDir, CREATE, TRUNCATE_EXISTING, WRITE); try { - HttpResponse response = client.send(request, bh); - fail("UNEXPECTED response: " + response + ", path:" + response.body()); - } catch (UncheckedIOException | IOException ioe) { - System.out.println("Caught expected: " + ioe); + URI uri = URI.create(uriString); + HttpRequest request = HttpRequest.newBuilder(uri) + .POST(BodyPublishers.ofString("Does not matter")) + .build(); + + BodyHandler bh = ofFileDownload(tempDir, CREATE, TRUNCATE_EXISTING, WRITE); + try { + HttpResponse response = client.send(request, bh); + fail("UNEXPECTED response: " + response + ", path:" + response.body()); + } catch (UncheckedIOException | IOException ioe) { + System.out.println("Caught expected: " + ioe); + } + } finally { + client = null; + System.gc(); + while (!ref.refersTo(null)) { + System.gc(); + if (queue.remove(100) == ref) break; + } + AssertionError failed = TRACKER.checkShutdown(1000); + if (failed != null) throw failed; } } diff --git a/test/jdk/java/net/httpclient/DigestEchoClient.java b/test/jdk/java/net/httpclient/DigestEchoClient.java index f7bac2038d1db..9f963e71658bb 100644 --- a/test/jdk/java/net/httpclient/DigestEchoClient.java +++ b/test/jdk/java/net/httpclient/DigestEchoClient.java @@ -23,6 +23,8 @@ import java.io.IOException; import java.io.UncheckedIOException; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; import java.math.BigInteger; import java.net.ProxySelector; import java.net.URI; @@ -32,7 +34,6 @@ import java.net.http.HttpRequest.BodyPublisher; import java.net.http.HttpRequest.BodyPublishers; import java.net.http.HttpResponse; -import java.net.http.HttpResponse.BodyHandler; import java.net.http.HttpResponse.BodyHandlers; import java.nio.charset.StandardCharsets; import java.security.NoSuchAlgorithmException; @@ -55,6 +56,7 @@ import jdk.test.lib.net.SimpleSSLContext; import sun.net.NetProperties; import sun.net.www.HeaderParser; + import static java.lang.System.out; import static java.lang.String.format; @@ -386,6 +388,8 @@ void testBasic(Version clientVersion, Version serverVersion, boolean async, server.getServerAddress(), "/foo/"); HttpClient client = newHttpClient(server); + ReferenceQueue queue = new ReferenceQueue<>(); + WeakReference ref = new WeakReference<>(client, queue); HttpResponse r; CompletableFuture> cf1; String auth = null; @@ -497,6 +501,14 @@ void testBasic(Version clientVersion, Version serverVersion, boolean async, } } } finally { + client = null; + System.gc(); + while (!ref.refersTo(null)) { + System.gc(); + if (queue.remove(100) == ref) break; + } + var error = TRACKER.checkShutdown(500); + if (error != null) throw error; } System.out.println("OK"); } diff --git a/test/jdk/java/net/httpclient/ReferenceTracker.java b/test/jdk/java/net/httpclient/ReferenceTracker.java index df26c0f790529..dc704fa81fd4d 100644 --- a/test/jdk/java/net/httpclient/ReferenceTracker.java +++ b/test/jdk/java/net/httpclient/ReferenceTracker.java @@ -179,13 +179,15 @@ public AssertionError check(long graceDelayMs, boolean printThreads) { AssertionError fail = null; graceDelayMs = Math.max(graceDelayMs, 100); - long delay = Math.min(graceDelayMs, 500); + long delay = Math.min(graceDelayMs, 10); var count = delay > 0 ? graceDelayMs / delay : 1; for (int i = 0; i < count; i++) { if (TRACKERS.stream().anyMatch(hasOutstanding)) { System.gc(); try { - System.out.println("Waiting for HTTP operations to terminate..."); + if (i == 0) { + System.out.println("Waiting for HTTP operations to terminate..."); + } Thread.sleep(Math.min(graceDelayMs, Math.max(delay, 1))); } catch (InterruptedException x) { // OK diff --git a/test/jdk/java/net/httpclient/ResponseBodyBeforeError.java b/test/jdk/java/net/httpclient/ResponseBodyBeforeError.java index f176531f93e1a..d1cffff72cfd9 100644 --- a/test/jdk/java/net/httpclient/ResponseBodyBeforeError.java +++ b/test/jdk/java/net/httpclient/ResponseBodyBeforeError.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 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 @@ -25,6 +25,7 @@ * @test * @summary Tests that all response body is delivered to the BodySubscriber * before an abortive error terminates the flow + * @modules java.net.http/jdk.internal.net.http.common * @library /test/lib * @build jdk.test.lib.net.SimpleSSLContext * @run testng/othervm ResponseBodyBeforeError @@ -59,6 +60,8 @@ import org.testng.annotations.Test; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocketFactory; + +import static java.lang.System.err; import static java.lang.System.out; import static java.net.http.HttpClient.Builder.NO_PROXY; import static java.net.http.HttpResponse.BodyHandlers.ofString; @@ -177,6 +180,7 @@ public Object[][] variants() { } static final int ITERATION_COUNT = 3; + static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE; @Test(dataProvider = "uris") void testSynchronousAllRequestBody(String url, @@ -186,24 +190,34 @@ void testSynchronousAllRequestBody(String url, { out.print("---\n"); HttpClient client = null; - for (int i=0; i< ITERATION_COUNT; i++) { - if (!sameClient || client == null) - client = HttpClient.newBuilder() - .proxy(NO_PROXY) - .sslContext(sslContext) - .build(); - HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build(); - CustomBodySubscriber bs = new CustomBodySubscriber(); - try { - HttpResponse response = client.send(request, r -> bs); - String body = response.body(); - out.println(response + ": " + body); - fail("UNEXPECTED RESPONSE: " + response); - } catch (IOException expected) { - String pm = bs.receivedAsString(); - out.println("partial body received: " + pm); - assertEquals(pm, expectedPatrialBody); + try { + for (int i = 0; i < ITERATION_COUNT; i++) { + if (!sameClient || client == null) { + client = HttpClient.newBuilder() + .proxy(NO_PROXY) + .sslContext(sslContext) + .build(); + TRACKER.track(client); + System.gc(); + } + HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build(); + CustomBodySubscriber bs = new CustomBodySubscriber(); + try { + HttpResponse response = client.send(request, r -> bs); + String body = response.body(); + out.println(response + ": " + body); + fail("UNEXPECTED RESPONSE: " + response); + } catch (IOException expected) { + String pm = bs.receivedAsString(); + out.println("partial body received: " + pm); + assertEquals(pm, expectedPatrialBody); + } } + } finally { + client = null; + System.gc(); + var error = TRACKER.checkShutdown(1000); + if (error != null) throw error; } } @@ -215,28 +229,38 @@ void testAsynchronousAllRequestBody(String url, { out.print("---\n"); HttpClient client = null; - for (int i=0; i< ITERATION_COUNT; i++) { - if (!sameClient || client == null) - client = HttpClient.newBuilder() - .proxy(NO_PROXY) - .sslContext(sslContext) - .build(); - HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build(); - CustomBodySubscriber bs = new CustomBodySubscriber(); - try { - HttpResponse response = client.sendAsync(request, r -> bs).get(); - String body = response.body(); - out.println(response + ": " + body); - fail("UNEXPECTED RESPONSE: " + response); - } catch (ExecutionException ee) { - if (ee.getCause() instanceof IOException) { - String pm = bs.receivedAsString(); - out.println("partial body received: " + pm); - assertEquals(pm, expectedPatrialBody); - } else { - throw ee; + try { + for (int i = 0; i < ITERATION_COUNT; i++) { + if (!sameClient || client == null) { + client = HttpClient.newBuilder() + .proxy(NO_PROXY) + .sslContext(sslContext) + .build(); + System.gc(); + TRACKER.track(client); + } + HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build(); + CustomBodySubscriber bs = new CustomBodySubscriber(); + try { + HttpResponse response = client.sendAsync(request, r -> bs).get(); + String body = response.body(); + out.println(response + ": " + body); + fail("UNEXPECTED RESPONSE: " + response); + } catch (ExecutionException ee) { + if (ee.getCause() instanceof IOException) { + String pm = bs.receivedAsString(); + out.println("partial body received: " + pm); + assertEquals(pm, expectedPatrialBody); + } else { + throw ee; + } } } + } finally { + client = null; + System.gc(); + var error = TRACKER.checkShutdown(1000); + if (error != null) throw error; } } From 4b40f900f47af62d7c0072b65e1c6bc3e9985ef1 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 25 Jun 2025 07:58:32 +0000 Subject: [PATCH 344/846] 8294916: Cancelling a request must eventually cause its response body subscriber to be unregistered Reviewed-by: rschmelter Backport-of: dcd46501e6a25ac875d61bfbd412555b933ce34c --- .../jdk/internal/net/http/Http1Exchange.java | 17 +- .../jdk/internal/net/http/HttpClientImpl.java | 31 +- .../classes/jdk/internal/net/http/Stream.java | 10 +- .../common/HttpBodySubscriberWrapper.java | 39 +- .../net/http/common/OperationTrackers.java | 2 + .../net/httpclient/CancelRequestTest.java | 22 + .../httpclient/CancelStreamedBodyTest.java | 448 ++++++++++++++++++ .../java/net/httpclient/ReferenceTracker.java | 79 ++- .../jdk/java/net/httpclient/SmallTimeout.java | 42 +- 9 files changed, 665 insertions(+), 25 deletions(-) create mode 100644 test/jdk/java/net/httpclient/CancelStreamedBodyTest.java diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java index 4b7d55c3b3466..d308718efbfea 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java @@ -39,6 +39,7 @@ import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.Executor; import java.util.concurrent.Flow; +import java.util.concurrent.Flow.Subscription; import jdk.internal.net.http.common.Demand; import jdk.internal.net.http.common.HttpBodySubscriberWrapper; @@ -210,11 +211,19 @@ static final class Http1ResponseBodySubscriber extends HttpBodySubscriberWrap @Override protected void complete(Throwable t) { try { - exchange.responseSubscriberCompleted(this); + exchange.unregisterResponseSubscriber(this); } finally { super.complete(t); } } + + @Override + protected void onCancel() { + // If the subscription is cancelled the + // subscriber may or may not get completed. + // Therefore we need to unregister it + exchange.unregisterResponseSubscriber(this); + } } @Override @@ -264,7 +273,7 @@ private void connectFlows(HttpConnection connection) { // The Http1ResponseBodySubscriber is registered with the HttpClient // to ensure that it gets completed if the SelectorManager aborts due // to unexpected exceptions. - void registerResponseSubscriber(Http1ResponseBodySubscriber subscriber) { + private void registerResponseSubscriber(Http1ResponseBodySubscriber subscriber) { Throwable failed = null; synchronized (lock) { failed = this.failed; @@ -279,8 +288,8 @@ void registerResponseSubscriber(Http1ResponseBodySubscriber subscriber) { } } - void responseSubscriberCompleted(HttpBodySubscriberWrapper subscriber) { - client.subscriberCompleted(subscriber); + private void unregisterResponseSubscriber(Http1ResponseBodySubscriber subscriber) { + client.unregisterSubscriber(subscriber); } @Override diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java index d444ec775d06c..bb71ac664f11a 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java @@ -396,6 +396,7 @@ static void abortPendingRequests(HttpClientImpl client, Throwable reason) { private final AtomicLong pendingHttpRequestCount = new AtomicLong(); private final AtomicLong pendingHttp2StreamCount = new AtomicLong(); private final AtomicLong pendingTCPConnectionCount = new AtomicLong(); + private final AtomicLong pendingSubscribersCount = new AtomicLong(); private final AtomicBoolean isAlive = new AtomicBoolean(); /** A Set of, deadline first, ordered timeout events. */ @@ -537,7 +538,12 @@ public void registerSubscriber(HttpBodySubscriberWrapper subscriber) { if (!selmgr.isClosed()) { synchronized (selmgr) { if (!selmgr.isClosed()) { - subscribers.add(subscriber); + if (subscribers.add(subscriber)) { + long count = pendingSubscribersCount.incrementAndGet(); + if (debug.on()) { + debug.log("body subscriber registered: " + count); + } + } return; } } @@ -545,8 +551,13 @@ public void registerSubscriber(HttpBodySubscriberWrapper subscriber) { subscriber.onError(selmgr.selectorClosedException()); } - public void subscriberCompleted(HttpBodySubscriberWrapper subscriber) { - subscribers.remove(subscriber); + public void unregisterSubscriber(HttpBodySubscriberWrapper subscriber) { + if (subscribers.remove(subscriber)) { + long count = pendingSubscribersCount.decrementAndGet(); + if (debug.on()) { + debug.log("body subscriber unregistered: " + count); + } + } } private void closeConnection(HttpConnection conn) { @@ -616,7 +627,7 @@ final long unreference() { final long httpCount = pendingHttpOperationsCount.decrementAndGet(); final long http2Count = pendingHttp2StreamCount.get(); final long webSocketCount = pendingWebSocketCount.get(); - if (count == 0 && facade() == null) { + if (count == 0 && facadeRef.refersTo(null)) { selmgr.wakeupSelector(); } assert httpCount >= 0 : "count of HTTP/1.1 operations < 0"; @@ -638,7 +649,7 @@ final long streamUnreference() { final long http2Count = pendingHttp2StreamCount.decrementAndGet(); final long httpCount = pendingHttpOperationsCount.get(); final long webSocketCount = pendingWebSocketCount.get(); - if (count == 0 && facade() == null) { + if (count == 0 && facadeRef.refersTo(null)) { selmgr.wakeupSelector(); } assert httpCount >= 0 : "count of HTTP/1.1 operations < 0"; @@ -660,7 +671,7 @@ final long webSocketClose() { final long webSocketCount = pendingWebSocketCount.decrementAndGet(); final long httpCount = pendingHttpOperationsCount.get(); final long http2Count = pendingHttp2StreamCount.get(); - if (count == 0 && facade() == null) { + if (count == 0 && facadeRef.refersTo(null)) { selmgr.wakeupSelector(); } assert httpCount >= 0 : "count of HTTP/1.1 operations < 0"; @@ -686,6 +697,7 @@ final static class HttpClientTracker implements Tracker { final AtomicLong websocketCount; final AtomicLong operationsCount; final AtomicLong connnectionsCount; + final AtomicLong subscribersCount; final Reference reference; final AtomicBoolean isAlive; final String name; @@ -695,6 +707,7 @@ final static class HttpClientTracker implements Tracker { AtomicLong ws, AtomicLong ops, AtomicLong conns, + AtomicLong subscribers, Reference ref, AtomicBoolean isAlive, String name) { @@ -704,11 +717,16 @@ final static class HttpClientTracker implements Tracker { this.websocketCount = ws; this.operationsCount = ops; this.connnectionsCount = conns; + this.subscribersCount = subscribers; this.reference = ref; this.isAlive = isAlive; this.name = name; } @Override + public long getOutstandingSubscribers() { + return subscribersCount.get(); + } + @Override public long getOutstandingOperations() { return operationsCount.get(); } @@ -748,6 +766,7 @@ public Tracker getOperationsTracker() { pendingWebSocketCount, pendingOperationCount, pendingTCPConnectionCount, + pendingSubscribersCount, facadeRef, isAlive, dbgTag); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java index f4b2600a599f0..734139d434ba4 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java @@ -357,8 +357,8 @@ private void registerResponseSubscriber(Http2StreamResponseSubscriber subscri client().registerSubscriber(subscriber); } - private void subscriberCompleted(Http2StreamResponseSubscriber subscriber) { - client().subscriberCompleted(subscriber); + private void unregisterResponseSubscriber(Http2StreamResponseSubscriber subscriber) { + client().unregisterSubscriber(subscriber); } @Override @@ -1661,11 +1661,15 @@ final class Http2StreamResponseSubscriber extends HttpBodySubscriberWrapper userSubscriber; final AtomicBoolean completed = new AtomicBoolean(); final AtomicBoolean subscribed = new AtomicBoolean(); - volatile Subscription subscription; + volatile SubscriptionWrapper subscription; volatile Throwable withError; public HttpBodySubscriberWrapper(BodySubscriber userSubscriber) { this.userSubscriber = userSubscriber; } + private class SubscriptionWrapper implements Subscription { + final Subscription subscription; + SubscriptionWrapper(Subscription s) { + this.subscription = Objects.requireNonNull(s); + } + @Override + public void request(long n) { + subscription.request(n); + } + + @Override + public void cancel() { + try { + subscription.cancel(); + onCancel(); + } catch (Throwable t) { + onError(t); + } + } + } + final long id() { return id; } @Override @@ -97,6 +119,14 @@ private void propagateError(Throwable t) { } } + /** + * Called when the subscriber cancels its subscription. + * @apiNote + * This method may be used by subclasses to perform cleanup + * actions after a subscription has been cancelled. + */ + protected void onCancel() { } + /** * Complete the subscriber, either normally or exceptionally * ensure that the subscriber is completed only once. @@ -137,12 +167,12 @@ public CompletionStage getBody() { @Override public void onSubscribe(Flow.Subscription subscription) { - this.subscription = subscription; // race condition with propagateError: we need to wait until // subscription is finished before calling onError; synchronized (this) { if (subscribed.compareAndSet(false, true)) { - userSubscriber.onSubscribe(subscription); + SubscriptionWrapper wrapped = new SubscriptionWrapper(subscription); + userSubscriber.onSubscribe(this.subscription = wrapped); } else { // could be already subscribed and completed // if an unexpected error occurred before the actual @@ -156,8 +186,9 @@ public void onSubscribe(Flow.Subscription subscription) { @Override public void onNext(List item) { if (completed.get()) { + SubscriptionWrapper subscription = this.subscription; if (subscription != null) { - subscription.cancel(); + subscription.subscription.cancel(); } } else { userSubscriber.onNext(item); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/OperationTrackers.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/OperationTrackers.java index e8a095cedef62..f65021492dea5 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/OperationTrackers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/OperationTrackers.java @@ -59,6 +59,8 @@ public interface Tracker { long getOutstandingWebSocketOperations(); // number of TCP connections still opened long getOutstandingTcpConnections(); + // number of body subscribers not yet completed or canceled + long getOutstandingSubscribers(); // Whether the facade returned to the // user is still referenced boolean isFacadeReferenced(); diff --git a/test/jdk/java/net/httpclient/CancelRequestTest.java b/test/jdk/java/net/httpclient/CancelRequestTest.java index 651c5d0c3130f..18ca970415811 100644 --- a/test/jdk/java/net/httpclient/CancelRequestTest.java +++ b/test/jdk/java/net/httpclient/CancelRequestTest.java @@ -54,6 +54,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.lang.ref.Reference; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.URI; @@ -377,6 +378,13 @@ public void testGetSendAsync(String uri, boolean sameClient, boolean mayInterrup assertEquals(cf2.isDone(), true); assertEquals(cf2.isCancelled(), false); assertEquals(latch.getCount(), 0); + + var error = TRACKER.check(1, + (t) -> t.getOutstandingOperations() > 0 || t.getOutstandingSubscribers() > 0, + "subscribers for testGetSendAsync(%s)\n\t step [%s]".formatted(req.uri(), i), + false); + Reference.reachabilityFence(client); + if (error != null) throw error; } } @@ -481,6 +489,13 @@ public Iterator iterator() { assertEquals(cf2.isDone(), true); assertEquals(cf2.isCancelled(), false); assertEquals(latch.getCount(), 0); + + var error = TRACKER.check(1, + (t) -> t.getOutstandingOperations() > 0 || t.getOutstandingSubscribers() > 0, + "subscribers for testPostSendAsync(%s)\n\t step [%s]".formatted(req.uri(), i), + false); + Reference.reachabilityFence(client); + if (error != null) throw error; } } @@ -536,6 +551,13 @@ public void testPostInterrupt(String uri, boolean sameClient) assertEquals(body, Stream.of(BODY.split("\\|")).collect(Collectors.joining())); throw failed; } + + var error = TRACKER.check(1, + (t) -> t.getOutstandingOperations() > 0 || t.getOutstandingSubscribers() > 0, + "subscribers for testPostInterrupt(%s)\n\t step [%s]".formatted(req.uri(), i), + false); + Reference.reachabilityFence(client); + if (error != null) throw error; } } diff --git a/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java b/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java new file mode 100644 index 0000000000000..1c608227640b8 --- /dev/null +++ b/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2022, 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. + */ + +/* + * @test + * @bug 8294916 + * @summary Tests that closing a streaming handler (ofInputStream()/ofLines()) + * without reading all the bytes unregisters the underlying subscriber. + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker CancelStreamedBodyTest + * @run testng/othervm -Djdk.internal.httpclient.debug=true + * CancelStreamedBodyTest + */ +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsServer; +import jdk.internal.net.http.common.OperationTrackers.Tracker; +import jdk.test.lib.RandomFactory; +import jdk.test.lib.net.SimpleSSLContext; +import org.testng.ITestContext; +import org.testng.ITestResult; +import org.testng.SkipException; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import javax.net.ssl.SSLContext; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.ref.Reference; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpConnectTimeoutException; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandler; +import java.net.http.HttpResponse.BodyHandlers; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; + +import static java.lang.System.arraycopy; +import static java.lang.System.out; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +public class CancelStreamedBodyTest implements HttpServerAdapters { + + SSLContext sslContext; + HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ] + HttpTestServer httpsTestServer; // HTTPS/1.1 + HttpTestServer http2TestServer; // HTTP/2 ( h2c ) + HttpTestServer https2TestServer; // HTTP/2 ( h2 ) + String httpURI; + String httpsURI; + String http2URI; + String https2URI; + + static final long SERVER_LATENCY = 75; + static final int ITERATION_COUNT = 3; + // a shared executor helps reduce the amount of threads created by the test + static final Executor executor = new TestExecutor(Executors.newCachedThreadPool()); + static final ConcurrentMap FAILURES = new ConcurrentHashMap<>(); + static volatile boolean tasksFailed; + static final AtomicLong serverCount = new AtomicLong(); + static final AtomicLong clientCount = new AtomicLong(); + static final long start = System.nanoTime(); + public static String now() { + long now = System.nanoTime() - start; + long secs = now / 1000_000_000; + long mill = (now % 1000_000_000) / 1000_000; + long nan = now % 1000_000; + return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan); + } + + final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE; + private volatile HttpClient sharedClient; + + static class TestExecutor implements Executor { + final AtomicLong tasks = new AtomicLong(); + Executor executor; + TestExecutor(Executor executor) { + this.executor = executor; + } + + @Override + public void execute(Runnable command) { + long id = tasks.incrementAndGet(); + executor.execute(() -> { + try { + command.run(); + } catch (Throwable t) { + tasksFailed = true; + System.out.printf(now() + "Task %s failed: %s%n", id, t); + System.err.printf(now() + "Task %s failed: %s%n", id, t); + FAILURES.putIfAbsent("Task " + id, t); + throw t; + } + }); + } + } + + protected boolean stopAfterFirstFailure() { + return Boolean.getBoolean("jdk.internal.httpclient.debug"); + } + + final AtomicReference skiptests = new AtomicReference<>(); + void checkSkip() { + var skip = skiptests.get(); + if (skip != null) throw skip; + } + static String name(ITestResult result) { + var params = result.getParameters(); + return result.getName() + + (params == null ? "()" : Arrays.toString(result.getParameters())); + } + + @BeforeMethod + void beforeMethod(ITestContext context) { + if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) { + if (skiptests.get() == null) { + SkipException skip = new SkipException("some tests failed"); + skip.setStackTrace(new StackTraceElement[0]); + skiptests.compareAndSet(null, skip); + } + } + } + + @AfterClass + static final void printFailedTests(ITestContext context) { + out.println("\n========================="); + var failed = context.getFailedTests().getAllResults().stream() + .collect(Collectors.toMap(r -> name(r), ITestResult::getThrowable)); + FAILURES.putAll(failed); + try { + out.printf("%n%sCreated %d servers and %d clients%n", + now(), serverCount.get(), clientCount.get()); + if (FAILURES.isEmpty()) return; + out.println("Failed tests: "); + FAILURES.entrySet().forEach((e) -> { + out.printf("\t%s: %s%n", e.getKey(), e.getValue()); + e.getValue().printStackTrace(out); + }); + if (tasksFailed) { + System.out.println("WARNING: Some tasks failed"); + } + } finally { + out.println("\n=========================\n"); + } + } + + private String[] uris() { + return new String[] { + httpURI, + httpsURI, + http2URI, + https2URI, + }; + } + + + @DataProvider(name = "urls") + public Object[][] alltests() { + String[] uris = uris(); + Object[][] result = new Object[uris.length * 2][]; + int i = 0; + for (boolean sameClient : List.of(false, true)) { + for (String uri : uris()) { + String path = sameClient ? "same" : "new"; + result[i++] = new Object[]{uri + path, sameClient}; + } + } + assert i == uris.length * 2; + return result; + } + + private HttpClient makeNewClient() { + clientCount.incrementAndGet(); + var client = HttpClient.newBuilder() + .proxy(HttpClient.Builder.NO_PROXY) + .executor(executor) + .sslContext(sslContext) + .build(); + // It is OK to even track the shared client here: + // the test methods will verify that the client has shut down + // only if it's not the shared client. + // Only the teardown() method verify that the shared client + // has shut down in this test. + return TRACKER.track(client); + } + + HttpClient newHttpClient(boolean share) { + if (!share) return makeNewClient(); + HttpClient shared = sharedClient; + if (shared != null) return shared; + synchronized (this) { + shared = sharedClient; + if (shared == null) { + shared = sharedClient = makeNewClient(); + } + return shared; + } + } + + final static String BODY = "Some string |\n that ?\n can |\n be split ?\n several |\n ways."; + + + @Test(dataProvider = "urls") + public void testAsLines(String uri, boolean sameClient) + throws Exception { + checkSkip(); + HttpClient client = null; + uri = uri + "/testAsLines"; + out.printf("%n%s testAsLines(%s, %b)%n", now(), uri, sameClient); + for (int i=0; i< ITERATION_COUNT; i++) { + if (!sameClient || client == null) + client = newHttpClient(sameClient); + var tracker = TRACKER.getTracker(client); + + HttpRequest req = HttpRequest.newBuilder(URI.create(uri)) + .GET() + .build(); + List lines; + for (int j = 0; j < 2; j++) { + try (Stream body = client.send(req, BodyHandlers.ofLines()).body()) { + lines = body.limit(j).toList(); + assertEquals(lines, BODY.replaceAll("\\||\\?", "") + .lines().limit(j).toList()); + } + // Only check our still alive client for outstanding operations + // and outstanding subscribers here: it should have none. + var error = TRACKER.check(tracker, 500, + (t) -> t.getOutstandingOperations() > 0 || t.getOutstandingSubscribers() > 0, + "subscribers for testAsLines(%s)\n\t step [%s,%s]".formatted(req.uri(), i,j), + false); + Reference.reachabilityFence(client); + if (error != null) throw error; + } + // The shared client is only shut down at the end. + // Skip shutdown check for the shared client. + if (sameClient) continue; + client = null; + System.gc(); + var error = TRACKER.check(tracker, 500); + if (error != null) throw error; + } + } + + @Test(dataProvider = "urls") + public void testInputStream(String uri, boolean sameClient) + throws Exception { + checkSkip(); + HttpClient client = null; + uri = uri + "/testInputStream"; + out.printf("%n%s testInputStream(%s, %b)%n", now(), uri, sameClient); + for (int i=0; i< ITERATION_COUNT; i++) { + if (!sameClient || client == null) + client = newHttpClient(sameClient); + var tracker = TRACKER.getTracker(client); + + HttpRequest req = HttpRequest.newBuilder(URI.create(uri)) + .GET() + .build(); + int read = -1; + for (int j = 0; j < 2; j++) { + try (InputStream is = client.send(req, BodyHandlers.ofInputStream()).body()) { + for (int k = 0; k < j; k++) { + read = is.read(); + assertEquals(read, BODY.charAt(k)); + } + } + // Only check our still alive client for outstanding operations + // and outstanding subscribers here: it should have none. + var error = TRACKER.check(tracker, 1, + (t) -> t.getOutstandingOperations() > 0 || t.getOutstandingSubscribers() > 0, + "subscribers for testInputStream(%s)\n\t step [%s,%s]".formatted(req.uri(), i,j), + false); + Reference.reachabilityFence(client); + if (error != null) throw error; + } + // The shared client is only shut down at the end. + // Skip shutdown check for the shared client. + if (sameClient) continue; + client = null; + System.gc(); + var error = TRACKER.check(tracker, 1); + if (error != null) throw error; + } + } + + + + @BeforeTest + public void setup() throws Exception { + sslContext = new SimpleSSLContext().get(); + if (sslContext == null) + throw new AssertionError("Unexpected null sslContext"); + + // HTTP/1.1 + HttpTestHandler h1_chunkHandler = new HTTPSlowHandler(); + InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); + httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer.addHandler(h1_chunkHandler, "/http1/x/"); + httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/x/"; + + HttpsServer httpsServer = HttpsServer.create(sa, 0); + httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer.addHandler(h1_chunkHandler, "/https1/x/"); + httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/x/"; + + // HTTP/2 + HttpTestHandler h2_chunkedHandler = new HTTPSlowHandler(); + + http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer.addHandler(h2_chunkedHandler, "/http2/x/"); + http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/x/"; + + https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer.addHandler(h2_chunkedHandler, "/https2/x/"); + https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/x/"; + + serverCount.addAndGet(4); + httpTestServer.start(); + httpsTestServer.start(); + http2TestServer.start(); + https2TestServer.start(); + } + + @AfterTest + public void teardown() throws Exception { + String sharedClientName = + sharedClient == null ? null : sharedClient.toString(); + sharedClient = null; + // check that the shared client (and any other client) have + // properly shut down + System.gc(); + Thread.sleep(100); + AssertionError fail = TRACKER.check(500); + try { + httpTestServer.stop(); + httpsTestServer.stop(); + http2TestServer.stop(); + https2TestServer.stop(); + } finally { + if (fail != null) { + if (sharedClientName != null) { + System.err.println("Shared client name is: " + sharedClientName); + } + throw fail; + } + } + } + + /** + * A handler that slowly sends back a body to give time for the + * the request to get cancelled before the body is fully received. + */ + static class HTTPSlowHandler implements HttpTestHandler { + @Override + public void handle(HttpTestExchange t) throws IOException { + try { + out.println("HTTPSlowHandler received request to " + t.getRequestURI()); + System.err.println("HTTPSlowHandler received request to " + t.getRequestURI()); + + byte[] req; + try (InputStream is = t.getRequestBody()) { + req = is.readAllBytes(); + } + + // we're not expecting a request body. + // if we receive any, pretend we're a teapot. + int status = req.length == 0 ? 200 : 418; + t.sendResponseHeaders(status, -1); // chunked/variable + try (OutputStream os = t.getResponseBody()) { + // lets split the response in several chunks... + String msg = (req != null && req.length != 0) + ? new String(req, UTF_8) + : BODY; + String[] str = msg.split("\\|"); + for (var s : str) { + req = s.getBytes(UTF_8); + os.write(req); + os.flush(); + out.printf("Server wrote %d bytes%n", req.length); + try { + Thread.sleep(SERVER_LATENCY); + } catch (InterruptedException x) { + // OK + } + } + } + } catch (Throwable e) { + out.println("HTTPSlowHandler: unexpected exception: " + e); + e.printStackTrace(); + throw e; + } finally { + out.printf("HTTPSlowHandler reply sent: %s%n", t.getRequestURI()); + System.err.printf("HTTPSlowHandler reply sent: %s%n", t.getRequestURI()); + } + } + } + +} diff --git a/test/jdk/java/net/httpclient/ReferenceTracker.java b/test/jdk/java/net/httpclient/ReferenceTracker.java index dc704fa81fd4d..68bfdd33e404b 100644 --- a/test/jdk/java/net/httpclient/ReferenceTracker.java +++ b/test/jdk/java/net/httpclient/ReferenceTracker.java @@ -31,6 +31,7 @@ import java.lang.management.ThreadInfo; import java.net.http.HttpClient; import java.util.Arrays; +import java.util.Objects; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -61,9 +62,14 @@ public StringBuilder diagnose(StringBuilder warnings) { return diagnose(warnings, (t) -> t.getOutstandingHttpOperations() > 0); } + public StringBuilder diagnose(Tracker tracker, StringBuilder warnings, Predicate hasOutstanding) { + checkOutstandingOperations(warnings, tracker, hasOutstanding); + return warnings; + } + public StringBuilder diagnose(StringBuilder warnings, Predicate hasOutstanding) { for (Tracker tracker : TRACKERS) { - checkOutstandingOperations(warnings, tracker, hasOutstanding); + diagnose(tracker, warnings, hasOutstanding); } return warnings; } @@ -72,6 +78,10 @@ public boolean hasOutstandingOperations() { return TRACKERS.stream().anyMatch(t -> t.getOutstandingOperations() > 0); } + public boolean hasOutstandingSubscribers() { + return TRACKERS.stream().anyMatch(t -> t.getOutstandingSubscribers() > 0); + } + public long getOutstandingOperationsCount() { return TRACKERS.stream() .map(Tracker::getOutstandingOperations) @@ -86,10 +96,24 @@ public long getOutstandingClientCount() { .count(); } + public AssertionError check(Tracker tracker, long graceDelayMs) { + Predicate hasOperations = (t) -> t.getOutstandingOperations() > 0; + Predicate hasSubscribers = (t) -> t.getOutstandingSubscribers() > 0; + return check(tracker, graceDelayMs, + hasOperations.or(hasSubscribers) + .or(Tracker::isFacadeReferenced) + .or(Tracker::isSelectorAlive), + "outstanding operations or unreleased resources", false); + } + public AssertionError check(long graceDelayMs) { + Predicate hasOperations = (t) -> t.getOutstandingOperations() > 0; + Predicate hasSubscribers = (t) -> t.getOutstandingSubscribers() > 0; return check(graceDelayMs, - (t) -> t.getOutstandingHttpOperations() > 0, - "outstanding operations", true); + hasOperations.or(hasSubscribers) + .or(Tracker::isFacadeReferenced) + .or(Tracker::isSelectorAlive), + "outstanding operations or unreleased resources", true); } // This method is copied from ThreadInfo::toString, but removes the @@ -173,6 +197,49 @@ private void printThreads(String why, PrintStream out) { .forEach(out::println); } + public Tracker getTracker(HttpClient client) { + return OperationTrackers.getTracker(Objects.requireNonNull(client)); + } + + public AssertionError check(Tracker tracker, + long graceDelayMs, + Predicate hasOutstanding, + String description, + boolean printThreads) { + AssertionError fail = null; + graceDelayMs = Math.max(graceDelayMs, 100); + long delay = Math.min(graceDelayMs, 10); + var count = delay > 0 ? graceDelayMs / delay : 1; + for (int i = 0; i < count; i++) { + if (hasOutstanding.test(tracker)) { + System.gc(); + try { + if (i == 0) { + System.out.println("Waiting for HTTP operations to terminate..."); + } + Thread.sleep(Math.min(graceDelayMs, Math.max(delay, 1))); + } catch (InterruptedException x) { + // OK + } + } else break; + } + if (hasOutstanding.test(tracker)) { + StringBuilder warnings = diagnose(tracker, new StringBuilder(), hasOutstanding); + if (hasOutstanding.test(tracker)) { + fail = new AssertionError(warnings.toString()); + } + } else { + System.out.println("PASSED: No " + description + " found in " + tracker.getName()); + } + if (fail != null) { + if (printThreads && tracker.isSelectorAlive()) { + printThreads("Some selector manager threads are still alive: ", System.out); + printThreads("Some selector manager threads are still alive: ", System.err); + } + } + return fail; + } + public AssertionError check(long graceDelayMs, Predicate hasOutstanding, String description, @@ -243,6 +310,7 @@ private static void checkOutstandingOperations(StringBuilder warning, warning.append("\n\tPending HTTP/2 streams: " + tracker.getOutstandingHttp2Streams()); warning.append("\n\tPending WebSocket operations: " + tracker.getOutstandingWebSocketOperations()); warning.append("\n\tPending TCP connections: " + tracker.getOutstandingTcpConnections()); + warning.append("\n\tPending Subscribers: " + tracker.getOutstandingSubscribers()); warning.append("\n\tTotal pending operations: " + tracker.getOutstandingOperations()); warning.append("\n\tFacade referenced: " + tracker.isFacadeReferenced()); warning.append("\n\tSelector alive: " + tracker.isSelectorAlive()); @@ -267,8 +335,11 @@ public AssertionError checkShutdown(long graceDelayMs) { Predicate isAlive = Tracker::isSelectorAlive; Predicate hasPendingRequests = (t) -> t.getOutstandingHttpRequests() > 0; Predicate hasPendingConnections = (t) -> t.getOutstandingTcpConnections() > 0; + Predicate hasPendingSubscribers = (t) -> t.getOutstandingSubscribers() > 0; AssertionError failed = check(graceDelayMs, - isAlive.or(hasPendingRequests).or(hasPendingConnections), + isAlive.or(hasPendingRequests) + .or(hasPendingConnections) + .or(hasPendingSubscribers), "outstanding unclosed resources", true); return failed; } diff --git a/test/jdk/java/net/httpclient/SmallTimeout.java b/test/jdk/java/net/httpclient/SmallTimeout.java index 91ffb3305c662..6515c38647e13 100644 --- a/test/jdk/java/net/httpclient/SmallTimeout.java +++ b/test/jdk/java/net/httpclient/SmallTimeout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -21,6 +21,8 @@ * questions. */ +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; @@ -35,6 +37,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + import static java.lang.System.out; /** @@ -79,6 +83,7 @@ static HttpResult of(HttpRequest request, Throwable t) { public static void main(String[] args) throws Exception { HttpClient client = HttpClient.newHttpClient(); ReferenceTracker.INSTANCE.track(client); + Reference reference = new WeakReference<>(client); Throwable failed = null; try (ServerSocket ss = new ServerSocket()) { @@ -151,10 +156,12 @@ public static void main(String[] args) throws Exception { .build(); final HttpRequest req = requests[i]; + executor.execute(() -> { Throwable cause = null; try { - HttpResponse r = client.send(req, BodyHandlers.replacing(null)); + HttpClient httpClient = reference.get(); + HttpResponse r = httpClient.send(req, BodyHandlers.replacing(null)); out.println("Unexpected success for r" + n +": " + r); } catch (HttpTimeoutException e) { out.println("Caught expected timeout for r" + n +": " + e); @@ -173,7 +180,31 @@ public static void main(String[] args) throws Exception { checkReturn(requests); - executor.shutdownNow(); + // shuts down the executor and awaits its termination + //executor.close(); + // In 17, ExecutorService does not implement close(). + // I derived this from the implementation of the method + // in 21. + { + boolean terminated = executor.isTerminated(); + if (!terminated) { + executor.shutdown(); + boolean interrupted = false; + while (!terminated) { + try { + terminated = executor.awaitTermination(1L, TimeUnit.DAYS); + } catch (InterruptedException e) { + if (!interrupted) { + executor.shutdownNow(); + interrupted = true; + } + } + } + if (interrupted) { + Thread.currentThread().interrupt(); + } + } + } if (error) throw new RuntimeException("Failed. Check output"); @@ -182,8 +213,11 @@ public static void main(String[] args) throws Exception { failed = t; throw t; } finally { + Reference.reachabilityFence(client); + client = null; + System.gc(); try { - Thread.sleep(100); + Thread.sleep(10); } catch (InterruptedException t) { // ignore; } From a797cccbce1a131596ab64a790af2a5796168795 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 25 Jun 2025 09:12:59 +0000 Subject: [PATCH 345/846] 8297149: REDO JDK-8296889: Race condition when cancelling a request 8297075: java/net/httpclient/CancelStreamedBodyTest.java fails with "java.lang.AssertionError: WARNING: tracker for HttpClientImpl(1) has outstanding operations" Backport-of: 134acab5a40b3f927ff6343aa49477a490e410b5 --- .../jdk/internal/net/http/Http1Exchange.java | 6 +++- .../classes/jdk/internal/net/http/Stream.java | 10 ++++-- .../common/HttpBodySubscriberWrapper.java | 31 ++++++++++++++----- .../net/httpclient/CancelRequestTest.java | 2 +- .../httpclient/CancelStreamedBodyTest.java | 2 +- 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java index d308718efbfea..02461893d00ee 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java @@ -208,6 +208,11 @@ static final class Http1ResponseBodySubscriber extends HttpBodySubscriberWrap this.exchange = exchange; } + @Override + protected void onSubscribed() { + exchange.registerResponseSubscriber(this); + } + @Override protected void complete(Throwable t) { try { @@ -459,7 +464,6 @@ Http1ResponseBodySubscriber createResponseSubscriber(BodyHandler handler, BodySubscriber subscriber = handler.apply(response); Http1ResponseBodySubscriber bs = new Http1ResponseBodySubscriber(subscriber, this); - registerResponseSubscriber(bs); return bs; } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java index 734139d434ba4..da080709a0328 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java @@ -346,7 +346,6 @@ CompletableFuture readBodyAsync(HttpResponse.BodyHandler handler, Http2StreamResponseSubscriber createResponseSubscriber(BodyHandler handler, ResponseInfo response) { Http2StreamResponseSubscriber subscriber = new Http2StreamResponseSubscriber<>(handler.apply(response)); - registerResponseSubscriber(subscriber); return subscriber; } @@ -1658,17 +1657,22 @@ final class Http2StreamResponseSubscriber extends HttpBodySubscriberWrapper userSubscriber; final AtomicBoolean completed = new AtomicBoolean(); final AtomicBoolean subscribed = new AtomicBoolean(); + final ReentrantLock subscriptionLock = new ReentrantLock(); volatile SubscriptionWrapper subscription; volatile Throwable withError; public HttpBodySubscriberWrapper(BodySubscriber userSubscriber) { @@ -100,16 +103,20 @@ public boolean needsExecutor() { // subscribed yet. private void propagateError(Throwable t) { assert t != null; + assert completed.get(); try { // if unsubscribed at this point, it will not // get subscribed later - so do it now and // propagate the error // Race condition with onSubscribe: we need to wait until // subscription is finished before calling onError; - synchronized (this) { + subscriptionLock.lock(); + try { if (subscribed.compareAndSet(false, true)) { userSubscriber.onSubscribe(NOP); } + } finally { + subscriptionLock.unlock(); } } finally { // if onError throws then there is nothing to do @@ -127,6 +134,15 @@ private void propagateError(Throwable t) { */ protected void onCancel() { } + /** + * Called right before the userSubscriber::onSubscribe is called. + * @apiNote + * This method may be used by subclasses to perform cleanup + * related actions after a subscription has been succesfully + * accepted. + */ + protected void onSubscribed() { } + /** * Complete the subscriber, either normally or exceptionally * ensure that the subscriber is completed only once. @@ -169,22 +185,23 @@ public CompletionStage getBody() { public void onSubscribe(Flow.Subscription subscription) { // race condition with propagateError: we need to wait until // subscription is finished before calling onError; - synchronized (this) { + subscriptionLock.lock(); + try { if (subscribed.compareAndSet(false, true)) { + onSubscribed(); SubscriptionWrapper wrapped = new SubscriptionWrapper(subscription); userSubscriber.onSubscribe(this.subscription = wrapped); } else { - // could be already subscribed and completed - // if an unexpected error occurred before the actual - // subscription - though that's not supposed - // happen. - assert completed.get(); + subscription.cancel(); } + } finally { + subscriptionLock.unlock(); } } @Override public void onNext(List item) { + assert subscribed.get(); if (completed.get()) { SubscriptionWrapper subscription = this.subscription; if (subscription != null) { diff --git a/test/jdk/java/net/httpclient/CancelRequestTest.java b/test/jdk/java/net/httpclient/CancelRequestTest.java index 18ca970415811..54fd07d0b0ecb 100644 --- a/test/jdk/java/net/httpclient/CancelRequestTest.java +++ b/test/jdk/java/net/httpclient/CancelRequestTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8245462 8229822 8254786 + * @bug 8245462 8229822 8254786 8297075 8297149 * @summary Tests cancelling the request. * @library /test/lib /test/jdk/java/net/httpclient/lib * @key randomness diff --git a/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java b/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java index 1c608227640b8..99a773a042ac7 100644 --- a/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java +++ b/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8294916 + * @bug 8294916 8297075 8297149 * @summary Tests that closing a streaming handler (ofInputStream()/ofLines()) * without reading all the bytes unregisters the underlying subscriber. * @library /test/lib /test/jdk/java/net/httpclient/lib From 62adc0dd6f7e06c704cefc9847123caa4712793e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 25 Jun 2025 09:13:56 +0000 Subject: [PATCH 346/846] 8313367: SunMSCAPI cannot read Local Computer certs w/o Windows elevation Backport-of: db535c86bc56b89b7213b3b097d80935fe9e8516 --- .../windows/native/libsunmscapi/security.cpp | 12 ++++++--- test/jdk/sun/security/mscapi/AllTypes.java | 27 +++---------------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp b/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp index 82e6f2cc5bd7d..f7685982abe50 100644 --- a/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp +++ b/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -444,7 +444,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC } else if (jCertStoreLocation == KEYSTORE_LOCATION_LOCALMACHINE) { hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, NULL, - CERT_SYSTEM_STORE_LOCAL_MACHINE, pszCertStoreName); + CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_MAXIMUM_ALLOWED_FLAG, pszCertStoreName); } else { PP("jCertStoreLocation is not a valid value"); @@ -792,11 +792,15 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_signHash ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER, //deprecated (BYTE *)pbData, &cbData, 0); + DWORD keysetType = 0; + DWORD keysetTypeLen = sizeof(keysetType); + ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_KEYSET_TYPE, //deprecated + (BYTE*)&keysetType, &keysetTypeLen, 0); + // Acquire an alternative CSP handle if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL, //deprecated - PROV_RSA_AES, 0) == FALSE) + PROV_RSA_AES, 0 | keysetType) == FALSE) { - ThrowException(env, SIGNATURE_EXCEPTION, GetLastError()); __leave; } diff --git a/test/jdk/sun/security/mscapi/AllTypes.java b/test/jdk/sun/security/mscapi/AllTypes.java index f9c9886070258..9f5fb2f13d69d 100644 --- a/test/jdk/sun/security/mscapi/AllTypes.java +++ b/test/jdk/sun/security/mscapi/AllTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,33 +45,12 @@ public static void main(String[] args) throws Exception { var nr = test("windows-root"); var nmu = test("windows-my-currentuser"); var nru = test("windows-root-currentuser"); - var hasAdminPrivileges = detectIfRunningWithAdminPrivileges(); - var nmm = adminTest("windows-my-localmachine", hasAdminPrivileges); - var nrm = adminTest("windows-root-localmachine", hasAdminPrivileges); + var nmm = test("windows-my-localmachine"); + var nrm = test("windows-root-localmachine"); Asserts.assertEQ(nm, nmu); Asserts.assertEQ(nr, nru); } - private static boolean detectIfRunningWithAdminPrivileges() { - try { - Process p = Runtime.getRuntime().exec("reg query \"HKU\\S-1-5-19\""); - p.waitFor(); - return (p.exitValue() == 0); - } - catch (Exception ex) { - System.out.println("Warning: unable to detect admin privileges, assuming none"); - return false; - } - } - - private static List adminTest(String type, boolean hasAdminPrivileges) throws Exception { - if (hasAdminPrivileges) { - return test(type); - } - System.out.println("Ignoring: " + type + " as it requires admin privileges"); - return null; - } - private static List test(String type) throws Exception { var stdType = "Windows-" + type.substring(8).toUpperCase(Locale.ROOT); SecurityTools.keytool("-storetype " + type + " -list") From e21340398b5aaadc79a93ae612d080b9782d564d Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 25 Jun 2025 09:16:16 +0000 Subject: [PATCH 347/846] 8345471: Clean up compiler/intrinsics/sha/cli tests Backport-of: dfa0f73ea49115c79da3b46abcaeff3bd834f2ce --- ...seMD5IntrinsicsOptionOnUnsupportedCPU.java | 13 +- ...eSHA1IntrinsicsOptionOnUnsupportedCPU.java | 15 +-- ...HA256IntrinsicsOptionOnUnsupportedCPU.java | 15 +-- ...eSHA3IntrinsicsOptionOnUnsupportedCPU.java | 10 +- ...HA512IntrinsicsOptionOnUnsupportedCPU.java | 15 +-- .../cli/TestUseSHAOptionOnUnsupportedCPU.java | 15 +-- .../testcases/GenericTestCaseForOtherCPU.java | 106 ---------------- ... => GenericTestCaseForUnsupportedCPU.java} | 18 +-- ...nericTestCaseForUnsupportedRISCV64CPU.java | 115 ------------------ .../GenericTestCaseForUnsupportedX86CPU.java | 110 ----------------- 10 files changed, 26 insertions(+), 406 deletions(-) delete mode 100644 test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java rename test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/{GenericTestCaseForUnsupportedAArch64CPU.java => GenericTestCaseForUnsupportedCPU.java} (88%) delete mode 100644 test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedRISCV64CPU.java delete mode 100644 test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseMD5IntrinsicsOptionOnUnsupportedCPU.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseMD5IntrinsicsOptionOnUnsupportedCPU.java index e9ae2f6c1634d..0b973b61672dc 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseMD5IntrinsicsOptionOnUnsupportedCPU.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseMD5IntrinsicsOptionOnUnsupportedCPU.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,19 +37,12 @@ package compiler.intrinsics.sha.cli; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForOtherCPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedAArch64CPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedX86CPU; -import compiler.intrinsics.sha.cli.testcases.UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU; +import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedCPU; public class TestUseMD5IntrinsicsOptionOnUnsupportedCPU { public static void main(String args[]) throws Throwable { new DigestOptionsBase( - new GenericTestCaseForUnsupportedX86CPU( - DigestOptionsBase.USE_MD5_INTRINSICS_OPTION, /* checkUseSHA = */ false), - new GenericTestCaseForUnsupportedAArch64CPU( - DigestOptionsBase.USE_MD5_INTRINSICS_OPTION, /* checkUseSHA = */ false), - new GenericTestCaseForOtherCPU( + new GenericTestCaseForUnsupportedCPU( DigestOptionsBase.USE_MD5_INTRINSICS_OPTION, /* checkUseSHA = */ false)).test(); } } diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java index 740fd142da0e4..dd7437ee86a87 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,24 +37,15 @@ package compiler.intrinsics.sha.cli; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForOtherCPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedAArch64CPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedRISCV64CPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedX86CPU; +import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedCPU; import compiler.intrinsics.sha.cli.testcases.UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU; public class TestUseSHA1IntrinsicsOptionOnUnsupportedCPU { public static void main(String args[]) throws Throwable { new DigestOptionsBase( - new GenericTestCaseForUnsupportedX86CPU( - DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION), - new GenericTestCaseForUnsupportedAArch64CPU( - DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION), - new GenericTestCaseForUnsupportedRISCV64CPU( + new GenericTestCaseForUnsupportedCPU( DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION), new UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU( - DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION), - new GenericTestCaseForOtherCPU( DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION)).test(); } } diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java index 4111df5f01b9a..8c4ac6b886021 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,24 +37,15 @@ package compiler.intrinsics.sha.cli; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForOtherCPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedAArch64CPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedRISCV64CPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedX86CPU; +import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedCPU; import compiler.intrinsics.sha.cli.testcases.UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU; public class TestUseSHA256IntrinsicsOptionOnUnsupportedCPU { public static void main(String args[]) throws Throwable { new DigestOptionsBase( - new GenericTestCaseForUnsupportedX86CPU( - DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION), - new GenericTestCaseForUnsupportedAArch64CPU( - DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION), - new GenericTestCaseForUnsupportedRISCV64CPU( + new GenericTestCaseForUnsupportedCPU( DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION), new UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU( - DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION), - new GenericTestCaseForOtherCPU( DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION)).test(); } } diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA3IntrinsicsOptionOnUnsupportedCPU.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA3IntrinsicsOptionOnUnsupportedCPU.java index b3f4054b565af..633ceb1d9ab74 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA3IntrinsicsOptionOnUnsupportedCPU.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA3IntrinsicsOptionOnUnsupportedCPU.java @@ -38,21 +38,15 @@ package compiler.intrinsics.sha.cli; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForOtherCPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedAArch64CPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedX86CPU; +import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedCPU; import compiler.intrinsics.sha.cli.testcases.UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU; public class TestUseSHA3IntrinsicsOptionOnUnsupportedCPU { public static void main(String args[]) throws Throwable { new DigestOptionsBase( - new GenericTestCaseForUnsupportedX86CPU( - DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION), - new GenericTestCaseForUnsupportedAArch64CPU( + new GenericTestCaseForUnsupportedCPU( DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION), new UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU( - DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION), - new GenericTestCaseForOtherCPU( DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION)).test(); } } diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java index cc5704f32c713..f7e34e54febf8 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,24 +37,15 @@ package compiler.intrinsics.sha.cli; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForOtherCPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedAArch64CPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedRISCV64CPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedX86CPU; +import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedCPU; import compiler.intrinsics.sha.cli.testcases.UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU; public class TestUseSHA512IntrinsicsOptionOnUnsupportedCPU { public static void main(String args[]) throws Throwable { new DigestOptionsBase( - new GenericTestCaseForUnsupportedX86CPU( - DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION), - new GenericTestCaseForUnsupportedAArch64CPU( - DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION), - new GenericTestCaseForUnsupportedRISCV64CPU( + new GenericTestCaseForUnsupportedCPU( DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION), new UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU( - DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION), - new GenericTestCaseForOtherCPU( DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION)).test(); } } diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java index 20e45a0dd35a6..12085cc4915ea 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,24 +37,15 @@ package compiler.intrinsics.sha.cli; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForOtherCPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedAArch64CPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedRISCV64CPU; -import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedX86CPU; +import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedCPU; import compiler.intrinsics.sha.cli.testcases.UseSHASpecificTestCaseForUnsupportedCPU; public class TestUseSHAOptionOnUnsupportedCPU { public static void main(String args[]) throws Throwable { new DigestOptionsBase( - new GenericTestCaseForUnsupportedX86CPU( - DigestOptionsBase.USE_SHA_OPTION), - new GenericTestCaseForUnsupportedAArch64CPU( - DigestOptionsBase.USE_SHA_OPTION), - new GenericTestCaseForUnsupportedRISCV64CPU( + new GenericTestCaseForUnsupportedCPU( DigestOptionsBase.USE_SHA_OPTION), new UseSHASpecificTestCaseForUnsupportedCPU( - DigestOptionsBase.USE_SHA_OPTION), - new GenericTestCaseForOtherCPU( DigestOptionsBase.USE_SHA_OPTION)).test(); } } diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java deleted file mode 100644 index 468cd83d7a288..0000000000000 --- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2014, 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. - */ - -package compiler.intrinsics.sha.cli.testcases; - -import compiler.intrinsics.sha.cli.DigestOptionsBase; -import jdk.test.lib.process.ExitCode; -import jdk.test.lib.Platform; -import jdk.test.lib.cli.CommandLineOptionTest; -import jdk.test.lib.cli.predicate.NotPredicate; -import jdk.test.lib.cli.predicate.OrPredicate; - -/** - * Generic test case for SHA-related options targeted to any CPU except - * AArch64, RISCV64, PPC, S390x, and X86. - */ -public class GenericTestCaseForOtherCPU extends - DigestOptionsBase.TestCase { - - final private boolean checkUseSHA; - - public GenericTestCaseForOtherCPU(String optionName) { - this(optionName, true); - } - - public GenericTestCaseForOtherCPU(String optionName, boolean checkUseSHA) { - // Execute the test case on any CPU except AArch64, RISCV64, PPC, S390x, and X86. - super(optionName, new NotPredicate( - new OrPredicate(Platform::isAArch64, - new OrPredicate(Platform::isRISCV64, - new OrPredicate(Platform::isS390x, - new OrPredicate(Platform::isPPC, - new OrPredicate(Platform::isX64, - Platform::isX86))))))); - - this.checkUseSHA = checkUseSHA; - } - - @Override - protected void verifyWarnings() throws Throwable { - String shouldPassMessage = String.format("JVM should start with " - + "option '%s' without any warnings", optionName); - // Verify that on non-x86, non-RISCV64 and non-AArch64 CPU usage of SHA-related - // options will not cause any warnings. - CommandLineOptionTest.verifySameJVMStartup(null, - new String[] { ".*" + optionName + ".*" }, shouldPassMessage, - shouldPassMessage, ExitCode.OK, - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, - CommandLineOptionTest.prepareBooleanFlag(optionName, true)); - - CommandLineOptionTest.verifySameJVMStartup(null, - new String[] { ".*" + optionName + ".*" }, shouldPassMessage, - shouldPassMessage, ExitCode.OK, - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, - CommandLineOptionTest.prepareBooleanFlag(optionName, false)); - } - - @Override - protected void verifyOptionValues() throws Throwable { - // Verify that option is disabled by default. - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", - String.format("Option '%s' should be disabled by default", - optionName), - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS); - - // Verify that option is disabled even if it was explicitly enabled - // using CLI options. - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", - String.format("Option '%s' should be off on unsupported " - + "CPU even if set to true directly", optionName), - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, - CommandLineOptionTest.prepareBooleanFlag(optionName, true)); - - if (checkUseSHA) { - // Verify that option is disabled when it explicitly disabled - // using CLI options. - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", - String.format("Option '%s' should be off on unsupported CPU" - + " even if '%s' flag set to JVM", optionName, - CommandLineOptionTest.prepareBooleanFlag( - DigestOptionsBase.USE_SHA_OPTION, true)), - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, - CommandLineOptionTest.prepareBooleanFlag(optionName, false)); - } - } -} diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedAArch64CPU.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedCPU.java similarity index 88% rename from test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedAArch64CPU.java rename to test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedCPU.java index 4a257c74fc493..8df27030446bb 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedAArch64CPU.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedCPU.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,22 +31,22 @@ import jdk.test.lib.cli.predicate.NotPredicate; /** - * Generic test case for SHA-related options targeted to AArch64 CPUs + * Generic test case for SHA-related options targeted to CPUs * which don't support instruction required by the tested option. */ -public class GenericTestCaseForUnsupportedAArch64CPU extends +public class GenericTestCaseForUnsupportedCPU extends DigestOptionsBase.TestCase { final private boolean checkUseSHA; - public GenericTestCaseForUnsupportedAArch64CPU(String optionName) { + public GenericTestCaseForUnsupportedCPU(String optionName) { this(optionName, true); } - public GenericTestCaseForUnsupportedAArch64CPU(String optionName, boolean checkUseSHA) { - super(optionName, new AndPredicate(Platform::isAArch64, + public GenericTestCaseForUnsupportedCPU(String optionName, boolean checkUseSHA) { + super(optionName, new NotPredicate(DigestOptionsBase.getPredicateForOption( - optionName)))); + optionName))); this.checkUseSHA = checkUseSHA; } @@ -95,7 +95,7 @@ protected void verifyOptionValues() throws Throwable { // using CLI options. CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", String.format("Option '%s' should be off on unsupported " - + "AArch64CPU even if set to true directly", optionName), + + "CPU even if set to true directly", optionName), DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, CommandLineOptionTest.prepareBooleanFlag(optionName, true)); @@ -103,7 +103,7 @@ protected void verifyOptionValues() throws Throwable { // Verify that option is disabled when +UseSHA was passed to JVM. CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", String.format("Option '%s' should be off on unsupported " - + "AArch64CPU even if %s flag set to JVM", + + "CPU even if %s flag set to JVM", optionName, CommandLineOptionTest.prepareBooleanFlag( DigestOptionsBase.USE_SHA_OPTION, true)), DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedRISCV64CPU.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedRISCV64CPU.java deleted file mode 100644 index 2ecfec07a4ca5..0000000000000 --- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedRISCV64CPU.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. 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 compiler.intrinsics.sha.cli.testcases; - -import compiler.intrinsics.sha.cli.DigestOptionsBase; -import jdk.test.lib.process.ExitCode; -import jdk.test.lib.Platform; -import jdk.test.lib.cli.CommandLineOptionTest; -import jdk.test.lib.cli.predicate.AndPredicate; -import jdk.test.lib.cli.predicate.NotPredicate; - -/** - * Generic test case for SHA-related options targeted to RISCV64 CPUs - * which don't support instruction required by the tested option. - */ -public class GenericTestCaseForUnsupportedRISCV64CPU extends - DigestOptionsBase.TestCase { - - final private boolean checkUseSHA; - - public GenericTestCaseForUnsupportedRISCV64CPU(String optionName) { - this(optionName, true); - } - - public GenericTestCaseForUnsupportedRISCV64CPU(String optionName, boolean checkUseSHA) { - super(optionName, new AndPredicate(Platform::isRISCV64, - new NotPredicate(DigestOptionsBase.getPredicateForOption( - optionName)))); - - this.checkUseSHA = checkUseSHA; - } - - @Override - protected void verifyWarnings() throws Throwable { - String shouldPassMessage = String.format("JVM startup should pass with" - + "option '-XX:-%s' without any warnings", optionName); - //Verify that option could be disabled without any warnings. - CommandLineOptionTest.verifySameJVMStartup(null, new String[] { - DigestOptionsBase.getWarningForUnsupportedCPU(optionName) - }, shouldPassMessage, shouldPassMessage, ExitCode.OK, - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, - CommandLineOptionTest.prepareBooleanFlag(optionName, false)); - - if (checkUseSHA) { - shouldPassMessage = String.format("If JVM is started with '-XX:-" - + "%s' '-XX:+%s', output should contain warning.", - DigestOptionsBase.USE_SHA_OPTION, optionName); - - // Verify that when the tested option is enabled, then - // a warning will occur in VM output if UseSHA is disabled. - if (!optionName.equals(DigestOptionsBase.USE_SHA_OPTION)) { - CommandLineOptionTest.verifySameJVMStartup( - new String[] { DigestOptionsBase.getWarningForUnsupportedCPU(optionName) }, - null, - shouldPassMessage, - shouldPassMessage, - ExitCode.OK, - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, - CommandLineOptionTest.prepareBooleanFlag(DigestOptionsBase.USE_SHA_OPTION, false), - CommandLineOptionTest.prepareBooleanFlag(optionName, true)); - } - } - } - - @Override - protected void verifyOptionValues() throws Throwable { - // Verify that option is disabled by default. - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", - String.format("Option '%s' should be disabled by default", - optionName), - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS); - - if (checkUseSHA) { - // Verify that option is disabled even if it was explicitly enabled - // using CLI options. - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", - String.format("Option '%s' should be off on unsupported " - + "RISCV64CPU even if set to true directly", optionName), - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, - CommandLineOptionTest.prepareBooleanFlag(optionName, true)); - - // Verify that option is disabled when +UseSHA was passed to JVM. - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", - String.format("Option '%s' should be off on unsupported " - + "RISCV64CPU even if %s flag set to JVM", - optionName, CommandLineOptionTest.prepareBooleanFlag( - DigestOptionsBase.USE_SHA_OPTION, true)), - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, - CommandLineOptionTest.prepareBooleanFlag( - DigestOptionsBase.USE_SHA_OPTION, true)); - } - } -} diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java deleted file mode 100644 index 27548dd0e277e..0000000000000 --- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2014, 2020, 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 compiler.intrinsics.sha.cli.testcases; - -import compiler.intrinsics.sha.cli.DigestOptionsBase; -import jdk.test.lib.process.ExitCode; -import jdk.test.lib.Platform; -import jdk.test.lib.cli.CommandLineOptionTest; -import jdk.test.lib.cli.predicate.AndPredicate; -import jdk.test.lib.cli.predicate.NotPredicate; -import jdk.test.lib.cli.predicate.OrPredicate; - -/** - * Generic test case for SHA-related options targeted to X86 CPUs that don't - * support SHA-related instructions. - */ -public class GenericTestCaseForUnsupportedX86CPU - extends DigestOptionsBase.TestCase { - - final private boolean checkUseSHA; - - public GenericTestCaseForUnsupportedX86CPU(String optionName) { - this(optionName, true); - } - - public GenericTestCaseForUnsupportedX86CPU(String optionName, boolean checkUseSHA) { - super(optionName, new AndPredicate(new OrPredicate(Platform::isX64, Platform::isX86), - new NotPredicate(DigestOptionsBase.getPredicateForOption( - optionName)))); - - this.checkUseSHA = checkUseSHA; - } - - @Override - protected void verifyWarnings() throws Throwable { - String shouldPassMessage = String.format("JVM should start with '-XX:-%s' " - + "flag without any warnings", optionName); - // Verify that the tested option could be explicitly disabled without - // a warning. - CommandLineOptionTest.verifySameJVMStartup(null, new String[] { - DigestOptionsBase.getWarningForUnsupportedCPU(optionName) - }, shouldPassMessage, shouldPassMessage, ExitCode.OK, - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, - CommandLineOptionTest.prepareBooleanFlag(optionName, false)); - - // Verify that when the tested option is enabled, then - // a warning will occur in VM output if UseSHA is disabled. - if (checkUseSHA && !optionName.equals(DigestOptionsBase.USE_SHA_OPTION)) { - CommandLineOptionTest.verifySameJVMStartup( - new String[] { DigestOptionsBase.getWarningForUnsupportedCPU(optionName) }, - null, - shouldPassMessage, - shouldPassMessage, - ExitCode.OK, - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, - CommandLineOptionTest.prepareBooleanFlag(DigestOptionsBase.USE_SHA_OPTION, false), - CommandLineOptionTest.prepareBooleanFlag(optionName, true)); - } - } - - @Override - protected void verifyOptionValues() throws Throwable { - // Verify that the tested option is disabled by default. - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", - String.format("Option '%s' should be disabled by default", - optionName), - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS); - - // Verify that it is not possible to explicitly enable the option. - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", - String.format("Option '%s' should be off on unsupported " - + "X86CPU even if set to true directly", optionName), - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, - CommandLineOptionTest.prepareBooleanFlag(optionName, true)); - - if (checkUseSHA) { - // Verify that the tested option is disabled even if +UseSHA was passed - // to JVM. - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", - String.format("Option '%s' should be off on unsupported " - + "X86CPU even if %s flag set to JVM", - optionName, CommandLineOptionTest.prepareBooleanFlag( - DigestOptionsBase.USE_SHA_OPTION, true)), - DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS, - CommandLineOptionTest.prepareBooleanFlag( - DigestOptionsBase.USE_SHA_OPTION, true)); - } - } -} From 34f76e39b4ed9984e157c932d8145f7adfeeed98 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 25 Jun 2025 09:17:28 +0000 Subject: [PATCH 348/846] 8344671: Few JFR streaming tests fail with application not alive error on MacOS 15 Backport-of: 12edcff1fcf19955de67d8d34e03f080ed905db6 --- .../sun/tools/attach/VirtualMachineImpl.java | 19 ++++--- .../native/libattach/VirtualMachineImpl.c | 51 +++++++++++++++++-- 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java b/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java index 5c49e14f88292..2c9d7a5d84de5 100644 --- a/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java @@ -74,13 +74,15 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { if (!socket_file.exists()) { File f = createAttachFile(pid); try { - sendQuitTo(pid); + checkCatchesAndSendQuitTo(pid, false); // give the target VM time to start the attach mechanism final int delay_step = 100; final long timeout = attachTimeout(); - long time_spend = 0; + long time_spent = 0; long delay = 0; + + boolean timedout = false; do { // Increase timeout on each attempt to reduce polling delay += delay_step; @@ -88,18 +90,19 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { Thread.sleep(delay); } catch (InterruptedException x) { } - time_spend += delay; - if (time_spend > timeout/2 && !socket_file.exists()) { + timedout = (time_spent += delay) > timeout; + + if (time_spent > timeout/2 && !socket_file.exists()) { // Send QUIT again to give target VM the last chance to react - sendQuitTo(pid); + checkCatchesAndSendQuitTo(pid, !timedout); } - } while (time_spend <= timeout && !socket_file.exists()); + } while (!timedout && !socket_file.exists()); if (!socket_file.exists()) { throw new AttachNotSupportedException( String.format("Unable to open socket file %s: " + "target process %d doesn't respond within %dms " + "or HotSpot VM not loaded", socket_path, - pid, time_spend)); + pid, time_spent)); } } finally { f.delete(); @@ -296,7 +299,7 @@ private File createAttachFile(int pid) throws IOException { //-- native methods - static native void sendQuitTo(int pid) throws IOException; + static native boolean checkCatchesAndSendQuitTo(int pid, boolean throwIfNotReady) throws IOException, AttachNotSupportedException; static native void checkPermissions(String path) throws IOException; diff --git a/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c b/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c index d20a6f012f20b..2d960fba72ce5 100644 --- a/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c +++ b/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c @@ -28,11 +28,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -116,15 +118,54 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_connect /* * Class: sun_tools_attach_VirtualMachineImpl - * Method: sendQuitTo + * Method: checkCatchesAndSendQuitTo * Signature: (I)V */ -JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_sendQuitTo - (JNIEnv *env, jclass cls, jint pid) +JNIEXPORT jboolean JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkCatchesAndSendQuitTo + (JNIEnv *env, jclass cls, jint pid, jboolean throwIfNotReady) { - if (kill((pid_t)pid, SIGQUIT)) { - JNU_ThrowIOExceptionWithLastError(env, "kill"); + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid }; + + struct kinfo_proc kiproc; + size_t kipsz = sizeof(struct kinfo_proc); + + /* + * Early in the lifetime of a JVM it has not yet initialized its signal handlers, in particular the QUIT + * handler, note that the default behavior of QUIT is to terminate the receiving process, if unhandled. + * + * Since we use QUIT to initiate an attach operation, if we signal a JVM during this period early in its + * lifetime before it has initialized its QUIT handler, such a signal delivery will terminate the JVM we + * are attempting to attach to! + * + * The following code guards the QUIT delivery by testing the current signal masks. It is okay to send QUIT + * if the signal is caught but not ignored, as that implies a handler has been installed. + */ + + if (sysctl(mib, sizeof(mib) / sizeof(int), &kiproc, &kipsz, NULL, 0) == 0) { + const bool ignored = (kiproc.kp_proc.p_sigignore & sigmask(SIGQUIT)) != 0; + const bool caught = (kiproc.kp_proc.p_sigcatch & sigmask(SIGQUIT)) != 0; + + // note: obviously the masks could change between testing and signalling however this is not the + // observed behavior of the current JVM implementation. + + if (caught && !ignored) { + if (kill((pid_t)pid, SIGQUIT) != 0) { + JNU_ThrowIOExceptionWithLastError(env, "kill"); + } else { + return JNI_TRUE; + } + } else if (throwIfNotReady) { + char msg[100]; + + snprintf(msg, sizeof(msg), "pid: %d, state is not ready to participate in attach handshake!", (int)pid); + + JNU_ThrowByName(env, "com/sun/tools/attach/AttachNotSupportedException", msg); + } + } else { + JNU_ThrowIOExceptionWithLastError(env, "sysctl"); } + + return JNI_FALSE; } /* From cd08601f2036d92427caec7eac96cea16ddcbbba Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 25 Jun 2025 15:43:35 +0000 Subject: [PATCH 349/846] 8358538: Update GHA Windows runner to 2025 8360042: GHA: Bump MSVC to 14.44 Reviewed-by: phh Backport-of: b787ff6def08a050b690b60e4a0ceb3aec2b73c8 --- .github/workflows/build-windows.yml | 6 +++--- .github/workflows/main.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 8e2c0c8e63c14..6b8f084394097 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -63,7 +63,7 @@ env: jobs: build-windows: name: build - runs-on: windows-2019 + runs-on: windows-2025 defaults: run: shell: bash @@ -102,7 +102,7 @@ jobs: id: toolchain-check run: | set +e - '/c/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/vc/auxiliary/build/vcvars64.bat' -vcvars_ver=${{ inputs.msvc-toolset-version }} + '/c/Program Files/Microsoft Visual Studio/2022/Enterprise/vc/auxiliary/build/vcvars64.bat' -vcvars_ver=${{ inputs.msvc-toolset-version }} if [ $? -eq 0 ]; then echo "Toolchain is already installed" echo "toolchain-installed=true" >> $GITHUB_OUTPUT @@ -115,7 +115,7 @@ jobs: run: | # Run Visual Studio Installer '/c/Program Files (x86)/Microsoft Visual Studio/Installer/vs_installer.exe' \ - modify --quiet --installPath 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise' \ + modify --quiet --installPath 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise' \ --add Microsoft.VisualStudio.Component.VC.${{ inputs.msvc-toolset-version }}.${{ inputs.msvc-toolset-architecture }} if: steps.toolchain-check.outputs.toolchain-installed != 'true' diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c02454fa8ac17..06342f9e5a9e1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -259,7 +259,7 @@ jobs: uses: ./.github/workflows/build-windows.yml with: platform: windows-x64 - msvc-toolset-version: '14.29' + msvc-toolset-version: '14.44' msvc-toolset-architecture: 'x86.x64' configure-arguments: ${{ github.event.inputs.configure-arguments }} make-arguments: ${{ github.event.inputs.make-arguments }} @@ -271,7 +271,7 @@ jobs: uses: ./.github/workflows/build-windows.yml with: platform: windows-aarch64 - msvc-toolset-version: '14.29' + msvc-toolset-version: '14.44' msvc-toolset-architecture: 'arm64' make-target: 'hotspot' extra-conf-options: '--openjdk-target=aarch64-unknown-cygwin' @@ -323,7 +323,7 @@ jobs: with: platform: windows-x64 bootjdk-platform: windows-x64 - runs-on: windows-2019 + runs-on: windows-2025 # Remove bundles so they are not misconstrued as binary distributions from the JDK project remove-bundles: From 93ae31e9308781122841374b2a2f150cb3a255f2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 26 Jun 2025 09:46:59 +0000 Subject: [PATCH 350/846] 8297200: java/net/httpclient/SpecialHeadersTest.java failed once in AssertionError due to selector thread remaining alive Backport-of: d83a07b72cfd4dc42c5d4815262fcba05c653bd5 --- .../jdk/internal/net/http/HttpClientImpl.java | 27 ++++++- .../net/http/common/OperationTrackers.java | 3 + .../java/net/httpclient/ReferenceTracker.java | 27 +++++-- .../net/httpclient/SpecialHeadersTest.java | 70 +++++++++++++++---- 4 files changed, 103 insertions(+), 24 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java index bb71ac664f11a..09fabded2c03b 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java @@ -355,6 +355,7 @@ static void abortPendingRequests(HttpClientImpl client, Throwable reason) { // nature of the API, we also need to wait until all pending operations // have completed. private final WeakReference facadeRef; + private final WeakReference implRef; private final ConcurrentSkipListSet openedConnections = new ConcurrentSkipListSet<>(HttpConnection.COMPARE_BY_ID); @@ -398,6 +399,7 @@ static void abortPendingRequests(HttpClientImpl client, Throwable reason) { private final AtomicLong pendingTCPConnectionCount = new AtomicLong(); private final AtomicLong pendingSubscribersCount = new AtomicLong(); private final AtomicBoolean isAlive = new AtomicBoolean(); + private final AtomicBoolean isStarted = new AtomicBoolean(); /** A Set of, deadline first, ordered timeout events. */ private final TreeSet timeouts; @@ -455,6 +457,7 @@ private HttpClientImpl(HttpClientBuilderImpl builder, delegatingExecutor = new DelegatingExecutor(this::isSelectorThread, ex, this::onSubmitFailure); facadeRef = new WeakReference<>(facadeFactory.createFacade(this)); + implRef = new WeakReference<>(this); client2 = new Http2ClientImpl(this); cookieHandler = builder.cookieHandler; connectTimeout = builder.connectTimeout; @@ -504,7 +507,12 @@ void onSubmitFailure(Runnable command, Throwable failure) { } private void start() { - selmgr.start(); + try { + selmgr.start(); + } catch (Throwable t) { + isStarted.set(true); + throw t; + } } // Called from the SelectorManager thread, just before exiting. @@ -699,7 +707,9 @@ final static class HttpClientTracker implements Tracker { final AtomicLong connnectionsCount; final AtomicLong subscribersCount; final Reference reference; + final Reference implRef; final AtomicBoolean isAlive; + final AtomicBoolean isStarted; final String name; HttpClientTracker(AtomicLong request, AtomicLong http, @@ -709,7 +719,9 @@ final static class HttpClientTracker implements Tracker { AtomicLong conns, AtomicLong subscribers, Reference ref, + Reference implRef, AtomicBoolean isAlive, + AtomicBoolean isStarted, String name) { this.requestCount = request; this.httpCount = http; @@ -719,7 +731,9 @@ final static class HttpClientTracker implements Tracker { this.connnectionsCount = conns; this.subscribersCount = subscribers; this.reference = ref; + this.implRef = implRef; this.isAlive = isAlive; + this.isStarted = isStarted; this.name = name; } @Override @@ -750,8 +764,12 @@ public long getOutstandingWebSocketOperations() { public boolean isFacadeReferenced() { return !reference.refersTo(null); } + public boolean isImplementationReferenced() { + return !implRef.refersTo(null); + } + // The selector is considered alive if it's not yet started @Override - public boolean isSelectorAlive() { return isAlive.get(); } + public boolean isSelectorAlive() { return isAlive.get() || !isStarted.get(); } @Override public String getName() { return name; @@ -768,7 +786,9 @@ public Tracker getOperationsTracker() { pendingTCPConnectionCount, pendingSubscribersCount, facadeRef, + implRef, isAlive, + isStarted, dbgTag); } @@ -1144,7 +1164,8 @@ public void run() { List> errorList = new ArrayList<>(); List readyList = new ArrayList<>(); List resetList = new ArrayList<>(); - owner.isAlive.set(true); + owner.isAlive.set(true); // goes back to false when run exits + owner.isStarted.set(true); // never goes back to false try { if (Log.channel()) Log.logChannel(getName() + ": starting"); while (!Thread.currentThread().isInterrupted() && !closed) { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/OperationTrackers.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/OperationTrackers.java index f65021492dea5..3aec13b59ec71 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/OperationTrackers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/OperationTrackers.java @@ -64,6 +64,9 @@ public interface Tracker { // Whether the facade returned to the // user is still referenced boolean isFacadeReferenced(); + // Whether the implementation of the facade + // is still referenced + boolean isImplementationReferenced(); // whether the Selector Manager thread is still running boolean isSelectorAlive(); // The name of the object being tracked. diff --git a/test/jdk/java/net/httpclient/ReferenceTracker.java b/test/jdk/java/net/httpclient/ReferenceTracker.java index 68bfdd33e404b..32734deea4772 100644 --- a/test/jdk/java/net/httpclient/ReferenceTracker.java +++ b/test/jdk/java/net/httpclient/ReferenceTracker.java @@ -30,6 +30,7 @@ import java.lang.management.MonitorInfo; import java.lang.management.ThreadInfo; import java.net.http.HttpClient; +import java.time.Duration; import java.util.Arrays; import java.util.Objects; import java.util.concurrent.ConcurrentLinkedQueue; @@ -103,7 +104,7 @@ public AssertionError check(Tracker tracker, long graceDelayMs) { hasOperations.or(hasSubscribers) .or(Tracker::isFacadeReferenced) .or(Tracker::isSelectorAlive), - "outstanding operations or unreleased resources", false); + "outstanding operations or unreleased resources", true); } public AssertionError check(long graceDelayMs) { @@ -210,6 +211,9 @@ public AssertionError check(Tracker tracker, graceDelayMs = Math.max(graceDelayMs, 100); long delay = Math.min(graceDelayMs, 10); var count = delay > 0 ? graceDelayMs / delay : 1; + long waitStart = System.nanoTime(); + long waited = 0; + long toWait = Math.min(graceDelayMs, Math.max(delay, 1)); for (int i = 0; i < count; i++) { if (hasOutstanding.test(tracker)) { System.gc(); @@ -217,25 +221,36 @@ public AssertionError check(Tracker tracker, if (i == 0) { System.out.println("Waiting for HTTP operations to terminate..."); } - Thread.sleep(Math.min(graceDelayMs, Math.max(delay, 1))); + waited += toWait; + Thread.sleep(toWait); } catch (InterruptedException x) { // OK } - } else break; + } else { + System.out.println("No outstanding HTTP operations remaining after " + + i + "/" + count + " iterations and " + waited + "/" + graceDelayMs + + " ms, (wait/iteration " + toWait + " ms)"); + break; + } } + long duration = Duration.ofNanos(System.nanoTime() - waitStart).toMillis(); if (hasOutstanding.test(tracker)) { StringBuilder warnings = diagnose(tracker, new StringBuilder(), hasOutstanding); if (hasOutstanding.test(tracker)) { fail = new AssertionError(warnings.toString()); } } else { - System.out.println("PASSED: No " + description + " found in " + tracker.getName()); + System.out.println("PASSED: No " + description + " found in " + + tracker.getName() + " in " + duration + " ms"); } if (fail != null) { if (printThreads && tracker.isSelectorAlive()) { - printThreads("Some selector manager threads are still alive: ", System.out); - printThreads("Some selector manager threads are still alive: ", System.err); + var msg = "Selector manager threads are still alive for " + tracker.getName() + ": "; + printThreads(msg, System.out); + printThreads(msg, System.err); } + System.out.println("AssertionError: Found some " + description + " in " + + tracker.getName() + " after " + duration + " ms, waited " + waited + " ms"); } return fail; } diff --git a/test/jdk/java/net/httpclient/SpecialHeadersTest.java b/test/jdk/java/net/httpclient/SpecialHeadersTest.java index 4f6e5ad2b546d..37cb47a6872fb 100644 --- a/test/jdk/java/net/httpclient/SpecialHeadersTest.java +++ b/test/jdk/java/net/httpclient/SpecialHeadersTest.java @@ -25,7 +25,7 @@ * @test * @summary Verify that some special headers - such as User-Agent * can be specified by the caller. - * @bug 8203771 8218546 + * @bug 8203771 8218546 8297200 * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.httpclient.test.lib.common.HttpServerAdapters * jdk.httpclient.test.lib.http2.Http2TestServer @@ -42,6 +42,7 @@ import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; +import jdk.internal.net.http.common.OperationTrackers.Tracker; import jdk.test.lib.net.SimpleSSLContext; import org.testng.ITestContext; import org.testng.ITestResult; @@ -300,13 +301,18 @@ static String userAgent() { static final Map> DEFAULTS = Map.of( "USER-AGENT", u -> userAgent(), "HOST", u -> u.getRawAuthority()); + static void throwIfNotNull(Throwable throwable) throws Exception { + if (throwable instanceof Exception ex) throw ex; + if (throwable instanceof Error e) throw e; + } + @Test(dataProvider = "variants") void test(String uriString, String headerNameAndValue, boolean sameClient) throws Exception { - out.println("\n--- Starting "); + out.println("\n--- Starting test " + now()); int index = headerNameAndValue.indexOf(":"); String name = headerNameAndValue.substring(0, index); @@ -318,10 +324,14 @@ void test(String uriString, String value = useDefault ? DEFAULTS.get(key).apply(uri) : v; HttpClient client = null; + Tracker tracker = null; + Throwable thrown = null; for (int i=0; i< ITERATION_COUNT; i++) { try { - if (!sameClient || client == null) + if (!sameClient || client == null) { client = newHttpClient("test", sameClient); + tracker = TRACKER.getTracker(client); + } HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(uri); if (!useDefault) { @@ -361,14 +371,20 @@ void test(String uriString, assertEquals(resp.headers().allValues("X-" + key).size(), 0); } } + } catch (Throwable x) { + thrown = x; } finally { if (!sameClient) { client = null; System.gc(); - var error = TRACKER.check(500); - if (error != null) throw error; + var error = TRACKER.check(tracker, 500); + if (error != null) { + if (thrown != null) error.addSuppressed(thrown); + throw error; + } } } + throwIfNotNull(thrown); } } @@ -378,11 +394,12 @@ void testHomeMadeIllegalHeader(String uriString, boolean sameClient) throws Exception { - out.println("\n--- Starting "); + out.println("\n--- Starting testHomeMadeIllegalHeader " + now()); final URI uri = URI.create(uriString); HttpClient client = newHttpClient("testHomeMadeIllegalHeader", sameClient); - + Tracker tracker = TRACKER.getTracker(client); + Throwable thrown = null; try { // Test a request which contains an illegal header created HttpRequest req = new HttpRequest() { @@ -429,19 +446,29 @@ public HttpHeaders headers() { } catch (IllegalArgumentException ee) { out.println("Got IAE as expected"); } + } catch (Throwable x) { + thrown = x; } finally { if (!sameClient) { client = null; System.gc(); - var error = TRACKER.check(500); - if (error != null) throw error; + var error = TRACKER.check(tracker, 500); + if (error != null) { + if (thrown != null) error.addSuppressed(thrown); + throw error; + } } } + throwIfNotNull(thrown); } + + @Test(dataProvider = "variants") - void testAsync(String uriString, String headerNameAndValue, boolean sameClient) { - out.println("\n--- Starting "); + void testAsync(String uriString, String headerNameAndValue, boolean sameClient) + throws Exception + { + out.println("\n--- Starting testAsync " + now()); int index = headerNameAndValue.indexOf(":"); String name = headerNameAndValue.substring(0, index); String v = headerNameAndValue.substring(index+1).trim(); @@ -452,10 +479,14 @@ void testAsync(String uriString, String headerNameAndValue, boolean sameClient) String value = useDefault ? DEFAULTS.get(key).apply(uri) : v; HttpClient client = null; + Tracker tracker = null; + Throwable thrown = null; for (int i=0; i< ITERATION_COUNT; i++) { try { - if (!sameClient || client == null) + if (!sameClient || client == null) { client = newHttpClient("testAsync", sameClient); + tracker = TRACKER.getTracker(client); + } HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(uri); if (!useDefault) { @@ -498,14 +529,20 @@ void testAsync(String uriString, String headerNameAndValue, boolean sameClient) } }) .join(); + } catch (Throwable x) { + thrown = x; } finally { if (!sameClient) { client = null; System.gc(); - var error = TRACKER.check(500); - if (error != null) throw error; + var error = TRACKER.check(tracker, 500); + if (error != null) { + if (thrown != null) error.addSuppressed(thrown); + throw error; + } } } + throwIfNotNull(thrown); } } @@ -516,6 +553,7 @@ static String serverAuthority(HttpTestServer server) { @BeforeTest public void setup() throws Exception { + out.println("--- Starting setup " + now()); sslContext = new SimpleSSLContext().get(); if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); @@ -545,13 +583,15 @@ public void setup() throws Exception { @AfterTest public void teardown() throws Exception { + out.println("\n--- Teardown " + now()); HttpClient shared = sharedClient; String sharedClientName = shared == null ? null : shared.toString(); if (shared != null) TRACKER.track(shared); shared = sharedClient = null; Thread.sleep(100); - AssertionError fail = TRACKER.check(500); + AssertionError fail = TRACKER.check(2500); + out.println("--- Stopping servers " + now()); try { httpTestServer.stop(); httpsTestServer.stop(); From 8e1ab5ec71fa44b8f6fd2cf3897c9ec4a9bfbeaf Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 26 Jun 2025 09:48:00 +0000 Subject: [PATCH 351/846] 8298340: java/net/httpclient/CancelRequestTest.java fails with AssertionError: Found some subscribers for testPostInterrupt Backport-of: 05d67f69e34a76702406b36436ddb5db18e8fa68 --- .../internal/net/http/Http2Connection.java | 1 + .../classes/jdk/internal/net/http/Stream.java | 43 +++++++++++++++++-- .../common/HttpBodySubscriberWrapper.java | 9 +++- .../net/httpclient/CancelRequestTest.java | 2 +- 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java index 819c72de6632c..bcdfee31a08cd 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java @@ -1124,6 +1124,7 @@ synchronized void decrementStreamsCount(int streamid) { // This method is called when the HTTP/2 client is being // stopped. Do not call it from anywhere else. void closeAllStreams() { + if (debug.on()) debug.log("Close all streams"); for (var streamId : streams.keySet()) { // safe to call without locking - see Stream::deRegister decrementStreamsCount(streamId); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java index da080709a0328..ef0fe7c0a6d5b 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java @@ -283,6 +283,7 @@ void nullBody(HttpResponse resp, Throwable t) { if (debug.on()) debug.log("nullBody: streamid=%d", streamid); // We should have an END_STREAM data frame waiting in the inputQ. // We need a subscriber to force the scheduler to process it. + assert pendingResponseSubscriber == null; pendingResponseSubscriber = HttpResponse.BodySubscribers.replacing(null); sched.runOrSchedule(); } @@ -475,8 +476,14 @@ void incoming(Http2Frame frame) throws IOException { receiveDataFrame(new DataFrame(streamid, DataFrame.END_STREAM, List.of())); } } else if (frame instanceof DataFrame) { - if (cancelled) connection.dropDataFrame((DataFrame) frame); - else receiveDataFrame((DataFrame) frame); + if (cancelled) { + if (debug.on()) { + debug.log("request cancelled or stream closed: dropping data frame"); + } + connection.dropDataFrame((DataFrame) frame); + } else { + receiveDataFrame((DataFrame) frame); + } } else { if (!cancelled) otherFrame(frame); } @@ -1338,10 +1345,24 @@ void cancelImpl(final Throwable e, final int resetFrameErrCode) { } } } + if (closing) { // true if the stream has not been closed yet - if (responseSubscriber != null || pendingResponseSubscriber != null) + if (responseSubscriber != null || pendingResponseSubscriber != null) { + if (debug.on()) + debug.log("stream %s closing due to %s", streamid, (Object)errorRef.get()); sched.runOrSchedule(); + } else { + if (debug.on()) + debug.log("stream %s closing due to %s before subscriber registered", + streamid, (Object)errorRef.get()); + } + } else { + if (debug.on()) { + debug.log("stream %s already closed due to %s", + streamid, (Object)errorRef.get()); + } } + completeResponseExceptionally(e); if (!requestBodyCF.isDone()) { requestBodyCF.completeExceptionally(errorRef.get()); // we may be sending the body.. @@ -1385,6 +1406,20 @@ void close() { if (debug.on()) debug.log("close stream %d", streamid); Log.logTrace("Closing stream {0}", streamid); connection.closeStream(streamid); + var s = responseSubscriber == null + ? pendingResponseSubscriber + : responseSubscriber; + if (debug.on()) debug.log("subscriber is %s", s); + if (s instanceof Http2StreamResponseSubscriber sw) { + if (debug.on()) debug.log("closing response subscriber stream %s", streamid); + // if the subscriber has already completed, + // there is nothing to do... + if (!sw.completed()) { + // otherwise make sure it will be completed + var cause = errorRef.get(); + sw.complete(cause == null ? new IOException("stream closed") : cause); + } + } Log.logTrace("Stream {0} closed", streamid); } @@ -1670,10 +1705,12 @@ protected void complete(Throwable t) { super.complete(t); } } + @Override protected void onCancel() { unregisterResponseSubscriber(this); } + } private static final VarHandle STREAM_STATE; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/HttpBodySubscriberWrapper.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/HttpBodySubscriberWrapper.java index 78185bcbcfc44..a896a8eb08407 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/HttpBodySubscriberWrapper.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/HttpBodySubscriberWrapper.java @@ -30,7 +30,6 @@ import java.util.Comparator; import java.util.List; import java.util.Objects; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.Flow; import java.util.concurrent.Flow.Subscription; @@ -176,6 +175,14 @@ protected void complete(Throwable t) { } } + /** + * {@return true if this subscriber has already completed, either normally + * or abnormally} + */ + public boolean completed() { + return completed.get(); + } + @Override public CompletionStage getBody() { return userSubscriber.getBody(); diff --git a/test/jdk/java/net/httpclient/CancelRequestTest.java b/test/jdk/java/net/httpclient/CancelRequestTest.java index 54fd07d0b0ecb..28ad68bd40970 100644 --- a/test/jdk/java/net/httpclient/CancelRequestTest.java +++ b/test/jdk/java/net/httpclient/CancelRequestTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8245462 8229822 8254786 8297075 8297149 + * @bug 8245462 8229822 8254786 8297075 8297149 8298340 * @summary Tests cancelling the request. * @library /test/lib /test/jdk/java/net/httpclient/lib * @key randomness From 2a9bba29dde0bbce4356c2e75317a68ca98c7ea4 Mon Sep 17 00:00:00 2001 From: Sorna Sarathi N Date: Thu, 26 Jun 2025 14:01:59 +0000 Subject: [PATCH 352/846] 8336499: Failure when creating non-CRT RSA private keys in SunPKCS11 Backport-of: 3251eea1f4289a0505052be204407c02ca38b0ad --- .../classes/sun/security/pkcs11/P11Key.java | 100 +++++++++++------- 1 file changed, 63 insertions(+), 37 deletions(-) diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java index e05892e2c2250..006aa67f62124 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java @@ -533,47 +533,73 @@ static class P11RSAPrivateKeyInternal extends P11PrivateKey { static P11RSAPrivateKeyInternal of(Session session, long keyID, String algorithm, int keyLength, CK_ATTRIBUTE[] attrs, boolean keySensitive) { - if (keySensitive) { - return new P11RSAPrivateKeyInternal(session, keyID, algorithm, + P11RSAPrivateKeyInternal p11Key = null; + if (!keySensitive) { + // Key is not sensitive: try to interpret as CRT or non-CRT. + p11Key = asCRT(session, keyID, algorithm, keyLength, attrs); + if (p11Key == null) { + p11Key = asNonCRT(session, keyID, algorithm, keyLength, + attrs); + } + } + if (p11Key == null) { + // Key is sensitive or there was a failure while querying its + // attributes: handle as opaque. + p11Key = new P11RSAPrivateKeyInternal(session, keyID, algorithm, keyLength, attrs); - } else { - CK_ATTRIBUTE[] rsaAttrs = new CK_ATTRIBUTE[] { - new CK_ATTRIBUTE(CKA_MODULUS), - new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT), - new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT), - new CK_ATTRIBUTE(CKA_PRIME_1), - new CK_ATTRIBUTE(CKA_PRIME_2), - new CK_ATTRIBUTE(CKA_EXPONENT_1), - new CK_ATTRIBUTE(CKA_EXPONENT_2), - new CK_ATTRIBUTE(CKA_COEFFICIENT), - }; - boolean isCRT = true; - Session tempSession = null; - try { - tempSession = session.token.getOpSession(); - session.token.p11.C_GetAttributeValue(tempSession.id(), - keyID, rsaAttrs); - for (CK_ATTRIBUTE attr : rsaAttrs) { - isCRT &= (attr.pValue instanceof byte[]); - if (!isCRT) break; + } + return p11Key; + } + + private static CK_ATTRIBUTE[] tryFetchAttributes(Session session, + long keyID, long... attrTypes) { + int i = 0; + CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[attrTypes.length]; + for (long attrType : attrTypes) { + attrs[i++] = new CK_ATTRIBUTE(attrType); + } + try { + session.token.p11.C_GetAttributeValue(session.id(), keyID, + attrs); + for (CK_ATTRIBUTE attr : attrs) { + if (!(attr.pValue instanceof byte[])) { + return null; } - } catch (PKCS11Exception e) { - // ignore, assume not available - isCRT = false; - } finally { - session.token.releaseSession(tempSession); - } - BigInteger n = rsaAttrs[0].getBigInteger(); - BigInteger d = rsaAttrs[1].getBigInteger(); - if (isCRT) { - return new P11RSAPrivateKey(session, keyID, algorithm, - keyLength, attrs, n, d, - Arrays.copyOfRange(rsaAttrs, 2, rsaAttrs.length)); - } else { - return new P11RSAPrivateNonCRTKey(session, keyID, - algorithm, keyLength, attrs, n, d); } + return attrs; + } catch (PKCS11Exception ignored) { + // ignore, assume not available + return null; + } + } + + private static P11RSAPrivateKeyInternal asCRT(Session session, + long keyID, String algorithm, int keyLength, + CK_ATTRIBUTE[] attrs) { + CK_ATTRIBUTE[] rsaCRTAttrs = tryFetchAttributes(session, keyID, + CKA_MODULUS, CKA_PRIVATE_EXPONENT, CKA_PUBLIC_EXPONENT, + CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, + CKA_COEFFICIENT); + if (rsaCRTAttrs == null) { + return null; + } + return new P11RSAPrivateKey(session, keyID, algorithm, keyLength, + attrs, rsaCRTAttrs[0].getBigInteger(), + rsaCRTAttrs[1].getBigInteger(), + Arrays.copyOfRange(rsaCRTAttrs, 2, rsaCRTAttrs.length)); + } + + private static P11RSAPrivateKeyInternal asNonCRT(Session session, + long keyID, String algorithm, int keyLength, + CK_ATTRIBUTE[] attrs) { + CK_ATTRIBUTE[] rsaNonCRTAttrs = tryFetchAttributes(session, keyID, + CKA_MODULUS, CKA_PRIVATE_EXPONENT); + if (rsaNonCRTAttrs == null) { + return null; } + return new P11RSAPrivateNonCRTKey(session, keyID, algorithm, + keyLength, attrs, rsaNonCRTAttrs[0].getBigInteger(), + rsaNonCRTAttrs[1].getBigInteger()); } protected transient BigInteger n; From 183b9a0ab4d6d37d120ea239cac61d6bbd6a7d43 Mon Sep 17 00:00:00 2001 From: Daniel Hu Date: Thu, 26 Jun 2025 17:29:30 +0000 Subject: [PATCH 353/846] 8314978: Multiple server call from connection failing with expect100 in getOutputStream Backport-of: 460ebcd9cb94867608e22e07092bd1cf33228700 --- .../www/protocol/http/HttpURLConnection.java | 14 + .../HttpURLConnectionExpect100Test.java | 254 ++++++++++++++++++ 2 files changed, 268 insertions(+) create mode 100644 test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpect100Test.java diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index e3e72723428f4..b04449f43eec6 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -420,6 +420,10 @@ private static Set schemesListToSet(String list) { calls getInputStream after disconnect */ private Exception rememberedException = null; + /* Remembered Exception, we will throw it again if somebody + calls getOutputStream after disconnect or error */ + private Exception rememberedExceptionOut = null; + /* If we decide we want to reuse a client, we put it here */ private HttpClient reuseClient = null; @@ -1449,6 +1453,14 @@ private OutputStream getOutputStream0() throws IOException { + " if doOutput=false - call setDoOutput(true)"); } + if (rememberedExceptionOut != null) { + if (rememberedExceptionOut instanceof RuntimeException) { + throw new RuntimeException(rememberedExceptionOut); + } else { + throw getChainedException((IOException) rememberedExceptionOut); + } + } + if (method.equals("GET")) { method = "POST"; // Backward compatibility } @@ -1511,9 +1523,11 @@ private OutputStream getOutputStream0() throws IOException { int i = responseCode; disconnectInternal(); responseCode = i; + rememberedExceptionOut = e; throw e; } catch (IOException e) { disconnectInternal(); + rememberedExceptionOut = e; throw e; } } diff --git a/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpect100Test.java b/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpect100Test.java new file mode 100644 index 0000000000000..2a858d32fc23c --- /dev/null +++ b/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpect100Test.java @@ -0,0 +1,254 @@ +/* + * Copyright (c) 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. + */ + +/** + * @test + * @bug 8314978 + * @summary Multiple server call from connection failing with expect100 in + * getOutputStream + * @library /test/lib + * @run junit/othervm HttpURLConnectionExpect100Test + */ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.URL; +import java.net.HttpURLConnection; + +import jdk.test.lib.net.URIBuilder; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class HttpURLConnectionExpect100Test { + + private HttpServer server; + private int port; + static final String RESPONSE = "This is default response."; + + @BeforeAll + void setup() throws Exception { + server = HttpServer.create(); + port = server.getPort(); + } + + @AfterAll + void teardown() throws Exception { + server.close(); + } + + @Test + public void expect100ContinueHitCountTest() throws Exception { + server.resetHitCount(); + URL url = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(port) + .toURL(); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("PUT"); + //send expect continue + conn.setRequestProperty("Expect", "100-continue"); + sendRequest(conn); + getHeaderField(conn); + assertEquals(1, server.getServerHitCount()); + // Server rejects the expect 100-continue request with 417 response + assertEquals(417, conn.getResponseCode()); + } + + @Test + public void defaultRequestHitCountTest() throws Exception { + server.resetHitCount(); + URL url = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(port) + .toURL(); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("PUT"); + sendRequest(conn); + getHeaderField(conn); + assertEquals(1, server.getServerHitCount()); + assertEquals(200, conn.getResponseCode()); + try ( InputStream in = conn.getInputStream()) { + byte[] data = in.readAllBytes(); + assertEquals(RESPONSE.length(), data.length); + } + } + + private void sendRequest(final HttpURLConnection conn) throws Exception { + conn.setDoOutput(true); + conn.setFixedLengthStreamingMode(10); + byte[] payload = new byte[10]; + try ( OutputStream os = conn.getOutputStream()) { + os.write(payload); + os.flush(); + } catch (IOException e) { + // intentional, server will reject the expect 100 + } + } + + private void getHeaderField(final HttpURLConnection conn) { + // Call getHeaderFiels in loop, this should not hit server. + for (int i = 0; i < 5; i++) { + System.out.println("Getting: field" + i); + conn.getHeaderField("field" + i); + } + } + + static class HttpServer extends Thread { + + private final ServerSocket ss; + private static HttpServer inst; + private volatile int hitCount; + private volatile boolean isRunning; + private final int port; + + private HttpServer() throws IOException { + InetAddress loopback = InetAddress.getLoopbackAddress(); + ss = new ServerSocket(); + ss.bind(new InetSocketAddress(loopback, 0)); + port = ss.getLocalPort(); + isRunning = true; + } + + static HttpServer create() throws IOException { + if (inst != null) { + return inst; + } else { + inst = new HttpServer(); + inst.setDaemon(true); + inst.start(); + return inst; + } + } + + int getServerHitCount() { + return hitCount; + } + + void resetHitCount() { + hitCount = 0; + } + + int getPort() { + return port; + } + + void close() { + isRunning = false; + if (ss != null && !ss.isClosed()) { + try { + ss.close(); + } catch (IOException ex) { + } + } + } + + @Override + public void run() { + Socket client; + try { + while (isRunning) { + client = ss.accept(); + System.out.println(client.getRemoteSocketAddress().toString()); + hitCount++; + handleConnection(client); + } + } catch (IOException ex) { + // throw exception only if isRunning is true + if (isRunning) { + throw new RuntimeException(ex); + } + } finally { + if (ss != null && !ss.isClosed()) { + try { + ss.close(); + } catch (IOException ex) { + //ignore + } + } + } + } + + private void handleConnection(Socket client) throws IOException { + try ( BufferedReader in = new BufferedReader( + new InputStreamReader(client.getInputStream())); + PrintStream out = new PrintStream(client.getOutputStream())) { + handle_connection(in, out); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } finally { + try { + client.close(); + } catch (IOException e) { + } + } + } + + private void handle_connection(BufferedReader in, PrintStream out) + throws IOException, InterruptedException { + StringBuilder clientRequest = new StringBuilder(); + String line = null; + do { + line = in.readLine(); + clientRequest.append(line); + } while (line != null && line.length() != 0); + if (clientRequest.toString().contains("100-continue")) { + rejectExpect100Continue(out); + } else { + defaultResponse(out); + } + } + + private void rejectExpect100Continue(PrintStream out) { + out.print("HTTP/1.1 417 Expectation Failed\r\n"); + out.print("Server: Test-Server\r\n"); + out.print("Connection: close\r\n"); + out.print("Content-Length: 0\r\n"); + out.print("\r\n"); + out.flush(); + } + + private void defaultResponse(PrintStream out) { + // send the 200 OK + out.print("HTTP/1.1 200 OK\r\n"); + out.print("Server: Test-Server\r\n"); + out.print("Connection: close\r\n"); + out.print("Content-Length: " + RESPONSE.length() + "\r\n\r\n"); + out.print(RESPONSE); + out.flush(); + } + } +} From fb0a796fef29283071ed765065512d71174616d6 Mon Sep 17 00:00:00 2001 From: Daniel Hu Date: Thu, 26 Jun 2025 17:30:34 +0000 Subject: [PATCH 354/846] 8315505: CompileTask timestamp printed can overflow Backport-of: ad7a8e86e0334390f87ae44cf749d2b47f1409a1 --- src/hotspot/share/compiler/compileTask.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/compiler/compileTask.cpp b/src/hotspot/share/compiler/compileTask.cpp index d610d8bdcf814..689e529fa93dd 100644 --- a/src/hotspot/share/compiler/compileTask.cpp +++ b/src/hotspot/share/compiler/compileTask.cpp @@ -240,13 +240,13 @@ void CompileTask::print_impl(outputStream* st, Method* method, int compile_id, i jlong time_queued, jlong time_started) { if (!short_form) { // Print current time - st->print("%7d ", (int)tty->time_stamp().milliseconds()); + st->print(UINT64_FORMAT " ", (uint64_t) tty->time_stamp().milliseconds()); if (Verbose && time_queued != 0) { // Print time in queue and time being processed by compiler thread jlong now = os::elapsed_counter(); - st->print("%d ", (int)TimeHelper::counter_to_millis(now-time_queued)); + st->print("%.0f ", TimeHelper::counter_to_millis(now-time_queued)); if (time_started != 0) { - st->print("%d ", (int)TimeHelper::counter_to_millis(now-time_started)); + st->print("%.0f ", TimeHelper::counter_to_millis(now-time_started)); } } } From 76e132986406ad3c0a557aa907e593490a31ebcf Mon Sep 17 00:00:00 2001 From: Feilong Jiang Date: Fri, 27 Jun 2025 08:16:46 +0000 Subject: [PATCH 355/846] 8357968: RISC-V: Interpreter volatile reference stores with G1 are not sequentially consistent Reviewed-by: rehn, fyang Backport-of: c5a1543ee3e68775f09ca29fb07efd9aebfdb33e --- src/hotspot/cpu/riscv/templateTable_riscv.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hotspot/cpu/riscv/templateTable_riscv.cpp b/src/hotspot/cpu/riscv/templateTable_riscv.cpp index db847a0e7bc3b..7a9165ccf5d78 100644 --- a/src/hotspot/cpu/riscv/templateTable_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateTable_riscv.cpp @@ -1129,6 +1129,7 @@ void TemplateTable::aastore() { // Get the value we will store __ ld(x10, at_tos()); // Now store using the appropriate barrier + // Clobbers: x11, x13, x29 do_oop_store(_masm, element_address, x10, IS_ARRAY); __ j(done); @@ -1137,6 +1138,7 @@ void TemplateTable::aastore() { __ profile_null_seen(x12); // Store a NULL + // Clobbers: x11, x13, x29 do_oop_store(_masm, element_address, noreg, IS_ARRAY); // Pop stack arguments @@ -2716,6 +2718,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr __ add(off, obj, off); // if static, obj from cache, else obj from stack. const Address field(off, 0); // Store into the field + // Clobbers: x11, x13, x29 do_oop_store(_masm, field, x10, IN_HEAP); if (rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_aputfield, bc, x11, true, byte_no); @@ -2950,8 +2953,8 @@ void TemplateTable::fast_storefield(TosState state) // Must prevent reordering of the following cp cache loads with bytecode load __ membar(MacroAssembler::LoadLoad); - // test for volatile with x13 - __ lwu(x13, Address(x12, in_bytes(base + + // test for volatile with x15 + __ lwu(x15, Address(x12, in_bytes(base + ConstantPoolCacheEntry::flags_offset()))); // replace index with field offset from cache entry @@ -2959,7 +2962,7 @@ void TemplateTable::fast_storefield(TosState state) { Label notVolatile; - __ test_bit(t0, x13, ConstantPoolCacheEntry::is_volatile_shift); + __ test_bit(t0, x15, ConstantPoolCacheEntry::is_volatile_shift); __ beqz(t0, notVolatile); __ membar(MacroAssembler::StoreStore | MacroAssembler::LoadStore); __ bind(notVolatile); @@ -2975,6 +2978,7 @@ void TemplateTable::fast_storefield(TosState state) // access field switch (bytecode()) { case Bytecodes::_fast_aputfield: + // Clobbers: x11, x13, x29 do_oop_store(_masm, field, x10, IN_HEAP); break; case Bytecodes::_fast_lputfield: @@ -3007,7 +3011,7 @@ void TemplateTable::fast_storefield(TosState state) { Label notVolatile; - __ test_bit(t0, x13, ConstantPoolCacheEntry::is_volatile_shift); + __ test_bit(t0, x15, ConstantPoolCacheEntry::is_volatile_shift); __ beqz(t0, notVolatile); __ membar(MacroAssembler::StoreLoad | MacroAssembler::StoreStore); __ bind(notVolatile); From ee3834deebd2fd1c37d6a48d1ad43b79984159dc Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 27 Jun 2025 09:11:47 +0000 Subject: [PATCH 356/846] 8275079: Remove unnecessary conversion to String in java.net.http Backport-of: 19f76c215dbe9528dde10acd744be54618ea5e4c --- .../jdk/internal/net/http/AuthenticationFilter.java | 4 ++-- .../jdk/internal/net/http/Http1AsyncReceiver.java | 12 +++++------- .../classes/jdk/internal/net/http/Http1Request.java | 2 +- .../classes/jdk/internal/net/http/Http1Response.java | 4 ++-- .../jdk/internal/net/http/Http2Connection.java | 2 +- .../jdk/internal/net/http/HttpRequestImpl.java | 3 +-- .../classes/jdk/internal/net/http/common/Demand.java | 4 ++-- .../internal/net/http/common/SSLFlowDelegate.java | 4 ++-- .../internal/net/http/common/SubscriberWrapper.java | 12 ++++++------ .../classes/jdk/internal/net/http/common/Utils.java | 2 +- .../jdk/internal/net/http/frame/ErrorFrame.java | 4 ++-- .../jdk/internal/net/http/frame/Http2Frame.java | 4 ++-- .../jdk/internal/net/http/frame/SettingsFrame.java | 4 ++-- 13 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java b/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java index 6b112a65cbba3..2561afd645d07 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -323,7 +323,7 @@ public HttpRequestImpl response(Response r) throws IOException { return req; } else if (au.retries > retry_limit) { throw new IOException("too many authentication attempts. Limit: " + - Integer.toString(retry_limit)); + retry_limit); } else { // we sent credentials, but they were rejected if (au.fromcache) { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1AsyncReceiver.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1AsyncReceiver.java index 7a2d7107182ec..b8af164d88481 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1AsyncReceiver.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1AsyncReceiver.java @@ -116,7 +116,7 @@ static interface Http1AsyncDelegate { public AbstractSubscription subscription(); /** - * Called to make sure resources are released when the + * Called to make sure resources are released * when the Http1AsyncReceiver is stopped. * @param error The Http1AsyncReceiver pending error ref, * if any. @@ -478,7 +478,7 @@ void onReadError(Throwable ex) { // the pool. if (retry && (ex instanceof IOException)) { // could be either EOFException, or - // IOException("connection reset by peer), or + // IOException("connection reset by peer"), or // SSLHandshakeException resulting from the server having // closed the SSL session. if (received.get() == 0) { @@ -710,7 +710,7 @@ private String debugQBB(ByteBuffer[] qbb) { for (ByteBuffer b : lbb) { if (!sbb.remove(b)) { msg.append(sep) - .append(String.valueOf(b)) + .append(b) .append("[remaining=") .append(b.remaining()) .append(", position=") @@ -728,14 +728,12 @@ private String debugQBB(ByteBuffer[] qbb) { String dbgString() { String tag = dbgTag; if (tag == null) { - String flowTag = null; Http1Exchange exchg = owner; Object flow = (exchg != null) ? exchg.connection().getConnectionFlow() : null; - flowTag = tag = flow == null ? null: (String.valueOf(flow)); - if (flowTag != null) { - dbgTag = tag = "Http1AsyncReceiver("+ flowTag + ")"; + if (flow != null) { + dbgTag = tag = "Http1AsyncReceiver(" + flow + ")"; } else { tag = "Http1AsyncReceiver(?)"; } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java index 84c0bd7ea0ecf..7a1b11478f688 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java @@ -237,7 +237,7 @@ private String hostString() { if (defaultPort) { return host; } else { - return host + ":" + Integer.toString(port); + return host + ":" + port; } } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java index b642dc8177b98..f582d175f5087 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java @@ -110,7 +110,7 @@ private String dbgString() { } // The ClientRefCountTracker is used to track the state - // of a pending operation. Altough there usually is a single + // of a pending operation. Although there usually is a single // point where the operation starts, it may terminate at // different places. private final class ClientRefCountTracker { @@ -734,7 +734,7 @@ public final void close(Throwable error) { @Override public String toString() { - return super.toString() + "/parser=" + String.valueOf(parser); + return super.toString() + "/parser=" + parser; } } } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java index bcdfee31a08cd..ae3afd3d6c8e7 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java @@ -1227,7 +1227,7 @@ private void handleGoAway(GoAwayFrame frame) throws IOException { shutdown(new IOException( - String.valueOf(connection.channel().getLocalAddress()) + connection.channel().getLocalAddress() +": GOAWAY received")); } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java index 27e65446844f4..f58e4a10635f9 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java @@ -44,7 +44,6 @@ import jdk.internal.net.http.common.HttpHeadersBuilder; import jdk.internal.net.http.common.Utils; -import jdk.internal.net.http.websocket.OpeningHandshake; import jdk.internal.net.http.websocket.WebSocketRequest; import static jdk.internal.net.http.common.Utils.ALLOWED_HEADERS; @@ -216,7 +215,7 @@ private BodyPublisher publisher(HttpRequestImpl other) { this.systemHeadersBuilder.map().putAll(headers.systemHeaders().map()); this.userHeaders = headers.userHeaders(); this.uri = URI.create("socket://" + authority.getHostString() + ":" - + Integer.toString(authority.getPort()) + "/"); + + authority.getPort() + "/"); this.proxy = null; this.requestPublisher = null; this.authority = authority; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/Demand.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/Demand.java index 842b57588e720..2e9575d2885e1 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/Demand.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/Demand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -47,7 +47,7 @@ public final class Demand { */ public boolean increase(long n) { if (n <= 0) { - throw new IllegalArgumentException("non-positive subscription request: " + String.valueOf(n)); + throw new IllegalArgumentException("non-positive subscription request: " + n); } long prev = val.getAndAccumulate(n, (p, i) -> p + i < 0 ? Long.MAX_VALUE : p + i); return prev == 0; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java index e64e4034a1ba1..e8cceaa8486f1 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java @@ -953,7 +953,7 @@ private void sendResultBytes(EngineResult result) { @Override public String toString() { return "WRITER: " + super.toString() - + ", writeList size: " + Integer.toString(writeList.size()) + + ", writeList size: " + writeList.size() + ", scheduler: " + (scheduler.isStopped() ? "stopped" : "running") + ", status: " + lastWrappedStatus; //" writeList: " + writeList.toString(); @@ -1128,7 +1128,7 @@ private void executeTasks(List tasks) { exec.execute(() -> { try { List nextTasks = tasks; - if (debug.on()) debug.log("#tasks to execute: " + Integer.toString(nextTasks.size())); + if (debug.on()) debug.log("#tasks to execute: " + nextTasks.size()); do { nextTasks.forEach(Runnable::run); if (engine.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/SubscriberWrapper.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/SubscriberWrapper.java index 43fbc2a1e460e..7b5e2ec460409 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/SubscriberWrapper.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/SubscriberWrapper.java @@ -492,13 +492,13 @@ public void resetDownstreamDemand() { public String toString() { StringBuilder sb = new StringBuilder(); sb.append("SubscriberWrapper:") - .append(" upstreamCompleted: ").append(Boolean.toString(upstreamCompleted)) - .append(" upstreamWindow: ").append(upstreamWindow.toString()) - .append(" downstreamCompleted: ").append(Boolean.toString(downstreamCompleted)) - .append(" completionAcknowledged: ").append(Boolean.toString(completionAcknowledged)) - .append(" outputQ size: ").append(Integer.toString(outputQ.size())) + .append(" upstreamCompleted: ").append(upstreamCompleted) + .append(" upstreamWindow: ").append(upstreamWindow) + .append(" downstreamCompleted: ").append(downstreamCompleted) + .append(" completionAcknowledged: ").append(completionAcknowledged) + .append(" outputQ size: ").append(outputQ.size()) //.append(" outputQ: ").append(outputQ.toString()) - .append(" cf: ").append(cf.toString()) + .append(" cf: ").append(cf) .append(" downstreamSubscription: ").append(downstreamSubscription) .append(" downstreamSubscriber: ").append(downstreamSubscriber); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java index 323042de3d75c..cf3f8db497fa1 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java @@ -909,7 +909,7 @@ public static String hostString(HttpRequestImpl request) { if (defaultPort) { return host; } else { - return host + ":" + Integer.toString(port); + return host + ":" + port; } } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/frame/ErrorFrame.java b/src/java.net.http/share/classes/jdk/internal/net/http/frame/ErrorFrame.java index 2d25193c11814..bf281368a9869 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/frame/ErrorFrame.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/frame/ErrorFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -67,7 +67,7 @@ public static String stringForCode(int code) { } if (code > LAST_ERROR) { - return "Error: " + Integer.toString(code); + return "Error: " + code; } else { return errorStrings[code]; } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/frame/Http2Frame.java b/src/java.net.http/share/classes/jdk/internal/net/http/frame/Http2Frame.java index 36fc0c8dffdda..f837645696fcc 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/frame/Http2Frame.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/frame/Http2Frame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -101,7 +101,7 @@ public String toString() { StringBuilder sb = new StringBuilder(); sb.append(typeAsString()) .append(": length=") - .append(Integer.toString(length())) + .append(length()) .append(", streamid=") .append(streamid) .append(", flags="); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/frame/SettingsFrame.java b/src/java.net.http/share/classes/jdk/internal/net/http/frame/SettingsFrame.java index ca68eae8cf684..8a0119594176a 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/frame/SettingsFrame.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/frame/SettingsFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -55,7 +55,7 @@ public String toString() { if (parameters[i] != -1) { sb.append(name(i)) .append("=") - .append(Integer.toString(parameters[i])) + .append(parameters[i]) .append(' '); } } From 9f988b5ce867b3fc373c8902ae2dcd2d0968e81e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 27 Jun 2025 09:13:08 +0000 Subject: [PATCH 357/846] 8276401: Use blessed modifier order in java.net.http Reviewed-by: mdoerr Backport-of: 7115892f96a5a57ce9d37602038b787d19da5d81 --- .../jdk/internal/net/http/Http1Response.java | 6 +++--- .../jdk/internal/net/http/Http2ClientImpl.java | 2 +- .../jdk/internal/net/http/Http2Connection.java | 6 +++--- .../jdk/internal/net/http/HttpClientImpl.java | 8 ++++---- .../jdk/internal/net/http/HttpConnection.java | 2 +- .../jdk/internal/net/http/ResponseSubscribers.java | 6 +++--- .../classes/jdk/internal/net/http/SocketTube.java | 2 +- .../jdk/internal/net/http/common/DebugLogger.java | 14 +++++++------- .../jdk/internal/net/http/common/FlowTube.java | 4 ++-- .../internal/net/http/common/MinimalFuture.java | 2 +- .../jdk/internal/net/http/common/SSLTube.java | 2 +- .../net/http/common/SequentialScheduler.java | 4 ++-- 12 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java index f582d175f5087..3f64770f2e993 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java @@ -67,14 +67,14 @@ class Http1Response { private volatile EOFException eof; private volatile BodyParser bodyParser; // max number of bytes of (fixed length) body to ignore on redirect - private final static int MAX_IGNORE = 1024; + private static final int MAX_IGNORE = 1024; // Revisit: can we get rid of this? enum State {INITIAL, READING_HEADERS, READING_BODY, DONE} private volatile State readProgress = State.INITIAL; final Logger debug = Utils.getDebugLogger(this::dbgString, Utils.DEBUG); - final static AtomicLong responseCount = new AtomicLong(); + static final AtomicLong responseCount = new AtomicLong(); final long id = responseCount.incrementAndGet(); private Http1HeaderParser hd; @@ -475,7 +475,7 @@ Receiver receiver(State state) { } - static abstract class Receiver + abstract static class Receiver implements Http1AsyncReceiver.Http1AsyncDelegate { abstract void start(T parser); abstract CompletableFuture completion(); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java index 339b5b469508f..2321d8c9d7657 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java @@ -53,7 +53,7 @@ */ class Http2ClientImpl { - final static Logger debug = + static final Logger debug = Utils.getDebugLogger("Http2ClientImpl"::toString, Utils.DEBUG); private final HttpClientImpl client; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java index ae3afd3d6c8e7..02450c7dcf854 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java @@ -118,14 +118,14 @@ class Http2Connection { final Logger debug = Utils.getDebugLogger(this::dbgString, Utils.DEBUG); - final static Logger DEBUG_LOGGER = + static final Logger DEBUG_LOGGER = Utils.getDebugLogger("Http2Connection"::toString, Utils.DEBUG); private final Logger debugHpack = Utils.getHpackLogger(this::dbgString, Utils.DEBUG_HPACK); static final ByteBuffer EMPTY_TRIGGER = ByteBuffer.allocate(0); - static private final int MAX_CLIENT_STREAM_ID = Integer.MAX_VALUE; // 2147483647 - static private final int MAX_SERVER_STREAM_ID = Integer.MAX_VALUE - 1; // 2147483646 + private static final int MAX_CLIENT_STREAM_ID = Integer.MAX_VALUE; // 2147483647 + private static final int MAX_SERVER_STREAM_ID = Integer.MAX_VALUE - 1; // 2147483646 /** * Flag set when no more streams to be opened on this connection. diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java index 09fabded2c03b..c7643106640b6 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java @@ -148,7 +148,7 @@ public Thread newThread(Runnable r) { * is the SelectorManager thread. If the current thread is not * the selector manager thread the given task is executed inline. */ - final static class DelegatingExecutor implements Executor { + static final class DelegatingExecutor implements Executor { private final BooleanSupplier isInSelectorThread; private final Executor delegate; private final BiConsumer errorHandler; @@ -698,7 +698,7 @@ final long referenceCount() { // Trackers are used in test to verify that an instance of // HttpClient has shutdown correctly, and that all operations // have terminated. - final static class HttpClientTracker implements Tracker { + static final class HttpClientTracker implements Tracker { final AtomicLong requestCount; final AtomicLong httpCount; final AtomicLong http2Count; @@ -996,7 +996,7 @@ private void debugCompleted(String tag, long startNanos, HttpRequest req) { } // Main loop for this client's selector - private final static class SelectorManager extends Thread { + private static final class SelectorManager extends Thread { // For testing purposes we have an internal System property that // can control the frequency at which the selector manager will wake @@ -1409,7 +1409,7 @@ private static class SelectorAttachment { private final SelectableChannel chan; private final Selector selector; private final Set pending; - private final static Logger debug = + private static final Logger debug = Utils.getDebugLogger("SelectorAttachment"::toString, Utils.DEBUG); private int interestOps; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpConnection.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpConnection.java index 5234a25f94280..6515bb12248a7 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpConnection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpConnection.java @@ -67,7 +67,7 @@ abstract class HttpConnection implements Closeable { final Logger debug = Utils.getDebugLogger(this::dbgString, Utils.DEBUG); - final static Logger DEBUG_LOGGER = Utils.getDebugLogger( + static final Logger DEBUG_LOGGER = Utils.getDebugLogger( () -> "HttpConnection(SocketTube(?))", Utils.DEBUG); public static final Comparator COMPARE_BY_ID = Comparator.comparing(HttpConnection::id); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java index f9b546d485eaa..0413274c068c0 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java @@ -366,7 +366,7 @@ public void onError(Throwable throwable) { result.completeExceptionally(throwable); } - static private byte[] join(List bytes) { + private static byte[] join(List bytes) { int size = Utils.remaining(bytes, Integer.MAX_VALUE); byte[] res = new byte[size]; int from = 0; @@ -400,7 +400,7 @@ public CompletionStage getBody() { public static class HttpResponseInputStream extends InputStream implements TrustedSubscriber { - final static int MAX_BUFFERS_IN_QUEUE = 1; // lock-step with the producer + static final int MAX_BUFFERS_IN_QUEUE = 1; // lock-step with the producer // An immutable ByteBuffer sentinel to mark that the last byte was received. private static final ByteBuffer LAST_BUFFER = ByteBuffer.wrap(new byte[0]); @@ -886,7 +886,7 @@ Flow.Subscriber> clear() { // A subscription that wraps an upstream subscription and // holds a reference to a subscriber. The subscriber reference // is cleared when the subscription is cancelled - final static class SubscriptionRef implements Flow.Subscription { + static final class SubscriptionRef implements Flow.Subscription { final Flow.Subscription subscription; final SubscriberRef subscriberRef; SubscriptionRef(Flow.Subscription subscription, diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java b/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java index dfbe9e6b3397b..1ef602eb90cf9 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java @@ -226,7 +226,7 @@ void debugState(String when) { * signaled. It is the responsibility of the code triggered by * {@code signalEvent} to resume the event if required. */ - private static abstract class SocketFlowEvent extends AsyncEvent { + private abstract static class SocketFlowEvent extends AsyncEvent { final SocketChannel channel; final int defaultInterest; volatile int interestOps; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/DebugLogger.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/DebugLogger.java index 57358e33bcc11..01f962f5bbe5d 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/DebugLogger.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/DebugLogger.java @@ -46,19 +46,19 @@ */ final class DebugLogger implements Logger { // deliberately not in the same subtree than standard loggers. - final static String HTTP_NAME = "jdk.internal.httpclient.debug"; - final static String WS_NAME = "jdk.internal.httpclient.websocket.debug"; - final static String HPACK_NAME = "jdk.internal.httpclient.hpack.debug"; - final static System.Logger HTTP = System.getLogger(HTTP_NAME); - final static System.Logger WS = System.getLogger(WS_NAME); - final static System.Logger HPACK = System.getLogger(HPACK_NAME); + static final String HTTP_NAME = "jdk.internal.httpclient.debug"; + static final String WS_NAME = "jdk.internal.httpclient.websocket.debug"; + static final String HPACK_NAME = "jdk.internal.httpclient.hpack.debug"; + static final System.Logger HTTP = System.getLogger(HTTP_NAME); + static final System.Logger WS = System.getLogger(WS_NAME); + static final System.Logger HPACK = System.getLogger(HPACK_NAME); private static final DebugLogger NO_HTTP_LOGGER = new DebugLogger(HTTP, "HTTP"::toString, Level.OFF, Level.OFF); private static final DebugLogger NO_WS_LOGGER = new DebugLogger(HTTP, "WS"::toString, Level.OFF, Level.OFF); private static final DebugLogger NO_HPACK_LOGGER = new DebugLogger(HTTP, "HPACK"::toString, Level.OFF, Level.OFF); - final static long START_NANOS = System.nanoTime(); + static final long START_NANOS = System.nanoTime(); private final Supplier dbgTag; private final Level errLevel; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/FlowTube.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/FlowTube.java index f079f400c123b..023086e3dee5f 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/FlowTube.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/FlowTube.java @@ -138,7 +138,7 @@ static TubePublisher asTubePublisher(Flow.Publisher> p) { * It is not required that a {@code TubePublisher} implementation extends * this class. */ - static abstract class AbstractTubePublisher implements TubePublisher { + abstract static class AbstractTubePublisher implements TubePublisher { static final class TubePublisherWrapper extends AbstractTubePublisher { final Flow.Publisher> delegate; public TubePublisherWrapper(Flow.Publisher> delegate) { @@ -156,7 +156,7 @@ public void subscribe(Flow.Subscriber> subscriber) { * It is not required that a {@code TubeSubscriber} implementation extends * this class. */ - static abstract class AbstractTubeSubscriber implements TubeSubscriber { + abstract static class AbstractTubeSubscriber implements TubeSubscriber { static final class TubeSubscriberWrapper extends AbstractTubeSubscriber { final Flow.Subscriber> delegate; TubeSubscriberWrapper(Flow.Subscriber> delegate) { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/MinimalFuture.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/MinimalFuture.java index 8fc79b0437cc0..ddbcce661aa17 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/MinimalFuture.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/MinimalFuture.java @@ -42,7 +42,7 @@ public interface ExceptionalSupplier { U get() throws Throwable; } - private final static AtomicLong TOKENS = new AtomicLong(); + private static final AtomicLong TOKENS = new AtomicLong(); private final long id; private final Cancelable cancelable; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLTube.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLTube.java index 620b9af372e9e..42174ef9c44fe 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLTube.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLTube.java @@ -184,7 +184,7 @@ public boolean isFinished() { // The DelegateWrapper wraps a subscribed {@code Flow.Subscriber} and // tracks the subscriber's state. In particular it makes sure that // onComplete/onError are not called before onSubscribed. - final static class DelegateWrapper implements FlowTube.TubeSubscriber { + static final class DelegateWrapper implements FlowTube.TubeSubscriber { private final FlowTube.TubeSubscriber delegate; private final Logger debug; volatile boolean subscribedCalled; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/SequentialScheduler.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/SequentialScheduler.java index 499aa944ac38b..88809ec0678a5 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/SequentialScheduler.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/SequentialScheduler.java @@ -111,7 +111,7 @@ TryEndDeferredCompleter that this ("parent") TryEndDeferredCompleter is * later time, and maybe in different thread. This type exists for * readability purposes at use-sites only. */ - public static abstract class DeferredCompleter { + public abstract static class DeferredCompleter { /** Extensible from this (outer) class ONLY. */ private DeferredCompleter() { } @@ -140,7 +140,7 @@ public interface RestartableTask { * A simple and self-contained task that completes once its {@code run} * method returns. */ - public static abstract class CompleteRestartableTask + public abstract static class CompleteRestartableTask implements RestartableTask { @Override From 01ed3d2334f7be9a2dd5207f585ad61c51b2436e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 27 Jun 2025 09:14:48 +0000 Subject: [PATCH 358/846] 8276681: Additional malformed Javadoc inline tags in JDK source Reviewed-by: mdoerr, mbaesken Backport-of: b8ac0d20ceec26b3a1dd0b9577817fa6320ea9ef --- .../sun/java/swing/plaf/windows/AnimationController.java | 2 +- .../javax/management/modelmbean/RequiredModelMBean.java | 2 +- .../classes/jdk/internal/net/http/ResponseSubscribers.java | 2 +- .../share/classes/java/rmi/server/RemoteObject.java | 6 +++--- .../internal/security/signature/SignatureProperties.java | 2 +- .../share/classes/com/sun/source/util/Trees.java | 2 +- .../DesktopEventsExceptions/DesktopEventsExceptions.java | 2 +- .../awt/regtesthelpers/process/ProcessCommunicator.java | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/AnimationController.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/AnimationController.java index 05c2f5c0a40cb..b50a5ad583ec5 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/AnimationController.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/AnimationController.java @@ -59,7 +59,7 @@ *
  • It tracks the animation state for every UI component involved in the * animation and paints {@code Skin} in new {@code State} over the * {@code Skin} in last {@code State} using - * {@code AlphaComposite.SrcOver.derive(alpha)} where {code alpha} + * {@code AlphaComposite.SrcOver.derive(alpha)} where {@code alpha} * depends on the state of animation * * diff --git a/src/java.management/share/classes/javax/management/modelmbean/RequiredModelMBean.java b/src/java.management/share/classes/javax/management/modelmbean/RequiredModelMBean.java index c706ababeca75..9b865081d4392 100644 --- a/src/java.management/share/classes/javax/management/modelmbean/RequiredModelMBean.java +++ b/src/java.management/share/classes/javax/management/modelmbean/RequiredModelMBean.java @@ -192,7 +192,7 @@ public RequiredModelMBean() * * @exception MBeanException Wraps a distributed communication Exception. * @exception RuntimeOperationsException Wraps an - * {link java.lang.IllegalArgumentException}: + * {@link java.lang.IllegalArgumentException}: * The MBeanInfo passed in parameter is null. * **/ diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java index 0413274c068c0..e7b4ff806d03f 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java @@ -1090,7 +1090,7 @@ public static CompletionStage getBodyAsync(Executor e, BodySubscriber * Invokes bs::getBody using the provided executor. * If invoking bs::getBody requires an executor, and the given executor * is a {@link HttpClientImpl.DelegatingExecutor}, then the executor's - * delegate is used. If an error occurs anywhere then the given {code cf} + * delegate is used. If an error occurs anywhere then the given {@code cf} * is completed exceptionally (this method does not throw). * @param e The executor that should be used to call bs::getBody * @param bs The BodySubscriber diff --git a/src/java.rmi/share/classes/java/rmi/server/RemoteObject.java b/src/java.rmi/share/classes/java/rmi/server/RemoteObject.java index 4bf8367865ea0..2d765ae07ffa4 100644 --- a/src/java.rmi/share/classes/java/rmi/server/RemoteObject.java +++ b/src/java.rmi/share/classes/java/rmi/server/RemoteObject.java @@ -251,7 +251,7 @@ public String toString() { * written by {@link java.io.ObjectOutput#writeInt(int)} * *
  • the data written as a result of calling - * {link java.rmi.server.ObjID#write(java.io.ObjectOutput)} + * {@link java.rmi.server.ObjID#write(java.io.ObjectOutput)} * on the ObjID instance contained in the reference * *
  • the boolean value false, @@ -275,7 +275,7 @@ public String toString() { * written by {@link java.io.ObjectOutput#writeInt(int)} * *
  • the data written as a result of calling - * {link java.rmi.server.ObjID#write(java.io.ObjectOutput)} + * {@link java.rmi.server.ObjID#write(java.io.ObjectOutput)} * on the ObjID instance contained in the reference * *
  • the boolean value false, @@ -304,7 +304,7 @@ public String toString() { * writeObject on the stream instance * *
  • the data written as a result of calling - * {link java.rmi.server.ObjID#write(java.io.ObjectOutput)} + * {@link java.rmi.server.ObjID#write(java.io.ObjectOutput)} * on the ObjID instance contained in the reference * *
  • the boolean value false, diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperties.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperties.java index 3e5c7e316fcbf..8434b291c94d0 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperties.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperties.java @@ -88,7 +88,7 @@ public int getLength() { /** * Return the ith SignatureProperty. Valid {@code i} - * values are 0 to {@code {link@ getSize}-1}. + * values are 0 to {@code {@link getSize}-1}. * * @param i Index of the requested {@link SignatureProperty} * @return the ith SignatureProperty diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/Trees.java b/src/jdk.compiler/share/classes/com/sun/source/util/Trees.java index 220df8ea03934..7a874ac553295 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/util/Trees.java +++ b/src/jdk.compiler/share/classes/com/sun/source/util/Trees.java @@ -72,7 +72,7 @@ public static Trees instance(CompilationTask task) { } /** - * Returns a Trees object for a given ProcessingEnvironment. + * Returns a {@code Trees} object for a given ProcessingEnvironment. * @param env the processing environment for which to get the Trees object * @throws IllegalArgumentException if the env does not support the Trees API. * @return the Trees object diff --git a/test/jdk/java/awt/Desktop/DesktopEventsExceptions/DesktopEventsExceptions.java b/test/jdk/java/awt/Desktop/DesktopEventsExceptions/DesktopEventsExceptions.java index 2a1b88d7d7336..83a35b71a120f 100644 --- a/test/jdk/java/awt/Desktop/DesktopEventsExceptions/DesktopEventsExceptions.java +++ b/test/jdk/java/awt/Desktop/DesktopEventsExceptions/DesktopEventsExceptions.java @@ -45,7 +45,7 @@ * @test * @bug 8203224 * @summary tests that the correct exceptions are thrown by the events classes - * in {code java.awt.desktop} package + * in {@code java.awt.desktop} package * @run main/othervm DesktopEventsExceptions * @run main/othervm -Djava.awt.headless=true DesktopEventsExceptions */ diff --git a/test/jdk/java/awt/regtesthelpers/process/ProcessCommunicator.java b/test/jdk/java/awt/regtesthelpers/process/ProcessCommunicator.java index 60a5952b32c03..474a23717ea91 100644 --- a/test/jdk/java/awt/regtesthelpers/process/ProcessCommunicator.java +++ b/test/jdk/java/awt/regtesthelpers/process/ProcessCommunicator.java @@ -76,7 +76,7 @@ public static ProcessResults executeChildProcess(final Class classToExecute, } /** - * Executes child {code Process} + * Executes child {@code Process} * * @param classToExecute class to be executed as a child java process * @param args args to be passed in to the child process From bad5a100e77c91c2cc8c7524229d028c6bbce83c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 27 Jun 2025 09:16:12 +0000 Subject: [PATCH 359/846] 8298931: java/net/httpclient/CancelStreamedBodyTest.java fails with AssertionError due to Pending TCP connections: 1 Backport-of: 5df00d34fe83648fb833dac738a45653865ca426 --- .../httpclient/CancelStreamedBodyTest.java | 5 +-- .../java/net/httpclient/ISO_8859_1_Test.java | 2 +- .../java/net/httpclient/ReferenceTracker.java | 32 +++++++++++++++---- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java b/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java index 99a773a042ac7..f3603982c4923 100644 --- a/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java +++ b/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java @@ -102,6 +102,7 @@ public class CancelStreamedBodyTest implements HttpServerAdapters { static final long SERVER_LATENCY = 75; static final int ITERATION_COUNT = 3; + static final long CLIENT_SHUTDOWN_GRACE_DELAY = 1500; // milliseconds // a shared executor helps reduce the amount of threads created by the test static final Executor executor = new TestExecutor(Executors.newCachedThreadPool()); static final ConcurrentMap FAILURES = new ConcurrentHashMap<>(); @@ -285,7 +286,7 @@ public void testAsLines(String uri, boolean sameClient) if (sameClient) continue; client = null; System.gc(); - var error = TRACKER.check(tracker, 500); + var error = TRACKER.check(tracker, CLIENT_SHUTDOWN_GRACE_DELAY); if (error != null) throw error; } } @@ -327,7 +328,7 @@ public void testInputStream(String uri, boolean sameClient) if (sameClient) continue; client = null; System.gc(); - var error = TRACKER.check(tracker, 1); + var error = TRACKER.check(tracker, CLIENT_SHUTDOWN_GRACE_DELAY); if (error != null) throw error; } } diff --git a/test/jdk/java/net/httpclient/ISO_8859_1_Test.java b/test/jdk/java/net/httpclient/ISO_8859_1_Test.java index 4e3f428dbfb3b..e81b013041894 100644 --- a/test/jdk/java/net/httpclient/ISO_8859_1_Test.java +++ b/test/jdk/java/net/httpclient/ISO_8859_1_Test.java @@ -445,7 +445,7 @@ public void teardown() throws Exception { sharedClient == null ? null : sharedClient.toString(); sharedClient = null; Thread.sleep(100); - AssertionError fail = TRACKER.check(500); + AssertionError fail = TRACKER.check(1500); try { http1TestServer.stop(); https1TestServer.stop(); diff --git a/test/jdk/java/net/httpclient/ReferenceTracker.java b/test/jdk/java/net/httpclient/ReferenceTracker.java index 32734deea4772..ae55f969c7173 100644 --- a/test/jdk/java/net/httpclient/ReferenceTracker.java +++ b/test/jdk/java/net/httpclient/ReferenceTracker.java @@ -214,12 +214,15 @@ public AssertionError check(Tracker tracker, long waitStart = System.nanoTime(); long waited = 0; long toWait = Math.min(graceDelayMs, Math.max(delay, 1)); - for (int i = 0; i < count; i++) { + int i = 0; + for (i = 0; i < count; i++) { if (hasOutstanding.test(tracker)) { System.gc(); try { if (i == 0) { System.out.println("Waiting for HTTP operations to terminate..."); + System.out.println("\tgracedelay: " + graceDelayMs + + " ms, iterations: " + count + ", wait/iteration: " + toWait + "ms"); } waited += toWait; Thread.sleep(toWait); @@ -250,7 +253,8 @@ public AssertionError check(Tracker tracker, printThreads(msg, System.err); } System.out.println("AssertionError: Found some " + description + " in " - + tracker.getName() + " after " + duration + " ms, waited " + waited + " ms"); + + tracker.getName() + " after " + i + " iterations and " + duration + + " ms, waited " + waited + " ms"); } return fail; } @@ -261,21 +265,34 @@ public AssertionError check(long graceDelayMs, boolean printThreads) { AssertionError fail = null; graceDelayMs = Math.max(graceDelayMs, 100); + long waitStart = System.nanoTime(); long delay = Math.min(graceDelayMs, 10); + long toWait = Math.min(graceDelayMs, Math.max(delay, 1)); + long waited = 0; var count = delay > 0 ? graceDelayMs / delay : 1; - for (int i = 0; i < count; i++) { + int i = 0; + for (i = 0; i < count; i++) { if (TRACKERS.stream().anyMatch(hasOutstanding)) { System.gc(); try { if (i == 0) { System.out.println("Waiting for HTTP operations to terminate..."); + System.out.println("\tgracedelay: " + graceDelayMs + + " ms, iterations: " + count + ", wait/iteration: " + toWait + "ms"); } - Thread.sleep(Math.min(graceDelayMs, Math.max(delay, 1))); + waited += toWait; + Thread.sleep(toWait); } catch (InterruptedException x) { // OK } - } else break; + } else { + System.out.println("No outstanding HTTP operations remaining after " + + i + "/" + count + " iterations and " + waited + "/" + graceDelayMs + + " ms, (wait/iteration " + toWait + " ms)"); + break; + } } + long duration = Duration.ofNanos(System.nanoTime() - waitStart).toMillis(); if (TRACKERS.stream().anyMatch(hasOutstanding)) { StringBuilder warnings = diagnose(new StringBuilder(), hasOutstanding); addSummary(warnings); @@ -284,7 +301,7 @@ public AssertionError check(long graceDelayMs, } } else { System.out.println("PASSED: No " + description + " found in " - + getTrackedClientCount() + " clients"); + + getTrackedClientCount() + " clients in " + duration + " ms"); } if (fail != null) { Predicate isAlive = Tracker::isSelectorAlive; @@ -292,6 +309,9 @@ public AssertionError check(long graceDelayMs, printThreads("Some selector manager threads are still alive: ", System.out); printThreads("Some selector manager threads are still alive: ", System.err); } + System.out.println("AssertionError: Found some " + description + " in " + + getTrackedClientCount() + " clients after " + i + " iterations and " + duration + + " ms, waited " + waited + " ms"); } return fail; } From 759dc5fbd56ecb9f68e06dab648feb4560153ec1 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 27 Jun 2025 09:18:45 +0000 Subject: [PATCH 360/846] 8328089: Automate javax/swing/JTable/4222153/bug4222153.java applet test Backport-of: f6390e5f801a3e25bda591e30e49db86519bf028 --- .../swing/JTable/4222153/bug4222153.html | 31 ----- .../swing/JTable/4222153/bug4222153.java | 48 ------- test/jdk/javax/swing/JTable/bug4222153.java | 117 ++++++++++++++++++ 3 files changed, 117 insertions(+), 79 deletions(-) delete mode 100644 test/jdk/javax/swing/JTable/4222153/bug4222153.html delete mode 100644 test/jdk/javax/swing/JTable/4222153/bug4222153.java create mode 100644 test/jdk/javax/swing/JTable/bug4222153.java diff --git a/test/jdk/javax/swing/JTable/4222153/bug4222153.html b/test/jdk/javax/swing/JTable/4222153/bug4222153.html deleted file mode 100644 index efa7e634c53de..0000000000000 --- a/test/jdk/javax/swing/JTable/4222153/bug4222153.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - -Click in the upper-left cell and then press TAB two times. -If table cell selection is not on the left cell of the second row -then test fails. - - - diff --git a/test/jdk/javax/swing/JTable/4222153/bug4222153.java b/test/jdk/javax/swing/JTable/4222153/bug4222153.java deleted file mode 100644 index 75871c59974e6..0000000000000 --- a/test/jdk/javax/swing/JTable/4222153/bug4222153.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import javax.swing.JApplet; -import javax.swing.JTable; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; - -/** - * @test - * @bug 4222153 - * @author Konstantin Eremin - * @run applet/manual=yesno bug4222153.html - */ -public class bug4222153 extends JApplet { - - public void init() { - SwingUtilities.invokeLater(() -> { - try { - UIManager.setLookAndFeel( - "javax.swing.plaf.metal.MetalLookAndFeel"); - } catch (Exception e) { - throw new RuntimeException(e); - } - getContentPane().add(new JTable(2, 2)); - }); - } -} diff --git a/test/jdk/javax/swing/JTable/bug4222153.java b/test/jdk/javax/swing/JTable/bug4222153.java new file mode 100644 index 0000000000000..7d37c3d083039 --- /dev/null +++ b/test/jdk/javax/swing/JTable/bug4222153.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +import javax.swing.JFrame; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +/* + * @test + * @bug 4222153 + * @key headful + * @summary Verify that when tab is pressed, the focus shift to next row first cell, + * if the current selected cell is the last cell in that row. + * @run main bug4222153 + */ + +public class bug4222153 { + private static JFrame frame; + private static JTable table; + private static volatile Point tableLoc; + private static volatile Rectangle cellRect; + private static volatile int selectedRowBeforeTabPress; + private static volatile int selectedColumnBeforeTabPress; + private static volatile int selectedRowAfterTabPress; + private static volatile int selectedColumnAfterTabPress; + + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + Robot robot = new Robot(); + robot.setAutoDelay(50); + try { + SwingUtilities.invokeAndWait(bug4222153::createAndShowUI); + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + tableLoc = table.getLocationOnScreen(); + cellRect = table.getCellRect(0, 0, true); + }); + + robot.mouseMove(tableLoc.x + cellRect.x + cellRect.width / 2, + tableLoc.y + cellRect.y + cellRect.height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.delay(20); + + SwingUtilities.invokeAndWait(() -> { + selectedRowBeforeTabPress = table.getSelectedRow(); + selectedColumnBeforeTabPress = table.getSelectedColumn(); + }); + + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + robot.waitForIdle(); + robot.delay(20); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + robot.waitForIdle(); + robot.delay(20); + + SwingUtilities.invokeAndWait(() -> { + selectedRowAfterTabPress = table.getSelectedRow(); + selectedColumnAfterTabPress = table.getSelectedColumn(); + }); + + if (selectedRowAfterTabPress != (selectedRowBeforeTabPress + 1) + && selectedColumnAfterTabPress != selectedColumnBeforeTabPress) { + throw new RuntimeException("JTable's cell focus didn't shift to next" + + " row first cell on TAB press"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + frame = new JFrame("Test JTable Tab Press"); + table = new JTable(2, 2); + frame.getContentPane().add(table); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setVisible(true); + } +} From b5f7d6427c8b81f40d17222cf33c7b70da8bd395 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 27 Jun 2025 09:19:55 +0000 Subject: [PATCH 361/846] 8203867: Delete test java/awt/TrayIcon/DblClickActionEventTest/DblClickActionEventTest.html Backport-of: 605800e5abd244c57a421f3a511a79c531583471 --- test/jdk/ProblemList.txt | 1 - .../DblClickActionEventTest.html | 48 -------- .../DblClickActionEventTest.java | 116 ------------------ 3 files changed, 165 deletions(-) delete mode 100644 test/jdk/java/awt/TrayIcon/DblClickActionEventTest/DblClickActionEventTest.html delete mode 100644 test/jdk/java/awt/TrayIcon/DblClickActionEventTest/DblClickActionEventTest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 6a6fa1e54e449..3be9fa08146ed 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -834,7 +834,6 @@ java/awt/event/MouseEvent/AltGraphModifierTest/AltGraphModifierTest.java 8162380 java/awt/image/VolatileImage/VolatileImageConfigurationTest.java 8171069 macosx-all,linux-all java/awt/Modal/InvisibleParentTest/InvisibleParentTest.java 8172245 linux-all java/awt/print/Dialog/RestoreActiveWindowTest/RestoreActiveWindowTest.java 8185429 macosx-all -java/awt/TrayIcon/DblClickActionEventTest/DblClickActionEventTest.html 8203867 macosx-all java/awt/Frame/FrameStateTest/FrameStateTest.java 8203920 macosx-all,linux-all javax/swing/SwingUtilities/TestTextPosInPrint.java 8227025 windows-all java/awt/print/PrinterJob/ScaledText/ScaledText.java 8231226 macosx-all diff --git a/test/jdk/java/awt/TrayIcon/DblClickActionEventTest/DblClickActionEventTest.html b/test/jdk/java/awt/TrayIcon/DblClickActionEventTest/DblClickActionEventTest.html deleted file mode 100644 index bb92e6990fe44..0000000000000 --- a/test/jdk/java/awt/TrayIcon/DblClickActionEventTest/DblClickActionEventTest.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - DblClickActionEventTest - - - -

    DblClickActionEventTest
    Bug ID: 6284070

    - -

    See the dialog box (usually in upper left corner) for instructions

    - - - - diff --git a/test/jdk/java/awt/TrayIcon/DblClickActionEventTest/DblClickActionEventTest.java b/test/jdk/java/awt/TrayIcon/DblClickActionEventTest/DblClickActionEventTest.java deleted file mode 100644 index e3c4bc916098f..0000000000000 --- a/test/jdk/java/awt/TrayIcon/DblClickActionEventTest/DblClickActionEventTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 6284070 - @summary Tests that ActionEvent is generated when a tray icon is double-clicked - @library ../../regtesthelpers - @build Sysout - @author artem.ananiev: area=awt.tray - @run applet/manual=yesno DblClickActionEventTest.html -*/ - -import java.applet.*; - -import java.awt.*; -import java.awt.event.*; -import java.awt.image.*; - -import jdk.test.lib.Platform; -import test.java.awt.regtesthelpers.Sysout; - -public class DblClickActionEventTest extends Applet { - boolean traySupported; - - public void init() { - this.setLayout(new BorderLayout()); - - String[] instructions; - traySupported = SystemTray.isSupported(); - if (traySupported) { - String clickInstruction; - if (Platform.isOSX()) { - clickInstruction = "right"; - } else { - clickInstruction = "left"; - } - instructions = new String[]{ - "When the test starts an icon is added to the SystemTray area.", - " Double-click on it with a " + clickInstruction + " button and make sure that", - " ACTION_PERFORMED event is sent to Java (all the clicks and", - " action events are shown below these instructions).", - "Then, if your system allows the tray icon to get focus (for", - " example, windows 2000 or windows XP), double-click on the", - " icon with SPACE button and single-click with RETURN button.", - " Both of them must also trigger ACTION_PERFORMED event.", - "If you see ACTION_PERFORMED events after each of your actions", - " (either mouse clicks or key presses), press PASS, else FAIL" - }; - } else { - instructions = new String[]{ - "The test cannot be run because SystemTray is not supported.", - "Simply press PASS button." - }; - } - Sysout.createDialogWithInstructions(instructions); - } - - public void start() { - setSize(200, 200); - setVisible(true); - validate(); - - if (!traySupported) { - return; - } - - BufferedImage img = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB); - Graphics g = img.createGraphics(); - g.setColor(Color.WHITE); - g.fillRect(0, 0, 32, 32); - g.setColor(Color.RED); - g.fillRect(6, 6, 20, 20); - g.dispose(); - - SystemTray tray = SystemTray.getSystemTray(); - TrayIcon icon = new TrayIcon(img); - icon.setImageAutoSize(true); - icon.addActionListener(ev -> Sysout.println(ev.toString())); - icon.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent ev) { - Sysout.println(ev.toString()); - } - } - ); - - try { - tray.add(icon); - } catch (AWTException e) { - Sysout.println(e.toString()); - Sysout.println("!!! The test coudn't be performed !!!"); - } - } -} - From 2dc6bac7bf3c39ad35b2db2c70d839130de036b9 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Fri, 27 Jun 2025 09:21:12 +0000 Subject: [PATCH 362/846] 8328087: Automate javax/swing/JTable/TAB/TAB.java applet test Backport-of: 5249cc0a79f05b71f4c31bb6b02775976eef77aa --- test/jdk/javax/swing/JTable/TAB/TAB.html | 43 ----- .../swing/JTable/{TAB/TAB.java => Tab.java} | 154 ++++++++++++------ 2 files changed, 105 insertions(+), 92 deletions(-) delete mode 100644 test/jdk/javax/swing/JTable/TAB/TAB.html rename test/jdk/javax/swing/JTable/{TAB/TAB.java => Tab.java} (54%) diff --git a/test/jdk/javax/swing/JTable/TAB/TAB.html b/test/jdk/javax/swing/JTable/TAB/TAB.html deleted file mode 100644 index 7c37825365997..0000000000000 --- a/test/jdk/javax/swing/JTable/TAB/TAB.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - Tabbing test - - - -

    Tabbing test

    - - - -

    - Select a cell by double clicking it, press tab. Check that the focus moves to the next cell. - If it does, press "pass", otherwise press "fail". -


    -
    Philip Milne
    - - - - diff --git a/test/jdk/javax/swing/JTable/TAB/TAB.java b/test/jdk/javax/swing/JTable/Tab.java similarity index 54% rename from test/jdk/javax/swing/JTable/TAB/TAB.java rename to test/jdk/javax/swing/JTable/Tab.java index 8c4f7035772b9..ebda63bc88b75 100644 --- a/test/jdk/javax/swing/JTable/TAB/TAB.java +++ b/test/jdk/javax/swing/JTable/Tab.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,12 +22,16 @@ */ import java.awt.Color; -import java.awt.Container; import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; import javax.swing.DefaultCellEditor; -import javax.swing.JApplet; import javax.swing.JComboBox; +import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTable; @@ -40,43 +44,105 @@ import javax.swing.table.TableColumn; import javax.swing.table.TableModel; -/** +/* * @test * @bug 4128521 - * @summary - * Tabbing test - * @author milne - * @run applet/manual=yesno TAB.html + * @key headful + * @summary Verify focus changes correctly when tab is pressed while editing + * a JTextField in a JTable + * @run main Tab */ -public class TAB extends JApplet -{ - static void initTest(Container contentPane) - { + +public class Tab { + private static Robot robot; + private static JFrame frame; + private static JTable tableView; + private static volatile Point tableLoc; + private static volatile Rectangle cellRect; + private static volatile int selectedRowBeforeTabPress; + private static volatile int selectedColumnBeforeTabPress; + private static volatile int selectedRowAfterTabPress; + private static volatile int selectedColumnAfterTabPress; + + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + robot = new Robot(); + robot.setAutoDelay(50); + try { + SwingUtilities.invokeAndWait(Tab::createAndShowUI); + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + tableLoc = tableView.getLocationOnScreen(); + cellRect = tableView.getCellRect(2, 1, true); + }); + + robot.mouseMove(tableLoc.x + cellRect.x + cellRect.width / 2, + tableLoc.y + cellRect.y + cellRect.height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.delay(20); + + SwingUtilities.invokeAndWait(() -> { + selectedRowBeforeTabPress = tableView.getSelectedRow(); + selectedColumnBeforeTabPress = tableView.getSelectedColumn(); + }); + + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + robot.waitForIdle(); + robot.delay(20); + + SwingUtilities.invokeAndWait(() -> { + selectedRowAfterTabPress = tableView.getSelectedRow(); + selectedColumnAfterTabPress = tableView.getSelectedColumn(); + }); + + if (selectedRowAfterTabPress != selectedRowBeforeTabPress + && selectedColumnAfterTabPress != (selectedColumnBeforeTabPress + 1)) { + throw new RuntimeException("JTable's cell focus didn't move to next" + + " cell on TAB press"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + static void createAndShowUI() { + frame = new JFrame("Test JTable's Focus Component"); // Take the dummy data from SwingSet. final String[] names = {"First Name", "Last Name", "Favorite Color", "Favorite Number", "Vegetarian"}; final Object[][] data = { - {"Mark", "Andrews", "Red", new Integer(2), new Boolean(true)}, - {"Tom", "Ball", "Blue", new Integer(99), new Boolean(false)}, - {"Alan", "Chung", "Green", new Integer(838), new Boolean(false)}, - {"Jeff", "Dinkins", "Turquois", new Integer(8), new Boolean(true)}, - {"Amy", "Fowler", "Yellow", new Integer(3), new Boolean(false)}, - {"Brian", "Gerhold", "Green", new Integer(0), new Boolean(false)}, - {"James", "Gosling", "Pink", new Integer(21), new Boolean(false)}, - {"David", "Karlton", "Red", new Integer(1), new Boolean(false)}, - {"Dave", "Kloba", "Yellow", new Integer(14), new Boolean(false)}, - {"Peter", "Korn", "Purple", new Integer(12), new Boolean(false)}, - {"Phil", "Milne", "Purple", new Integer(3), new Boolean(false)}, - {"Dave", "Moore", "Green", new Integer(88), new Boolean(false)}, - {"Hans", "Muller", "Maroon", new Integer(5), new Boolean(false)}, - {"Rick", "Levenson", "Blue", new Integer(2), new Boolean(false)}, - {"Tim", "Prinzing", "Blue", new Integer(22), new Boolean(false)}, - {"Chester", "Rose", "Black", new Integer(0), new Boolean(false)}, - {"Ray", "Ryan", "Gray", new Integer(77), new Boolean(false)}, - {"Georges", "Saab", "Red", new Integer(4), new Boolean(false)}, - {"Willie", "Walker", "Phthalo Blue", new Integer(4), new Boolean(false)}, - {"Kathy", "Walrath", "Blue", new Integer(8), new Boolean(false)}, - {"Arnaud", "Weber", "Green", new Integer(44), new Boolean(false)} + {"Mark", "Andrews", "Red", 2, true}, + {"Tom", "Ball", "Blue", 99, false}, + {"Alan", "Chung", "Green", 838, false}, + {"Jeff", "Dinkins", "Turquois", 8, true}, + {"Amy", "Fowler", "Yellow", 3, false}, + {"Brian", "Gerhold", "Green", 0, false}, + {"James", "Gosling", "Pink", 21, false}, + {"David", "Karlton", "Red", 1, false}, + {"Dave", "Kloba", "Yellow", 14, false}, + {"Peter", "Korn", "Purple", 12, false}, + {"Phil", "Milne", "Purple", 3, false}, + {"Dave", "Moore", "Green", 88, false}, + {"Hans", "Muller", "Maroon", 5, false}, + {"Rick", "Levenson", "Blue", 2, false}, + {"Tim", "Prinzing", "Blue", 22, false}, + {"Chester", "Rose", "Black", 0, false}, + {"Ray", "Ryan", "Gray", 77, false}, + {"Georges", "Saab", "Red", 4, false}, + {"Willie", "Walker", "Phthalo Blue", 4, false}, + {"Kathy", "Walrath", "Blue", 8, false}, + {"Arnaud", "Weber", "Green", 44, false} }; // Create a model of the data. @@ -98,7 +164,7 @@ public void setValueAt(Object aValue, int row, int column) { }; // Create the table - JTable tableView = new JTable(dataModel); + tableView = new JTable(dataModel); // Turn off auto-resizing so that we can set column sizes programmatically. // In this mode, all columns will get their preferred widths, as set blow. tableView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); @@ -150,20 +216,10 @@ public void setValue(Object value) { scrollpane.setBorder(new BevelBorder(BevelBorder.LOWERED)); scrollpane.setPreferredSize(new Dimension(430, 200)); - contentPane.add(scrollpane); - } - - - public void init() { - SwingUtilities.invokeLater(() -> { - try { - UIManager.setLookAndFeel( - "javax.swing.plaf.metal.MetalLookAndFeel"); - } catch (Exception e) { - throw new RuntimeException(e); - } - - initTest(getContentPane()); - }); + frame.getContentPane().add(scrollpane); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setVisible(true); } } From a897ee8cb0602d374d6bcbe7c28bf5d38b804e8b Mon Sep 17 00:00:00 2001 From: Dmitry Chuyko Date: Fri, 27 Jun 2025 17:53:23 +0000 Subject: [PATCH 363/846] 8351933: Inaccurate masking of TC subfield decrement in ForkJoinPool Reviewed-by: phh, dl --- .../share/classes/java/util/concurrent/ForkJoinPool.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java index 1f029bc022dd2..16d538364416a 100644 --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java @@ -1725,7 +1725,7 @@ else if (deadline == 0L) else if (deadline - System.currentTimeMillis() > TIMEOUT_SLOP) LockSupport.parkUntil(deadline); else if (((int)c & SMASK) == (w.config & SMASK) && - compareAndSetCtl(c, ((UC_MASK & (c - TC_UNIT)) | + compareAndSetCtl(c, ((c & RC_MASK) | ((c - TC_UNIT) & TC_MASK) | (prevCtl & SP_MASK)))) { w.config |= QUIET; // sentinel for deregisterWorker return -1; // drop on timeout From c5f41eba4dc12fded813d7b6b302cc7a8f0b2e10 Mon Sep 17 00:00:00 2001 From: Patrick Zhang Date: Sun, 29 Jun 2025 09:50:50 +0000 Subject: [PATCH 364/846] 8350483: AArch64: turn on signum intrinsics by default on Ampere CPUs Backport-of: f529bf712d8946584999dfc98abea60c22c97167 --- src/hotspot/cpu/aarch64/vm_version_aarch64.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index 8e3dbfd5db779..55444db3da51f 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -157,6 +157,9 @@ void VM_Version::initialize() { if (FLAG_IS_DEFAULT(OnSpinWaitInstCount)) { FLAG_SET_DEFAULT(OnSpinWaitInstCount, 2); } + if (FLAG_IS_DEFAULT(UseSignumIntrinsic)) { + FLAG_SET_DEFAULT(UseSignumIntrinsic, true); + } } // ThunderX From f40b56e12dd26b15bd2c1364332162620cbbf4a5 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Mon, 30 Jun 2025 09:57:04 +0000 Subject: [PATCH 365/846] 8339725: Concurrent GC crashed due to GetMethodDeclaringClass Reviewed-by: phh Backport-of: c91fa278fe17ab204beef0fcef1ada6dd0bc37bb --- make/test/JtregNativeHotspot.gmk | 3 +- src/hotspot/share/prims/jvmtiEnv.cpp | 8 +- src/hotspot/share/prims/jvmtiEnvBase.cpp | 1 + .../TestUnloadedClass.java | 106 ++++++++++++++ .../libTestUnloadedClass.cpp | 129 ++++++++++++++++++ 5 files changed, 244 insertions(+), 3 deletions(-) create mode 100644 test/hotspot/jtreg/serviceability/jvmti/GetMethodDeclaringClass/TestUnloadedClass.java create mode 100644 test/hotspot/jtreg/serviceability/jvmti/GetMethodDeclaringClass/libTestUnloadedClass.cpp diff --git a/make/test/JtregNativeHotspot.gmk b/make/test/JtregNativeHotspot.gmk index cd03747d98d8c..27623c3db853c 100644 --- a/make/test/JtregNativeHotspot.gmk +++ b/make/test/JtregNativeHotspot.gmk @@ -873,7 +873,7 @@ BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exesigtest := -ljvm ifeq ($(call isTargetOs, windows), true) BUILD_HOTSPOT_JTREG_EXECUTABLES_CFLAGS_exeFPRegs := -MT - BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libnativeStack.c exeGetCreatedJavaVMs.c + BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libnativeStack.c exeGetCreatedJavaVMs.c libTestUnloadedClass.cpp BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit := jvm.lib else BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libbootclssearch_agent += -lpthread @@ -1511,6 +1511,7 @@ else BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libterminatedThread += -lpthread BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit += -ljvm BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libnativeStack += -lpthread + BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libTestUnloadedClass += -lpthread BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeGetCreatedJavaVMs := -ljvm -lpthread endif diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp index f04dc7dd27ca2..ccb35889f5d70 100644 --- a/src/hotspot/share/prims/jvmtiEnv.cpp +++ b/src/hotspot/share/prims/jvmtiEnv.cpp @@ -2747,7 +2747,9 @@ JvmtiEnv::GetFieldName(fieldDescriptor* fdesc_ptr, char** name_ptr, char** signa // declaring_class_ptr - pre-checked for NULL jvmtiError JvmtiEnv::GetFieldDeclaringClass(fieldDescriptor* fdesc_ptr, jclass* declaring_class_ptr) { - + // As for the GetFieldDeclaringClass method, the XSL generated C++ code that calls it has + // a jclass of the relevant class or a subclass of it, which is fine in terms of ensuring + // the holder is kept alive. *declaring_class_ptr = get_jni_class_non_null(fdesc_ptr->field_holder()); return JVMTI_ERROR_NONE; } /* end GetFieldDeclaringClass */ @@ -2825,7 +2827,9 @@ JvmtiEnv::GetMethodName(Method* method, char** name_ptr, char** signature_ptr, c jvmtiError JvmtiEnv::GetMethodDeclaringClass(Method* method, jclass* declaring_class_ptr) { NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID); - (*declaring_class_ptr) = get_jni_class_non_null(method->method_holder()); + Klass* k = method->method_holder(); + Handle holder(Thread::current(), k->klass_holder()); // keep the klass alive + (*declaring_class_ptr) = get_jni_class_non_null(k); return JVMTI_ERROR_NONE; } /* end GetMethodDeclaringClass */ diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp index 943aedd2e5ef6..353112079818a 100644 --- a/src/hotspot/share/prims/jvmtiEnvBase.cpp +++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp @@ -584,6 +584,7 @@ JvmtiEnvBase::vframeForNoProcess(JavaThread* java_thread, jint depth) { jclass JvmtiEnvBase::get_jni_class_non_null(Klass* k) { assert(k != NULL, "k != NULL"); + assert(k->is_loader_alive(), "Must be alive"); Thread *thread = Thread::current(); return (jclass)jni_reference(Handle(thread, k->java_mirror())); } diff --git a/test/hotspot/jtreg/serviceability/jvmti/GetMethodDeclaringClass/TestUnloadedClass.java b/test/hotspot/jtreg/serviceability/jvmti/GetMethodDeclaringClass/TestUnloadedClass.java new file mode 100644 index 0000000000000..dafec97111e2f --- /dev/null +++ b/test/hotspot/jtreg/serviceability/jvmti/GetMethodDeclaringClass/TestUnloadedClass.java @@ -0,0 +1,106 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2024, Alibaba Group Holding Limited. 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 8339725 + * @summary Stress test GetMethodDeclaringClass + * @requires vm.jvmti + * @requires (os.family == "linux") + * @library /test/lib + * @run driver/timeout=300 TestUnloadedClass + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.Utils; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.Platform; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.InputStream; +import java.lang.reflect.Constructor; + +public class TestUnloadedClass { + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("TestUnloadedClass"), + "-Xmx50m", + "Test"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + if (!Platform.isDebugBuild()) { + output.shouldContain("OutOfMemoryError"); + } + } +} + +class Test { + public static void main(String[] args) throws Exception { + long last = System.nanoTime(); + for (int i = 0;;i++) { + if (Platform.isDebugBuild() && i >= 1000) { + // Debug build costs too much time to OOM so limit the loop iteration + break; + } + CustomClassLoader loader = new CustomClassLoader(); + Class k = loader.findClass("MyClass"); + Constructor c = k.getDeclaredConstructor(); + c.setAccessible(true); + c.newInstance(); + + // call gc every ~1 second. + if ((System.nanoTime() - last) >= 1e9) { + System.gc(); + last = System.nanoTime(); + } + } + } +} + +class CustomClassLoader extends ClassLoader { + static byte[] BYTES; + + static { + try (InputStream in = CustomClassLoader.class.getResourceAsStream("MyClass.class")) { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + byte[] buf = new byte[4096]; + int len; + while ((len = in.read(buf)) != -1) { + baos.write(buf, 0, len); + } + BYTES = baos.toByteArray(); + } + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + @Override + public Class findClass(String name) throws ClassNotFoundException { + return defineClass(name, BYTES, 0, BYTES.length); + } +} + +class MyClass { +} diff --git a/test/hotspot/jtreg/serviceability/jvmti/GetMethodDeclaringClass/libTestUnloadedClass.cpp b/test/hotspot/jtreg/serviceability/jvmti/GetMethodDeclaringClass/libTestUnloadedClass.cpp new file mode 100644 index 0000000000000..c32b787d57894 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/jvmti/GetMethodDeclaringClass/libTestUnloadedClass.cpp @@ -0,0 +1,129 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2024, Alibaba Group Holding Limited. 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. + */ + +#include + +#include +#include +#include +#include +#include +#include + +static jvmtiEnv *_jvmti; +static JavaVM *_jvm; + +#define BUFFER_SIZE 100000 +static std::atomic ring_buffer[BUFFER_SIZE]; + +void get_method_details(jmethodID method) { + jclass method_class; + char *class_name = NULL; + if (_jvmti->GetMethodDeclaringClass(method, &method_class) == JVMTI_ERROR_NONE) { + if (_jvmti->GetClassSignature(method_class, &class_name, NULL) == JVMTI_ERROR_NONE) { + _jvmti->Deallocate((unsigned char *)class_name); + } + } +} + +void* read_ringbuffer(void* arg) { + JNIEnv *env; + _jvm->AttachCurrentThreadAsDaemon((void **)&env, NULL); + for (;;) { + jmethodID id = ring_buffer[rand() % BUFFER_SIZE].load(std::memory_order_relaxed); + if (id != (jmethodID)0) { + get_method_details(id); + } + } + return NULL; +} + +static void JNICALL ClassPrepareCallback(jvmtiEnv *jvmti_env, + JNIEnv *jni_env, + jthread thread, + jclass klass) { + static bool reader_created = false; + static int ring_buffer_idx = 0; + + char *class_name = NULL; + if (jvmti_env->GetClassSignature(klass, &class_name, NULL) != JVMTI_ERROR_NONE) { + return; + } + // We only care MyClass and only one thread loads it + bool is_my_class = strcmp(class_name, "LMyClass;") == 0; + jvmti_env->Deallocate((unsigned char *)class_name); + if (!is_my_class) { + return; + } + + if (!reader_created) { + pthread_t tid; + pthread_create(&tid, NULL, read_ringbuffer, NULL); + reader_created = true; + } + + jint method_count; + jmethodID *methods; + if (jvmti_env->GetClassMethods(klass, &method_count, &methods) == JVMTI_ERROR_NONE) { + ring_buffer[ring_buffer_idx++].store(methods[0], std::memory_order_relaxed); + ring_buffer_idx = ring_buffer_idx % BUFFER_SIZE; + jvmti_env->Deallocate((unsigned char *)methods); + } +} + +JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) { + for (int i = 0; i < BUFFER_SIZE; i++) { + ring_buffer[i].store(0, std::memory_order_relaxed); + } + + jvmtiEventCallbacks callbacks; + jvmtiError error; + + _jvm = jvm; + + if (jvm->GetEnv((void **)&_jvmti, JVMTI_VERSION_1_0) != JNI_OK) { + fprintf(stderr, "Unable to access JVMTI!\n"); + return JNI_ERR; + } + + // Set up the event callbacks + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.ClassPrepare = &ClassPrepareCallback; + + // Register the callbacks + error = _jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)); + if (error != JVMTI_ERROR_NONE) { + fprintf(stderr, "Error setting event callbacks: %d\n", error); + return JNI_ERR; + } + + // Enable the ClassPrepare event + error = _jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL); + if (error != JVMTI_ERROR_NONE) { + fprintf(stderr, "Error enabling ClassPrepare event: %d\n", error); + return JNI_ERR; + } + + return JNI_OK; +} From 0756108920b52dd9f9039758e6929d4e45275247 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 30 Jun 2025 13:04:26 +0000 Subject: [PATCH 366/846] 8297424: java/net/httpclient/AsyncExecutorShutdown.java fails in AssertionError due to misplaced assert Backport-of: 5d2772a43ef6409bf556cefb4eb4242594451674 --- .../jdk/internal/net/http/ResponseSubscribers.java | 2 +- .../share/classes/jdk/internal/net/http/Stream.java | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java index e7b4ff806d03f..b24b75da8c3c5 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java @@ -552,13 +552,13 @@ public void onSubscribe(Flow.Subscription s) { closed = this.closed; if (!closed) { this.subscription = s; + assert buffers.remainingCapacity() > 1; // should contain at least 2 } } if (closed) { s.cancel(); return; } - assert buffers.remainingCapacity() > 1; // should contain at least 2 if (debug.on()) debug.log("onSubscribe: requesting " + Math.max(1, buffers.remainingCapacity() - 1)); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java index ef0fe7c0a6d5b..a7dd61d7c9de4 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java @@ -184,10 +184,9 @@ private void schedule() { if (subscriber == null) { // can't process anything yet return; - } else { - if (debug.on()) debug.log("subscribing user subscriber"); - subscriber.onSubscribe(userSubscription); } + if (debug.on()) debug.log("subscribing user subscriber"); + subscriber.onSubscribe(userSubscription); } while (!inputQ.isEmpty()) { Http2Frame frame = inputQ.peek(); @@ -420,7 +419,7 @@ CompletableFuture receiveData(BodySubscriber bodySubscriber, Executor exec responseBodyCF.completeExceptionally(t); } - // ensure that the body subscriber will be subsribed and onError() is + // ensure that the body subscriber will be subscribed and onError() is // invoked pendingResponseSubscriber = bodySubscriber; sched.runOrSchedule(); // in case data waiting already to be processed, or error @@ -600,9 +599,9 @@ void incoming_reset(ResetFrame frame) { Flow.Subscriber subscriber = responseSubscriber == null ? pendingResponseSubscriber : responseSubscriber; if (response == null && subscriber == null) { - // we haven't receive the headers yet, and won't receive any! + // we haven't received the headers yet, and won't receive any! // handle reset now. - handleReset(frame, subscriber); + handleReset(frame, null); } else { // put it in the input queue in order to read all // pending data frames first. Indeed, a server may send From faaa691dfdd823e0d49b24eb51eb8d6ef90ed696 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 30 Jun 2025 13:13:02 +0000 Subject: [PATCH 367/846] 8301004: httpclient: Add more debug to HttpResponseInputStream Backport-of: c8ad6000646abd6e1faac396d901135c85c73cf5 --- .../internal/net/http/ResponseSubscribers.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java index b24b75da8c3c5..be3f73de524e1 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -540,8 +540,10 @@ public int available() throws IOException { @Override public void onSubscribe(Flow.Subscription s) { Objects.requireNonNull(s); + if (debug.on()) debug.log("onSubscribed called"); try { if (!subscribed.compareAndSet(false, true)) { + if (debug.on()) debug.log("Already subscribed: canceling"); s.cancel(); } else { // check whether the stream is already closed. @@ -552,10 +554,14 @@ public void onSubscribe(Flow.Subscription s) { closed = this.closed; if (!closed) { this.subscription = s; - assert buffers.remainingCapacity() > 1; // should contain at least 2 + // should contain at least 2 + assert buffers.remainingCapacity() > 1 + : "buffers capacity: " + buffers.remainingCapacity() + + " closed: " + closed + " failed: " + failed; } } if (closed) { + if (debug.on()) debug.log("Already closed: canceling"); s.cancel(); return; } @@ -566,6 +572,8 @@ public void onSubscribe(Flow.Subscription s) { } } catch (Throwable t) { failed = t; + if (debug.on()) + debug.log("onSubscribed failed", t); try { close(); } catch (IOException x) { @@ -599,6 +607,8 @@ public void onNext(List t) { @Override public void onError(Throwable thrwbl) { + if (debug.on()) + debug.log("onError called: " + thrwbl); subscription = null; failed = Objects.requireNonNull(thrwbl); // The client process that reads the input stream might @@ -613,6 +623,8 @@ public void onError(Throwable thrwbl) { @Override public void onComplete() { + if (debug.on()) + debug.log("onComplete called"); subscription = null; onNext(LAST_LIST); } @@ -626,6 +638,8 @@ public void close() throws IOException { s = subscription; subscription = null; } + if (debug.on()) + debug.log("close called"); // s will be null if already completed try { if (s != null) { From 6317de858def824ab1c2d1150f750fa6e27560a2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 30 Jun 2025 13:14:17 +0000 Subject: [PATCH 368/846] 8301255: Http2Connection may send too many GOAWAY frames Reviewed-by: rschmelter Backport-of: 041a12e65530b5832b4a500180c97a2a60e0dc51 --- .../internal/net/http/Http2ClientImpl.java | 2 +- .../internal/net/http/Http2Connection.java | 128 +++++++++++++----- .../java/net/httpclient/http2/NoBodyTest.java | 4 +- 3 files changed, 101 insertions(+), 33 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java index 2321d8c9d7657..8130921ea3815 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java @@ -213,10 +213,10 @@ void deleteConnection(Http2Connection c) { private EOFException STOPPED; void stop() { - synchronized (this) {stopping = true;} if (debug.on()) debug.log("stopping"); STOPPED = new EOFException("HTTP/2 client stopped"); STOPPED.setStackTrace(new StackTraceElement[0]); + synchronized (this) {stopping = true;} do { connections.values().forEach(this::close); } while (!connections.isEmpty()); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java index 02450c7dcf854..14fd7b6fc5b41 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java @@ -28,6 +28,8 @@ import java.io.EOFException; import java.io.IOException; import java.io.UncheckedIOException; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; import java.net.InetSocketAddress; import java.net.ProtocolException; import java.net.URI; @@ -287,7 +289,10 @@ public void onMaxHeaderListSizeReached(long size, int maxHeaderListSize) throws } } - volatile boolean closed; + private static final int HALF_CLOSED_LOCAL = 1; + private static final int HALF_CLOSED_REMOTE = 2; + private static final int SHUTDOWN_REQUESTED = 4; + volatile int closedState; //------------------------------------- final HttpConnection connection; @@ -703,13 +708,15 @@ final int maxConcurrentServerInitiatedStreams() { } void close() { - Log.logTrace("Closing HTTP/2 connection: to {0}", connection.address()); - if (connection.channel().isOpen()) { - GoAwayFrame f = new GoAwayFrame(0, - ErrorFrame.NO_ERROR, - "Requested by user".getBytes(UTF_8)); - // TODO: set last stream. For now zero ok. - sendFrame(f); + if (markHalfClosedLocal()) { + if (connection.channel().isOpen()) { + Log.logTrace("Closing HTTP/2 connection: to {0}", connection.address()); + GoAwayFrame f = new GoAwayFrame(0, + ErrorFrame.NO_ERROR, + "Requested by user".getBytes(UTF_8)); + // TODO: set last stream. For now zero ok. + sendFrame(f); + } } } @@ -771,18 +778,17 @@ Throwable getRecordedCause() { } void shutdown(Throwable t) { - if (debug.on()) debug.log(() -> "Shutting down h2c (closed="+closed+"): " + t); - if (closed == true) return; - synchronized (this) { - if (closed == true) return; - closed = true; - } + int state = closedState; + if (debug.on()) debug.log(() -> "Shutting down h2c (state="+describeClosedState(state)+"): " + t); + if (!markShutdownRequested()) return; cause.compareAndSet(null, t); if (Log.errors()) { - if (!(t instanceof EOFException) || isActive()) { + if (t!= null && (!(t instanceof EOFException) || isActive())) { Log.logError(t); } else if (t != null) { Log.logError("Shutting down connection: {0}", t.getMessage()); + } else { + Log.logError("Shutting down connection"); } } client2.deleteConnection(this); @@ -966,7 +972,7 @@ private String checkMaxOrphanedHeadersExceeded(HeaderFrame hf) { } final void dropDataFrame(DataFrame df) { - if (closed) return; + if (isMarked(closedState, SHUTDOWN_REQUESTED)) return; if (debug.on()) { debug.log("Dropping data frame for stream %d (%d payload bytes)", df.streamid(), df.payloadLength()); @@ -976,7 +982,7 @@ final void dropDataFrame(DataFrame df) { final void ensureWindowUpdated(DataFrame df) { try { - if (closed) return; + if (isMarked(closedState, SHUTDOWN_REQUESTED)) return; int length = df.payloadLength(); if (length > 0) { windowUpdater.update(length); @@ -1076,7 +1082,8 @@ private void handleConnectionFrame(Http2Frame frame) } boolean isOpen() { - return !closed && connection.channel().isOpen(); + return !isMarked(closedState, SHUTDOWN_REQUESTED) + && connection.channel().isOpen(); } void resetStream(int streamid, int code) { @@ -1189,11 +1196,13 @@ private void protocolError(int errorCode, String msg) String protocolError = "protocol error" + (msg == null?"":(": " + msg)); ProtocolException protocolException = new ProtocolException(protocolError); - framesDecoder.close(protocolError); - subscriber.stop(protocolException); - if (debug.on()) debug.log("Sending GOAWAY due to " + protocolException); - GoAwayFrame frame = new GoAwayFrame(0, errorCode); - sendFrame(frame); + if (markHalfClosedLocal()) { + framesDecoder.close(protocolError); + subscriber.stop(protocolException); + if (debug.on()) debug.log("Sending GOAWAY due to " + protocolException); + GoAwayFrame frame = new GoAwayFrame(0, errorCode); + sendFrame(frame); + } shutdown(protocolException); } @@ -1226,9 +1235,11 @@ private void handlePing(PingFrame frame) private void handleGoAway(GoAwayFrame frame) throws IOException { - shutdown(new IOException( - connection.channel().getLocalAddress() - +": GOAWAY received")); + if (markHalfClosedLRemote()) { + shutdown(new IOException( + connection.channel().getLocalAddress() + + ": GOAWAY received")); + } } /** @@ -1342,7 +1353,7 @@ void putStream(Stream stream, int streamid) { // to prevent the SelectorManager thread from exiting until // the stream is closed. synchronized (this) { - if (!closed) { + if (!isMarked(closedState, SHUTDOWN_REQUESTED)) { if (debug.on()) { debug.log("Opened stream %d", streamid); } @@ -1353,7 +1364,6 @@ void putStream(Stream stream, int streamid) { } if (debug.on()) debug.log("connection closed: closing stream %d", stream); stream.cancel(); - } /** @@ -1491,7 +1501,7 @@ void sendFrame(Http2Frame frame) { } publisher.signalEnqueued(); } catch (IOException e) { - if (!closed) { + if (!isMarked(closedState, SHUTDOWN_REQUESTED)) { Log.logError(e); shutdown(e); } @@ -1509,7 +1519,7 @@ void sendDataFrame(DataFrame frame) { publisher.enqueue(encodeFrame(frame)); publisher.signalEnqueued(); } catch (IOException e) { - if (!closed) { + if (!isMarked(closedState, SHUTDOWN_REQUESTED)) { Log.logError(e); shutdown(e); } @@ -1527,7 +1537,7 @@ void sendUnorderedFrame(Http2Frame frame) { publisher.enqueueUnordered(encodeFrame(frame)); publisher.signalEnqueued(); } catch (IOException e) { - if (!closed) { + if (!isMarked(closedState, SHUTDOWN_REQUESTED)) { Log.logError(e); shutdown(e); } @@ -1693,4 +1703,60 @@ AbstractAsyncSSLConnection getConnection() { return connection; } } + + private boolean isMarked(int state, int mask) { + return (state & mask) == mask; + } + + private boolean markShutdownRequested() { + return markClosedState(SHUTDOWN_REQUESTED); + } + + private boolean markHalfClosedLocal() { + return markClosedState(HALF_CLOSED_LOCAL); + } + + private boolean markHalfClosedLRemote() { + return markClosedState(HALF_CLOSED_REMOTE); + } + + private boolean markClosedState(int flag) { + int state, desired; + do { + state = desired = closedState; + if ((state & flag) == flag) return false; + desired = state | flag; + } while (!CLOSED_STATE.compareAndSet(this, state, desired)); + return true; + } + + String describeClosedState(int state) { + if (state == 0) return "active"; + String desc = null; + if (isMarked(state, SHUTDOWN_REQUESTED)) { + desc = "shutdown"; + } + if (isMarked(state, HALF_CLOSED_LOCAL | HALF_CLOSED_REMOTE)) { + if (desc == null) return "closed"; + else return desc + "+closed"; + } + if (isMarked(state, HALF_CLOSED_LOCAL)) { + if (desc == null) return "half-closed-local"; + else return desc + "+half-closed-local"; + } + if (isMarked(state, HALF_CLOSED_REMOTE)) { + if (desc == null) return "half-closed-remote"; + else return desc + "+half-closed-remote"; + } + return "0x" + Integer.toString(state, 16); + } + + private static final VarHandle CLOSED_STATE; + static { + try { + CLOSED_STATE = MethodHandles.lookup().findVarHandle(Http2Connection.class, "closedState", int.class); + } catch (Exception x) { + throw new ExceptionInInitializerError(x); + } + } } diff --git a/test/jdk/java/net/httpclient/http2/NoBodyTest.java b/test/jdk/java/net/httpclient/http2/NoBodyTest.java index 2dc7508f5ee70..4dcd99e2c87ac 100644 --- a/test/jdk/java/net/httpclient/http2/NoBodyTest.java +++ b/test/jdk/java/net/httpclient/http2/NoBodyTest.java @@ -26,7 +26,9 @@ * @bug 8087112 * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer - * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors NoBodyTest + * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors + * -Djdk.internal.httpclient.debug=true + * NoBodyTest */ import java.io.IOException; From ee991b7607b8011599e6d6d0334afb4199f42328 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 30 Jun 2025 13:19:43 +0000 Subject: [PATCH 369/846] 8301169: java/net/httpclient/ThrowingSubscribersAsInputStream.java,ThrowingSubscribersAsInputStreamAsync.java, and other httpclient tests failing on windows: Unable to establish loopback connection Backport-of: 98e8616a0c27ac73caf8f91cc83adc88b3490dcb --- .../AbstractThrowingPublishers.java | 36 +++++++++++++++++++ .../AbstractThrowingPushPromises.java | 36 +++++++++++++++++++ .../AbstractThrowingSubscribers.java | 36 +++++++++++++++++++ 3 files changed, 108 insertions(+) diff --git a/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java b/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java index f2a47734e40c4..4079bd81e3e19 100644 --- a/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java +++ b/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java @@ -388,6 +388,24 @@ protected void testSanityImpl(String uri, boolean sameClient) String body = response.join().body(); assertEquals(body, Stream.of(BODY.split("\\|")).collect(Collectors.joining())); + if (!sameClient) { + // Wait for the client to be garbage collected. + // we use the ReferenceTracker API rather than HttpClient::close here, + // because these tests inject faults by throwing inside callbacks, which + // is more likely to get HttpClient::close wedged until jtreg times out. + // By using the ReferenceTracker, we will get some diagnosis about what + // is keeping the client alive if it doesn't get GC'ed within the + // expected time frame. + var tracker = TRACKER.getTracker(client); + client = null; + System.gc(); + System.out.println(now() + "waiting for client to shutdown: " + tracker.getName()); + System.err.println(now() + "waiting for client to shutdown: " + tracker.getName()); + var error = TRACKER.check(tracker, 10000); + if (error != null) throw error; + System.out.println(now() + "client shutdown normally: " + tracker.getName()); + System.err.println(now() + "client shutdown normally: " + tracker.getName()); + } } } @@ -470,6 +488,24 @@ private void testThrowing(String uri, boolean sameClient, if (response != null) { finisher.finish(where, response, thrower); } + if (!sameClient) { + // Wait for the client to be garbage collected. + // we use the ReferenceTracker API rather than HttpClient::close here, + // because these tests inject faults by throwing inside callbacks, which + // is more likely to get HttpClient::close wedged until jtreg times out. + // By using the ReferenceTracker, we will get some diagnosis about what + // is keeping the client alive if it doesn't get GC'ed within the + // expected time frame. + var tracker = TRACKER.getTracker(client); + client = null; + System.gc(); + System.out.println(now() + "waiting for client to shutdown: " + tracker.getName()); + System.err.println(now() + "waiting for client to shutdown: " + tracker.getName()); + var error = TRACKER.check(tracker, 10000); + if (error != null) throw error; + System.out.println(now() + "client shutdown normally: " + tracker.getName()); + System.err.println(now() + "client shutdown normally: " + tracker.getName()); + } } } diff --git a/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java b/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java index a9d1906430da4..b5230d48d1040 100644 --- a/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java +++ b/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java @@ -340,6 +340,24 @@ public void applyPushPromise(HttpRequest initiatingRequest, assertEquals(promisedBody, promised.uri().toASCIIString()); } assertEquals(3, pushPromises.size()); + if (!sameClient) { + // Wait for the client to be garbage collected. + // we use the ReferenceTracker API rather than HttpClient::close here, + // because these tests inject faults by throwing inside callbacks, which + // is more likely to get HttpClient::close wedged until jtreg times out. + // By using the ReferenceTracker, we will get some diagnosis about what + // is keeping the client alive if it doesn't get GC'ed within the + // expected time frame. + var tracker = TRACKER.getTracker(client); + client = null; + System.gc(); + System.out.println(now() + "waiting for client to shutdown: " + tracker.getName()); + System.err.println(now() + "waiting for client to shutdown: " + tracker.getName()); + var error = TRACKER.check(tracker, 10000); + if (error != null) throw error; + System.out.println(now() + "client shutdown normally: " + tracker.getName()); + System.err.println(now() + "client shutdown normally: " + tracker.getName()); + } } } @@ -425,6 +443,24 @@ private void testThrowing(String uri, boolean sameClient, if (response != null) { finisher.finish(where, req.uri(), response, thrower, promiseMap); } + if (!sameClient) { + // Wait for the client to be garbage collected. + // we use the ReferenceTracker API rather than HttpClient::close here, + // because these tests inject faults by throwing inside callbacks, which + // is more likely to get HttpClient::close wedged until jtreg times out. + // By using the ReferenceTracker, we will get some diagnosis about what + // is keeping the client alive if it doesn't get GC'ed within the + // expected time frame. + var tracker = TRACKER.getTracker(client); + client = null; + System.gc(); + System.out.println(now() + "waiting for client to shutdown: " + tracker.getName()); + System.err.println(now() + "waiting for client to shutdown: " + tracker.getName()); + var error = TRACKER.check(tracker, 10000); + if (error != null) throw error; + System.out.println(now() + "client shutdown normally: " + tracker.getName()); + System.err.println(now() + "client shutdown normally: " + tracker.getName()); + } } } diff --git a/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java b/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java index 893950608b1e6..d4100b7eb041d 100644 --- a/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java +++ b/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java @@ -314,6 +314,24 @@ protected void testSanityImpl(String uri, boolean sameClient) HttpResponse response = client.send(req, handler); String body = response.body(); assertEquals(URI.create(body).getPath(), URI.create(uri2).getPath()); + if (!sameClient) { + // Wait for the client to be garbage collected. + // we use the ReferenceTracker API rather than HttpClient::close here, + // because these tests inject faults by throwing inside callbacks, which + // is more likely to get HttpClient::close wedged until jtreg times out. + // By using the ReferenceTracker, we will get some diagnosis about what + // is keeping the client alive if it doesn't get GC'ed within the + // expected time frame. + var tracker = TRACKER.getTracker(client); + client = null; + System.gc(); + System.out.println(now() + "waiting for client to shutdown: " + tracker.getName()); + System.err.println(now() + "waiting for client to shutdown: " + tracker.getName()); + var error = TRACKER.check(tracker, 10000); + if (error != null) throw error; + System.out.println(now() + "client shutdown normally: " + tracker.getName()); + System.err.println(now() + "client shutdown normally: " + tracker.getName()); + } } } @@ -461,6 +479,24 @@ private void testThrowing(String uri, boolean sameClient, if (response != null) { finisher.finish(where, response, thrower); } + if (!sameClient) { + // Wait for the client to be garbage collected. + // we use the ReferenceTracker API rather than HttpClient::close here, + // because these tests inject faults by throwing inside callbacks, which + // is more likely to get HttpClient::close wedged until jtreg times out. + // By using the ReferenceTracker, we will get some diagnosis about what + // is keeping the client alive if it doesn't get GC'ed within the + // expected time frame. + var tracker = TRACKER.getTracker(client); + client = null; + System.gc(); + System.out.println(now() + "waiting for client to shutdown: " + tracker.getName()); + System.err.println(now() + "waiting for client to shutdown: " + tracker.getName()); + var error = TRACKER.check(tracker, 10000); + if (error != null) throw error; + System.out.println(now() + "client shutdown normally: " + tracker.getName()); + System.err.println(now() + "client shutdown normally: " + tracker.getName()); + } } } From c53cae6a0b510201f0dd62236c273b85820693c6 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 3 Jul 2025 13:29:23 +0000 Subject: [PATCH 370/846] 8302635: Race condition in HttpBodySubscriberWrapper when cancelling request Backport-of: edf238b65e441a1d626f3a4ba06170badd05ca7c --- .../jdk/internal/net/http/Http1Exchange.java | 18 +- .../classes/jdk/internal/net/http/Stream.java | 13 +- .../common/HttpBodySubscriberWrapper.java | 225 ++++++++++++++++-- .../net/httpclient/CancelRequestTest.java | 2 +- 4 files changed, 213 insertions(+), 45 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java index 02461893d00ee..2daba87fb3fc4 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -209,24 +209,12 @@ static final class Http1ResponseBodySubscriber extends HttpBodySubscriberWrap } @Override - protected void onSubscribed() { + protected void register() { exchange.registerResponseSubscriber(this); } @Override - protected void complete(Throwable t) { - try { - exchange.unregisterResponseSubscriber(this); - } finally { - super.complete(t); - } - } - - @Override - protected void onCancel() { - // If the subscription is cancelled the - // subscriber may or may not get completed. - // Therefore we need to unregister it + protected void unregister() { exchange.unregisterResponseSubscriber(this); } } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java index a7dd61d7c9de4..bd3c4cdc04966 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java @@ -1692,21 +1692,12 @@ final class Http2StreamResponseSubscriber extends HttpBodySubscriberWrapper userSubscriber; - final AtomicBoolean completed = new AtomicBoolean(); - final AtomicBoolean subscribed = new AtomicBoolean(); + private volatile int state; final ReentrantLock subscriptionLock = new ReentrantLock(); volatile SubscriptionWrapper subscription; volatile Throwable withError; @@ -83,14 +88,55 @@ public void request(long n) { @Override public void cancel() { try { - subscription.cancel(); - onCancel(); + try { + subscription.cancel(); + } finally { + if (markCancelled()) { + onCancel(); + } + } } catch (Throwable t) { onError(t); } } } + private final boolean markState(final int flag) { + int state = this.state; + if ((state & flag) == flag) { + return false; + } + synchronized (this) { + state = this.state; + if ((state & flag) == flag) { + return false; + } + state = this.state = (state | flag); + } + assert (state & flag) == flag; + return true; + } + + private boolean markSubscribed() { + return markState(SUBSCRIBED); + } + + private boolean markCancelled() { + return markState(CANCELLED); + } + + private boolean markCompleted() { + return markState(COMPLETED); + } + + private boolean markRegistered() { + return markState(REGISTERED); + } + + private boolean markUnregistered() { + return markState(UNREGISTERED); + } + final long id() { return id; } @Override @@ -101,8 +147,9 @@ public boolean needsExecutor() { // propagate the error to the user subscriber, even if not // subscribed yet. private void propagateError(Throwable t) { + var state = this.state; assert t != null; - assert completed.get(); + assert (state & COMPLETED) != 0; try { // if unsubscribed at this point, it will not // get subscribed later - so do it now and @@ -111,7 +158,7 @@ private void propagateError(Throwable t) { // subscription is finished before calling onError; subscriptionLock.lock(); try { - if (subscribed.compareAndSet(false, true)) { + if (markSubscribed()) { userSubscriber.onSubscribe(NOP); } } finally { @@ -125,34 +172,139 @@ private void propagateError(Throwable t) { } } + /** + * This method attempts to mark the state of this + * object as registered, and then call the + * {@link #register()} method. + *

    + * The state will be marked as registered, and the + * {@code register()} method will be called only + * if not already registered or unregistered, + * or cancelled, or completed. + * + * @return {@code true} if {@link #register()} was called, + * false otherwise. + */ + protected final boolean tryRegister() { + subscriptionLock.lock(); + try { + int state = this.state; + if ((state & (REGISTERED | UNREGISTERED | CANCELLED | COMPLETED)) != 0) return false; + if (markRegistered()) { + register(); + return true; + } + } finally { + subscriptionLock.unlock(); + } + return false; + } + + /** + * This method attempts to mark the state of this + * object as unregistered, and then call the + * {@link #unregister()} method. + *

    + * The {@code unregister()} method will be called only + * if already registered and not yet unregistered. + * Whether {@code unregister()} is called or not, + * the state is marked as unregistered, to prevent + * {@link #tryRegister()} from calling {@link #register()} + * after {@link #tryUnregister()} has been called. + * + * @return {@code true} if {@link #unregister()} was called, + * false otherwise. + */ + protected final boolean tryUnregister() { + subscriptionLock.lock(); + try { + int state = this.state; + if ((state & REGISTERED) == 0) { + markUnregistered(); + return false; + } + if (markUnregistered()) { + unregister(); + return true; + } + } finally { + subscriptionLock.unlock(); + } + return false; + } + + /** + * This method can be implemented by subclasses + * to perform registration actions. It will not be + * called if already registered or unregistered. + * @apiNote + * This method is called while holding a subscription + * lock. + * @see #tryRegister() + */ + protected void register() { + assert subscriptionLock.isHeldByCurrentThread(); + } + + /** + * This method can be implemented by subclasses + * to perform unregistration actions. It will not be + * called if not already registered, or already unregistered. + * @apiNote + * This method is called while holding a subscription + * lock. + * @see #tryUnregister() + */ + protected void unregister() { + assert subscriptionLock.isHeldByCurrentThread(); + } + /** * Called when the subscriber cancels its subscription. * @apiNote * This method may be used by subclasses to perform cleanup * actions after a subscription has been cancelled. + * @implSpec + * This method calls {@link #tryUnregister()} */ - protected void onCancel() { } + protected void onCancel() { + // If the subscription is cancelled the + // subscriber may or may not get completed. + // Therefore we need to unregister it + tryUnregister(); + } /** * Called right before the userSubscriber::onSubscribe is called. * @apiNote * This method may be used by subclasses to perform cleanup - * related actions after a subscription has been succesfully + * related actions after a subscription has been successfully * accepted. + * This method is called while holding a subscription + * lock. + * @implSpec + * This method calls {@link #tryRegister()} */ - protected void onSubscribed() { } + protected void onSubscribed() { + tryRegister(); + } /** * Complete the subscriber, either normally or exceptionally * ensure that the subscriber is completed only once. * @param t a throwable, or {@code null} + * @implSpec + * If not {@linkplain #completed()} yet, this method + * calls {@link #tryUnregister()} */ - protected void complete(Throwable t) { - if (completed.compareAndSet(false, true)) { + public final void complete(Throwable t) { + if (markCompleted()) { + tryUnregister(); t = withError = Utils.getCompletionCause(t); if (t == null) { try { - assert subscribed.get(); + var state = this.state; + assert (state & SUBSCRIBED) != 0; userSubscriber.onComplete(); } catch (Throwable x) { // Simply propagate the error by calling @@ -179,10 +331,45 @@ protected void complete(Throwable t) { * {@return true if this subscriber has already completed, either normally * or abnormally} */ - public boolean completed() { - return completed.get(); + public final boolean completed() { + int state = this.state; + return (state & COMPLETED) != 0; } + /** + * {@return true if this subscriber has already subscribed} + */ + public final boolean subscribed() { + int state = this.state; + return (state & SUBSCRIBED) != 0; + } + + /** + * {@return true if this subscriber has already been registered} + */ + public final boolean registered() { + int state = this.state; + return (state & REGISTERED) != 0; + } + + /** + * {@return true if this subscriber has already been unregistered} + */ + public final boolean unregistered() { + int state = this.state; + return (state & UNREGISTERED) != 0; + } + + /** + * {@return true if this subscriber's subscription has already + * been cancelled} + */ + public final boolean cancelled() { + int state = this.state; + return (state & CANCELLED) != 0; + } + + @Override public CompletionStage getBody() { return userSubscriber.getBody(); @@ -194,7 +381,7 @@ public void onSubscribe(Flow.Subscription subscription) { // subscription is finished before calling onError; subscriptionLock.lock(); try { - if (subscribed.compareAndSet(false, true)) { + if (markSubscribed()) { onSubscribed(); SubscriptionWrapper wrapped = new SubscriptionWrapper(subscription); userSubscriber.onSubscribe(this.subscription = wrapped); @@ -208,8 +395,9 @@ public void onSubscribe(Flow.Subscription subscription) { @Override public void onNext(List item) { - assert subscribed.get(); - if (completed.get()) { + var state = this.state; + assert (state & SUBSCRIBED) != 0; + if ((state & COMPLETED) != 0) { SubscriptionWrapper subscription = this.subscription; if (subscription != null) { subscription.subscription.cancel(); @@ -222,6 +410,7 @@ public void onNext(List item) { public void onError(Throwable throwable) { complete(throwable); } + @Override public void onComplete() { complete(null); diff --git a/test/jdk/java/net/httpclient/CancelRequestTest.java b/test/jdk/java/net/httpclient/CancelRequestTest.java index 28ad68bd40970..f393d437e285c 100644 --- a/test/jdk/java/net/httpclient/CancelRequestTest.java +++ b/test/jdk/java/net/httpclient/CancelRequestTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8245462 8229822 8254786 8297075 8297149 8298340 + * @bug 8245462 8229822 8254786 8297075 8297149 8298340 8302635 * @summary Tests cancelling the request. * @library /test/lib /test/jdk/java/net/httpclient/lib * @key randomness From ffa7dd58711fc711d71c94753bcfdfdcaaaed752 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 3 Jul 2025 13:56:31 +0000 Subject: [PATCH 371/846] 8299338: AssertionError in ResponseSubscribers$HttpResponseInputStream::onSubscribe Backport-of: 575484806ce11634d4fa8bef6c0c5987e4e0a1c7 --- .../jdk/internal/net/http/Http1Exchange.java | 9 ++++---- .../jdk/internal/net/http/HttpClientImpl.java | 21 ++++++++++++++++--- .../net/http/ResponseSubscribers.java | 12 ++++++----- .../classes/jdk/internal/net/http/Stream.java | 8 +++---- .../common/HttpBodySubscriberWrapper.java | 17 +-------------- .../net/httpclient/AsyncExecutorShutdown.java | 2 +- 6 files changed, 36 insertions(+), 33 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java index 2daba87fb3fc4..e59ef8233cf98 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java @@ -266,7 +266,7 @@ private void connectFlows(HttpConnection connection) { // The Http1ResponseBodySubscriber is registered with the HttpClient // to ensure that it gets completed if the SelectorManager aborts due // to unexpected exceptions. - private void registerResponseSubscriber(Http1ResponseBodySubscriber subscriber) { + private boolean registerResponseSubscriber(Http1ResponseBodySubscriber subscriber) { Throwable failed = null; synchronized (lock) { failed = this.failed; @@ -276,13 +276,14 @@ private void registerResponseSubscriber(Http1ResponseBodySubscriber subscribe } if (failed != null) { subscriber.onError(failed); + return false; } else { - client.registerSubscriber(subscriber); + return client.registerSubscriber(subscriber); } } - private void unregisterResponseSubscriber(Http1ResponseBodySubscriber subscriber) { - client.unregisterSubscriber(subscriber); + private boolean unregisterResponseSubscriber(Http1ResponseBodySubscriber subscriber) { + return client.unregisterSubscriber(subscriber); } @Override diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java index c7643106640b6..96bdda7eb9cb8 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java @@ -542,7 +542,14 @@ private static void closeSubscribers(HttpClientImpl client, Throwable t) { client.subscribers.forEach(s -> s.onError(t)); } - public void registerSubscriber(HttpBodySubscriberWrapper subscriber) { + /** + * Adds the given subscriber to the subscribers list, or call + * its {@linkplain HttpBodySubscriberWrapper#onError onError} + * method if the client is shutting down. + * @param subscriber the subscriber + * @return true if the subscriber was added to the list. + */ + public boolean registerSubscriber(HttpBodySubscriberWrapper subscriber) { if (!selmgr.isClosed()) { synchronized (selmgr) { if (!selmgr.isClosed()) { @@ -552,20 +559,28 @@ public void registerSubscriber(HttpBodySubscriberWrapper subscriber) { debug.log("body subscriber registered: " + count); } } - return; + return true; } } } subscriber.onError(selmgr.selectorClosedException()); + return false; } - public void unregisterSubscriber(HttpBodySubscriberWrapper subscriber) { + /** + * Remove the given subscriber from the subscribers list. + * @param subscriber the subscriber + * @return true if the subscriber was found and removed from the list. + */ + public boolean unregisterSubscriber(HttpBodySubscriberWrapper subscriber) { if (subscribers.remove(subscriber)) { long count = pendingSubscribersCount.decrementAndGet(); if (debug.on()) { debug.log("body subscriber unregistered: " + count); } + return true; } + return false; } private void closeConnection(HttpConnection conn) { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java index be3f73de524e1..372a02a224bb3 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java @@ -540,7 +540,7 @@ public int available() throws IOException { @Override public void onSubscribe(Flow.Subscription s) { Objects.requireNonNull(s); - if (debug.on()) debug.log("onSubscribed called"); + if (debug.on()) debug.log("onSubscribe called"); try { if (!subscribed.compareAndSet(false, true)) { if (debug.on()) debug.log("Already subscribed: canceling"); @@ -554,10 +554,12 @@ public void onSubscribe(Flow.Subscription s) { closed = this.closed; if (!closed) { this.subscription = s; - // should contain at least 2 - assert buffers.remainingCapacity() > 1 + // should contain at least 2, unless closed or failed. + assert buffers.remainingCapacity() > 1 || failed != null : "buffers capacity: " + buffers.remainingCapacity() - + " closed: " + closed + " failed: " + failed; + + ", closed: " + closed + ", terminated: " + + buffers.contains(LAST_LIST) + + ", failed: " + failed; } } if (closed) { @@ -573,7 +575,7 @@ public void onSubscribe(Flow.Subscription s) { } catch (Throwable t) { failed = t; if (debug.on()) - debug.log("onSubscribed failed", t); + debug.log("onSubscribe failed", t); try { close(); } catch (IOException x) { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java index bd3c4cdc04966..b145c1c3fc096 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java @@ -352,12 +352,12 @@ Http2StreamResponseSubscriber createResponseSubscriber(BodyHandler handler // The Http2StreamResponseSubscriber is registered with the HttpClient // to ensure that it gets completed if the SelectorManager aborts due // to unexpected exceptions. - private void registerResponseSubscriber(Http2StreamResponseSubscriber subscriber) { - client().registerSubscriber(subscriber); + private boolean registerResponseSubscriber(Http2StreamResponseSubscriber subscriber) { + return client().registerSubscriber(subscriber); } - private void unregisterResponseSubscriber(Http2StreamResponseSubscriber subscriber) { - client().unregisterSubscriber(subscriber); + private boolean unregisterResponseSubscriber(Http2StreamResponseSubscriber subscriber) { + return client().unregisterSubscriber(subscriber); } @Override diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/HttpBodySubscriberWrapper.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/HttpBodySubscriberWrapper.java index 7cd0943aa60b4..6dc79760b0a1f 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/HttpBodySubscriberWrapper.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/HttpBodySubscriberWrapper.java @@ -274,21 +274,6 @@ protected void onCancel() { tryUnregister(); } - /** - * Called right before the userSubscriber::onSubscribe is called. - * @apiNote - * This method may be used by subclasses to perform cleanup - * related actions after a subscription has been successfully - * accepted. - * This method is called while holding a subscription - * lock. - * @implSpec - * This method calls {@link #tryRegister()} - */ - protected void onSubscribed() { - tryRegister(); - } - /** * Complete the subscriber, either normally or exceptionally * ensure that the subscriber is completed only once. @@ -381,8 +366,8 @@ public void onSubscribe(Flow.Subscription subscription) { // subscription is finished before calling onError; subscriptionLock.lock(); try { + tryRegister(); if (markSubscribed()) { - onSubscribed(); SubscriptionWrapper wrapped = new SubscriptionWrapper(subscription); userSubscriber.onSubscribe(this.subscription = wrapped); } else { diff --git a/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java b/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java index 97037824a6a1f..1163c97fa3faa 100644 --- a/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java +++ b/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8277969 + * @bug 8277969 8299338 * @summary Test for edge case where the executor is not accepting * new tasks while the client is still running * @library /test/lib /test/jdk/java/net/httpclient/lib From ca47598016470bb997038b378a5dbde923b40e28 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 3 Jul 2025 13:57:51 +0000 Subject: [PATCH 372/846] 8226919: attach in linux hangs due to permission denied accessing /proc/pid/root Backport-of: ac4607ed81eb75f43e7d1062e38506972738d086 --- .../sun/tools/attach/VirtualMachineImpl.java | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java index 77ac7c85d60ae..235fe1c69d3b0 100644 --- a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -275,11 +275,8 @@ public synchronized void close() throws IOException { } // Return the socket file for the given process. - private File findSocketFile(int pid, int ns_pid) { - // A process may not exist in the same mount namespace as the caller. - // Instead, attach relative to the target root filesystem as exposed by - // procfs regardless of namespaces. - String root = "/proc/" + pid + "/root/" + tmpdir; + private File findSocketFile(int pid, int ns_pid) throws IOException { + String root = findTargetProcessTmpDirectory(pid, ns_pid); return new File(root, ".java_pid" + ns_pid); } @@ -295,21 +292,34 @@ private File createAttachFile(int pid, int ns_pid) throws IOException { // Do not canonicalize the file path, or we will fail to attach to a VM in a container. f.createNewFile(); } catch (IOException x) { - String root; - if (pid != ns_pid) { - // A process may not exist in the same mount namespace as the caller. - // Instead, attach relative to the target root filesystem as exposed by - // procfs regardless of namespaces. - root = "/proc/" + pid + "/root/" + tmpdir; - } else { - root = tmpdir; - } + String root = findTargetProcessTmpDirectory(pid, ns_pid); f = new File(root, fn); f.createNewFile(); } return f; } + private String findTargetProcessTmpDirectory(int pid, int ns_pid) throws IOException { + String root; + if (pid != ns_pid) { + // A process may not exist in the same mount namespace as the caller, e.g. + // if we are trying to attach to a JVM process inside a container. + // Instead, attach relative to the target root filesystem as exposed by + // procfs regardless of namespaces. + String procRootDirectory = "/proc/" + pid + "/root"; + if (!Files.isReadable(Path.of(procRootDirectory))) { + throw new IOException( + String.format("Unable to access root directory %s " + + "of target process %d", procRootDirectory, pid)); + } + + root = procRootDirectory + "/" + tmpdir; + } else { + root = tmpdir; + } + return root; + } + /* * Write/sends the given to the target VM. String is transmitted in * UTF-8 encoding. From 2f8944c0c6f075688ffe6b931df00fce15e2d22a Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Fri, 4 Jul 2025 11:30:07 +0000 Subject: [PATCH 373/846] 8352946: SEGV_BND signal code of SIGSEGV missing from our signal-code table Backport-of: bac2aa44454982684e06854add1dbbb806fba363 --- src/hotspot/os/posix/signals_posix.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/hotspot/os/posix/signals_posix.cpp b/src/hotspot/os/posix/signals_posix.cpp index d800fa3381a86..643b926a50a08 100644 --- a/src/hotspot/os/posix/signals_posix.cpp +++ b/src/hotspot/os/posix/signals_posix.cpp @@ -42,6 +42,9 @@ #include +#if !defined(SEGV_BNDERR) +#define SEGV_BNDERR 3 +#endif static const char* get_signal_name(int sig, char* out, size_t outlen); @@ -914,6 +917,9 @@ static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t { SIGFPE, FPE_FLTSUB, "FPE_FLTSUB", "Subscript out of range." }, { SIGSEGV, SEGV_MAPERR, "SEGV_MAPERR", "Address not mapped to object." }, { SIGSEGV, SEGV_ACCERR, "SEGV_ACCERR", "Invalid permissions for mapped object." }, +#if defined(LINUX) + { SIGSEGV, SEGV_BNDERR, "SEGV_BNDERR", "Failed address bound checks." }, +#endif #if defined(AIX) // no explanation found what keyerr would be { SIGSEGV, SEGV_KEYERR, "SEGV_KEYERR", "key error" }, From 0e9b1df4d75b9d233c0297b0763b052e9fde55ed Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Fri, 4 Jul 2025 13:24:52 +0000 Subject: [PATCH 374/846] 8351997: AArch64: Interpreter volatile reference stores with G1 are not sequentially consistent Reviewed-by: eosterlund, adinn Backport-of: 83b15da2eb3cb6c8937f517c9b75eaa9eeece314 --- src/hotspot/cpu/aarch64/templateTable_aarch64.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp index ec577c261d34a..ffbab796600fd 100644 --- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp @@ -1136,6 +1136,7 @@ void TemplateTable::aastore() { // Get the value we will store __ ldr(r0, at_tos()); // Now store using the appropriate barrier + // Clobbers: r10, r11, r3 do_oop_store(_masm, element_address, r0, IS_ARRAY); __ b(done); @@ -1144,6 +1145,7 @@ void TemplateTable::aastore() { __ profile_null_seen(r2); // Store a NULL + // Clobbers: r10, r11, r3 do_oop_store(_masm, element_address, noreg, IS_ARRAY); // Pop stack arguments @@ -2706,6 +2708,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr __ pop(atos); if (!is_static) pop_and_check_object(obj); // Store into the field + // Clobbers: r10, r11, r3 do_oop_store(_masm, field, r0, IN_HEAP); if (rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_aputfield, bc, r1, true, byte_no); @@ -2905,8 +2908,8 @@ void TemplateTable::fast_storefield(TosState state) // Must prevent reordering of the following cp cache loads with bytecode load __ membar(MacroAssembler::LoadLoad); - // test for volatile with r3 - __ ldrw(r3, Address(r2, in_bytes(base + + // test for volatile with r5 + __ ldrw(r5, Address(r2, in_bytes(base + ConstantPoolCacheEntry::flags_offset()))); // replace index with field offset from cache entry @@ -2914,7 +2917,7 @@ void TemplateTable::fast_storefield(TosState state) { Label notVolatile; - __ tbz(r3, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); + __ tbz(r5, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); __ membar(MacroAssembler::StoreStore | MacroAssembler::LoadStore); __ bind(notVolatile); } @@ -2930,6 +2933,7 @@ void TemplateTable::fast_storefield(TosState state) // access field switch (bytecode()) { case Bytecodes::_fast_aputfield: + // Clobbers: r10, r11, r3 do_oop_store(_masm, field, r0, IN_HEAP); break; case Bytecodes::_fast_lputfield: @@ -2962,7 +2966,7 @@ void TemplateTable::fast_storefield(TosState state) { Label notVolatile; - __ tbz(r3, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); + __ tbz(r5, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); __ membar(MacroAssembler::StoreLoad | MacroAssembler::StoreStore); __ bind(notVolatile); } From f893fa30de90ff07932b7e4dae4346e45cf63f7c Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Sat, 5 Jul 2025 16:15:48 +0000 Subject: [PATCH 375/846] 8196017: java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java fails Backport-of: b7104ba9a9006ab65e08ea9d7db22e72611ed07c --- test/jdk/ProblemList.txt | 1 - .../GetMousePositionWithPopup.java | 32 +++++++++++-------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 3be9fa08146ed..6fa631ee0a422 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -212,7 +212,6 @@ java/awt/dnd/DnDClipboardDeadlockTest.java 8079553 linux-all java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListToFileListBetweenJVMsTest.java 8194947 generic-all java/awt/Frame/FramesGC/FramesGC.java 8079069 macosx-all java/awt/GridLayout/LayoutExtraGaps/LayoutExtraGaps.java 8000171 windows-all -java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java 8196017 windows-all java/awt/Scrollbar/ScrollbarMouseWheelTest/ScrollbarMouseWheelTest.java 8196018 windows-all,linux-all java/awt/TrayIcon/ActionCommand/ActionCommand.java 8150540 windows-all java/awt/TrayIcon/ActionEventMask/ActionEventMask.java 8150540 windows-all diff --git a/test/jdk/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java b/test/jdk/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java index 28f1faa82ee4c..fd779d721f39d 100644 --- a/test/jdk/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java +++ b/test/jdk/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -23,8 +23,10 @@ import test.java.awt.regtesthelpers.Util; -import javax.swing.*; -import java.awt.*; +import javax.swing.SwingUtilities; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; @@ -33,11 +35,10 @@ * @key headful * @bug 8012026 8027154 * @summary Component.getMousePosition() does not work in an applet on MacOS - * @author Petr Pchelko * @library ../../regtesthelpers * @build Util * @compile GetMousePositionWithPopup.java - * @run main/othervm GetMousePositionWithPopup + * @run main GetMousePositionWithPopup */ public class GetMousePositionWithPopup { @@ -48,6 +49,7 @@ public class GetMousePositionWithPopup { public static void main(String[] args) throws Exception { try { Robot r = Util.createRobot(); + r.setAutoDelay(100); r.mouseMove(0, 0); Util.waitForIdle(null); @@ -61,7 +63,7 @@ public void run() { Util.waitForIdle(null); r.mouseMove(149, 149); Util.waitForIdle(null); - r.mouseMove(150, 150); + r.mouseMove(170, 170); Util.waitForIdle(null); } finally { @@ -78,20 +80,25 @@ public void run() { private static void constructTestUI() { frame1 = new Frame(); frame1.setBounds(100, 100, 100, 100); + frame1.setVisible(true); frame1.addMouseMotionListener(new MouseMotionAdapter() { - @Override public void mouseMoved(MouseEvent e) { + if (frame2 != null) { + return; + } frame2 = new Frame(); frame2.setBounds(120, 120, 120, 120); - + frame2.setVisible(true); frame2.addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseMoved(MouseEvent e) { Point positionInFrame2 = frame2.getMousePosition(); - if (positionInFrame2.x != 30 || positionInFrame2.y != 30) { - throw new RuntimeException("Wrong position reported. Should be [30, 30] but was [" + + int deltaX = Math.abs(50 - positionInFrame2.x); + int deltaY = Math.abs(50 - positionInFrame2.y); + if (deltaX > 2 || deltaY > 2) { + throw new RuntimeException("Wrong position reported. Should be [50, 50] but was [" + positionInFrame2.x + ", " + positionInFrame2.y + "]"); } @@ -101,10 +108,7 @@ public void mouseMoved(MouseEvent e) } } }); - - frame2.setVisible(true); } }); - frame1.setVisible(true); } -} \ No newline at end of file +} From ac04708432259c1b2076a50db13835dbe681d774 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Sat, 5 Jul 2025 16:16:54 +0000 Subject: [PATCH 376/846] 8297499: Parallel: Missing iteration over klass when marking objArrays/objArrayOops during Full GC Backport-of: 6a856bc3f67d539f858904667ee86cbed54f94f7 --- .../parallel/psCompactionManager.inline.hpp | 4 +- .../jtreg/runtime/ClassUnload/UnloadTest.java | 60 +++++++++++++++---- 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp index e40e3689da291..1b1e396bef0f6 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp @@ -168,10 +168,12 @@ inline void ParCompactionManager::follow_class_loader(ClassLoaderData* cld) { inline void ParCompactionManager::follow_contents(oop obj) { assert(PSParallelCompact::mark_bitmap()->is_marked(obj), "should be marked"); + PCIterateMarkAndPushClosure cl(this, PSParallelCompact::ref_processor()); + if (obj->is_objArray()) { + cl.do_klass(obj->klass()); follow_array(objArrayOop(obj), 0); } else { - PCIterateMarkAndPushClosure cl(this, PSParallelCompact::ref_processor()); obj->oop_iterate(&cl); } } diff --git a/test/hotspot/jtreg/runtime/ClassUnload/UnloadTest.java b/test/hotspot/jtreg/runtime/ClassUnload/UnloadTest.java index 31f28d9eee2e4..050261194ef59 100644 --- a/test/hotspot/jtreg/runtime/ClassUnload/UnloadTest.java +++ b/test/hotspot/jtreg/runtime/ClassUnload/UnloadTest.java @@ -35,29 +35,33 @@ import jdk.test.whitebox.WhiteBox; import jdk.test.lib.classloader.ClassUnloadCommon; +import java.lang.reflect.Array; + /** - * Test that verifies that classes are unloaded when they are no longer reachable. + * Test that verifies that liveness of classes is correctly tracked. * - * The test creates a class loader, uses the loader to load a class and creates an instance - * of that class. The it nulls out all the references to the instance, class and class loader - * and tries to trigger class unloading. Then it verifies that the class is no longer - * loaded by the VM. + * The test creates a class loader, uses the loader to load a class and creates + * an instance related to that class. + * 1. Then, it nulls out references to the class loader, triggers class + * unloading and verifies the class is *not* unloaded. + * 2. Next, it nulls out references to the instance, triggers class unloading + * and verifies the class is unloaded. */ public class UnloadTest { - private static String className = "test.Empty"; public static void main(String... args) throws Exception { - run(); + test_unload_instance_klass(); + test_unload_obj_array_klass(); } - private static void run() throws Exception { + private static void test_unload_instance_klass() throws Exception { + final String className = "test.Empty"; final WhiteBox wb = WhiteBox.getWhiteBox(); ClassUnloadCommon.failIf(wb.isClassAlive(className), "is not expected to be alive yet"); ClassLoader cl = ClassUnloadCommon.newClassLoader(); - Class c = cl.loadClass(className); - Object o = c.newInstance(); + Object o = cl.loadClass(className).newInstance(); ClassUnloadCommon.failIf(!wb.isClassAlive(className), "should be live here"); @@ -65,8 +69,42 @@ private static void run() throws Exception { int loadedRefcount = wb.getSymbolRefcount(loaderName); System.out.println("Refcount of symbol " + loaderName + " is " + loadedRefcount); - cl = null; c = null; o = null; + cl = null; + ClassUnloadCommon.triggerUnloading(); + + ClassUnloadCommon.failIf(!wb.isClassAlive(className), "should still be live"); + + o = null; ClassUnloadCommon.triggerUnloading(); + + + ClassUnloadCommon.failIf(wb.isClassAlive(className), "should have been unloaded"); + + int unloadedRefcount = wb.getSymbolRefcount(loaderName); + System.out.println("Refcount of symbol " + loaderName + " is " + unloadedRefcount); + ClassUnloadCommon.failIf(unloadedRefcount != (loadedRefcount - 1), "Refcount must be decremented"); + } + + private static void test_unload_obj_array_klass() throws Exception { + final WhiteBox wb = WhiteBox.getWhiteBox(); + + ClassLoader cl = ClassUnloadCommon.newClassLoader(); + Object o = Array.newInstance(cl.loadClass("test.Empty"), 1); + final String className = o.getClass().getName(); + + ClassUnloadCommon.failIf(!wb.isClassAlive(className), "should be live here"); + + String loaderName = cl.getName(); + int loadedRefcount = wb.getSymbolRefcount(loaderName); + System.out.println("Refcount of symbol " + loaderName + " is " + loadedRefcount); + + cl = null; + ClassUnloadCommon.triggerUnloading(); + ClassUnloadCommon.failIf(!wb.isClassAlive(className), "should still be live"); + + o = null; + ClassUnloadCommon.triggerUnloading(); + ClassUnloadCommon.failIf(wb.isClassAlive(className), "should have been unloaded"); int unloadedRefcount = wb.getSymbolRefcount(loaderName); From a14a93e64b83ca3bc234f195d80277c3b00d97d3 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Sat, 5 Jul 2025 16:20:36 +0000 Subject: [PATCH 377/846] 8297740: runtime/ClassUnload/UnloadTest.java failed with "Test failed: should still be live" Backport-of: a97e7d9887e448c88f59cf70bfb8ab72435ece9c --- test/hotspot/jtreg/runtime/ClassUnload/UnloadTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/runtime/ClassUnload/UnloadTest.java b/test/hotspot/jtreg/runtime/ClassUnload/UnloadTest.java index 050261194ef59..a1ca3aadac9e5 100644 --- a/test/hotspot/jtreg/runtime/ClassUnload/UnloadTest.java +++ b/test/hotspot/jtreg/runtime/ClassUnload/UnloadTest.java @@ -23,7 +23,7 @@ /* * @test UnloadTest - * @bug 8210559 + * @bug 8210559 8297740 * @requires vm.opt.final.ClassUnloading * @modules java.base/jdk.internal.misc * @library /test/lib @@ -48,6 +48,8 @@ * and verifies the class is unloaded. */ public class UnloadTest { + // Using a global static field to keep the object live in -Xcomp mode. + private static Object o; public static void main(String... args) throws Exception { test_unload_instance_klass(); @@ -61,7 +63,7 @@ private static void test_unload_instance_klass() throws Exception { ClassUnloadCommon.failIf(wb.isClassAlive(className), "is not expected to be alive yet"); ClassLoader cl = ClassUnloadCommon.newClassLoader(); - Object o = cl.loadClass(className).newInstance(); + o = cl.loadClass(className).newInstance(); ClassUnloadCommon.failIf(!wb.isClassAlive(className), "should be live here"); @@ -89,7 +91,7 @@ private static void test_unload_obj_array_klass() throws Exception { final WhiteBox wb = WhiteBox.getWhiteBox(); ClassLoader cl = ClassUnloadCommon.newClassLoader(); - Object o = Array.newInstance(cl.loadClass("test.Empty"), 1); + o = Array.newInstance(cl.loadClass("test.Empty"), 1); final String className = o.getClass().getName(); ClassUnloadCommon.failIf(!wb.isClassAlive(className), "should be live here"); From 0b8af09d5ed6b901d3a940c91a6c4d5673b48bcc Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Sat, 5 Jul 2025 16:21:32 +0000 Subject: [PATCH 378/846] 8317522: Test logic for BODY_CF in AbstractThrowingSubscribers.java is wrong Backport-of: 4c5b66dceab15ce27f742c4173e14156249eb61a --- .../AbstractThrowingSubscribers.java | 98 ++++++++++++++----- 1 file changed, 71 insertions(+), 27 deletions(-) diff --git a/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java b/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java index d4100b7eb041d..077ae3464625b 100644 --- a/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java +++ b/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java @@ -21,9 +21,6 @@ * questions. */ -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; -import com.sun.net.httpserver.HttpsServer; import jdk.test.lib.net.SimpleSSLContext; import org.testng.ITestContext; import org.testng.ITestResult; @@ -33,7 +30,6 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import javax.net.ssl.SSLContext; import java.io.BufferedReader; @@ -42,11 +38,8 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UncheckedIOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; import java.net.URI; import java.net.http.HttpClient; -import java.net.http.HttpHeaders; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandler; @@ -63,7 +56,7 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.Executor; import java.util.concurrent.Executors; -import java.util.concurrent.Flow; +import java.util.concurrent.Flow.Subscription; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; @@ -72,7 +65,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.httpclient.test.lib.common.HttpServerAdapters; -import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; import static java.lang.String.format; @@ -99,6 +91,7 @@ public abstract class AbstractThrowingSubscribers implements HttpServerAdapters String https2URI_chunk; static final int ITERATION_COUNT = 1; + static final int REPEAT_RESPONSE = 3; // a shared executor helps reduce the amount of threads created by the test static final Executor executor = new TestExecutor(Executors.newCachedThreadPool()); static final ConcurrentMap FAILURES = new ConcurrentHashMap<>(); @@ -313,7 +306,8 @@ protected void testSanityImpl(String uri, boolean sameClient) BodyHandlers.ofString()); HttpResponse response = client.send(req, handler); String body = response.body(); - assertEquals(URI.create(body).getPath(), URI.create(uri2).getPath()); + Stream.of(body.split("\n")).forEach(u -> + assertEquals(URI.create(u).getPath(), URI.create(uri2).getPath())); if (!sameClient) { // Wait for the client to be garbage collected. // we use the ReferenceTracker API rather than HttpClient::close here, @@ -443,6 +437,7 @@ private void testThrowing(String uri, boolean sameClient, throws Exception { HttpClient client = null; + var throwing = thrower; for (Where where : EnumSet.complementOf(excludes)) { if (!sameClient || client == null) @@ -451,6 +446,9 @@ private void testThrowing(String uri, boolean sameClient, HttpRequest req = HttpRequest. newBuilder(URI.create(uri2)) .build(); + + thrower = thrower(where, throwing); + BodyHandler handler = new ThrowingBodyHandler(where.select(thrower), handlers.get()); System.out.println("try throwing in " + where); @@ -468,12 +466,9 @@ private void testThrowing(String uri, boolean sameClient, response = client.send(req, handler); } catch (Error | Exception t) { // synchronous send will rethrow exceptions - Throwable throwable = t.getCause(); - assert throwable != null; - - if (thrower.test(throwable)) { - System.out.println(now() + "Got expected exception: " + throwable); - } else throw causeNotFound(where, t); + Throwable throwable = findCause(t, thrower); + if (throwable == null) throw causeNotFound(where, t); + System.out.println(now() + "Got expected exception: " + throwable); } } if (response != null) { @@ -658,9 +653,38 @@ public BodySubscriber apply(HttpResponse.ResponseInfo rinfo) { } } + static final class BodyCFThrower implements Thrower { + final Thrower thrower; + BodyCFThrower(Thrower thrower) { + this.thrower = thrower; + } + @Override + public boolean test(Throwable throwable) { + // In case of BODY_CF we also cancel the stream, + // which can cause "Stream XX cancelled" to be reported + return thrower.test(throwable) || + throwable instanceof IOException io && ( + io.getMessage().matches("Stream [0-9]+ cancelled") || + io.getMessage().equals("subscription cancelled") + ); + } + @Override + public void accept(Where where) { + thrower.accept(where); + } + } + + static Thrower thrower(Where where, Thrower thrower) { + return switch (where) { + case BODY_CF -> new BodyCFThrower(thrower); + default -> thrower; + }; + } + static final class ThrowingBodySubscriber implements BodySubscriber { private final BodySubscriber subscriber; - volatile boolean onSubscribeCalled; + volatile Subscription subscription; + final CompletableFuture subscriptionCF = new CompletableFuture<>(); final Consumer throwing; ThrowingBodySubscriber(Consumer throwing, BodySubscriber subscriber) { this.throwing = throwing; @@ -668,17 +692,22 @@ static final class ThrowingBodySubscriber implements BodySubscriber { } @Override - public void onSubscribe(Flow.Subscription subscription) { + public void onSubscribe(Subscription subscription) { //out.println("onSubscribe "); - onSubscribeCalled = true; + this.subscription = subscription; throwing.accept(Where.ON_SUBSCRIBE); subscriber.onSubscribe(subscription); + subscriptionCF.complete(subscription); + } + + boolean onSubscribeCalled() { + return subscription != null; } @Override public void onNext(List item) { // out.println("onNext " + item); - assertTrue(onSubscribeCalled); + assertTrue(onSubscribeCalled(), "onNext called before onSubscribe"); throwing.accept(Where.ON_NEXT); subscriber.onNext(item); } @@ -686,7 +715,7 @@ public void onNext(List item) { @Override public void onError(Throwable throwable) { //out.println("onError"); - assertTrue(onSubscribeCalled); + assertTrue(onSubscribeCalled(), "onError called before onSubscribe"); throwing.accept(Where.ON_ERROR); subscriber.onError(throwable); } @@ -694,7 +723,7 @@ public void onError(Throwable throwable) { @Override public void onComplete() { //out.println("onComplete"); - assertTrue(onSubscribeCalled, "onComplete called before onSubscribe"); + assertTrue(onSubscribeCalled(), "onComplete called before onSubscribe"); throwing.accept(Where.ON_COMPLETE); subscriber.onComplete(); } @@ -702,10 +731,19 @@ public void onComplete() { @Override public CompletionStage getBody() { throwing.accept(Where.GET_BODY); + boolean shouldCancel = false; try { throwing.accept(Where.BODY_CF); } catch (Throwable t) { + shouldCancel = true; return CompletableFuture.failedFuture(t); + } finally { + // if a BodySubscriber returns a failed future, it + // should take responsibility for cancelling the + // subscription explicitly if needed. + if (shouldCancel) { + subscriptionCF.thenAccept(Subscription::cancel); + } } return subscriber.getBody(); } @@ -785,10 +823,13 @@ public void handle(HttpTestExchange t) throws IOException { try (InputStream is = t.getRequestBody()) { is.readAllBytes(); } - byte[] resp = t.getRequestURI().toString().getBytes(StandardCharsets.UTF_8); - t.sendResponseHeaders(200, resp.length); //fixed content length + byte[] resp = (t.getRequestURI() + "\n").getBytes(StandardCharsets.UTF_8); + t.sendResponseHeaders(200, resp.length * 3); //fixed content length try (OutputStream os = t.getResponseBody()) { - os.write(resp); + for (int i=0 ; i < REPEAT_RESPONSE; i++) { + os.write(resp); + os.flush(); + } } } } @@ -797,13 +838,16 @@ static class HTTP_ChunkedHandler implements HttpTestHandler { @Override public void handle(HttpTestExchange t) throws IOException { out.println("HTTP_ChunkedHandler received request to " + t.getRequestURI()); - byte[] resp = t.getRequestURI().toString().getBytes(StandardCharsets.UTF_8); + byte[] resp = (t.getRequestURI() + "\n").getBytes(StandardCharsets.UTF_8); try (InputStream is = t.getRequestBody()) { is.readAllBytes(); } t.sendResponseHeaders(200, -1); // chunked/variable try (OutputStream os = t.getResponseBody()) { - os.write(resp); + for (int i=0 ; i < REPEAT_RESPONSE; i++) { + os.write(resp); + os.flush(); + } } } } From cb36233ff6fb3b1dda31501f6912436e83c2dbe9 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 7 Jul 2025 07:28:22 +0000 Subject: [PATCH 379/846] 8344338: javax/swing/JTextArea/bug4265784.java fails on Ubuntu 24.04.1 Backport-of: e21d06f488bce227eedc4c92d976301a7b54fda8 --- test/jdk/javax/swing/JTextArea/bug4265784.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/javax/swing/JTextArea/bug4265784.java b/test/jdk/javax/swing/JTextArea/bug4265784.java index 3465fced59598..2b1ea06834f65 100644 --- a/test/jdk/javax/swing/JTextArea/bug4265784.java +++ b/test/jdk/javax/swing/JTextArea/bug4265784.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ public static void main(String[] args) throws Exception { try { SwingUtilities.invokeAndWait(() -> { frame = new JFrame("bug4265784"); - ta = new JTextArea(); + ta = new JTextArea("some text", 50, 50); frame.getContentPane().add(ta); frame.pack(); frame.setLocationRelativeTo(null); From e7454faf3ebbc663dd36fad057a5670b1fa27f47 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 8 Jul 2025 07:55:26 +0000 Subject: [PATCH 380/846] 8344137: Update XML Security for Java to 3.0.5 Reviewed-by: mbaesken Backport-of: 2d30662c5dff99c2fa06fc9e06426a9baabd2b57 --- .../security/algorithms/JCEMapper.java | 16 + .../algorithms/MessageDigestAlgorithm.java | 2 +- .../algorithms/SignatureAlgorithm.java | 12 + .../implementations/ECDSAUtils.java | 40 ++ .../implementations/SignatureBaseRSA.java | 3 +- .../implementations/SignatureECDSA.java | 104 +++++ .../xml/internal/security/keys/KeyInfo.java | 40 +- .../keys/content/DEREncodedKeyValue.java | 6 +- .../security/keys/content/KeyValue.java | 15 +- .../keys/content/keyvalues/ECKeyValue.java | 53 ++- .../resource/xmlsecurity_de.properties | 396 +++++++++--------- .../security/signature/XMLSignature.java | 17 + .../internal/security/utils/Constants.java | 6 + .../internal/security/utils/ElementProxy.java | 3 + .../xml/crypto/dsig/SignatureMethod.java | 2 +- .../dsig/internal/dom/DOMKeyInfoFactory.java | 2 +- .../xml/dsig/internal/dom/DOMKeyValue.java | 77 +++- .../dsig/internal/dom/DOMSignatureMethod.java | 104 +++++ .../internal/dom/DOMXMLSignatureFactory.java | 8 + .../jcp/xml/dsig/internal/dom/XMLDSigRI.java | 2 +- src/java.xml.crypto/share/legal/santuario.md | 6 +- .../xml/crypto/dsig/GenerationTests.java | 41 +- test/jdk/javax/xml/crypto/dsig/PSS.java | 61 +++ test/lib/jdk/test/lib/security/XMLUtils.java | 46 +- 24 files changed, 825 insertions(+), 237 deletions(-) create mode 100644 test/jdk/javax/xml/crypto/dsig/PSS.java diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java index e4c1a30d52545..68cb86eb7fdcb 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java @@ -207,6 +207,22 @@ public static void registerDefaultAlgorithms() { XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA512, new Algorithm("EC", "SHA512withECDSA", "Signature") ); + algorithmsMap.put( + XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA3_224, + new Algorithm("EC", "SHA3-224withECDSA", "Signature") + ); + algorithmsMap.put( + XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA3_256, + new Algorithm("EC", "SHA3-256withECDSA", "Signature") + ); + algorithmsMap.put( + XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA3_384, + new Algorithm("EC", "SHA3-384withECDSA", "Signature") + ); + algorithmsMap.put( + XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA3_512, + new Algorithm("EC", "SHA3-512withECDSA", "Signature") + ); algorithmsMap.put( XMLSignature.ALGO_ID_SIGNATURE_ECDSA_RIPEMD160, new Algorithm("EC", "RIPEMD160withECDSA", "Signature") diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/MessageDigestAlgorithm.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/MessageDigestAlgorithm.java index 17351f0211e9e..931f3d5553c19 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/MessageDigestAlgorithm.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/MessageDigestAlgorithm.java @@ -103,7 +103,7 @@ public static MessageDigestAlgorithm getInstance( return new MessageDigestAlgorithm(doc, algorithmURI); } - private static MessageDigest getDigestInstance(String algorithmURI) throws XMLSignatureException { + public static MessageDigest getDigestInstance(String algorithmURI) throws XMLSignatureException { String algorithmID = JCEMapper.translateURItoJCEID(algorithmURI); if (algorithmID == null) { diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java index 439eefb10dc73..a74d373244ccf 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java @@ -494,6 +494,18 @@ public static void registerDefaultAlgorithms() { algorithmHash.put( XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA512, SignatureECDSA.SignatureECDSASHA512.class ); + algorithmHash.put( + XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA3_224, SignatureECDSA.SignatureECDSASHA3_224.class + ); + algorithmHash.put( + XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA3_256, SignatureECDSA.SignatureECDSASHA3_256.class + ); + algorithmHash.put( + XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA3_384, SignatureECDSA.SignatureECDSASHA3_384.class + ); + algorithmHash.put( + XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA3_512, SignatureECDSA.SignatureECDSASHA3_512.class + ); algorithmHash.put( XMLSignature.ALGO_ID_SIGNATURE_ECDSA_RIPEMD160, SignatureECDSA.SignatureECDSARIPEMD160.class ); diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/ECDSAUtils.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/ECDSAUtils.java index 73e02864bd926..4d38b2f07bda9 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/ECDSAUtils.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/ECDSAUtils.java @@ -770,6 +770,46 @@ public static byte[] convertXMLDSIGtoASN1(byte[] xmldsigBytes) throws IOExceptio "0340340340340340340340340340340340340340340340340340340323c313fab50589703b5ec68d3587fec60d161cc149c1ad4a91", 0x2760) ); + + ecCurveDefinitions.add( + new ECCurveDefinition( + "brainpoolP256r1 [RFC 5639]", + "1.3.36.3.3.2.8.1.1.7", + "a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377", + "7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9", + "26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6", + "8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262", + "547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997", + "a9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7", + 1) + ); + + ecCurveDefinitions.add( + new ECCurveDefinition( + "brainpoolP384r1 [RFC 5639]", + "1.3.36.3.3.2.8.1.1.11", + "8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123acd3a729901d1a71874700133107ec53", + "7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f8aa5814a503ad4eb04a8c7dd22ce2826", + "04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d57cb4390295dbc9943ab78696fa504c11", + "1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8e826e03436d646aaef87b2e247d4af1e", + "8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff99129280e4646217791811142820341263c5315", + "8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b31f166e6cac0425a7cf3ab6af6b7fc3103b883202e9046565", + 1) + ); + + ecCurveDefinitions.add( + new ECCurveDefinition( + "brainpoolP512r1 [RFC 5639]", + "1.3.36.3.3.2.8.1.1.13", + "aadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca703308717d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3", + "7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca", + "3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723", + "81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098eff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822", + "7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892", + "aadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330870553e5c414ca92619418661197fac10471db1d381085ddaddb58796829ca90069", + 1) + ); + } public static String getOIDFromPublicKey(ECPublicKey ecPublicKey) { diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java index 45dafc3ad3894..fc79e0c774e44 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java @@ -66,8 +66,7 @@ public SignatureBaseRSA() throws XMLSignatureException { public SignatureBaseRSA(Provider provider) throws XMLSignatureException { String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI()); this.signatureAlgorithm = getSignature(provider, algorithmID); - LOG.debug("Created SignatureRSA using {0} and provider {1}", - algorithmID, signatureAlgorithm.getProvider()); + LOG.debug("Created SignatureRSA using {0}", algorithmID); } Signature getSignature(Provider provider, String algorithmID) diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java index 75a88b8eb1332..a90a314ade294 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java @@ -371,6 +371,110 @@ public String engineGetURI() { } } + /** + * Class SignatureECDSASHA3-224 + * + */ + public static class SignatureECDSASHA3_224 extends SignatureECDSA { + + /** + * Constructor SignatureECDSASHA3-224 + * + * @throws XMLSignatureException + */ + public SignatureECDSASHA3_224() throws XMLSignatureException { + super(); + } + + public SignatureECDSASHA3_224(Provider provider) throws XMLSignatureException { + super(provider); + } + + /** {@inheritDoc} */ + @Override + public String engineGetURI() { + return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA3_224; + } + } + + /** + * Class SignatureECDSASHA3-256 + * + */ + public static class SignatureECDSASHA3_256 extends SignatureECDSA { + + /** + * Constructor SignatureECDSASHA3-256 + * + * @throws XMLSignatureException + */ + public SignatureECDSASHA3_256() throws XMLSignatureException { + super(); + } + + public SignatureECDSASHA3_256(Provider provider) throws XMLSignatureException { + super(provider); + } + + /** {@inheritDoc} */ + @Override + public String engineGetURI() { + return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA3_256; + } + } + + /** + * Class SignatureECDSASHA3-384 + * + */ + public static class SignatureECDSASHA3_384 extends SignatureECDSA { + + /** + * Constructor SignatureECDSASHA3-384 + * + * @throws XMLSignatureException + */ + public SignatureECDSASHA3_384() throws XMLSignatureException { + super(); + } + + public SignatureECDSASHA3_384(Provider provider) throws XMLSignatureException { + super(provider); + } + + /** {@inheritDoc} */ + @Override + public String engineGetURI() { + return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA3_384; + } + } + + /** + * Class SignatureECDSASHA3-512 + * + */ + public static class SignatureECDSASHA3_512 extends SignatureECDSA { + + /** + * Constructor SignatureECDSASHA3-512 + * + * @throws XMLSignatureException + */ + public SignatureECDSASHA3_512() throws XMLSignatureException { + super(); + } + + public SignatureECDSASHA3_512(Provider provider) throws XMLSignatureException { + super(provider); + } + + /** {@inheritDoc} */ + @Override + public String engineGetURI() { + return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA3_512; + } + } + /** * Class SignatureECDSARIPEMD160 */ diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java index 62f25d1298daf..01dd2ed16d7db 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java @@ -32,15 +32,7 @@ import javax.crypto.SecretKey; import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; -import com.sun.org.apache.xml.internal.security.keys.content.DEREncodedKeyValue; -import com.sun.org.apache.xml.internal.security.keys.content.KeyInfoReference; -import com.sun.org.apache.xml.internal.security.keys.content.KeyName; -import com.sun.org.apache.xml.internal.security.keys.content.KeyValue; -import com.sun.org.apache.xml.internal.security.keys.content.MgmtData; -import com.sun.org.apache.xml.internal.security.keys.content.PGPData; -import com.sun.org.apache.xml.internal.security.keys.content.RetrievalMethod; -import com.sun.org.apache.xml.internal.security.keys.content.SPKIData; -import com.sun.org.apache.xml.internal.security.keys.content.X509Data; +import com.sun.org.apache.xml.internal.security.keys.content.*; import com.sun.org.apache.xml.internal.security.keys.content.keyvalues.DSAKeyValue; import com.sun.org.apache.xml.internal.security.keys.content.keyvalues.RSAKeyValue; import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolver; @@ -50,7 +42,6 @@ import com.sun.org.apache.xml.internal.security.transforms.Transforms; import com.sun.org.apache.xml.internal.security.utils.Constants; import com.sun.org.apache.xml.internal.security.utils.ElementProxy; -import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy; import com.sun.org.apache.xml.internal.security.utils.XMLUtils; import org.w3c.dom.Attr; import org.w3c.dom.Document; @@ -88,7 +79,7 @@ * contains the corresponding type. * */ -public class KeyInfo extends SignatureElementProxy { +public class KeyInfo extends ElementProxy { private static final com.sun.org.slf4j.internal.Logger LOG = com.sun.org.slf4j.internal.LoggerFactory.getLogger(KeyInfo.class); @@ -231,12 +222,24 @@ public void add(RSAKeyValue rsakeyvalue) { } /** - * Method add + * Method adds public key encoded as KeyValue. If public key type is not supported by KeyValue, then + * DEREncodedKeyValue is used. If public key type is not supported by DEREncodedKeyValue, then + * IllegalArgumentException is thrown. * - * @param pk + * @param pk public key to be added to KeyInfo */ - public void add(PublicKey pk) { - this.add(new KeyValue(getDocument(), pk)); + public void add(PublicKey pk) { + + if (KeyValue.isSupportedKeyType(pk)) { + this.add(new KeyValue(getDocument(), pk)); + return; + } + + try { + this.add(new DEREncodedKeyValue(getDocument(), pk)); + } catch (XMLSecurityException ex) { + throw new IllegalArgumentException(ex); + } } /** @@ -772,6 +775,7 @@ public boolean containsKeyInfoReference() { return this.lengthKeyInfoReference() > 0; } + /** * This method returns the public key. * @@ -1188,4 +1192,10 @@ public void addStorageResolver(StorageResolver storageResolver) { public String getBaseLocalName() { return Constants._TAG_KEYINFO; } + + /** {@inheritDoc} */ + @Override + public String getBaseNamespace() { + return Constants.SignatureSpecNS; + } } diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/DEREncodedKeyValue.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/DEREncodedKeyValue.java index 823a50366801f..2b5b55a3d040d 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/DEREncodedKeyValue.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/DEREncodedKeyValue.java @@ -41,7 +41,10 @@ public class DEREncodedKeyValue extends Signature11ElementProxy implements KeyInfoContent { /** JCA algorithm key types supported by this implementation. */ - private static final String[] supportedKeyTypes = { "RSA", "DSA", "EC"}; + private static final String[] supportedKeyTypes = { "RSA", "DSA", "EC", + "DiffieHellman", "DH", "XDH", "X25519", "X448", + "EdDSA", "Ed25519", "Ed448", + "RSASSA-PSS"}; /** * Constructor DEREncodedKeyValue @@ -144,5 +147,4 @@ protected byte[] getEncodedDER(PublicKey publicKey) throws XMLSecurityException throw new XMLSecurityException(e, "DEREncodedKeyValue.UnsupportedPublicKey", exArgs); } } - } diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java index ee999e6578351..d1eb890f88571 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java @@ -41,7 +41,6 @@ * (section 6.4). The KeyValue element may include externally defined public * keys values represented as PCDATA or element types from an external * namespace. - * */ public class KeyValue extends SignatureElementProxy implements KeyInfoContent { @@ -120,6 +119,20 @@ public KeyValue(Document doc, PublicKey pk) { } } + /** + * Verifies that the XML KeyValue encoding is supported for the given key type. If the + * encoding is supported, it returns true else false. + * + * @return true if the public key has a KeyValue encoding, false otherwise. + */ + public static boolean isSupportedKeyType(PublicKey publicKey) { + + return publicKey instanceof java.security.interfaces.DSAPublicKey + || publicKey instanceof java.security.interfaces.RSAPublicKey + || publicKey instanceof java.security.interfaces.ECPublicKey; + + } + /** * Constructor KeyValue * diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/ECKeyValue.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/ECKeyValue.java index 839d9e4285da3..9bc6e55d7e557 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/ECKeyValue.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/ECKeyValue.java @@ -91,6 +91,45 @@ public class ECKeyValue extends Signature11ElementProxy implements KeyValueConte 1 ); + /* Supported curve brainpoolP256r1 */ + private static final Curve BRAINPOOLP256R1 = initializeCurve( + "brainpoolP256r1 [RFC 5639]", + "1.3.36.3.3.2.8.1.1.7", + "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", + "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", + "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", + "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", + "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", + "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", + 1 + ); + + /* Supported curve brainpoolP384r1 */ + private static final Curve BRAINPOOLP384R1 = initializeCurve( + "brainpoolP384r1 [RFC 5639]", + "1.3.36.3.3.2.8.1.1.11", + "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", + "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", + "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", + "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", + "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", + "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", + 1 + ); + + /* Supported curve brainpoolP512r1 */ + private static final Curve BRAINPOOLP512R1 = initializeCurve( + "brainpoolP512r1 [RFC 5639]", + "1.3.36.3.3.2.8.1.1.13", + "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", + "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", + "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", + "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", + "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", + "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", + 1 + ); + private static Curve initializeCurve(String name, String oid, String sfield, String a, String b, String x, String y, String n, int h) { @@ -264,7 +303,13 @@ private static String getCurveOid(ECParameterSpec params) { match = SECP384R1; } else if (matchCurve(params, SECP521R1)) { match = SECP521R1; - } else { + } else if (matchCurve(params, BRAINPOOLP256R1)) { + match = BRAINPOOLP256R1; + } else if (matchCurve(params, BRAINPOOLP384R1)) { + match = BRAINPOOLP384R1; + } else if (matchCurve(params, BRAINPOOLP512R1)) { + match = BRAINPOOLP512R1; + }else { return null; } return match.getObjectId(); @@ -332,6 +377,12 @@ private static ECParameterSpec getECParameterSpec(String oid) { return SECP384R1; } else if (oid.equals(SECP521R1.getObjectId())) { return SECP521R1; + } else if (oid.equals(BRAINPOOLP256R1.getObjectId())) { + return BRAINPOOLP256R1; + } else if (oid.equals(BRAINPOOLP384R1.getObjectId())) { + return BRAINPOOLP384R1; + } else if (oid.equals(BRAINPOOLP512R1.getObjectId())) { + return BRAINPOOLP512R1; } else { return null; } diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_de.properties b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_de.properties index 03a2369566c76..d3fa02febd8c7 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_de.properties +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_de.properties @@ -1,199 +1,199 @@ -# -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -# - -algorithm.alreadyRegistered = URI {0} wurde bereits an die Klasse {1} gebunden -algorithm.classDoesNotExist = Kann URI {0} nicht f\u00fcr Klasse {1} registrieren weil sie nicht existiert -algorithm.ClassDoesNotExist = Klasse {0} existiert nicht -algorithm.extendsWrongClass = Kann URI {0} nicht f\u00fcr Klasse {1} registrieren weil sie nicht von {2} abgeleitet ist -algorithms.CannotUseAlgorithmParameterSpecOnDSA = AlgorithmParameterSpec kann nicht f\u00fcr DSA Signaturen benutzt werden. -algorithms.CannotUseAlgorithmParameterSpecOnRSA = AlgorithmParameterSpec kann nicht f\u00fcr RSA Signaturen benutzt werden. -algorithms.CannotUseSecureRandomOnMAC = SecureRandom kann nicht f\u00fcr MAC's angewandt werden. -algorithms.HMACOutputLengthMax = HMACOutputLength darf nicht grosser als {0} sein -algorithms.HMACOutputLengthMin = HMACOutputLength darf nicht kleiner als {0} sein -algorithms.HMACOutputLengthOnlyForHMAC = Die HMACOutputLength kann nur bei HMAC integrit\u00e4ts Algorithmen angegeben werden -algorithms.MissingRSAPSSParams = RSAPSSParams is a required Element for http://www.w3.org/2007/05/xmldsig-more#rsa-pss -algorithms.NoSuchAlgorithm = Der Algorithmus {0} ist nicht verf\u00fcgbar. -algorithms.NoSuchAlgorithm = Der Algorithmus {0} ist nicht verf\u00fcgbar. Original Nachricht war\: {1} -algorithms.NoSuchMap = Algorithmus URI "{0}" konnte auf keinen JCE Algorithmus gemappt werden -algorithms.NoSuchProvider = Der angegebene Provider {0} existiert nicht. Original Nachricht war\: {1} -algorithms.operationOnlyVerification = Ein \u00f6ffentlicher Schl\u00fcssel (public key) kann nur zur Verifizierung einer Signatur verwendet werden. -algorithms.WrongKeyForThisOperation = Der angegebene Schl\u00fcssel-Typ kann nicht f\u00fcr diese Operation verwendet werden. Angegeben wurde {0} aber ein {1} wird ben\u00f6tigt. -attributeValueIllegal = Das Attribut {0} hat den Wert {1} muss aber {2} sein. -c14n.Canonicalizer.Exception = Fehler w\u00e4hrend der Kanonisierung\: Original Nachricht war {0} -c14n.Canonicalizer.IllegalNode = Unzul\u00e4ssiger NodeType {0}, NodeName lautete {1} -c14n.Canonicalizer.NoSuchCanonicalizer = Kein Kanonisierer mit dem URI {0} gefunden -c14n.Canonicalizer.ParserConfigurationException = ParserConfigurationException w\u00e4hrend der Kanonisierung\: Original Nachricht war {0} -c14n.Canonicalizer.RelativeNamespace = Das Element {0} hat einen relativen Namespace: {1}="{2}" -c14n.Canonicalizer.SAXException = SAXException w\u00e4hrend der Kanonisierung\: Original Nachricht war {0} -c14n.Canonicalizer.TraversalNotSupported = Das DOM Dokument unterst\u00fctzt keine Traversal {0} -c14n.Canonicalizer.UnsupportedEncoding = Nicht unterst\u00fctzte Kodierung {0} -c14n.Canonicalizer.UnsupportedOperation = Der Kanonisierer unterst\u00fctzt diese Operation nicht -c14n.XMLUtils.circumventBug2650forgotten = Die Baumstruktur wurde nicht vorbereitet f\u00fcr die Kanonisierung mit XMLUtils\#circumventBug2650(Document) -certificate.noSki.lowVersion = Das Zertifikat dard kein SubjectKeyIdentifier enthalten da es nur ein X509v{0} ist -certificate.noSki.notOctetString = Der SubjectKeyIdentifier des Zertifikates ist kein "OctetString" -certificate.noSki.null = Das Zertifikat enth\u00e4lt kein SubjectKeyIdentifier -defaultNamespaceCannotBeSetHere = Standard Namespace kann hier nicht gesetzt werden -ElementProxy.nullElement = Kann keinen ElementProxy aus einem null Argument erzeugen -empty = {0} -encryption.algorithmCannotBeUsedForEncryptedData = encryption.algorithmCannotBeUsedForEncryptedData {0} -encryption.algorithmCannotEatInitParams = encryption.algorithmCannotEatInitParams -encryption.algorithmCannotEncryptDecrypt = encryption.algorithmCannotEncryptDecrypt -encryption.algorithmCannotWrapUnWrap = encryption.algorithmCannotWrapUnWrap -encryption.ExplicitKeySizeMismatch = Das xenc\:KeySize Element fordert eine Schl\u00fcssel-L\u00e4nge von {0} bits aber der Algorithmus besitzt {1} bits -encryption.nonceLongerThanDecryptedPlaintext = Das angegebene "Nonce" ist l\u00e4nger als der verf\u00fcgbare Plaintext. -encryption.RSAOAEP.dataHashWrong = Falscher Hash-Wert -encryption.RSAOAEP.dataStartWrong = Falscher Start Input {0} -encryption.RSAOAEP.dataTooShort = Zu wenig Input -encryption.RSAPKCS15.blockTruncated = Block abgeschnitten -encryption.RSAPKCS15.noDataInBlock = Im Block sind keine Daten enthalten -encryption.RSAPKCS15.unknownBlockType = Unbekannter Block Typ -encryption.nokey = Es ist kein verschl\u00fcsselungs Schl\u00fcssel geladen und es konnte kein Schl\u00fcssel mit Hilfe der "key resolvers" gefunden werden. -endorsed.jdk1.4.0 = Leider scheint niemand unsere Installations-Anleitung zu lesen, deshalb m\u00fcssen wir es \u00fcber die Exception machen\: Du hast den "endorsing" Mechanismus vom JDK 1.4 nicht richtig angewandt. Schaue unter nach wie man das Problem l\u00f6st. -errorMessages.InvalidDigestValueException = Ung\u00fcltige Signatur\: Referen-Validierung fehlgeschlagen. -errorMessages.InvalidSignatureValueException = Ung\u00fcltige Signatur\: Core Validierung fehlgeschlagen. -errorMessages.IOException = Datei oder Resource kann nicht gelesen werden. -errorMessages.MissingKeyFailureException = Verifizierung fehlgeschlagen, weil der \u00f6ffentliche Schl\u00fcssel (public key) nicht verf\u00fcgbar ist. Resourcen via addResource() hinzuf\u00fcgen und erneut versuchen. -errorMessages.MissingResourceFailureException = Verifizierung fehlgeschlagen, weil Resourcen nicht verf\u00fcgbar sind. Resourcen via addResource() hinzuf\u00fcgen und erneut versuchen. -errorMessages.NoSuchAlgorithmException = Unbekannter Algorithmus {0} -errorMessages.NotYetImplementedException = Funktionalit\u00e4t noch nicht implementiert. -errorMessages.XMLSignatureException = Verifizierung aus unbekanntem Grund fehlgeschlagen. -decoding.divisible.four = It should be divisible by four -decoding.general = Fehler beim Decodieren -FileKeyStorageImpl.addToDefaultFromRemoteNotImplemented = Methode addToDefaultFromRemote() wurde noch nicht implementiert. -FileKeyStorageImpl.NoCert.Context = Kein X509-Zertifikat mit Kontext {0} gefunden -FileKeyStorageImpl.NoCert.IssNameSerNo = Kein X509-Zertifikat mit IssuerName {0} und serial number {1} gefunden -FileKeyStorageImpl.NoCert.SubjName = Kein X509-Zertifikat mit SubjectName {0} gefunden -generic.dontHaveConstructionElement = Konstruktions-Element fehlt -generic.EmptyMessage = {0} -generic.NotYetImplemented = {0} Leider noch nicht implementiert ;-(( -java.security.InvalidKeyException = Ung\u00fcltiger Schl\u00fcssel -java.security.NoSuchProviderException = Unbekannter oder nicht unterst\u00fctzter Provider -java.security.UnknownKeyType = Unbekannter oder nicht unterst\u00fctzter Schl\u00fcssel-Typ {0} -KeyInfo.error = Error loading Key Info -KeyInfo.needKeyResolver = Es m\u00fcssen mehrere KeyResolver registriert sein -KeyInfo.nokey = Kann keinen Schl\u00fcssel aus {0} gewinnen -KeyInfo.noKey = Kann keinen \u00f6ffentlichen Schl\u00fcssel finden -KeyInfo.wrongNumberOfObject = Ben\u00f6tige {0} keyObjects -KeyInfo.wrongUse = Dieses Objekt wird verwendet, um {0} zu gewinnen -keyResolver.alreadyRegistered = Die Klasse {1} wurde bereits registriert f\u00fcr {0} -KeyResolver.needStorageResolver = Es wird ein StorageResolver ben\u00f6tigt um ein Zertifikat aus {0} zu holen -KeyResoverSpiImpl.cannotGetCert = Cannot get the Certificate that include or in {1} in implement class {0} -KeyResoverSpiImpl.elementGeneration = Cannot make {1} element in implement class {0} -KeyResoverSpiImpl.getPoublicKey = Cannot get the public key from implement class {0} -KeyResoverSpiImpl.InvalidElement = Cannot set (2) Element in implement class {0} -KeyResoverSpiImpl.keyStore = KeyStorage Fehler in der implementierenden Klasse {0} -KeyResoverSpiImpl.need.Element = Es wird der Typ {1} ben\u00f6tigt in der implementierenden Klasse {0} -KeyResoverSpiImpl.wrongCRLElement = Cannot make CRL from {1} in implement class {0} -KeyResoverSpiImpl.wrongKeyObject = Need {1} type of KeyObject for generation Element in implement class{0} -KeyResoverSpiImpl.wrongNumberOfObject = Need {1} keyObject in implement class {0} -KeyStore.alreadyRegistered = Klasse {0} bereits registriert f\u00fcr {1} -KeyStore.register = {1} type class register error in class {0} -KeyStore.registerStore.register = Registrierungsfehler f\u00fcr Typ {0} -KeyValue.IllegalArgument = Kann kein {0} aus {1} erzeugen -namespacePrefixAlreadyUsedByOtherURI = Namespace {0} wird bereits von einer anderen URI {1} gebraucht -notYetInitialized = Das Modul {0} ist noch nicht initialisiert -prefix.AlreadyAssigned = Sie binden den Prefix {0} an den Namespace {1} aber er ist bereits an {2} zugewiesen -signature.Canonicalizer.UnknownCanonicalizer = Unbekannter Kanonisierer. Kein Handler installiert f\u00fcr URI {0} -signature.DSA.invalidFormat = Ung\u00fcltige ASN.1 Kodierung der DSA Signatur -signature.Generation.signBeforeGetValue = Es muss zuerst XMLSignature.sign(java.security.PrivateKey) aufgerufen werden -signature.Reference.ForbiddenResolver = Der "Resolver" {0} ist bei aktivierter "secure validation" nicht erlaubt -signature.Reference.NoDigestMethod = A Signature Reference Element must contain a DigestMethod child -signature.Reference.NoDigestValue = A Signature Reference Element must contain a DigestValue child -signature.signatureAlgorithm = Der Algorithmus {0} ist bei aktivierter "secure validation" nicht erlaubt -signature.signaturePropertyHasNoTarget = Das Target Attribut der SignatureProperty muss gesetzt sein -signature.tooManyReferences = Das Manifest enth\u00e4lt {0} Referenzen, bei aktivierter "secure validation" sind aber maximal {1} erlaubt -signature.tooManyTransforms = Die Referenz enth\u00e4lt {0} Transformationen, bei aktivierter "secure validation" sind aber maximal {1} erlaubt -signature.Transform.ErrorDuringTransform = W\u00e4hrend der Transformation {0} trat eine {1} auf. -signature.Transform.ForbiddenTransform = Die Transformation {0} ist bei aktivierter "secure validation" nicht erlaubt -signature.Transform.NotYetImplemented = Transform {0} noch nicht implementiert -signature.Transform.NullPointerTransform = Null pointer als URI \u00fcbergeben. Programmierfehler? -signature.Transform.UnknownTransform = Unbekannte Transformation. Kein Handler installiert f\u00fcr URI {0} -signature.Util.BignumNonPositive = bigInteger.signum() muss positiv sein -signature.Util.NonTextNode = Keine Text Node -signature.Util.TooManyChilds = Zu viele Kind-Elemente vom Typ {0} in {1} -signature.Verification.certificateError = Zertifikatsfehler -signature.Verification.IndexOutOfBounds = Index {0} illegal. Es sind nur {1} Referenzen vorhanden -signature.Verification.internalError = Interner Fehler -signature.Verification.InvalidDigestOrReference = Ung\u00fcltiger Digest Wert der Referenz {0} -signature.Verification.InvalidElement = Current Node {0} is not permitted in this location in the Signature -signature.Verification.keyStore = \u00d6ffnen des KeyStore fehlgeschlagen -signature.Verification.MissingID = Element mit der ID {0} nicht gefunden -signature.Verification.MissingResources = Kann die externe Resource {0} nicht aufl\u00f6sen -signature.Verification.MultipleIDs = Mehrere Elemente mit der ID {0} gefunden -signature.Verification.NoSignatureElement = Input Dokument enth\u00e4lt kein {0} Element mit dem Namespace {1} -signature.Verification.Reference.NoInput = Die Referenz f\u00fcr den URI {0} hat keinen XMLSignatureInput erhalten. -signature.Verification.SignatureError = Signatur Fehler -signature.XMLSignatureInput.MissingConstuctor = Kann aus der Klasse {0} keinen XMLSignatureInput erzeugen -signature.XMLSignatureInput.SerializeDOM = Input mit einem DOM Dokument initialisiert. Muss mit C14N serialisiert werden -transform.Init.IllegalContextArgument = Unzul\u00e4ssiges Kontext Argument der Klasse {0}. Muss String, org.w3c.dom.NodeList oder java.io.InputStream sein. -transform.init.NotInitialized = -transform.init.wrongURI = Initialisiert mit dem falschen URI. Das sollte nie passieren. Die Transformation implementiert {0} aber {1} wurde bei der Instantiierung verwendet. -utils.Base64.IllegalBitlength = Ung\u00fcltige Byte-L\u00e4nge; Muss ein vielfaches von 4 sein -utils.resolver.noClass = Keinen Resolver f\u00fcr URI {0} und Base {1} gefunden -xml.WrongContent = Kann {0} nicht finden in {1} -xml.WrongElement = Kann kein {0} aus einem {1} Element erzeugen -xpath.funcHere.documentsDiffer = Der XPath ist nicht im selben Dokument wie der Kontext Node -xpath.funcHere.noXPathContext = Versuch einer XPath-Evaluierung welcher die Funktion here() benutzt aber der XPath ist nicht innerhalb eines ds\:XPath Elements. XPath \: {0} -signature.Transform.node = Aktuelle Node\: {0} -signature.Transform.nodeAndType = Aktuelle Node\: {0}, Typ\: {1} -signature.XMLSignatureInput.nodesetReference = Das Node-Set der Referenz konnte nicht konvertieren werden -transform.envelopedSignatureTransformNotInSignatureElement = Enveloped Transform konnte kein Signatur Element finden -Base64Decoding = Fehler bei der Decodierung -secureProcessing.MaximumAllowedTransformsPerReference = Die Referenz enth\u00e4lt {0} Transformationen. Es sind aber maximal {1} erlaubt. Die Limite kann \u00fcber das Konfigurations-Property "MaximumAllowedTransformsPerReference" erh\u00f6ht werden. -secureProcessing.MaximumAllowedReferencesPerManifest = Das Manifest enh\u00e4lt {0} Referenzen. Es sind aber maximal {1} erlaubt. Die Limite kann \u00fcber das Konfigurations-Property "MaximumAllowedReferencesPerManifest" erh\u00f6ht werden. -secureProcessing.DoNotThrowExceptionForManifests = Signatur-Manifests werden nicht unterst\u00fctzt. Das werfen dieser Exception kann durch das Konfigurations-Property "DoNotThrowExceptionForManifests" verhindert werden. -secureProcessing.AllowMD5Algorithm = Vom Einsatz des MD5 Algorithmus wird strengstens abgeraten. Trotzdem kann er \u00fcber das Konfigurations-Property "AllowMD5Algorithm" erlaubt werden. -secureProcessing.AllowNotSameDocumentReferences = Externe Referenzen gefunden. Die Verarbeitung von externen Referenzen ist standardm\u00e4ssig ausgeschaltet. Es kann \u00fcber das Konfigurations-Property "AllowNotSameDocumentReferences" aktiviert werden. -secureProcessing.MaximumAllowedXMLStructureDepth = Die Maximum erlaubte Dokumenten-Tiefe von ({0}) wurde erreicht. Die Limite kann \u00fcber das Konfigurations-Property "MaximumAllowedXMLStructureDepth" erh\u00f6ht werden. -secureProcessing.inputStreamLimitReached = Maximal erlaubte Anzahl bytes ({0}) erreicht. -stax.duplicateActions=Doppelte Actions sind nicht erlaubt. -stax.missingSecurityProperties = SecurityProperties darf nicht null sein\! -stax.noOutputAction = Keine ausgehenden "Actions" definiert. -stax.noKey = Kein Schl\u00fcssel geladen und es konnte kein Schl\u00fcssel gefunden werden f\u00fcr {0} -stax.keyNotFound = Schl\u00fcssel nicht gefunden. -stax.unsupportedKeyValue = Kein oder ung\u00fcltiger KeyValue. -stax.emptyReferenceURI = Referenz enth\u00e4lt kein URI Attribut. -stax.encryption.unprocessedReferences = Es wurden nicht alle Verschl\u00fcsselungs-Referenzen verarbeitet... -stax.signature.unprocessedReferences = Es wurden nicht alle Signatur-Referenzen verarbeitet... -stax.unsupportedToken = {0} nicht unterst\u00fctzt. -stax.xmlStructureSizeExceeded = Maximal erlaubte ({0}) XML-Struktur Tiefe erreicht. -stax.unexpectedXMLEvent = Unerwarteter StAX-Event\: {0} -stax.encryption.noEncAlgo = xenc\:EncryptedKey enth\u00e4lt kein xenc\:EncryptionMethod/@Algorithm. -stax.encryption.noCipherValue = EncryptedKey enth\u00e4lt kein xenc\:CipherData/xenc\:CipherValue. -stax.unsecuredMessage = Ungesicherte Nachricht. Weder ein Signatur- noch ein EncryptedData- Element wurde gefunden. -stax.signature.signedInfoMissing = SignedInfo Element fehlt. -stax.signature.signatureMethodMissing = Signature method fehlt. -stax.signature.canonicalizationMethodMissing = Signature canonicalization method fehlt. -stax.signature.signatureValueMissing = Signature value fehlt. -stax.signature.publicKeyOrCertificateMissing = Weder ein Zertifikat noch ein public-key wurde konfiguriert. -stax.encryption.encryptionKeyMissing = Kein Schl\u00fcssel f\u00fcr die Verschl\u00fcsselung wurde konfiguriert. -stax.unsupportedKeyTransp = Der public-key Algorithmus ist zu kurz um den symmetrischen Schl\u00fcssel zu verschl\u00fcsseln. -stax.recursiveKeyReference = Rekursive Schl\u00fcssel referenzierung detektiert. -stax.ecParametersNotSupported = ECParameters werden nicht unterst\u00fctzt. -stax.namedCurveMissing = NamedCurve fehlt. -stax.encryption.securePartNotFound = Part zum Verschl\u00fcsseln nicht gefunden: {0} -stax.signature.securePartNotFound = Part zum Signieren nicht gefunden: {0} -stax.multipleSignaturesNotSupported = Mehrere Signaturen werden nicht unterstützt. -stax.signature.keyNameMissing = KeyName nicht konfiguriert. -stax.keyNotFoundForName = Kein Schl\u00fcssel für Schl\u00fcsselname konfiguriert: {0} -stax.keyTypeNotSupported = Key vom Typ {0} nicht f\u00fcr einen Key-Namenssuche unterst\u00fctzt -stax.idsetbutnotgenerated = An Id attribute is specified, but Id generation is disabled +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# + +algorithm.alreadyRegistered = URI {0} wurde bereits an die Klasse {1} gebunden +algorithm.classDoesNotExist = Kann URI {0} nicht f\u00fcr Klasse {1} registrieren weil sie nicht existiert +algorithm.ClassDoesNotExist = Klasse {0} existiert nicht +algorithm.extendsWrongClass = Kann URI {0} nicht f\u00fcr Klasse {1} registrieren weil sie nicht von {2} abgeleitet ist +algorithms.CannotUseAlgorithmParameterSpecOnDSA = AlgorithmParameterSpec kann nicht f\u00fcr DSA Signaturen benutzt werden. +algorithms.CannotUseAlgorithmParameterSpecOnRSA = AlgorithmParameterSpec kann nicht f\u00fcr RSA Signaturen benutzt werden. +algorithms.CannotUseSecureRandomOnMAC = SecureRandom kann nicht f\u00fcr MAC's angewandt werden. +algorithms.HMACOutputLengthMax = HMACOutputLength darf nicht grosser als {0} sein +algorithms.HMACOutputLengthMin = HMACOutputLength darf nicht kleiner als {0} sein +algorithms.HMACOutputLengthOnlyForHMAC = Die HMACOutputLength kann nur bei HMAC integrit\u00e4ts Algorithmen angegeben werden +algorithms.MissingRSAPSSParams = RSAPSSParams is a required Element for http://www.w3.org/2007/05/xmldsig-more#rsa-pss +algorithms.NoSuchAlgorithmNoEx = Der Algorithmus {0} ist nicht verf\u00fcgbar. +algorithms.NoSuchAlgorithm = Der Algorithmus {0} ist nicht verf\u00fcgbar. Original Nachricht war\: {1} +algorithms.NoSuchMap = Algorithmus URI "{0}" konnte auf keinen JCE Algorithmus gemappt werden +algorithms.NoSuchProvider = Der angegebene Provider {0} existiert nicht. Original Nachricht war\: {1} +algorithms.operationOnlyVerification = Ein \u00f6ffentlicher Schl\u00fcssel (public key) kann nur zur Verifizierung einer Signatur verwendet werden. +algorithms.WrongKeyForThisOperation = Der angegebene Schl\u00fcssel-Typ kann nicht f\u00fcr diese Operation verwendet werden. Angegeben wurde {0} aber ein {1} wird ben\u00f6tigt. +attributeValueIllegal = Das Attribut {0} hat den Wert {1} muss aber {2} sein. +c14n.Canonicalizer.Exception = Fehler w\u00e4hrend der Kanonisierung\: Original Nachricht war {0} +c14n.Canonicalizer.IllegalNode = Unzul\u00e4ssiger NodeType {0}, NodeName lautete {1} +c14n.Canonicalizer.NoSuchCanonicalizer = Kein Kanonisierer mit dem URI {0} gefunden +c14n.Canonicalizer.ParserConfigurationException = ParserConfigurationException w\u00e4hrend der Kanonisierung\: Original Nachricht war {0} +c14n.Canonicalizer.RelativeNamespace = Das Element {0} hat einen relativen Namespace: {1}="{2}" +c14n.Canonicalizer.SAXException = SAXException w\u00e4hrend der Kanonisierung\: Original Nachricht war {0} +c14n.Canonicalizer.TraversalNotSupported = Das DOM Dokument unterst\u00fctzt keine Traversal {0} +c14n.Canonicalizer.UnsupportedEncoding = Nicht unterst\u00fctzte Kodierung {0} +c14n.Canonicalizer.UnsupportedOperation = Der Kanonisierer unterst\u00fctzt diese Operation nicht +c14n.XMLUtils.circumventBug2650forgotten = Die Baumstruktur wurde nicht vorbereitet f\u00fcr die Kanonisierung mit XMLUtils\#circumventBug2650(Document) +certificate.noSki.lowVersion = Das Zertifikat dard kein SubjectKeyIdentifier enthalten da es nur ein X509v{0} ist +certificate.noSki.notOctetString = Der SubjectKeyIdentifier des Zertifikates ist kein "OctetString" +certificate.noSki.null = Das Zertifikat enth\u00e4lt kein SubjectKeyIdentifier +defaultNamespaceCannotBeSetHere = Standard Namespace kann hier nicht gesetzt werden +ElementProxy.nullElement = Kann keinen ElementProxy aus einem null Argument erzeugen +empty = {0} +encryption.algorithmCannotBeUsedForEncryptedData = encryption.algorithmCannotBeUsedForEncryptedData {0} +encryption.algorithmCannotEatInitParams = encryption.algorithmCannotEatInitParams +encryption.algorithmCannotEncryptDecrypt = encryption.algorithmCannotEncryptDecrypt +encryption.algorithmCannotWrapUnWrap = encryption.algorithmCannotWrapUnWrap +encryption.ExplicitKeySizeMismatch = Das xenc\:KeySize Element fordert eine Schl\u00fcssel-L\u00e4nge von {0} bits aber der Algorithmus besitzt {1} bits +encryption.nonceLongerThanDecryptedPlaintext = Das angegebene "Nonce" ist l\u00e4nger als der verf\u00fcgbare Plaintext. +encryption.RSAOAEP.dataHashWrong = Falscher Hash-Wert +encryption.RSAOAEP.dataStartWrong = Falscher Start Input {0} +encryption.RSAOAEP.dataTooShort = Zu wenig Input +encryption.RSAPKCS15.blockTruncated = Block abgeschnitten +encryption.RSAPKCS15.noDataInBlock = Im Block sind keine Daten enthalten +encryption.RSAPKCS15.unknownBlockType = Unbekannter Block Typ +encryption.nokey = Es ist kein verschl\u00fcsselungs Schl\u00fcssel geladen und es konnte kein Schl\u00fcssel mit Hilfe der "key resolvers" gefunden werden. +endorsed.jdk1.4.0 = Leider scheint niemand unsere Installations-Anleitung zu lesen, deshalb m\u00fcssen wir es \u00fcber die Exception machen\: Du hast den "endorsing" Mechanismus vom JDK 1.4 nicht richtig angewandt. Schaue unter nach wie man das Problem l\u00f6st. +errorMessages.InvalidDigestValueException = Ung\u00fcltige Signatur\: Referen-Validierung fehlgeschlagen. +errorMessages.InvalidSignatureValueException = Ung\u00fcltige Signatur\: Core Validierung fehlgeschlagen. +errorMessages.IOException = Datei oder Resource kann nicht gelesen werden. +errorMessages.MissingKeyFailureException = Verifizierung fehlgeschlagen, weil der \u00f6ffentliche Schl\u00fcssel (public key) nicht verf\u00fcgbar ist. Resourcen via addResource() hinzuf\u00fcgen und erneut versuchen. +errorMessages.MissingResourceFailureException = Verifizierung fehlgeschlagen, weil Resourcen nicht verf\u00fcgbar sind. Resourcen via addResource() hinzuf\u00fcgen und erneut versuchen. +errorMessages.NoSuchAlgorithmException = Unbekannter Algorithmus {0} +errorMessages.NotYetImplementedException = Funktionalit\u00e4t noch nicht implementiert. +errorMessages.XMLSignatureException = Verifizierung aus unbekanntem Grund fehlgeschlagen. +decoding.divisible.four = It should be divisible by four +decoding.general = Fehler beim Decodieren +FileKeyStorageImpl.addToDefaultFromRemoteNotImplemented = Methode addToDefaultFromRemote() wurde noch nicht implementiert. +FileKeyStorageImpl.NoCert.Context = Kein X509-Zertifikat mit Kontext {0} gefunden +FileKeyStorageImpl.NoCert.IssNameSerNo = Kein X509-Zertifikat mit IssuerName {0} und serial number {1} gefunden +FileKeyStorageImpl.NoCert.SubjName = Kein X509-Zertifikat mit SubjectName {0} gefunden +generic.dontHaveConstructionElement = Konstruktions-Element fehlt +generic.EmptyMessage = {0} +generic.NotYetImplemented = {0} Leider noch nicht implementiert ;-(( +java.security.InvalidKeyException = Ung\u00fcltiger Schl\u00fcssel +java.security.NoSuchProviderException = Unbekannter oder nicht unterst\u00fctzter Provider +java.security.UnknownKeyType = Unbekannter oder nicht unterst\u00fctzter Schl\u00fcssel-Typ {0} +KeyInfo.error = Error loading Key Info +KeyInfo.needKeyResolver = Es m\u00fcssen mehrere KeyResolver registriert sein +KeyInfo.nokey = Kann keinen Schl\u00fcssel aus {0} gewinnen +KeyInfo.noKey = Kann keinen \u00f6ffentlichen Schl\u00fcssel finden +KeyInfo.wrongNumberOfObject = Ben\u00f6tige {0} keyObjects +KeyInfo.wrongUse = Dieses Objekt wird verwendet, um {0} zu gewinnen +keyResolver.alreadyRegistered = Die Klasse {1} wurde bereits registriert f\u00fcr {0} +KeyResolver.needStorageResolver = Es wird ein StorageResolver ben\u00f6tigt um ein Zertifikat aus {0} zu holen +KeyResoverSpiImpl.cannotGetCert = Cannot get the Certificate that include or in {1} in implement class {0} +KeyResoverSpiImpl.elementGeneration = Cannot make {1} element in implement class {0} +KeyResoverSpiImpl.getPoublicKey = Cannot get the public key from implement class {0} +KeyResoverSpiImpl.InvalidElement = Cannot set (2) Element in implement class {0} +KeyResoverSpiImpl.keyStore = KeyStorage Fehler in der implementierenden Klasse {0} +KeyResoverSpiImpl.need.Element = Es wird der Typ {1} ben\u00f6tigt in der implementierenden Klasse {0} +KeyResoverSpiImpl.wrongCRLElement = Cannot make CRL from {1} in implement class {0} +KeyResoverSpiImpl.wrongKeyObject = Need {1} type of KeyObject for generation Element in implement class{0} +KeyResoverSpiImpl.wrongNumberOfObject = Need {1} keyObject in implement class {0} +KeyStore.alreadyRegistered = Klasse {0} bereits registriert f\u00fcr {1} +KeyStore.register = {1} type class register error in class {0} +KeyStore.registerStore.register = Registrierungsfehler f\u00fcr Typ {0} +KeyValue.IllegalArgument = Kann kein {0} aus {1} erzeugen +namespacePrefixAlreadyUsedByOtherURI = Namespace {0} wird bereits von einer anderen URI {1} gebraucht +notYetInitialized = Das Modul {0} ist noch nicht initialisiert +prefix.AlreadyAssigned = Sie binden den Prefix {0} an den Namespace {1} aber er ist bereits an {2} zugewiesen +signature.Canonicalizer.UnknownCanonicalizer = Unbekannter Kanonisierer. Kein Handler installiert f\u00fcr URI {0} +signature.DSA.invalidFormat = Ung\u00fcltige ASN.1 Kodierung der DSA Signatur +signature.Generation.signBeforeGetValue = Es muss zuerst XMLSignature.sign(java.security.PrivateKey) aufgerufen werden +signature.Reference.ForbiddenResolver = Der "Resolver" {0} ist bei aktivierter "secure validation" nicht erlaubt +signature.Reference.NoDigestMethod = A Signature Reference Element must contain a DigestMethod child +signature.Reference.NoDigestValue = A Signature Reference Element must contain a DigestValue child +signature.signatureAlgorithm = Der Algorithmus {0} ist bei aktivierter "secure validation" nicht erlaubt +signature.signaturePropertyHasNoTarget = Das Target Attribut der SignatureProperty muss gesetzt sein +signature.tooManyReferences = Das Manifest enth\u00e4lt {0} Referenzen, bei aktivierter "secure validation" sind aber maximal {1} erlaubt +signature.tooManyTransforms = Die Referenz enth\u00e4lt {0} Transformationen, bei aktivierter "secure validation" sind aber maximal {1} erlaubt +signature.Transform.ErrorDuringTransform = W\u00e4hrend der Transformation {0} trat eine {1} auf. +signature.Transform.ForbiddenTransform = Die Transformation {0} ist bei aktivierter "secure validation" nicht erlaubt +signature.Transform.NotYetImplemented = Transform {0} noch nicht implementiert +signature.Transform.NullPointerTransform = Null pointer als URI \u00fcbergeben. Programmierfehler? +signature.Transform.UnknownTransform = Unbekannte Transformation. Kein Handler installiert f\u00fcr URI {0} +signature.Util.BignumNonPositive = bigInteger.signum() muss positiv sein +signature.Util.NonTextNode = Keine Text Node +signature.Util.TooManyChilds = Zu viele Kind-Elemente vom Typ {0} in {1} +signature.Verification.certificateError = Zertifikatsfehler +signature.Verification.IndexOutOfBounds = Index {0} illegal. Es sind nur {1} Referenzen vorhanden +signature.Verification.internalError = Interner Fehler +signature.Verification.InvalidDigestOrReference = Ung\u00fcltiger Digest Wert der Referenz {0} +signature.Verification.InvalidElement = Current Node {0} is not permitted in this location in the Signature +signature.Verification.keyStore = \u00d6ffnen des KeyStore fehlgeschlagen +signature.Verification.MissingID = Element mit der ID {0} nicht gefunden +signature.Verification.MissingResources = Kann die externe Resource {0} nicht aufl\u00f6sen +signature.Verification.MultipleIDs = Mehrere Elemente mit der ID {0} gefunden +signature.Verification.NoSignatureElement = Input Dokument enth\u00e4lt kein {0} Element mit dem Namespace {1} +signature.Verification.Reference.NoInput = Die Referenz f\u00fcr den URI {0} hat keinen XMLSignatureInput erhalten. +signature.Verification.SignatureError = Signatur Fehler +signature.XMLSignatureInput.MissingConstuctor = Kann aus der Klasse {0} keinen XMLSignatureInput erzeugen +signature.XMLSignatureInput.SerializeDOM = Input mit einem DOM Dokument initialisiert. Muss mit C14N serialisiert werden +transform.Init.IllegalContextArgument = Unzul\u00e4ssiges Kontext Argument der Klasse {0}. Muss String, org.w3c.dom.NodeList oder java.io.InputStream sein. +transform.init.NotInitialized = +transform.init.wrongURI = Initialisiert mit dem falschen URI. Das sollte nie passieren. Die Transformation implementiert {0} aber {1} wurde bei der Instantiierung verwendet. +utils.Base64.IllegalBitlength = Ung\u00fcltige Byte-L\u00e4nge; Muss ein vielfaches von 4 sein +utils.resolver.noClass = Keinen Resolver f\u00fcr URI {0} und Base {1} gefunden +xml.WrongContent = Kann {0} nicht finden in {1} +xml.WrongElement = Kann kein {0} aus einem {1} Element erzeugen +xpath.funcHere.documentsDiffer = Der XPath ist nicht im selben Dokument wie der Kontext Node +xpath.funcHere.noXPathContext = Versuch einer XPath-Evaluierung welcher die Funktion here() benutzt aber der XPath ist nicht innerhalb eines ds\:XPath Elements. XPath \: {0} +signature.Transform.node = Aktuelle Node\: {0} +signature.Transform.nodeAndType = Aktuelle Node\: {0}, Typ\: {1} +signature.XMLSignatureInput.nodesetReference = Das Node-Set der Referenz konnte nicht konvertieren werden +transform.envelopedSignatureTransformNotInSignatureElement = Enveloped Transform konnte kein Signatur Element finden +Base64Decoding = Fehler bei der Decodierung +secureProcessing.MaximumAllowedTransformsPerReference = Die Referenz enth\u00e4lt {0} Transformationen. Es sind aber maximal {1} erlaubt. Die Limite kann \u00fcber das Konfigurations-Property "MaximumAllowedTransformsPerReference" erh\u00f6ht werden. +secureProcessing.MaximumAllowedReferencesPerManifest = Das Manifest enh\u00e4lt {0} Referenzen. Es sind aber maximal {1} erlaubt. Die Limite kann \u00fcber das Konfigurations-Property "MaximumAllowedReferencesPerManifest" erh\u00f6ht werden. +secureProcessing.DoNotThrowExceptionForManifests = Signatur-Manifests werden nicht unterst\u00fctzt. Das werfen dieser Exception kann durch das Konfigurations-Property "DoNotThrowExceptionForManifests" verhindert werden. +secureProcessing.AllowMD5Algorithm = Vom Einsatz des MD5 Algorithmus wird strengstens abgeraten. Trotzdem kann er \u00fcber das Konfigurations-Property "AllowMD5Algorithm" erlaubt werden. +secureProcessing.AllowNotSameDocumentReferences = Externe Referenzen gefunden. Die Verarbeitung von externen Referenzen ist standardm\u00e4ssig ausgeschaltet. Es kann \u00fcber das Konfigurations-Property "AllowNotSameDocumentReferences" aktiviert werden. +secureProcessing.MaximumAllowedXMLStructureDepth = Die Maximum erlaubte Dokumenten-Tiefe von ({0}) wurde erreicht. Die Limite kann \u00fcber das Konfigurations-Property "MaximumAllowedXMLStructureDepth" erh\u00f6ht werden. +secureProcessing.inputStreamLimitReached = Maximal erlaubte Anzahl bytes ({0}) erreicht. +stax.duplicateActions=Doppelte Actions sind nicht erlaubt. +stax.missingSecurityProperties = SecurityProperties darf nicht null sein\! +stax.noOutputAction = Keine ausgehenden "Actions" definiert. +stax.noKey = Kein Schl\u00fcssel geladen und es konnte kein Schl\u00fcssel gefunden werden f\u00fcr {0} +stax.keyNotFound = Schl\u00fcssel nicht gefunden. +stax.unsupportedKeyValue = Kein oder ung\u00fcltiger KeyValue. +stax.emptyReferenceURI = Referenz enth\u00e4lt kein URI Attribut. +stax.encryption.unprocessedReferences = Es wurden nicht alle Verschl\u00fcsselungs-Referenzen verarbeitet... +stax.signature.unprocessedReferences = Es wurden nicht alle Signatur-Referenzen verarbeitet... +stax.unsupportedToken = {0} nicht unterst\u00fctzt. +stax.xmlStructureSizeExceeded = Maximal erlaubte ({0}) XML-Struktur Tiefe erreicht. +stax.unexpectedXMLEvent = Unerwarteter StAX-Event\: {0} +stax.encryption.noEncAlgo = xenc\:EncryptedKey enth\u00e4lt kein xenc\:EncryptionMethod/@Algorithm. +stax.encryption.noCipherValue = EncryptedKey enth\u00e4lt kein xenc\:CipherData/xenc\:CipherValue. +stax.unsecuredMessage = Ungesicherte Nachricht. Weder ein Signatur- noch ein EncryptedData- Element wurde gefunden. +stax.signature.signedInfoMissing = SignedInfo Element fehlt. +stax.signature.signatureMethodMissing = Signature method fehlt. +stax.signature.canonicalizationMethodMissing = Signature canonicalization method fehlt. +stax.signature.signatureValueMissing = Signature value fehlt. +stax.signature.publicKeyOrCertificateMissing = Weder ein Zertifikat noch ein public-key wurde konfiguriert. +stax.encryption.encryptionKeyMissing = Kein Schl\u00fcssel f\u00fcr die Verschl\u00fcsselung wurde konfiguriert. +stax.unsupportedKeyTransp = Der public-key Algorithmus ist zu kurz um den symmetrischen Schl\u00fcssel zu verschl\u00fcsseln. +stax.recursiveKeyReference = Rekursive Schl\u00fcssel referenzierung detektiert. +stax.ecParametersNotSupported = ECParameters werden nicht unterst\u00fctzt. +stax.namedCurveMissing = NamedCurve fehlt. +stax.encryption.securePartNotFound = Part zum Verschl\u00fcsseln nicht gefunden: {0} +stax.signature.securePartNotFound = Part zum Signieren nicht gefunden: {0} +stax.multipleSignaturesNotSupported = Mehrere Signaturen werden nicht unterstützt. +stax.signature.keyNameMissing = KeyName nicht konfiguriert. +stax.keyNotFoundForName = Kein Schl\u00fcssel für Schl\u00fcsselname konfiguriert: {0} +stax.keyTypeNotSupported = Key vom Typ {0} nicht f\u00fcr einen Key-Namenssuche unterst\u00fctzt +stax.idsetbutnotgenerated = An Id attribute is specified, but Id generation is disabled stax.idgenerationdisablewithmultipleparts = Id generation must not be disabled when multiple parts need signing \ No newline at end of file diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java index cfa545e5826c6..b84556de0771e 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java @@ -209,6 +209,23 @@ public final class XMLSignature extends SignatureElementProxy { public static final String ALGO_ID_SIGNATURE_EDDSA_ED448 = "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448"; + + /**Signature - SHA3-224withECDSA */ + public static final String ALGO_ID_SIGNATURE_ECDSA_SHA3_224 = + "http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-224"; + + /**Signature - SHA3-256withECDSA */ + public static final String ALGO_ID_SIGNATURE_ECDSA_SHA3_256 = + "http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-256"; + + /**Signature - SHA3-384withECDSA */ + public static final String ALGO_ID_SIGNATURE_ECDSA_SHA3_384 = + "http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-384"; + + /**Signature - SHA3-512withECDSA */ + public static final String ALGO_ID_SIGNATURE_ECDSA_SHA3_512 = + "http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-512"; + /** Signature - Optional RSASSA-PSS */ public static final String ALGO_ID_SIGNATURE_RSA_PSS = Constants.XML_DSIG_NS_MORE_07_05 + "rsa-pss"; diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Constants.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Constants.java index d584eac32d191..5ec3e293252b6 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Constants.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Constants.java @@ -71,6 +71,9 @@ public final class Constants { /** The (newer) URL for more algorithms **/ public static final String XML_DSIG_NS_MORE_07_05 = "http://www.w3.org/2007/05/xmldsig-more#"; + /** The 2021 xmldsig-more URL for Internet Engineering Task Force (IETF) algorithms **/ + public static final String XML_DSIG_NS_MORE_21_04 = "http://www.w3.org/2021/04/xmldsig-more#"; + /** The URI for XML spec*/ public static final String XML_LANG_SPACE_SpecNS = "http://www.w3.org/XML/1998/namespace"; @@ -144,6 +147,9 @@ public final class Constants { /** Tag of Element MaskGenerationFunction **/ public static final String _TAG_MGF = "MaskGenerationFunction"; + /** Tag of Element Salt **/ + public static final String _TAG_SALT = "Salt"; + /** Tag of Element SaltLength **/ public static final String _TAG_SALTLENGTH = "SaltLength"; diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java index 6f061fc977244..b68a56fd8b916 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java @@ -512,6 +512,9 @@ public static void registerDefaultPrefixes() throws XMLSecurityException { "http://www.nue.et-inf.uni-siegen.de/~geuer-pollmann/#xpathFilter", "xx" ); setNamespacePrefix("http://www.w3.org/2009/xmldsig11#", "dsig11"); + setNamespacePrefix("http://www.w3.org/2001/04/xmldsig-more", "rfc4051"); + setNamespacePrefix("http://www.w3.org/2007/05/xmldsig-more#", "rfc6931"); + setNamespacePrefix("http://www.w3.org/2021/04/xmldsig-more#", "rfc9231"); } /** diff --git a/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/SignatureMethod.java b/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/SignatureMethod.java index 3a567db6fd50a..aba110f055719 100644 --- a/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/SignatureMethod.java +++ b/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/SignatureMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java index cec1224affade..2ce4858bc81cb 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java @@ -81,7 +81,7 @@ public KeyValue newKeyValue(PublicKey key) throws KeyException { String algorithm = key.getAlgorithm(); if ("DSA".equals(algorithm)) { return new DOMKeyValue.DSA((DSAPublicKey) key); - } else if ("RSA".equals(algorithm)) { + } else if ("RSA".equals(algorithm) || "RSASSA-PSS".equals(algorithm)) { return new DOMKeyValue.RSA((RSAPublicKey) key); } else if ("EC".equals(algorithm)) { return new DOMKeyValue.EC((ECPublicKey) key); diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java index 0933c21bfd3d4..738ab64693c5d 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java @@ -241,6 +241,33 @@ RSAPublicKey unmarshalKeyValue(Element kvtElem) RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent); return (RSAPublicKey) generatePublicKey(rsakf, spec); } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof KeyValue)) { + return false; + } + // This equality test allows RSA keys that have different + // algorithms (ex: RSA and RSASSA-PSS) to be equal as long + // as the key is the same. + try { + PublicKey otherKey = ((KeyValue)obj).getPublicKey(); + if (!(otherKey instanceof RSAPublicKey)) { + return false; + } + RSAPublicKey otherRSAKey = (RSAPublicKey)otherKey; + RSAPublicKey rsaKey = (RSAPublicKey)getPublicKey(); + return rsaKey.getPublicExponent().equals( + otherRSAKey.getPublicExponent()) + && rsaKey.getModulus().equals(otherRSAKey.getModulus()); + } catch (KeyException ke) { + // no practical way to determine if the keys are equal + return false; + } + } } static final class DSA extends DOMKeyValue { @@ -369,6 +396,42 @@ static final class EC extends DOMKeyValue { 1 ); + private static final Curve BRAINPOOLP256R1 = initializeCurve( + "brainpoolP256r1 [RFC 5639]", + "1.3.36.3.3.2.8.1.1.7", + "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", + "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", + "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", + "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", + "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", + "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", + 1 + ); + + private static final Curve BRAINPOOLP384R1 = initializeCurve( + "brainpoolP384r1 [RFC 5639]", + "1.3.36.3.3.2.8.1.1.11", + "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", + "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", + "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", + "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", + "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", + "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", + 1 + ); + + private static final Curve BRAINPOOLP512R1 = initializeCurve( + "brainpoolP512r1 [RFC 5639]", + "1.3.36.3.3.2.8.1.1.13", + "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", + "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", + "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", + "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", + "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", + "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", + 1 + ); + private static Curve initializeCurve(String name, String oid, String sfield, String a, String b, String x, String y, String n, int h) { @@ -448,6 +511,12 @@ private static String getCurveOid(ECParameterSpec params) { match = SECP384R1; } else if (matchCurve(params, SECP521R1)) { match = SECP521R1; + } else if (matchCurve(params, BRAINPOOLP256R1)) { + match = BRAINPOOLP256R1; + } else if (matchCurve(params, BRAINPOOLP384R1)) { + match = BRAINPOOLP384R1; + } else if (matchCurve(params, BRAINPOOLP512R1)) { + match = BRAINPOOLP512R1; } else { return null; } @@ -485,7 +554,7 @@ void marshalPublicKey(Node parent, Document doc, String dsPrefix, DOMUtils.setAttribute(namedCurveElem, "URI", "urn:oid:" + oid); String qname = (prefix == null || prefix.length() == 0) ? "xmlns" : "xmlns:" + prefix; - namedCurveElem.setAttributeNS("http://www.w3.org/2000/xmlns/", + ecKeyValueElem.setAttributeNS("http://www.w3.org/2000/xmlns/", qname, XMLDSIG_11_XMLNS); ecKeyValueElem.appendChild(namedCurveElem); String encoded = XMLUtils.encodeToString(ecPublicKey); @@ -555,6 +624,12 @@ private static ECParameterSpec getECParameterSpec(String oid) { return SECP384R1; } else if (oid.equals(SECP521R1.getObjectId())) { return SECP521R1; + } else if (oid.equals(BRAINPOOLP256R1.getObjectId())) { + return BRAINPOOLP256R1; + } else if (oid.equals(BRAINPOOLP384R1.getObjectId())) { + return BRAINPOOLP384R1; + } else if (oid.equals(BRAINPOOLP512R1.getObjectId())) { + return BRAINPOOLP512R1; } else { return null; } diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java index 5e44ccaeae8b0..6523b93935da8 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java @@ -100,6 +100,14 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod { "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519"; static final String ED448 = "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448"; + static final String ECDSA_SHA3_224 = + "http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-224"; + static final String ECDSA_SHA3_256 = + "http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-256"; + static final String ECDSA_SHA3_384 = + "http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-384"; + static final String ECDSA_SHA3_512 = + "http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-512"; // see RFC 6931 for these algorithm definitions static final String ECDSA_RIPEMD160 = @@ -241,6 +249,14 @@ static SignatureMethod unmarshal(Element smElem) throws MarshalException { return new SHA384withECDSA(smElem); } else if (alg.equals(ECDSA_SHA512)) { return new SHA512withECDSA(smElem); + } else if (alg.equals(ECDSA_SHA3_224)) { + return new SHA3_224withECDSA(smElem); + } else if (alg.equals(ECDSA_SHA3_256)) { + return new SHA3_256withECDSA(smElem); + } else if (alg.equals(ECDSA_SHA3_384)) { + return new SHA3_384withECDSA(smElem); + } else if (alg.equals(ECDSA_SHA3_512)) { + return new SHA3_512withECDSA(smElem); } else if (alg.equals(ECDSA_RIPEMD160)) { return new RIPEMD160withECDSA(smElem); } else if (alg.equals(SignatureMethod.HMAC_SHA1)) { @@ -1160,6 +1176,94 @@ String getJCAFallbackAlgorithm() { } } + static final class SHA3_224withECDSA extends AbstractECDSASignatureMethod { + SHA3_224withECDSA(AlgorithmParameterSpec params) + throws InvalidAlgorithmParameterException { + super(params); + } + SHA3_224withECDSA(Element dmElem) throws MarshalException { + super(dmElem); + } + @Override + public String getAlgorithm() { + return ECDSA_SHA3_224; + } + @Override + String getJCAAlgorithm() { + return "SHA3-224withECDSAinP1363Format"; + } + @Override + String getJCAFallbackAlgorithm() { + return "SHA3-224withECDSA"; + } + } + + static final class SHA3_256withECDSA extends AbstractECDSASignatureMethod { + SHA3_256withECDSA(AlgorithmParameterSpec params) + throws InvalidAlgorithmParameterException { + super(params); + } + SHA3_256withECDSA(Element dmElem) throws MarshalException { + super(dmElem); + } + @Override + public String getAlgorithm() { + return ECDSA_SHA3_256; + } + @Override + String getJCAAlgorithm() { + return "SHA3-256withECDSAinP1363Format"; + } + @Override + String getJCAFallbackAlgorithm() { + return "SHA3-256withECDSA"; + } + } + + static final class SHA3_384withECDSA extends AbstractECDSASignatureMethod { + SHA3_384withECDSA(AlgorithmParameterSpec params) + throws InvalidAlgorithmParameterException { + super(params); + } + SHA3_384withECDSA(Element dmElem) throws MarshalException { + super(dmElem); + } + @Override + public String getAlgorithm() { + return ECDSA_SHA3_384; + } + @Override + String getJCAAlgorithm() { + return "SHA3-384withECDSAinP1363Format"; + } + @Override + String getJCAFallbackAlgorithm() { + return "SHA3-384withECDSA"; + } + } + + static final class SHA3_512withECDSA extends AbstractECDSASignatureMethod { + SHA3_512withECDSA(AlgorithmParameterSpec params) + throws InvalidAlgorithmParameterException { + super(params); + } + SHA3_512withECDSA(Element dmElem) throws MarshalException { + super(dmElem); + } + @Override + public String getAlgorithm() { + return ECDSA_SHA3_512; + } + @Override + String getJCAAlgorithm() { + return "SHA3-512withECDSAinP1363Format"; + } + @Override + String getJCAFallbackAlgorithm() { + return "SHA3-512withECDSA"; + } + } + static final class RIPEMD160withECDSA extends AbstractECDSASignatureMethod { RIPEMD160withECDSA(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java index 119bf16bc3236..52ccc84d1d072 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java @@ -345,6 +345,14 @@ public SignatureMethod newSignatureMethod(String algorithm, return new DOMSignatureMethod.SHA384withECDSA(params); } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA512)) { return new DOMSignatureMethod.SHA512withECDSA(params); + } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA3_224)) { + return new DOMSignatureMethod.SHA3_224withECDSA(params); + } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA3_256)) { + return new DOMSignatureMethod.SHA3_256withECDSA(params); + } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA3_384)) { + return new DOMSignatureMethod.SHA3_384withECDSA(params); + } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA3_512)) { + return new DOMSignatureMethod.SHA3_512withECDSA(params); } else if (algorithm.equals(DOMSignatureMethod.ECDSA_RIPEMD160)) { return new DOMSignatureMethod.RIPEMD160withECDSA(params); } else if (algorithm.equals(DOMSignatureMethod.ED25519)) { diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java index 2982291c8e253..670d7b0c8673a 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java @@ -142,7 +142,7 @@ public Object newInstance(Object ctrParamObj) @SuppressWarnings("removal") public XMLDSigRI() { // This is the JDK XMLDSig provider, synced from - // Apache Santuario XML Security for Java, version 3.0.3 + // Apache Santuario XML Security for Java, version 3.0.5 super("XMLDSig", VER, INFO); final Provider p = this; diff --git a/src/java.xml.crypto/share/legal/santuario.md b/src/java.xml.crypto/share/legal/santuario.md index 768f0c7b144a4..4421e16df25a1 100644 --- a/src/java.xml.crypto/share/legal/santuario.md +++ b/src/java.xml.crypto/share/legal/santuario.md @@ -1,4 +1,4 @@ -## Apache Santuario v3.0.3 +## Apache Santuario v3.0.5 ### Apache 2.0 License ``` @@ -211,7 +211,7 @@ limitations under the License. ``` Apache Santuario - XML Security for Java -Copyright 1999-2023 The Apache Software Foundation +Copyright 1999-2024 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). @@ -223,5 +223,5 @@ The development of this software was partly funded by the European Commission in the project in the ISIS Programme. This product contains software that is -copyright (c) 2021, Oracle and/or its affiliates. +copyright (c) 2021, 2023, Oracle and/or its affiliates. ``` diff --git a/test/jdk/javax/xml/crypto/dsig/GenerationTests.java b/test/jdk/javax/xml/crypto/dsig/GenerationTests.java index 45b7223433c0f..29e14165ece7c 100644 --- a/test/jdk/javax/xml/crypto/dsig/GenerationTests.java +++ b/test/jdk/javax/xml/crypto/dsig/GenerationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test * @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184 8038349 8046949 - * 8046724 8079693 8177334 8205507 8210736 8217878 8241306 8305972 + * 8046724 8079693 8177334 8205507 8210736 8217878 8241306 8305972 8344137 * @summary Basic unit tests for generating XML Signatures with JSR 105 * @modules java.base/sun.security.util * java.base/sun.security.x509 @@ -99,6 +99,7 @@ public class GenerationTests { private static SignatureMethod dsaSha1, dsaSha256, rsaSha1, rsaSha224, rsaSha256, rsaSha384, rsaSha512, ecdsaSha1, ecdsaSha224, ecdsaSha256, ecdsaSha384, ecdsaSha512, + ecdsaSha3_224, ecdsaSha3_256, ecdsaSha3_384, ecdsaSha3_512, hmacSha1, hmacSha224, hmacSha256, hmacSha384, hmacSha512, rsaSha1mgf1, rsaSha224mgf1, rsaSha256mgf1, rsaSha384mgf1, rsaSha512mgf1, rsaSha3_224mgf1, rsaSha3_256mgf1, rsaSha3_384mgf1, rsaSha3_512mgf1, @@ -305,6 +306,10 @@ public static void main(String args[]) throws Exception { test_create_signature_enveloping_p256_sha256(); test_create_signature_enveloping_p256_sha384(); test_create_signature_enveloping_p256_sha512(); + test_create_signature_enveloping_p256_sha3_224(); + test_create_signature_enveloping_p256_sha3_256(); + test_create_signature_enveloping_p256_sha3_384(); + test_create_signature_enveloping_p256_sha3_512(); test_create_signature_enveloping_p384_sha1(); test_create_signature_enveloping_p521_sha1(); test_create_signature_enveloping_ed25519(); @@ -559,6 +564,10 @@ private static void setup() throws Exception { ecdsaSha256 = fac.newSignatureMethod(SignatureMethod.ECDSA_SHA256, null); ecdsaSha384 = fac.newSignatureMethod(SignatureMethod.ECDSA_SHA384, null); ecdsaSha512 = fac.newSignatureMethod(SignatureMethod.ECDSA_SHA512, null); + ecdsaSha3_224 = fac.newSignatureMethod("http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-224", null); + ecdsaSha3_256 = fac.newSignatureMethod("http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-256", null); + ecdsaSha3_384 = fac.newSignatureMethod("http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-384", null); + ecdsaSha3_512 = fac.newSignatureMethod("http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-512", null); ed25519 = fac.newSignatureMethod("http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519", null); ed448 = fac.newSignatureMethod("http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448", null); @@ -892,6 +901,34 @@ static void test_create_signature_enveloping_p256_sha512() throws Exception { System.out.println(); } + static void test_create_signature_enveloping_p256_sha3_224() throws Exception { + System.out.println("* Generating signature-enveloping-p256-sha3_224.xml"); + test_create_signature_enveloping(sha1, ecdsaSha3_224, p256ki, + getECPrivateKey("P256"), kvks, false, true); + System.out.println(); + } + + static void test_create_signature_enveloping_p256_sha3_256() throws Exception { + System.out.println("* Generating signature-enveloping-p256-sha3_256.xml"); + test_create_signature_enveloping(sha1, ecdsaSha3_256, p256ki, + getECPrivateKey("P256"), kvks, false, true); + System.out.println(); + } + + static void test_create_signature_enveloping_p256_sha3_384() throws Exception { + System.out.println("* Generating signature-enveloping-p256-sha3_384.xml"); + test_create_signature_enveloping(sha1, ecdsaSha3_384, p256ki, + getECPrivateKey("P256"), kvks, false, true); + System.out.println(); + } + + static void test_create_signature_enveloping_p256_sha3_512() throws Exception { + System.out.println("* Generating signature-enveloping-p256-sha3_512.xml"); + test_create_signature_enveloping(sha1, ecdsaSha3_512, p256ki, + getECPrivateKey("P256"), kvks, false, true); + System.out.println(); + } + static void test_create_signature_enveloping_p384_sha1() throws Exception { System.out.println("* Generating signature-enveloping-p384-sha1.xml"); test_create_signature_enveloping(sha1, ecdsaSha1, p384ki, diff --git a/test/jdk/javax/xml/crypto/dsig/PSS.java b/test/jdk/javax/xml/crypto/dsig/PSS.java new file mode 100644 index 0000000000000..3b5730577fb98 --- /dev/null +++ b/test/jdk/javax/xml/crypto/dsig/PSS.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.lib.Asserts; +import jdk.test.lib.security.XMLUtils; + +import javax.xml.crypto.dsig.DigestMethod; +import javax.xml.crypto.dsig.SignatureMethod; +import javax.xml.crypto.dsig.spec.RSAPSSParameterSpec; +import java.security.KeyPairGenerator; +import java.security.spec.MGF1ParameterSpec; +import java.security.spec.PSSParameterSpec; + +/** + * @test + * @bug 8344137 + * @summary check RSASSA-PSS key + * @library /test/lib + * @modules java.xml.crypto + */ +public class PSS { + + public static void main(String[] args) throws Exception { + + var doc = XMLUtils.string2doc("TextRaw"); + var kpg = KeyPairGenerator.getInstance("RSASSA-PSS"); + kpg.initialize(2048); + var keyPair = kpg.generateKeyPair(); + + var pspec = new PSSParameterSpec("SHA-384", "MGF1", + MGF1ParameterSpec.SHA512, 48, + PSSParameterSpec.TRAILER_FIELD_BC); + + var signed = XMLUtils.signer(keyPair.getPrivate(), keyPair.getPublic()) + .dm(DigestMethod.SHA384) + .sm(SignatureMethod.RSA_PSS, new RSAPSSParameterSpec(pspec)) + .sign(doc); + + Asserts.assertTrue(XMLUtils.validator().validate(signed)); + } +} diff --git a/test/lib/jdk/test/lib/security/XMLUtils.java b/test/lib/jdk/test/lib/security/XMLUtils.java index 4616dfa00a4ea..ad9e2c2ec9e73 100644 --- a/test/lib/jdk/test/lib/security/XMLUtils.java +++ b/test/lib/jdk/test/lib/security/XMLUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -198,6 +198,7 @@ public static class Signer { String dm = DigestMethod.SHA256; String cm = CanonicalizationMethod.EXCLUSIVE; String tr = Transform.ENVELOPED; + Map props = new HashMap<>(); public Signer(PrivateKey privateKey) { this.privateKey = Objects.requireNonNull(privateKey); @@ -247,6 +248,11 @@ public Signer sm(String method) throws Exception { return sm(method, null); } + public Signer prop(String name, Object o) { + props.put(name, o); + return this; + } + // Signs different sources // Signs an XML file in detached mode @@ -254,7 +260,7 @@ public Document sign(URI uri) throws Exception { Document newDocument = DocumentBuilderFactory.newInstance() .newDocumentBuilder().newDocument(); FAC.newXMLSignature(buildSignedInfo(uri.toString()), buildKeyInfo()).sign( - new DOMSignContext(privateKey, newDocument)); + withProps(new DOMSignContext(privateKey, newDocument))); return newDocument; } @@ -264,7 +270,8 @@ public Document sign(URI base, URI ref) throws Exception { .newDocumentBuilder().newDocument(); DOMSignContext ctxt = new DOMSignContext(privateKey, newDocument); ctxt.setBaseURI(base.toString()); - FAC.newXMLSignature(buildSignedInfo(ref.toString()), buildKeyInfo()).sign(ctxt); + FAC.newXMLSignature(buildSignedInfo(ref.toString()), buildKeyInfo()) + .sign(withProps(ctxt)); return newDocument; } @@ -275,7 +282,7 @@ public Document sign(Document document) throws Exception { .transform(new DOMSource(document), result); Document newDocument = (Document) result.getNode(); FAC.newXMLSignature(buildSignedInfo(""), buildKeyInfo()).sign( - new DOMSignContext(privateKey, newDocument.getDocumentElement())); + withProps(new DOMSignContext(privateKey, newDocument.getDocumentElement()))); return newDocument; } @@ -290,7 +297,7 @@ public Document signEnveloping(Document document, String id, String ref) throws id, null, null)), null, null) - .sign(new DOMSignContext(privateKey, newDocument)); + .sign(withProps(new DOMSignContext(privateKey, newDocument))); return newDocument; } @@ -308,7 +315,7 @@ public Document sign(byte[] data) throws Exception { "object", null, null)), null, null) - .sign(new DOMSignContext(privateKey, newDocument)); + .sign(withProps(new DOMSignContext(privateKey, newDocument))); return newDocument; } @@ -325,10 +332,18 @@ public Document sign(String str) throws Exception { "object", null, null)), null, null) - .sign(new DOMSignContext(privateKey, newDocument)); + .sign(withProps(new DOMSignContext(privateKey, newDocument))); return newDocument; } + // Add props to a context + private DOMSignContext withProps(DOMSignContext ctxt) { + for (var e : props.entrySet()) { + ctxt.setProperty(e.getKey(), e.getValue()); + } + return ctxt; + } + // Builds a SignedInfo for a string reference private SignedInfo buildSignedInfo(String ref) throws Exception { return buildSignedInfo(FAC.newReference( @@ -426,6 +441,7 @@ public static class Validator { private Boolean secureValidation = null; private String baseURI = null; private final KeyStore ks; + Map props = new HashMap<>(); public Validator(KeyStore ks) { this.ks = ks; @@ -441,6 +457,11 @@ public Validator baseURI(String base) { return this; } + public Validator prop(String name, Object o) { + props.put(name, o); + return this; + } + public boolean validate(Document document) throws Exception { return validate(document, null); } @@ -471,12 +492,21 @@ public KeySelectorResult select(KeyInfo ki, Purpose p, secureValidation); } return XMLSignatureFactory.getInstance("DOM") - .unmarshalXMLSignature(valContext).validate(valContext); + .unmarshalXMLSignature(valContext) + .validate(withProps(valContext)); } } return false; } + // Add props to a context + private DOMValidateContext withProps(DOMValidateContext ctxt) { + for (var e : props.entrySet()) { + ctxt.setProperty(e.getKey(), e.getValue()); + } + return ctxt; + } + // Find public key from KeyInfo, ks will be used if it's KeyName private static class MyKeySelector extends KeySelector { private final KeyStore ks; From 0877d64dd68f323ef5eb2f5b4bb0e5664e5f4a0a Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Tue, 8 Jul 2025 07:55:43 +0000 Subject: [PATCH 381/846] 8353568: SEGV_BNDERR signal code adjust definition Backport-of: 6abf4e6d4d9f948b8ae51aec731b94ba7acd022e --- src/hotspot/os/posix/signals_posix.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hotspot/os/posix/signals_posix.cpp b/src/hotspot/os/posix/signals_posix.cpp index 643b926a50a08..1f5e4c422272e 100644 --- a/src/hotspot/os/posix/signals_posix.cpp +++ b/src/hotspot/os/posix/signals_posix.cpp @@ -42,8 +42,12 @@ #include -#if !defined(SEGV_BNDERR) -#define SEGV_BNDERR 3 +#define SEGV_BNDERR_value 3 + +#if defined(SEGV_BNDERR) +STATIC_ASSERT(SEGV_BNDERR == SEGV_BNDERR_value); +#else +#define SEGV_BNDERR SEGV_BNDERR_value #endif static const char* get_signal_name(int sig, char* out, size_t outlen); From 8b306de46d88219722a57f6e72d0b4456eb6faf0 Mon Sep 17 00:00:00 2001 From: Daniel Huang Date: Tue, 8 Jul 2025 15:56:13 +0000 Subject: [PATCH 382/846] 8282144: RandomSupport.convertSeedBytesToLongs sign extension overwrites previous bytes Backport-of: 5fab27e1b8fdf2ea27cb3b349bd339a4a6ec828b --- .../internal/util/random/RandomSupport.java | 2 +- test/jdk/java/util/Random/T8282144.java | 71 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 test/jdk/java/util/Random/T8282144.java diff --git a/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java b/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java index 1fc1eeff46a03..24a73f734d3ce 100644 --- a/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java +++ b/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java @@ -265,7 +265,7 @@ public static long[] convertSeedBytesToLongs(byte[] seed, int n, int z) { final int m = Math.min(seed.length, n << 3); // Distribute seed bytes into the words to be formed. for (int j = 0; j < m; j++) { - result[j>>3] = (result[j>>3] << 8) | seed[j]; + result[j>>3] = (result[j>>3] << 8) | (seed[j] & 0xFF); } // If there aren't enough seed bytes for all the words we need, // use a SplitMix-style PRNG to fill in the rest. diff --git a/test/jdk/java/util/Random/T8282144.java b/test/jdk/java/util/Random/T8282144.java new file mode 100644 index 0000000000000..4a0218602f27e --- /dev/null +++ b/test/jdk/java/util/Random/T8282144.java @@ -0,0 +1,71 @@ +/* + * 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. + */ + +import java.util.random.*; +import jdk.internal.util.random.RandomSupport; + +/** + * @test + * @summary RandomSupport.convertSeedBytesToLongs sign extension overwrites previous bytes. + * @bug 8282144 + * @modules java.base/jdk.internal.util.random + * @run main T8282144 + * @key randomness + */ + + +public class T8282144 { + public static void main(String[] args) { + RandomGenerator rng = RandomGeneratorFactory.of("L64X128MixRandom").create(42); + + for (int i = 1; i < 8; i++) { + byte[] seed = new byte[i]; + + for (int j = 0; j < 10; j++) { + rng.nextBytes(seed); + + long[] existing = RandomSupport.convertSeedBytesToLongs(seed, 1, 1); + long[] testing = convertSeedBytesToLongsFixed(seed, 1, 1); + + for (int k = 0; k < existing.length; k++) { + if (existing[k] != testing[k]) { + throw new RuntimeException("convertSeedBytesToLongs incorrect"); + } + } + } + } + } + + + public static long[] convertSeedBytesToLongsFixed(byte[] seed, int n, int z) { + final long[] result = new long[n]; + final int m = Math.min(seed.length, n << 3); + + // Distribute seed bytes into the words to be formed. + for (int j = 0; j < m; j++) { + result[j >> 3] = (result[j >> 3] << 8) | (seed[j] & 0xff); + } + + return result; + } +} From a8f51b279f49f4acaade14b095756722b936b7d3 Mon Sep 17 00:00:00 2001 From: Alexey Bakhtin Date: Wed, 4 Jun 2025 12:54:51 -0700 Subject: [PATCH 383/846] 8345625: Better HTTP connections Reviewed-by: mbalao, andrew Backport-of: 2ad3d59e4eb8882ee46a70c70cc75c9c0d008211 --- .../classes/sun/net/ftp/impl/FtpClient.java | 8 +-- .../share/classes/sun/net/util/ProxyUtil.java | 49 +++++++++++++++++++ .../classes/sun/net/www/http/HttpClient.java | 10 ++-- .../www/protocol/ftp/FtpURLConnection.java | 6 ++- .../sun/net/www/protocol/ftp/Handler.java | 12 ++--- .../www/protocol/http/HttpURLConnection.java | 7 +-- .../internal/net/http/HttpRequestImpl.java | 44 +++++++++-------- .../jdk/internal/net/http/common/Utils.java | 14 +++++- .../net/http/websocket/OpeningHandshake.java | 5 +- 9 files changed, 111 insertions(+), 44 deletions(-) create mode 100644 src/java.base/share/classes/sun/net/util/ProxyUtil.java diff --git a/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java b/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java index 560fbfbea945c..0ec730072b497 100644 --- a/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java +++ b/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2025, 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 @@ -24,8 +24,6 @@ */ package sun.net.ftp.impl; - - import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; @@ -64,6 +62,7 @@ import java.util.regex.Pattern; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; + import sun.net.ftp.FtpDirEntry; import sun.net.ftp.FtpDirParser; import sun.net.ftp.FtpProtocolException; @@ -71,6 +70,7 @@ import sun.net.util.IPAddressUtil; import sun.util.logging.PlatformLogger; +import static sun.net.util.ProxyUtil.copyProxy; public class FtpClient extends sun.net.ftp.FtpClient { @@ -982,7 +982,7 @@ public int getReadTimeout() { } public sun.net.ftp.FtpClient setProxy(Proxy p) { - proxy = p; + proxy = copyProxy(p); return this; } diff --git a/src/java.base/share/classes/sun/net/util/ProxyUtil.java b/src/java.base/share/classes/sun/net/util/ProxyUtil.java new file mode 100644 index 0000000000000..dfb60671e3796 --- /dev/null +++ b/src/java.base/share/classes/sun/net/util/ProxyUtil.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 sun.net.util; + +import sun.net.ApplicationProxy; + +import java.net.Proxy; + +public final class ProxyUtil { + + private ProxyUtil() {} + + /** + * Creates a new {@link Proxy} instance for the given proxy iff it is + * neither null, {@link Proxy#NO_PROXY Proxy.NO_PROXY}, an + * {@link ApplicationProxy} instance, nor already a {@code Proxy} instance. + */ + public static Proxy copyProxy(Proxy proxy) { + return proxy == null + || proxy.getClass() == Proxy.class + || proxy instanceof ApplicationProxy + ? proxy + : new Proxy(proxy.type(), proxy.address()); + } + +} diff --git a/src/java.base/share/classes/sun/net/www/http/HttpClient.java b/src/java.base/share/classes/sun/net/www/http/HttpClient.java index ba5e38827c73a..4057dc43334b1 100644 --- a/src/java.base/share/classes/sun/net/www/http/HttpClient.java +++ b/src/java.base/share/classes/sun/net/www/http/HttpClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2025, 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 @@ -42,6 +42,8 @@ import sun.net.www.protocol.http.AuthenticatorKeys; import sun.net.www.protocol.http.HttpURLConnection; import sun.util.logging.PlatformLogger; + +import static sun.net.util.ProxyUtil.copyProxy; import static sun.net.www.protocol.http.HttpURLConnection.TunnelState.*; import sun.security.action.GetPropertyAction; @@ -268,7 +270,7 @@ public HttpClient(URL url, String proxyHost, int proxyPort) } protected HttpClient(URL url, Proxy p, int to) throws IOException { - proxy = (p == null) ? Proxy.NO_PROXY : p; + proxy = p == null ? Proxy.NO_PROXY : copyProxy(p); this.host = url.getHost(); this.url = url; port = url.getPort(); @@ -333,9 +335,7 @@ public static HttpClient New(URL url, boolean useCache) public static HttpClient New(URL url, Proxy p, int to, boolean useCache, HttpURLConnection httpuc) throws IOException { - if (p == null) { - p = Proxy.NO_PROXY; - } + p = p == null ? Proxy.NO_PROXY : copyProxy(p); HttpClient ret = null; /* see if one's already around */ if (useCache) { diff --git a/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java index 42555f01fc7fe..d5bd4e27b365f 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2025, 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 @@ -49,6 +49,7 @@ import java.util.Iterator; import java.security.Permission; import java.util.Properties; + import sun.net.NetworkClient; import sun.net.util.IPAddressUtil; import sun.net.www.MessageHeader; @@ -62,6 +63,7 @@ import sun.net.www.ParseUtil; import sun.security.action.GetPropertyAction; +import static sun.net.util.ProxyUtil.copyProxy; /** * This class Opens an FTP input (or output) stream given a URL. @@ -252,7 +254,7 @@ public ProxySelector run() { } final Iterator it = proxies.iterator(); while (it.hasNext()) { - p = it.next(); + p = copyProxy(it.next()); if (p == null || p == Proxy.NO_PROXY || p.type() == Proxy.Type.SOCKS) { break; diff --git a/src/java.base/share/classes/sun/net/www/protocol/ftp/Handler.java b/src/java.base/share/classes/sun/net/www/protocol/ftp/Handler.java index 80c85ea642b4c..4610c43a23d65 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/ftp/Handler.java +++ b/src/java.base/share/classes/sun/net/www/protocol/ftp/Handler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2025, 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 @@ -32,11 +32,9 @@ import java.io.IOException; import java.net.URL; import java.net.Proxy; -import java.util.Map; -import java.util.HashMap; import java.util.Objects; -import sun.net.ftp.FtpClient; -import sun.net.www.protocol.http.HttpURLConnection; + +import static sun.net.util.ProxyUtil.copyProxy; /** open an ftp connection given a URL */ public class Handler extends java.net.URLStreamHandler { @@ -56,8 +54,8 @@ protected java.net.URLConnection openConnection(URL u) return openConnection(u, null); } - protected java.net.URLConnection openConnection(URL u, Proxy p) + protected java.net.URLConnection openConnection(URL u, Proxy proxy) throws IOException { - return new FtpURLConnection(u, p); + return new FtpURLConnection(u, copyProxy(proxy)); } } diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index e3e72723428f4..f59b576bb3c2e 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, 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 @@ -83,6 +83,7 @@ import java.util.Properties; import java.util.concurrent.locks.ReentrantLock; +import static sun.net.util.ProxyUtil.copyProxy; import static sun.net.www.protocol.http.AuthScheme.BASIC; import static sun.net.www.protocol.http.AuthScheme.DIGEST; import static sun.net.www.protocol.http.AuthScheme.NTLM; @@ -936,7 +937,7 @@ protected HttpURLConnection(URL u, Proxy p, Handler handler) responses = new MessageHeader(maxHeaderSize); userHeaders = new MessageHeader(); this.handler = handler; - instProxy = p; + instProxy = copyProxy(p); if (instProxy instanceof sun.net.ApplicationProxy) { /* Application set Proxies should not have access to cookies * in a secure environment unless explicitly allowed. */ @@ -1251,7 +1252,7 @@ public ProxySelector run() { final Iterator it = proxies.iterator(); Proxy p; while (it.hasNext()) { - p = it.next(); + p = copyProxy(it.next()); try { if (!failedOnce) { http = getNewHttpClient(url, p, connectTimeout); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java index 27e65446844f4..890ed1de07fc5 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -49,6 +49,7 @@ import static jdk.internal.net.http.common.Utils.ALLOWED_HEADERS; import static jdk.internal.net.http.common.Utils.ProxyHeaders; +import static jdk.internal.net.http.common.Utils.copyProxy; public class HttpRequestImpl extends HttpRequest implements WebSocketRequest { @@ -129,15 +130,7 @@ public HttpRequestImpl(HttpRequest request, ProxySelector ps) { this.systemHeadersBuilder.setHeader("User-Agent", USER_AGENT); } this.uri = requestURI; - if (isWebSocket) { - // WebSocket determines and sets the proxy itself - this.proxy = ((HttpRequestImpl) request).proxy; - } else { - if (ps != null) - this.proxy = retrieveProxy(ps, uri); - else - this.proxy = null; - } + this.proxy = retrieveProxy(request, ps, uri); this.expectContinue = request.expectContinue(); this.secure = uri.getScheme().toLowerCase(Locale.US).equals("https"); this.requestPublisher = request.bodyPublisher().orElse(null); @@ -296,16 +289,27 @@ void setH2Upgrade(Exchange exchange) { @Override public boolean expectContinue() { return expectContinue; } - /** Retrieves the proxy, from the given ProxySelector, if there is one. */ - private static Proxy retrieveProxy(ProxySelector ps, URI uri) { - Proxy proxy = null; - List pl = ps.select(uri); - if (!pl.isEmpty()) { - Proxy p = pl.get(0); - if (p.type() == Proxy.Type.HTTP) - proxy = p; + /** Retrieves a copy of the proxy either from the given {@link HttpRequest} or {@link ProxySelector}, if there is one. */ + private static Proxy retrieveProxy(HttpRequest request, ProxySelector ps, URI uri) { + + // WebSocket determines and sets the proxy itself + if (request instanceof HttpRequestImpl requestImpl && requestImpl.isWebSocket) { + return requestImpl.proxy; + } + + // Try to find a matching one from the `ProxySelector` + if (ps != null) { + List pl = ps.select(uri); + if (!pl.isEmpty()) { + Proxy p = pl.get(0); + if (p.type() == Proxy.Type.HTTP) { + return copyProxy(p); + } + } } - return proxy; + + return null; + } InetSocketAddress proxy() { @@ -321,7 +325,7 @@ InetSocketAddress proxy() { @Override public void setProxy(Proxy proxy) { assert isWebSocket; - this.proxy = proxy; + this.proxy = copyProxy(proxy); } @Override diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java index 323042de3d75c..a51b3d35979c5 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -42,6 +42,7 @@ import java.lang.System.Logger.Level; import java.net.ConnectException; import java.net.InetSocketAddress; +import java.net.Proxy; import java.net.URI; import java.net.URLPermission; import java.net.http.HttpClient; @@ -273,6 +274,17 @@ public static boolean proxyHasDisabledSchemes(boolean tunnel) { : ! PROXY_AUTH_DISABLED_SCHEMES.isEmpty(); } + /** + * Creates a new {@link Proxy} instance for the given proxy iff it is + * neither null, {@link Proxy#NO_PROXY Proxy.NO_PROXY}, nor already a + * {@code Proxy} instance. + */ + public static Proxy copyProxy(Proxy proxy) { + return proxy == null || proxy.getClass() == Proxy.class + ? proxy + : new Proxy(proxy.type(), proxy.address()); + } + // WebSocket connection Upgrade headers private static final String HEADER_CONNECTION = "Connection"; private static final String HEADER_UPGRADE = "Upgrade"; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java index b4d456b764698..14cdd8854bbcf 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -66,6 +66,7 @@ import java.util.stream.Stream; import static java.lang.String.format; +import static jdk.internal.net.http.common.Utils.copyProxy; import static jdk.internal.net.http.common.Utils.isValidName; import static jdk.internal.net.http.common.Utils.permissionForProxy; import static jdk.internal.net.http.common.Utils.stringOf; @@ -375,7 +376,7 @@ private static Proxy proxyFor(Optional selector, URI uri) { if (proxy.type() != Proxy.Type.HTTP) { return null; } - return proxy; + return copyProxy(proxy); } /** From 5b443e9e817fa206dfaa87d9e2b9dbc87daa027f Mon Sep 17 00:00:00 2001 From: Ilarion Nakonechnyy Date: Tue, 27 May 2025 16:03:01 -0700 Subject: [PATCH 384/846] 8348989: Better Glyph drawing Reviewed-by: avoitylov, mbalao, andrew Backport-of: 191c37a280faccfaecae033a68313ad06cdfc411 --- .../native/libawt_lwawt/font/CGGlyphImages.m | 82 +++++++++++++++---- 1 file changed, 66 insertions(+), 16 deletions(-) diff --git a/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m b/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m index fdd855b699417..316f6e273f2d9 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m @@ -237,6 +237,7 @@ @implementation CGGI_GlyphCanvas { UInt32 *src = (UInt32 *)canvas->image->data; size_t srcRowWidth = canvas->image->width; + size_t srcHeight = canvas->image->height; UInt8 *dest = (UInt8 *)info->image; size_t destRowWidth = info->width; @@ -246,12 +247,12 @@ @implementation CGGI_GlyphCanvas size_t y; // fill empty glyph image with black-on-white glyph - for (y = 0; y < height; y++) { + for (y = 0; y < height && y < srcHeight; y++) { size_t destRow = y * destRowWidth * 3; size_t srcRow = y * srcRowWidth; size_t x; - for (x = 0; x < destRowWidth; x++) { + for (x = 0; x < destRowWidth && x < srcRowWidth; x++) { CGGI_CopyARGBPixelToRGBPixel(src[srcRow + x], dest + destRow + x * 3); } @@ -289,6 +290,7 @@ @implementation CGGI_GlyphCanvas { UInt32 *src = (UInt32 *)canvas->image->data; size_t srcRowWidth = canvas->image->width; + size_t srcHeight = canvas->image->height; UInt8 *dest = (UInt8 *)info->image; size_t destRowWidth = info->width; @@ -298,11 +300,11 @@ @implementation CGGI_GlyphCanvas size_t y; // fill empty glyph image with black-on-white glyph - for (y = 0; y < height; y++) { + for (y = 0; y < height && y < srcHeight; y++) { size_t destRow = y * destRowWidth; size_t srcRow = y * srcRowWidth; size_t x; - for (x = 0; x < destRowWidth; x++) { + for (x = 0; x < destRowWidth && x < srcRowWidth; x++) { UInt32 p = src[srcRow + x]; dest[destRow + x] = CGGI_ConvertBWPixelToByteGray(p); } @@ -317,6 +319,7 @@ @implementation CGGI_GlyphCanvas UInt32 *src = (UInt32 *)canvas->image->data; size_t srcRowWidth = canvas->image->width; + size_t srcHeight = canvas->image->height; UInt8 *dest = (UInt8 *)info->image; size_t destRowWidth = info->width; @@ -325,15 +328,16 @@ @implementation CGGI_GlyphCanvas size_t y; - for (y = 0; y < height; y++) { + for (y = 0; y < height && y < srcHeight; y++) { size_t srcRow = y * srcRowWidth; if (littleEndian) { - UInt16 destRowBytes = info->rowBytes; + size_t srcRowBytes = canvas->image->rowBytes; + UInt16 destRowBytes = (info->rowBytes < srcRowBytes) ? info->rowBytes : srcRowBytes; memcpy(dest, src + srcRow, destRowBytes); dest += destRowBytes; } else { size_t x; - for (x = 0; x < destRowWidth; x++) { + for (x = 0; x < destRowWidth && x < srcRowWidth; x++) { UInt32 p = src[srcRow + x]; *dest++ = (p >> 24 & 0xFF); // blue (alpha-premultiplied) *dest++ = (p >> 16 & 0xFF); // green (alpha-premultiplied) @@ -426,8 +430,10 @@ @implementation CGGI_GlyphCanvas canvas->image->data = (void *)calloc(byteCount, sizeof(UInt8)); if (canvas->image->data == NULL) { - [[NSException exceptionWithName:NSMallocException - reason:@"Failed to allocate memory for the buffer which backs the CGContext for glyph strikes." userInfo:nil] raise]; + canvas->image->width = 0; + canvas->image->height = 0; + canvas->image->rowBytes = 0; + canvas->image->data = malloc(0); } uint32_t bmpInfo = kCGImageAlphaPremultipliedFirst; @@ -477,6 +483,10 @@ @implementation CGGI_GlyphCanvas /* * Quick and easy inline to check if this canvas is big enough. + * This function only increases the size. To get a smaller canvas, free it first. + * This function adds padding / slack multiplier to the requested size. + * So resizes must be based on the size you need, not the size of the canvas. + * The function will internally account for the multiplier it uses. */ static inline void CGGI_SizeCanvas(CGGI_GlyphCanvas *canvas, const vImagePixelCount width, @@ -484,18 +494,31 @@ @implementation CGGI_GlyphCanvas const CGGI_RenderingMode* mode) { if (canvas->image != NULL && - width < canvas->image->width && - height < canvas->image->height) + width * CGGI_GLYPH_CANVAS_SLACK <= canvas->image->width && + height * CGGI_GLYPH_CANVAS_SLACK <= canvas->image->height) { return; } + vImagePixelCount w = width * CGGI_GLYPH_CANVAS_SLACK; + vImagePixelCount h = height * CGGI_GLYPH_CANVAS_SLACK; + + // Do not allow the canvas to be resized smaller. + if (canvas->image != NULL) { + if (w < canvas->image->width) { + w = canvas->image->width; + } + if (h < canvas->image->height) { + h = canvas->image->height; + } + } + // if we don't have enough space to strike the largest glyph in the // run, resize the canvas CGGI_FreeCanvas(canvas); CGGI_InitCanvas(canvas, - width * CGGI_GLYPH_CANVAS_SLACK, - height * CGGI_GLYPH_CANVAS_SLACK, + w, + h, mode); JRSFontSetRenderingStyleOnContext(canvas->context, mode->cgFontMode); } @@ -511,6 +534,12 @@ @implementation CGGI_GlyphCanvas canvasRectToClear.data = canvas->image->data; canvasRectToClear.height = info->height; canvasRectToClear.width = info->width; + if (canvas->image->width < canvasRectToClear.width) { + canvasRectToClear.width = canvas->image->width; + } + if (canvas->image->height < canvasRectToClear.height) { + canvasRectToClear.height = canvas->image->height; + } // use the row stride of the canvas, not the info canvasRectToClear.rowBytes = canvas->image->rowBytes; @@ -870,7 +899,6 @@ @implementation CGGI_GlyphCanvas CGRect bbox = bboxes[i]; GlyphInfo *glyphInfo = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike, mainFontDescriptor); - if (maxWidth < glyphInfo->width) maxWidth = glyphInfo->width; if (maxHeight < glyphInfo->height) maxHeight = glyphInfo->height; @@ -947,8 +975,7 @@ @implementation CGGI_GlyphCanvas } // just do one malloc, and carve it up for all the buffers - void *buffer = malloc(sizeof(CGRect) * sizeof(CGSize) * - sizeof(CGGlyph) * sizeof(UnicodeScalarValue) * len); + void *buffer = malloc((sizeof(CGRect) + sizeof(CGSize) + sizeof(CGGlyph) + sizeof(UnicodeScalarValue)) * len); if (buffer == NULL) { [[NSException exceptionWithName:NSMallocException reason:@"Failed to allocate memory for the temporary glyph strike and measurement buffers." userInfo:nil] raise]; @@ -966,6 +993,8 @@ @implementation CGGI_GlyphCanvas free(buffer); } +#define TX_FIXED_UNSAFE(v) (isinf(v) || isnan(v) || fabs(v) >= (1<<30)) + /* * Calculates bounding boxes (for given transform) and advance (for untransformed 1pt-size font) for specified glyphs. */ @@ -977,6 +1006,27 @@ @implementation CGGI_GlyphCanvas size_t count, CGRect bboxes[], CGSize advances[]) { + + if (TX_FIXED_UNSAFE(tx->a) || TX_FIXED_UNSAFE(tx->b) || TX_FIXED_UNSAFE(tx->c) || + TX_FIXED_UNSAFE(tx->d) || TX_FIXED_UNSAFE(tx->tx) || TX_FIXED_UNSAFE(tx->tx)) { + + if (bboxes) { + for (int i = 0; i < count; i++) { + bboxes[i].origin.x = 0; + bboxes[i].origin.y = 0; + bboxes[i].size.width = 0; + bboxes[i].size.height = 0; + } + } + if (advances) { + for (int i = 0; i < count; i++) { + advances[i].width = 0; + advances[i].height = 0; + } + } + return; + } + if (IsEmojiFont(font)) { // Glyph metrics for emoji font are not strictly proportional to font size, // so we need to construct real-sized font object to calculate them. From f07c7d3c33493d3bfe4d5107244af951b7b0a9d1 Mon Sep 17 00:00:00 2001 From: Alexei Voitylov Date: Fri, 6 Jun 2025 11:56:27 +0000 Subject: [PATCH 385/846] 8349111: Enhance Swing supports Reviewed-by: abakhtin, mbalao, andrew Backport-of: 8a34c18c6593da54b6b8695d645310db95f23509 --- .../com/apple/laf/AquaTabbedPaneCopyFromBasicUI.java | 12 +++++++++--- .../classes/javax/swing/border/TitledBorder.java | 6 +++++- .../javax/swing/plaf/basic/BasicOptionPaneUI.java | 6 +++++- .../javax/swing/plaf/basic/BasicTabbedPaneUI.java | 12 +++++++++--- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneCopyFromBasicUI.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneCopyFromBasicUI.java index 5722b28e576c6..5aeba8aa37f89 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneCopyFromBasicUI.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneCopyFromBasicUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, 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 @@ -404,7 +404,11 @@ protected void installListeners() { } tabPane.addContainerListener(getHandler()); if (tabPane.getTabCount() > 0) { - htmlViews = createHTMLVector(); + Boolean htmlDisabled = (Boolean) + tabPane.getClientProperty("html.disable"); + if (!(Boolean.TRUE.equals(htmlDisabled))) { + htmlViews = createHTMLVector(); + } } } @@ -3446,8 +3450,10 @@ public void componentAdded(final ContainerEvent e) { private void updateHtmlViews(int index, boolean inserted) { final String title = tabPane.getTitleAt(index); + Boolean htmlDisabled = (Boolean) + tabPane.getClientProperty("html.disable"); final boolean isHTML = BasicHTML.isHTMLString(title); - if (isHTML) { + if (isHTML && !(Boolean.TRUE.equals(htmlDisabled))) { if (htmlViews == null) { // Initialize vector htmlViews = createHTMLVector(); } else { // Vector already exists diff --git a/src/java.desktop/share/classes/javax/swing/border/TitledBorder.java b/src/java.desktop/share/classes/javax/swing/border/TitledBorder.java index e1f94783e2ad7..b7a10d889dde0 100644 --- a/src/java.desktop/share/classes/javax/swing/border/TitledBorder.java +++ b/src/java.desktop/share/classes/javax/swing/border/TitledBorder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -736,6 +736,10 @@ private Color getColor(Component c) { } private JLabel getLabel(Component c) { + if (c instanceof JComponent comp) { + this.label.putClientProperty("html.disable", + comp.getClientProperty("html.disable")); + } this.label.setText(getTitle()); this.label.setFont(getFont(c)); this.label.setForeground(getColor(c)); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java index 318fa88613ae2..f75c59869ceaf 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -472,6 +472,10 @@ protected void addMessageComponents(Container container, } JLabel label; label = new JLabel(s, JLabel.LEADING); + if (Boolean.TRUE.equals( + this.optionPane.getClientProperty("html.disable"))) { + label.putClientProperty("html.disable", true); + } label.setName("OptionPane.label"); configureMessageLabel(label); addMessageComponents(container, cons, label, maxll, true); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java index 8446354fe1426..662af3199ce5e 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -456,7 +456,11 @@ protected void installListeners() { } tabPane.addContainerListener(getHandler()); if (tabPane.getTabCount()>0) { - htmlViews = createHTMLVector(); + Boolean htmlDisabled = (Boolean) + tabPane.getClientProperty("html.disable"); + if (!(Boolean.TRUE.equals(htmlDisabled))) { + htmlViews = createHTMLVector(); + } } } @@ -4026,8 +4030,10 @@ else if (name =="indexForTitle") { private void updateHtmlViews(int index, boolean inserted) { String title = tabPane.getTitleAt(index); + Boolean htmlDisabled = (Boolean) + tabPane.getClientProperty("html.disable"); boolean isHTML = BasicHTML.isHTMLString(title); - if (isHTML) { + if (isHTML && !(Boolean.TRUE.equals(htmlDisabled))) { if (htmlViews==null) { // Initialize vector htmlViews = createHTMLVector(); } else { // Vector already exists From 645ef7b7c2f1d59200f80e62736d7a724a679906 Mon Sep 17 00:00:00 2001 From: Alexey Bakhtin Date: Fri, 16 May 2025 15:22:44 -0700 Subject: [PATCH 386/846] 8349594: Enhance TLS protocol support Reviewed-by: mbalao, andrew Backport-of: d40052ee9789908fb7c06527ab644fdd217a6bea --- .../classes/sun/security/ssl/CertificateMessage.java | 11 ++++++++++- .../classes/sun/security/ssl/CertificateVerify.java | 10 +++++++++- .../share/classes/sun/security/ssl/Finished.java | 10 +++++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java b/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java index 840c0055b9acb..665d2fee8bfdb 100644 --- a/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java +++ b/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -1160,6 +1160,15 @@ public void consume(ConnectionContext context, // clean up this consumer hc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE.id); + + // Ensure that the Certificate message has not been sent w/o + // an EncryptedExtensions preceding + if (hc.handshakeConsumers.containsKey( + SSLHandshake.ENCRYPTED_EXTENSIONS.id)) { + throw hc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, + "Unexpected Certificate handshake message"); + } + T13CertificateMessage cm = new T13CertificateMessage(hc, message); if (hc.sslConfig.isClientMode) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { diff --git a/src/java.base/share/classes/sun/security/ssl/CertificateVerify.java b/src/java.base/share/classes/sun/security/ssl/CertificateVerify.java index 66f651e28aecf..6041ddf6873f9 100644 --- a/src/java.base/share/classes/sun/security/ssl/CertificateVerify.java +++ b/src/java.base/share/classes/sun/security/ssl/CertificateVerify.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -1160,6 +1160,14 @@ public void consume(ConnectionContext context, // Clean up this consumer hc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_VERIFY.id); + // Ensure that the Certificate Verify message has not been sent w/o + // a Certificate message preceding + if (hc.handshakeConsumers.containsKey( + SSLHandshake.CERTIFICATE.id)) { + throw hc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, + "Unexpected Certificate Verify handshake message"); + } + T13CertificateVerifyMessage cvm = new T13CertificateVerifyMessage(hc, message); if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { diff --git a/src/java.base/share/classes/sun/security/ssl/Finished.java b/src/java.base/share/classes/sun/security/ssl/Finished.java index a1ecca519204d..64949ae62511f 100644 --- a/src/java.base/share/classes/sun/security/ssl/Finished.java +++ b/src/java.base/share/classes/sun/security/ssl/Finished.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, 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 @@ -900,6 +900,14 @@ public void consume(ConnectionContext context, private void onConsumeFinished(ClientHandshakeContext chc, ByteBuffer message) throws IOException { + // Ensure that the Finished message has not been sent w/o + // an EncryptedExtensions preceding + if (chc.handshakeConsumers.containsKey( + SSLHandshake.ENCRYPTED_EXTENSIONS.id)) { + throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, + "Unexpected Finished handshake message"); + } + // Make sure that any expected CertificateVerify message // has been received and processed. if (!chc.isResumption) { From b56182adc2effd9f927f394fe3030677765779c6 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Jul 2025 05:17:33 +0000 Subject: [PATCH 387/846] 8225777: java/awt/Mixing/MixingOnDialog.java fails on Ubuntu Backport-of: 36f2e5240b8c4d94643188d3a9d87d906c1e8bdf --- test/jdk/ProblemList.txt | 1 - test/jdk/java/awt/Mixing/MixingOnDialog.java | 205 ++++--------------- 2 files changed, 36 insertions(+), 170 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 6fa631ee0a422..33923fbfafd8f 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -186,7 +186,6 @@ java/awt/Mixing/AWT_Mixing/JTextFieldInGlassPaneOverlapping.java 8158801 windows java/awt/Mixing/AWT_Mixing/JTextFieldOverlapping.java 8158801 windows-all java/awt/Mixing/AWT_Mixing/JToggleButtonInGlassPaneOverlapping.java 8158801 windows-all java/awt/Mixing/AWT_Mixing/JToggleButtonOverlapping.java 8158801 windows-all -java/awt/Mixing/MixingOnDialog.java 8225777 linux-all java/awt/Mixing/NonOpaqueInternalFrame.java 7124549 macosx-all java/awt/Mouse/GetMousePositionTest/GetMousePositionWithOverlay.java 8168388 linux-all java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowRetaining.java 6829264 generic-all diff --git a/test/jdk/java/awt/Mixing/MixingOnDialog.java b/test/jdk/java/awt/Mixing/MixingOnDialog.java index 3e33d055dfb42..e5fdad76d3420 100644 --- a/test/jdk/java/awt/Mixing/MixingOnDialog.java +++ b/test/jdk/java/awt/Mixing/MixingOnDialog.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -27,70 +27,60 @@ @bug 4811096 @summary Tests whether mixing works on Dialogs @author anthony.petrov@...: area=awt.mixing - @library ../regtesthelpers - @build Util @run main MixingOnDialog */ -/** +/* * MixingOnDialog.java * * summary: Tests whether awt.Button and swing.JButton mix correctly */ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import test.java.awt.regtesthelpers.Util; - - - -public class MixingOnDialog -{ - static volatile boolean heavyClicked = false; +import java.awt.AWTException; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; +import javax.swing.JButton; +import javax.swing.SwingUtilities; + +public class MixingOnDialog { static volatile boolean lightClicked = false; + static Dialog d; + static volatile Button heavy; - private static void init() - { + private static void init() { // Create components - final Dialog d = new Dialog((Frame)null, "Button-JButton mix test"); - final Button heavy = new Button(" Heavyweight Button "); + d = new Dialog((Frame)null, "Button-JButton mix test"); + heavy = new Button(" Heavyweight Button "); final JButton light = new JButton(" LW Button "); // Actions for the buttons add appropriate number to the test sequence - heavy.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(java.awt.event.ActionEvent e) { - heavyClicked = true; - } - } - ); - - light.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(java.awt.event.ActionEvent e) { - lightClicked = true; - } - } - ); + light.addActionListener(e -> lightClicked = true); // Overlap the buttons - heavy.setBounds(30, 30, 200, 200); - light.setBounds(10, 10, 50, 50); + heavy.setBounds(230, 230, 200, 200); + light.setBounds(210, 210, 50, 50); // Put the components into the frame d.setLayout(null); d.add(light); d.add(heavy); - d.setBounds(50, 50, 400, 400); + d.setBounds(250, 250, 400, 400); d.setVisible(true); + } + public static void main(String[] args) throws InterruptedException, InvocationTargetException, AWTException { + SwingUtilities.invokeAndWait(MixingOnDialog::init); - Robot robot = Util.createRobot(); - robot.setAutoDelay(20); - - Util.waitForIdle(robot); + Robot robot = new Robot(); + robot.setAutoDelay(50); + robot.waitForIdle(); + robot.delay(500); // Move the mouse pointer to the position where both // buttons overlap @@ -98,137 +88,14 @@ public void actionPerformed(java.awt.event.ActionEvent e) { robot.mouseMove(heavyLoc.x + 5, heavyLoc.y + 5); // Now perform the click at this point - robot.mousePress(InputEvent.BUTTON1_MASK); - robot.mouseRelease(InputEvent.BUTTON1_MASK); - Util.waitForIdle(robot); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); - // If the buttons are correctly mixed, the test sequence - // is equal to the check sequence. - if (lightClicked == true) { - MixingOnDialog.pass(); - } else { - MixingOnDialog.fail("The lightweight component left behind the heavyweight one."); - } - }//End init() + SwingUtilities.invokeAndWait(() -> d.dispose()); - - - /***************************************************** - * Standard Test Machinery Section - * DO NOT modify anything in this section -- it's a - * standard chunk of code which has all of the - * synchronisation necessary for the test harness. - * By keeping it the same in all tests, it is easier - * to read and understand someone else's test, as - * well as insuring that all tests behave correctly - * with the test harness. - * There is a section following this for test- - * classes - ******************************************************/ - private static boolean theTestPassed = false; - private static boolean testGeneratedInterrupt = false; - private static String failureMessage = ""; - - private static Thread mainThread = null; - - private static int sleepTime = 300000; - - // Not sure about what happens if multiple of this test are - // instantiated in the same VM. Being static (and using - // static vars), it aint gonna work. Not worrying about - // it for now. - public static void main( String args[] ) throws InterruptedException - { - mainThread = Thread.currentThread(); - try - { - init(); - } - catch( TestPassedException e ) - { - //The test passed, so just return from main and harness will - // interepret this return as a pass - return; + if (!lightClicked) { + throw new RuntimeException("The lightweight component left behind the heavyweight one."); } - //At this point, neither test pass nor test fail has been - // called -- either would have thrown an exception and ended the - // test, so we know we have multiple threads. - - //Test involves other threads, so sleep and wait for them to - // called pass() or fail() - try - { - Thread.sleep( sleepTime ); - //Timed out, so fail the test - throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); - } - catch (InterruptedException e) - { - //The test harness may have interrupted the test. If so, rethrow the exception - // so that the harness gets it and deals with it. - if( ! testGeneratedInterrupt ) throw e; - - //reset flag in case hit this code more than once for some reason (just safety) - testGeneratedInterrupt = false; - - if ( theTestPassed == false ) - { - throw new RuntimeException( failureMessage ); - } - } - - }//main - - public static synchronized void setTimeoutTo( int seconds ) - { - sleepTime = seconds * 1000; - } - - public static synchronized void pass() - { - System.out.println( "The test passed." ); - System.out.println( "The test is over, hit Ctl-C to stop Java VM" ); - //first check if this is executing in main thread - if ( mainThread == Thread.currentThread() ) - { - //Still in the main thread, so set the flag just for kicks, - // and throw a test passed exception which will be caught - // and end the test. - theTestPassed = true; - throw new TestPassedException(); - } - theTestPassed = true; - testGeneratedInterrupt = true; - mainThread.interrupt(); - }//pass() - - public static synchronized void fail() - { - //test writer didn't specify why test failed, so give generic - fail( "it just plain failed! :-)" ); } - - public static synchronized void fail( String whyFailed ) - { - System.out.println( "The test failed: " + whyFailed ); - System.out.println( "The test is over, hit Ctl-C to stop Java VM" ); - //check if this called from main thread - if ( mainThread == Thread.currentThread() ) - { - //If main thread, fail now 'cause not sleeping - throw new RuntimeException( whyFailed ); - } - theTestPassed = false; - testGeneratedInterrupt = true; - failureMessage = whyFailed; - mainThread.interrupt(); - }//fail() - -}// class MixingOnDialog - -//This exception is used to exit from any level of call nesting -// when it's determined that the test has passed, and immediately -// end the test. -class TestPassedException extends RuntimeException -{ } From 976f317f234cdd5636d4cb8169d7fc98d022a5a6 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Jul 2025 05:18:57 +0000 Subject: [PATCH 388/846] 8325910: Rename jnihelper.h Backport-of: 810daf820633e16e3ab058325c539695087486d5 --- .../jtreg/vmTestbase/nsk/stress/jni/gclocker/libgcl001.cpp | 2 +- .../vmTestbase/nsk/stress/jni/{jnihelper.h => jnihelper.hpp} | 4 ++-- .../jtreg/vmTestbase/nsk/stress/jni/libjnistress001.cpp | 2 +- .../jtreg/vmTestbase/nsk/stress/jni/libjnistress002.cpp | 4 ++-- .../jtreg/vmTestbase/nsk/stress/jni/libjnistress003.cpp | 2 +- .../jtreg/vmTestbase/nsk/stress/jni/libjnistress004.cpp | 4 ++-- .../jtreg/vmTestbase/nsk/stress/jni/libjnistress005.cpp | 4 ++-- .../jtreg/vmTestbase/nsk/stress/jni/libjnistress006.cpp | 4 ++-- .../jtreg/vmTestbase/nsk/stress/jni/libjnistress007.cpp | 4 ++-- 9 files changed, 15 insertions(+), 15 deletions(-) rename test/hotspot/jtreg/vmTestbase/nsk/stress/jni/{jnihelper.h => jnihelper.hpp} (95%) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/gclocker/libgcl001.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/gclocker/libgcl001.cpp index 54b9e9df6e4c9..22251dbf9d746 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/gclocker/libgcl001.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/gclocker/libgcl001.cpp @@ -23,7 +23,7 @@ #include #include -#include "jnihelper.h" +#include "jnihelper.hpp" /* basic routine: provide critical sections and calculations diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/jnihelper.h b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/jnihelper.hpp similarity index 95% rename from test/hotspot/jtreg/vmTestbase/nsk/stress/jni/jnihelper.h rename to test/hotspot/jtreg/vmTestbase/nsk/stress/jni/jnihelper.hpp index 4edbde50cbcd3..1f850d019f3cc 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/jnihelper.h +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/jnihelper.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ // checked malloc to trap OOM conditions static void* c_malloc(JNIEnv* env, size_t size) { void* ret = malloc(size); - if (ret == NULL) + if (ret == nullptr) env->FatalError("malloc failed"); return ret; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress001.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress001.cpp index 2e056006824ea..f726acddb7336 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress001.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress001.cpp @@ -26,7 +26,7 @@ /* Changed from strings.h to string.h for Windows. */ #include #include -#include "jnihelper.h" +#include "jnihelper.hpp" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress002.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress002.cpp index 38f2afc67fefa..ade5e8224cec4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress002.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress002.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ #include #include -#include "jnihelper.h" +#include "jnihelper.hpp" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress003.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress003.cpp index 7bccbc95900d5..da84ec22f2df3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress003.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress003.cpp @@ -24,7 +24,7 @@ #include #include #include -#include "jnihelper.h" +#include "jnihelper.hpp" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress004.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress004.cpp index dbe8e2f828b92..8347d00da803f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress004.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress004.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #include #include #include -#include "jnihelper.h" +#include "jnihelper.hpp" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress005.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress005.cpp index 03ace5daa70e9..bafd23b4cec88 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress005.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress005.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #include #include #include -#include "jnihelper.h" +#include "jnihelper.hpp" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress006.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress006.cpp index b10cb539fdcbe..c84685a50fe82 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress006.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress006.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #include #include #include -#include "jnihelper.h" +#include "jnihelper.hpp" extern "C" { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress007.cpp b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress007.cpp index 6732780bcd216..44c195cfd6b03 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress007.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress007.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ #include #include -#include "jnihelper.h" +#include "jnihelper.hpp" extern "C" { From 770ad1fa038d4df857f4c769580ed27bb5d211e6 Mon Sep 17 00:00:00 2001 From: Alexey Bakhtin Date: Wed, 21 May 2025 17:11:28 -0700 Subject: [PATCH 389/846] 8350991: Improve HTTP client header handling Reviewed-by: mbalao, andrew Backport-of: 3b0f6ebdf8dbaf0caf9a9ec1f201d5938f674021 --- .../internal/net/http/HttpRequestImpl.java | 21 ++++++++++++++++--- .../jdk/internal/net/http/common/Utils.java | 12 +++++++++++ .../java/net/httpclient/DigestEchoClient.java | 5 +++-- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java index 890ed1de07fc5..7fe05edcec033 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java @@ -41,6 +41,7 @@ import java.net.http.HttpClient; import java.net.http.HttpHeaders; import java.net.http.HttpRequest; +import java.util.function.BiPredicate; import jdk.internal.net.http.common.HttpHeadersBuilder; import jdk.internal.net.http.common.Utils; @@ -151,7 +152,11 @@ public static HttpRequestImpl newInstanceForRedirection(URI uri, String method, HttpRequestImpl other, boolean mayHaveBody) { - return new HttpRequestImpl(uri, method, other, mayHaveBody); + if (uri.getScheme().equalsIgnoreCase(other.uri.getScheme()) && + uri.getRawAuthority().equals(other.uri.getRawAuthority())) { + return new HttpRequestImpl(uri, method, other, mayHaveBody, Optional.empty()); + } + return new HttpRequestImpl(uri, method, other, mayHaveBody, Optional.of(Utils.ALLOWED_REDIRECT_HEADERS)); } /** Returns a new instance suitable for authentication. */ @@ -171,9 +176,19 @@ private HttpRequestImpl(URI uri, String method, HttpRequestImpl other, boolean mayHaveBody) { + this(uri, method, other, mayHaveBody, Optional.empty()); + } + + private HttpRequestImpl(URI uri, + String method, + HttpRequestImpl other, + boolean mayHaveBody, + Optional> redirectHeadersFilter) { assert method == null || Utils.isValidName(method); - this.method = method == null? "GET" : method; - this.userHeaders = other.userHeaders; + this.method = method == null ? "GET" : method; + HttpHeaders userHeaders = redirectHeadersFilter.isPresent() ? + HttpHeaders.of(other.userHeaders.map(), redirectHeadersFilter.get()) : other.userHeaders; + this.userHeaders = userHeaders; this.isWebSocket = other.isWebSocket; this.systemHeadersBuilder = new HttpHeadersBuilder(); if (!userHeaders.firstValue("User-Agent").isPresent()) { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java index a51b3d35979c5..2d18be13cafda 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java @@ -152,6 +152,18 @@ private static Set getDisallowedHeaders() { public static final BiPredicate ALLOWED_HEADERS = (header, unused) -> !DISALLOWED_HEADERS_SET.contains(header); + private static final Set DISALLOWED_REDIRECT_HEADERS_SET = getDisallowedRedirectHeaders(); + + private static Set getDisallowedRedirectHeaders() { + Set headers = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + headers.addAll(Set.of("Authorization", "Cookie", "Origin", "Referer", "Host")); + + return Collections.unmodifiableSet(headers); + } + + public static final BiPredicate + ALLOWED_REDIRECT_HEADERS = (header, unused) -> !DISALLOWED_REDIRECT_HEADERS_SET.contains(header); + public static final BiPredicate VALIDATE_USER_HEADER = (name, value) -> { assert name != null : "null header name"; diff --git a/test/jdk/java/net/httpclient/DigestEchoClient.java b/test/jdk/java/net/httpclient/DigestEchoClient.java index f7bac2038d1db..071eb5bd6f5dc 100644 --- a/test/jdk/java/net/httpclient/DigestEchoClient.java +++ b/test/jdk/java/net/httpclient/DigestEchoClient.java @@ -258,8 +258,9 @@ public static void main(String[] args) throws Exception { } try { for (DigestEchoServer.HttpAuthType authType : types) { - // The test server does not support PROXY305 properly - if (authType == DigestEchoServer.HttpAuthType.PROXY305) continue; + // The test server does not support PROXY305 or SERVER307 properly + if (authType == DigestEchoServer.HttpAuthType.PROXY305 || + authType == DigestEchoServer.HttpAuthType.SERVER307) continue; EnumSet basics = EnumSet.of(DigestEchoServer.HttpAuthSchemeType.BASICSERVER, DigestEchoServer.HttpAuthSchemeType.BASIC); From 08c1b9d655f8f4b04ee99d0ccb216be0327bd901 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Jul 2025 05:20:00 +0000 Subject: [PATCH 390/846] 8326606: Test javax/swing/text/BoxView/6494356/bug6494356.java performs a synchronization on a value based class Backport-of: 013aff87ce7ece5cd4676aa452557ea3f222cede --- .../javax/swing/text/BoxView/bug6494356.java | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 test/jdk/javax/swing/text/BoxView/bug6494356.java diff --git a/test/jdk/javax/swing/text/BoxView/bug6494356.java b/test/jdk/javax/swing/text/BoxView/bug6494356.java new file mode 100644 index 0000000000000..fe899d5798461 --- /dev/null +++ b/test/jdk/javax/swing/text/BoxView/bug6494356.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6494356 + * @key headful + * @summary Test that BoxView.layout() is not called with negative arguments + * @run main bug6494356 + */ + +import java.awt.Dimension; +import java.awt.Toolkit; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.CountDownLatch; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.text.Element; +import javax.swing.text.StyleConstants; +import javax.swing.text.View; +import javax.swing.text.ViewFactory; +import javax.swing.text.html.HTML; +import javax.swing.text.html.HTMLEditorKit; +import javax.swing.text.html.ParagraphView; + +public class bug6494356 { + static JEditorPane ep; + private static final CountDownLatch latch = new CountDownLatch(1); + + public static void main(final String[] args) throws Exception { + final Path file = Path.of("bug6494356.html"); + try (Writer writer = Files.newBufferedWriter(file)) { + writer.write("

    Paragraph

    "); + } + try { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + ep = new JEditorPane(); + ep.setEditorKitForContentType("text/html", new MyEditorKit()); + ep.addPropertyChangeListener("page", new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent pce) { + if (pce.getPropertyName().equals("page")) { + latch.countDown(); + } + } + }); + JFrame f = new JFrame(); + f.setTitle("6494356"); + f.setSize(new Dimension( + Toolkit.getDefaultToolkit().getScreenSize().width, 600)); + f.setContentPane(ep); + f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + f.setVisible(true); + try { + ep.setPage("file:" + file); + } catch (Exception ex) { + testPassed = false; + throw new RuntimeException(ex); + } + } + }); + + latch.await(); + if (!testPassed) { + throw new RuntimeException("test failed."); + } + } finally { + Files.delete(file); + } + System.out.println("6494356 OK"); + } + + static volatile boolean testPassed = true; + + static class MyEditorKit extends HTMLEditorKit { + static class MyViewFactory extends HTMLFactory { + public View create(Element elem) { + HTML.Tag tag = (HTML.Tag) elem.getAttributes().getAttribute( + StyleConstants.NameAttribute); + if ((tag != null) && (tag == HTML.Tag.P)) { + return new MyParagraphView(elem); + } else { + return super.create(elem); + } + } + + static class MyParagraphView extends ParagraphView { + MyParagraphView(Element elem) { + super(elem); + } + + protected void layout(int width, int height) { + if ((width < 0) || (height < 0)) { + testPassed = false; + throw new RuntimeException("w=" + width + " h=" + height); + } + super.layout(width, height); + } + } + + } + + final ViewFactory viewFactory = new MyViewFactory(); + + public ViewFactory getViewFactory() { + return viewFactory; + } + } + +} + From 6cf00cc741cb55c9d8207bc1011cc45e4937e6ec Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Jul 2025 05:21:20 +0000 Subject: [PATCH 391/846] 8330535: Update nsk/jdb tests to use driver instead of othervm Reviewed-by: mdoerr Backport-of: 4417c276e484c1fe137ed7f4a7c28709d0c99af2 --- .../caught_exception002/caught_exception002.java | 10 +++------- .../nsk/jdb/classes/classes001/classes001.java | 10 +++------- .../jdb/classpath/classpath001/classpath001.java | 10 +++------- .../vmTestbase/nsk/jdb/clear/clear002/clear002.java | 10 +++------- .../vmTestbase/nsk/jdb/clear/clear003/clear003.java | 10 +++------- .../vmTestbase/nsk/jdb/clear/clear004/clear004.java | 8 ++------ .../vmTestbase/nsk/jdb/down/down002/down002.java | 10 +++------- .../vmTestbase/nsk/jdb/dump/dump002/dump002.java | 10 +++------- .../vmTestbase/nsk/jdb/eval/eval001/eval001.java | 10 +++------- .../nsk/jdb/exclude/exclude001/exclude001.java | 10 +++------- .../nsk/jdb/fields/fields001/fields001.java | 10 +++------- .../nsk/jdb/hidden_class/hc001/hc001.java | 10 +++------- .../nsk/jdb/ignore/ignore001/ignore001.java | 10 +++------- .../jdb/interrupt/interrupt001/interrupt001.java | 10 +++------- .../vmTestbase/nsk/jdb/kill/kill001/kill001.java | 10 +++------- .../vmTestbase/nsk/jdb/kill/kill002/kill002.java | 10 +++------- .../vmTestbase/nsk/jdb/klass/class001/class001.java | 10 +++------- .../vmTestbase/nsk/jdb/list/list002/list002.java | 10 +++------- .../nsk/jdb/locals/locals002/locals002.java | 10 +++------- .../nsk/jdb/methods/methods002/methods002.java | 10 +++------- .../nsk/jdb/monitor/monitor001/monitor001.java | 10 +++------- .../nsk/jdb/monitor/monitor002/monitor002.java | 10 +++------- .../vmTestbase/nsk/jdb/next/next001/next001.java | 10 +++------- .../jdb/options/connect/connect001/connect001.java | 10 +++------- .../jdb/options/connect/connect002/connect002.java | 10 +++------- .../jdb/options/connect/connect003/connect003.java | 10 +++------- .../jdb/options/connect/connect004/connect004.java | 10 +++------- .../jdb/options/connect/connect005/connect005.java | 13 ++++--------- .../listconnectors001/listconnectors001.java | 10 +++------- .../jtreg/vmTestbase/nsk/jdb/pop/pop001/pop001.java | 10 +++------- .../pop_exception001/pop_exception001.java | 10 +++------- .../vmTestbase/nsk/jdb/print/print002/print002.java | 10 +++------- .../vmTestbase/nsk/jdb/read/read001/read001.java | 10 +++------- .../nsk/jdb/redefine/redefine001/redefine001.java | 10 +++------- .../nsk/jdb/reenter/reenter001/reenter001.java | 10 +++------- .../nsk/jdb/regression/b4689395/b4689395.java | 10 +++------- .../nsk/jdb/resume/resume002/resume002.java | 10 +++------- .../jtreg/vmTestbase/nsk/jdb/run/run002/run002.java | 10 +++------- .../jtreg/vmTestbase/nsk/jdb/set/set001/set001.java | 10 +++------- .../jtreg/vmTestbase/nsk/jdb/set/set002/set002.java | 10 +++------- .../vmTestbase/nsk/jdb/step/step002/step002.java | 10 +++------- .../nsk/jdb/step_up/step_up001/step_up001.java | 10 +++------- .../nsk/jdb/stop_at/stop_at002/stop_at002.java | 8 ++------ .../nsk/jdb/stop_at/stop_at003/stop_at003.java | 10 +++------- .../nsk/jdb/stop_in/stop_in002/stop_in002.java | 10 +++------- .../nsk/jdb/suspend/suspend001/suspend001.java | 10 +++------- .../nsk/jdb/thread/thread002/thread002.java | 10 +++------- .../threadgroup/threadgroup002/threadgroup002.java | 10 +++------- .../threadgroups002/threadgroups002.java | 10 +++------- .../nsk/jdb/threads/threads002/threads002.java | 10 +++------- .../vmTestbase/nsk/jdb/trace/trace001/trace001.java | 10 +++------- .../uncaught_exception002.java | 10 +++------- .../jdb/unmonitor/unmonitor001/unmonitor001.java | 10 +++------- .../nsk/jdb/untrace/untrace001/untrace001.java | 10 +++------- .../nsk/jdb/unwatch/unwatch001/unwatch001.java | 10 +++------- .../nsk/jdb/unwatch/unwatch002/unwatch002.java | 10 +++------- .../jtreg/vmTestbase/nsk/jdb/up/up002/up002.java | 10 +++------- .../jtreg/vmTestbase/nsk/jdb/use/use001/use001.java | 10 +++------- .../vmTestbase/nsk/jdb/watch/watch001/watch001.java | 10 +++------- .../vmTestbase/nsk/jdb/watch/watch002/watch002.java | 10 +++------- .../vmTestbase/nsk/jdb/where/where004/where004.java | 10 +++------- .../vmTestbase/nsk/jdb/where/where005/where005.java | 10 +++------- .../vmTestbase/nsk/jdb/where/where006/where006.java | 10 +++------- .../nsk/jdb/wherei/wherei001/wherei001.java | 10 +++------- .../jtreg/vmTestbase/nsk/share/jdb/JdbTest.java | 11 +++++------ .../jtreg/vmTestbase/nsk/share/jdb/Launcher.java | 6 ++++-- 66 files changed, 200 insertions(+), 456 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/caught_exception/caught_exception002/caught_exception002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/caught_exception/caught_exception002/caught_exception002.java index 4eef7900d4231..04ace5ba49c5d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/caught_exception/caught_exception002/caught_exception002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/caught_exception/caught_exception002/caught_exception002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.caught_exception.caught_exception002.caught_exception002a - * @run main/othervm + * @run driver * nsk.jdb.caught_exception.caught_exception002.caught_exception002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -69,14 +69,10 @@ public class caught_exception002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new caught_exception002().runTest(argv, out); + new caught_exception002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.caught_exception.caught_exception002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/classes/classes001/classes001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/classes/classes001/classes001.java index 40a5ebaa9393c..8543c7c6f1e1d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/classes/classes001/classes001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/classes/classes001/classes001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.classes.classes001.classes001a - * @run main/othervm + * @run driver * nsk.jdb.classes.classes001.classes001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -60,14 +60,10 @@ public class classes001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new classes001().runTest(argv, out); + new classes001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.classes.classes001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/classpath/classpath001/classpath001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/classpath/classpath001/classpath001.java index 0eea9a92ab26f..25a86fe64cbd9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/classpath/classpath001/classpath001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/classpath/classpath001/classpath001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.classpath.classpath001.classpath001a - * @run main/othervm + * @run driver * nsk.jdb.classpath.classpath001.classpath001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -59,14 +59,10 @@ public class classpath001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new classpath001().runTest(argv, out); + new classpath001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.classpath.classpath001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear002/clear002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear002/clear002.java index 7869a1340a7cd..cca80dad46502 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear002/clear002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear002/clear002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.clear.clear002.clear002a - * @run main/othervm + * @run driver * nsk.jdb.clear.clear002.clear002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -61,14 +61,10 @@ public class clear002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new clear002().runTest(argv, out); + new clear002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.clear.clear002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear003/clear003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear003/clear003.java index cbbc851f29a6f..003b1f36eddb7 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear003/clear003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear003/clear003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -39,7 +39,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.clear.clear003.clear003a - * @run main/othervm + * @run driver * nsk.jdb.clear.clear003.clear003 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -62,14 +62,10 @@ public class clear003 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new clear003().runTest(argv, out); + new clear003().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.clear.clear003"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear004/clear004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear004/clear004.java index c0ec8d2037095..5dfd33430e38c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear004/clear004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear004/clear004.java @@ -40,7 +40,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.clear.clear004.clear004a - * @run main/othervm + * @run driver * nsk.jdb.clear.clear004.clear004 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -63,14 +63,10 @@ public class clear004 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new clear004().runTest(argv, out); + new clear004().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.clear.clear004"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/down/down002/down002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/down/down002/down002.java index 29a40d9471d67..99f4254891d1e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/down/down002/down002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/down/down002/down002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.down.down002.down002a - * @run main/othervm + * @run driver * nsk.jdb.down.down002.down002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -66,14 +66,10 @@ public class down002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new down002().runTest(argv, out); + new down002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.down.down002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/dump/dump002/dump002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/dump/dump002/dump002.java index 3e3b5b9b85872..66a26e69f7769 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/dump/dump002/dump002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/dump/dump002/dump002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.dump.dump002.dump002a - * @run main/othervm + * @run driver * nsk.jdb.dump.dump002.dump002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -70,15 +70,11 @@ public class dump002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; compoundPromptIdent = COMPOUND_PROMPT_IDENT; - return new dump002().runTest(argv, out); + new dump002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.dump.dump002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/eval/eval001/eval001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/eval/eval001/eval001.java index 98848ced90bc7..fc4fb14dd2db6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/eval/eval001/eval001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/eval/eval001/eval001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ * @clean nsk.jdb.eval.eval001.eval001a * @compile -g:lines,source,vars eval001a.java * - * @run main/othervm + * @run driver * nsk.jdb.eval.eval001.eval001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -75,14 +75,10 @@ public class eval001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new eval001().runTest(argv, out); + new eval001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.eval.eval001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/exclude/exclude001/exclude001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/exclude/exclude001/exclude001.java index cee8ca44d585b..c7805cc6c95de 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/exclude/exclude001/exclude001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/exclude/exclude001/exclude001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.exclude.exclude001.exclude001a - * @run main/othervm/timeout=600 + * @run driver/timeout=600 * nsk.jdb.exclude.exclude001.exclude001 * -arch=${os.family}-${os.simpleArch} * -waittime=10 @@ -82,14 +82,10 @@ public class exclude001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new exclude001().runTest(argv, out); + new exclude001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.exclude.exclude001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/fields/fields001/fields001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/fields/fields001/fields001.java index b5e2ccb58e566..c1cbba3232a84 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/fields/fields001/fields001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/fields/fields001/fields001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.fields.fields001.fields001a - * @run main/othervm + * @run driver * nsk.jdb.fields.fields001.fields001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -64,14 +64,10 @@ public class fields001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new fields001().runTest(argv, out); + new fields001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.fields.fields001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/hidden_class/hc001/hc001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/hidden_class/hc001/hc001.java index 5040eef9cefb2..a7c74e28aaece 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/hidden_class/hc001/hc001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/hidden_class/hc001/hc001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ * jdk.jdwp.agent * @build nsk.jdb.hidden_class.hc001.hc001a * - * @run main/othervm + * @run driver * nsk.jdb.hidden_class.hc001.hc001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -60,13 +60,9 @@ public class hc001 extends JdbTest { static final int MAX_SLEEP_CNT = 3; public static void main(String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; // needed for JdbTest.runTest firstBreak = MAIN_METHOD_NAME; // needed for JdbTest.runTest - return new hc001().runTest(argv, out); + new hc001().runTest(argv); } static boolean checkPattern(String[] arr, String pattern) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/ignore/ignore001/ignore001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/ignore/ignore001/ignore001.java index 6eb8c91e1eb78..48d256d22fc7e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/ignore/ignore001/ignore001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/ignore/ignore001/ignore001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.ignore.ignore001.ignore001a - * @run main/othervm + * @run driver * nsk.jdb.ignore.ignore001.ignore001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -63,14 +63,10 @@ public class ignore001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new ignore001().runTest(argv, out); + new ignore001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.ignore.ignore001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/interrupt/interrupt001/interrupt001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/interrupt/interrupt001/interrupt001.java index 73f251b71e998..51bbdf6757a2d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/interrupt/interrupt001/interrupt001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/interrupt/interrupt001/interrupt001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.interrupt.interrupt001.interrupt001a - * @run main/othervm + * @run driver * nsk.jdb.interrupt.interrupt001.interrupt001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -73,13 +73,9 @@ public class interrupt001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; - return new interrupt001().runTest(argv, out); + new interrupt001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.interrupt.interrupt001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill001/kill001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill001/kill001.java index 15ec0902021b4..1021fd188c2b9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill001/kill001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill001/kill001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.kill.kill001.kill001a - * @run main/othervm + * @run driver * nsk.jdb.kill.kill001.kill001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -70,13 +70,9 @@ public class kill001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; - return new kill001().runTest(argv, out); + new kill001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.kill.kill001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill002/kill002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill002/kill002.java index 230dcdf12baaf..ed5306346dc3c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill002/kill002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill002/kill002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.kill.kill002.kill002a - * @run main/othervm + * @run driver * nsk.jdb.kill.kill002.kill002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -66,13 +66,9 @@ public class kill002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; - return new kill002().runTest(argv, out); + new kill002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.kill.kill002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/klass/class001/class001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/klass/class001/class001.java index 4c548348dc356..ee37e393f702d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/klass/class001/class001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/klass/class001/class001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.klass.class001.class001a - * @run main/othervm + * @run driver * nsk.jdb.klass.class001.class001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -63,14 +63,10 @@ public class class001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new class001().runTest(argv, out); + new class001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.klass.class001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/list/list002/list002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/list/list002/list002.java index 4180ea3bb453b..38282a425ecd4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/list/list002/list002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/list/list002/list002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ * /test/lib * @build nsk.jdb.list.list002.list002a * @run driver jdk.test.lib.FileInstaller list002a.java src/nsk/jdb/list/list002/list002a.java - * @run main/othervm + * @run driver * nsk.jdb.list.list002.list002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -68,14 +68,10 @@ public class list002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new list002().runTest(argv, out); + new list002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.list.list002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/locals/locals002/locals002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/locals/locals002/locals002.java index 793cdc0460876..09a97ff83a528 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/locals/locals002/locals002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/locals/locals002/locals002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ * @clean nsk.jdb.locals.locals002.locals002a * @compile -g:lines,source,vars locals002a.java * - * @run main/othervm + * @run driver * nsk.jdb.locals.locals002.locals002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -75,15 +75,11 @@ public class locals002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; compoundPromptIdent = COMPOUND_PROMPT_IDENT; - return new locals002().runTest(argv, out); + new locals002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.locals.locals002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/methods/methods002/methods002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/methods/methods002/methods002.java index 2bacbab101bd4..ef480d52c037c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/methods/methods002/methods002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/methods/methods002/methods002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.methods.methods002.methods002a - * @run main/othervm + * @run driver * nsk.jdb.methods.methods002.methods002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -73,14 +73,10 @@ public class methods002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new methods002().runTest(argv, out); + new methods002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.methods.methods002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor001/monitor001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor001/monitor001.java index 181fe199dfecd..2f6391591c31a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor001/monitor001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor001/monitor001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.monitor.monitor001.monitor001a - * @run main/othervm + * @run driver * nsk.jdb.monitor.monitor001.monitor001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -69,14 +69,10 @@ public class monitor001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new monitor001().runTest(argv, out); + new monitor001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.monitor.monitor001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor002/monitor002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor002/monitor002.java index 53c856128ce7b..790eb7469168d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor002/monitor002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor002/monitor002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.monitor.monitor002.monitor002a - * @run main/othervm + * @run driver * nsk.jdb.monitor.monitor002.monitor002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -65,14 +65,10 @@ public class monitor002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new monitor002().runTest(argv, out); + new monitor002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.monitor.monitor002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/next/next001/next001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/next/next001/next001.java index 206199f0bb325..3d0c810b5c4a4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/next/next001/next001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/next/next001/next001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.next.next001.next001a - * @run main/othervm + * @run driver * nsk.jdb.next.next001.next001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -69,14 +69,10 @@ public class next001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new next001().runTest(argv, out); + new next001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.next.next001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect001/connect001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect001/connect001.java index a78f3a96db421..85cdbb279974e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect001/connect001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect001/connect001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.options.connect.connect001.connect001a - * @run main/othervm + * @run driver * nsk.jdb.options.connect.connect001.connect001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -71,14 +71,10 @@ public class connect001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new connect001().runTest(argv, out); + new connect001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.options.connect.connect001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect002/connect002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect002/connect002.java index 78bcf2fb9737e..a3219de0cc4e3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect002/connect002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect002/connect002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.options.connect.connect002.connect002a - * @run main/othervm + * @run driver * nsk.jdb.options.connect.connect002.connect002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -71,14 +71,10 @@ public class connect002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new connect002().runTest(argv, out); + new connect002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.options.connect.connect002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect003/connect003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect003/connect003.java index 701f611d2ff39..465e3c9deb241 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect003/connect003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect003/connect003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.options.connect.connect003.connect003a - * @run main/othervm + * @run driver * nsk.jdb.options.connect.connect003.connect003 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -71,14 +71,10 @@ public class connect003 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new connect003().runTest(argv, out); + new connect003().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.options.connect.connect003"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect004/connect004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect004/connect004.java index adaa58627dd47..075e9c30268ef 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect004/connect004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect004/connect004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.options.connect.connect004.connect004a - * @run main/othervm + * @run driver * nsk.jdb.options.connect.connect004.connect004 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -71,14 +71,10 @@ public class connect004 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new connect004().runTest(argv, out); + new connect004().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.options.connect.connect004"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect005/connect005.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect005/connect005.java index 8a67039246605..7bd44a5927cc7 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect005/connect005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect005/connect005.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.options.connect.connect005.connect005a - * @run main/othervm + * @run driver * nsk.jdb.options.connect.connect005.connect005 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -70,15 +70,10 @@ public class connect005 extends JdbTest { - public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { - debuggeeClass = DEBUGGEE_CLASS; + public static void main (String argv[]) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new connect005().runTest(argv, out); + new connect005().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.options.connect.connect005"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/listconnectors/listconnectors001/listconnectors001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/listconnectors/listconnectors001/listconnectors001.java index d814df91cc693..b4961be11eeee 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/listconnectors/listconnectors001/listconnectors001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/listconnectors/listconnectors001/listconnectors001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ * * @library /vmTestbase * /test/lib - * @run main/othervm + * @run driver * nsk.jdb.options.listconnectors.listconnectors001.listconnectors001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -75,14 +75,10 @@ public class listconnectors001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new listconnectors001().runTest(argv, out); + new listconnectors001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.options.connect"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop/pop001/pop001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop/pop001/pop001.java index e449a5771f27c..c508538fa1e66 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop/pop001/pop001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop/pop001/pop001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.pop.pop001.pop001a - * @run main/othervm + * @run driver * nsk.jdb.pop.pop001.pop001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -70,14 +70,10 @@ public class pop001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new pop001().runTest(argv, out); + new pop001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.pop.pop001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop_exception/pop_exception001/pop_exception001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop_exception/pop_exception001/pop_exception001.java index f70a5ffb96023..49921cd26cc0e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop_exception/pop_exception001/pop_exception001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop_exception/pop_exception001/pop_exception001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.pop_exception.pop_exception001.pop_exception001a - * @run main/othervm + * @run driver * nsk.jdb.pop_exception.pop_exception001.pop_exception001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -63,14 +63,10 @@ public class pop_exception001 extends JdbTest { static final String LAST_BREAK = DEBUGGEE_CLASS + ".lastBreak"; public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new pop_exception001().runTest(argv, out); + new pop_exception001().runTest(argv); } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/print/print002/print002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/print/print002/print002.java index e339a0a321b97..1993c1f4d95fc 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/print/print002/print002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/print/print002/print002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ * @clean nsk.jdb.print.print002.print002a * @compile -g:lines,source,vars print002a.java * - * @run main/othervm + * @run driver * nsk.jdb.print.print002.print002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -75,14 +75,10 @@ public class print002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new print002().runTest(argv, out); + new print002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.print.print002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/read/read001/read001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/read/read001/read001.java index b5ca64334d775..60c80139a651f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/read/read001/read001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/read/read001/read001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ * @clean nsk.jdb.read.read001.read001a * @compile -g:lines,source,vars read001a.java * - * @run main/othervm + * @run driver * nsk.jdb.read.read001.read001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -76,14 +76,10 @@ public class read001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new read001().runTest(argv, out); + new read001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.read.read001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/redefine/redefine001/redefine001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/redefine/redefine001/redefine001.java index 80ff33889a410..d3988ac443ca8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/redefine/redefine001/redefine001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/redefine/redefine001/redefine001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ * -cp ${test.class.path} * ${test.src}/newclass_g/RedefinedClass.java * - * @run main/othervm + * @run driver * nsk.jdb.redefine.redefine001.redefine001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -80,14 +80,10 @@ public class redefine001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new redefine001().runTest(argv, out); + new redefine001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.redefine.redefine001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/reenter/reenter001/reenter001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/reenter/reenter001/reenter001.java index ebc063942c608..4013d85ab7527 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/reenter/reenter001/reenter001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/reenter/reenter001/reenter001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.reenter.reenter001.reenter001a - * @run main/othervm + * @run driver * nsk.jdb.reenter.reenter001.reenter001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -69,14 +69,10 @@ public class reenter001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new reenter001().runTest(argv, out); + new reenter001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.reenter.reenter001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/regression/b4689395/b4689395.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/regression/b4689395/b4689395.java index 82d8235fee724..2cb3cc0eccfc4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/regression/b4689395/b4689395.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/regression/b4689395/b4689395.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -101,7 +101,7 @@ * -cp ${test.class.path} * ${test.src}/newclass/b4689395a.java * - * @run main/othervm + * @run driver * nsk.jdb.regression.b4689395.b4689395 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -131,13 +131,9 @@ public class b4689395 extends JdbTest { private String classFile; public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; - return new b4689395().runTest(argv, out); + new b4689395().runTest(argv); } public b4689395() { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/resume/resume002/resume002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/resume/resume002/resume002.java index 1643ff28fe5c8..6c7336b20933a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/resume/resume002/resume002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/resume/resume002/resume002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.resume.resume002.resume002a - * @run main/othervm + * @run driver * nsk.jdb.resume.resume002.resume002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -73,14 +73,10 @@ public class resume002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new resume002().runTest(argv, out); + new resume002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.resume.resume002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/run/run002/run002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/run/run002/run002.java index da837ab0f8bce..9b23ac4de25a9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/run/run002/run002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/run/run002/run002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.run.run002.run002a - * @run main/othervm + * @run driver * nsk.jdb.run.run002.run002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -67,14 +67,10 @@ public class run002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new run002().runTest(argv, out); + new run002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.run.run002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set001/set001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set001/set001.java index d00362b228cbf..7b97f47b5294a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set001/set001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set001/set001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ * @clean nsk.jdb.set.set001.set001a * @compile -g:lines,source,vars set001a.java * - * @run main/othervm + * @run driver * nsk.jdb.set.set001.set001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -76,14 +76,10 @@ public class set001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new set001().runTest(argv, out); + new set001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.set.set001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set002/set002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set002/set002.java index dca4e554afaf9..91d8482104045 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set002/set002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set002/set002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ * @clean nsk.jdb.set.set002.set002a * @compile -g:lines,source,vars set002a.java * - * @run main/othervm + * @run driver * nsk.jdb.set.set002.set002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -76,15 +76,11 @@ public class set002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new set002().runTest(argv, out); + new set002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.set.set002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/step/step002/step002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/step/step002/step002.java index 4df163ca1a92c..c9cc342783e3f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/step/step002/step002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/step/step002/step002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ * @clean nsk.jdb.step.step002.step002a * @compile -g:lines,source,vars step002a.java * - * @run main/othervm + * @run driver * nsk.jdb.step.step002.step002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -79,14 +79,10 @@ public class step002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new step002().runTest(argv, out); + new step002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.step.step002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/step_up/step_up001/step_up001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/step_up/step_up001/step_up001.java index 590a476dbbe60..d4c60f937fa2e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/step_up/step_up001/step_up001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/step_up/step_up001/step_up001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.step_up.step_up001.step_up001a - * @run main/othervm + * @run driver * nsk.jdb.step_up.step_up001.step_up001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -68,14 +68,10 @@ public class step_up001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new step_up001().runTest(argv, out); + new step_up001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.step_up.step_up001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002.java index 9dae8c17cfc36..30cb6ed2c68af 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002.java @@ -37,7 +37,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.stop_at.stop_at002.stop_at002a - * @run main/othervm + * @run driver * nsk.jdb.stop_at.stop_at002.stop_at002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -67,14 +67,10 @@ public class stop_at002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new stop_at002().runTest(argv, out); + new stop_at002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.stop_at.stop_at002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at003/stop_at003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at003/stop_at003.java index ecd66ca7c9573..06eacea58b913 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at003/stop_at003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at003/stop_at003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.stop_at.stop_at003.stop_at003a - * @run main/othervm + * @run driver * nsk.jdb.stop_at.stop_at003.stop_at003 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -79,14 +79,10 @@ public class stop_at003 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new stop_at003().runTest(argv, out); + new stop_at003().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.stop_at.stop_at003"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_in/stop_in002/stop_in002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_in/stop_in002/stop_in002.java index e4c2058fd97a3..710f05c078c46 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_in/stop_in002/stop_in002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_in/stop_in002/stop_in002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.stop_in.stop_in002.stop_in002a - * @run main/othervm + * @run driver * nsk.jdb.stop_in.stop_in002.stop_in002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -80,14 +80,10 @@ public class stop_in002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new stop_in002().runTest(argv, out); + new stop_in002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.stop_in.stop_in002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/suspend/suspend001/suspend001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/suspend/suspend001/suspend001.java index 18e5c27d31c6c..20c9778f25109 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/suspend/suspend001/suspend001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/suspend/suspend001/suspend001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.suspend.suspend001.suspend001a - * @run main/othervm + * @run driver * nsk.jdb.suspend.suspend001.suspend001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -69,14 +69,10 @@ public class suspend001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new suspend001().runTest(argv, out); + new suspend001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.suspend.suspend001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/thread/thread002/thread002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/thread/thread002/thread002.java index 487ac49e66ec9..c8b55b0beee56 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/thread/thread002/thread002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/thread/thread002/thread002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.thread.thread002.thread002a - * @run main/othervm + * @run driver * nsk.jdb.thread.thread002.thread002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -66,14 +66,10 @@ public class thread002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new thread002().runTest(argv, out); + new thread002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.thread.thread002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroup/threadgroup002/threadgroup002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroup/threadgroup002/threadgroup002.java index cb8004643d3b7..1c23cb7aae398 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroup/threadgroup002/threadgroup002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroup/threadgroup002/threadgroup002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.threadgroup.threadgroup002.threadgroup002a - * @run main/othervm + * @run driver * nsk.jdb.threadgroup.threadgroup002.threadgroup002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -64,14 +64,10 @@ public class threadgroup002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new threadgroup002().runTest(argv, out); + new threadgroup002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.threadgroup.threadgroup002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroups/threadgroups002/threadgroups002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroups/threadgroups002/threadgroups002.java index 67ee29006b474..56f4dceda9e2d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroups/threadgroups002/threadgroups002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroups/threadgroups002/threadgroups002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.threadgroups.threadgroups002.threadgroups002a - * @run main/othervm + * @run driver * nsk.jdb.threadgroups.threadgroups002.threadgroups002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -64,14 +64,10 @@ public class threadgroups002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new threadgroups002().runTest(argv, out); + new threadgroups002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.threadgroups.threadgroups002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads002/threads002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads002/threads002.java index 3197c371943b0..46096c7a3134e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads002/threads002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads002/threads002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.threads.threads002.threads002a - * @run main/othervm + * @run driver * nsk.jdb.threads.threads002.threads002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -63,14 +63,10 @@ public class threads002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new threads002().runTest(argv, out); + new threads002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.threads.threads002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/trace/trace001/trace001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/trace/trace001/trace001.java index c345e80073659..dd0d1ddcf684b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/trace/trace001/trace001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/trace/trace001/trace001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.trace.trace001.trace001a - * @run main/othervm + * @run driver * nsk.jdb.trace.trace001.trace001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -70,14 +70,10 @@ public class trace001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new trace001().runTest(argv, out); + new trace001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.trace.trace001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/uncaught_exception/uncaught_exception002/uncaught_exception002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/uncaught_exception/uncaught_exception002/uncaught_exception002.java index dd1d0748c0ff2..32f7750cdb5ec 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/uncaught_exception/uncaught_exception002/uncaught_exception002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/uncaught_exception/uncaught_exception002/uncaught_exception002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ * @clean nsk.jdb.uncaught_exception.uncaught_exception002.uncaught_exception002a * @compile -g:lines,source,vars uncaught_exception002a.java * - * @run main/othervm + * @run driver * nsk.jdb.uncaught_exception.uncaught_exception002.uncaught_exception002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -75,14 +75,10 @@ public class uncaught_exception002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new uncaught_exception002(true).runTest(argv, out); + new uncaught_exception002(true).runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.uncaught_exception.uncaught_exception002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/unmonitor/unmonitor001/unmonitor001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/unmonitor/unmonitor001/unmonitor001.java index 54a90a930f277..1c43ded326c4c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/unmonitor/unmonitor001/unmonitor001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/unmonitor/unmonitor001/unmonitor001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ * @clean nsk.jdb.unmonitor.unmonitor001.unmonitor001a * @compile -g:lines,source,vars unmonitor001a.java * - * @run main/othervm + * @run driver * nsk.jdb.unmonitor.unmonitor001.unmonitor001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -79,14 +79,10 @@ public class unmonitor001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new unmonitor001().runTest(argv, out); + new unmonitor001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.unmonitor.unmonitor001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/untrace/untrace001/untrace001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/untrace/untrace001/untrace001.java index daad477dbb439..0891e5b931cc4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/untrace/untrace001/untrace001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/untrace/untrace001/untrace001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.untrace.untrace001.untrace001a - * @run main/othervm + * @run driver * nsk.jdb.untrace.untrace001.untrace001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -77,14 +77,10 @@ public class untrace001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new untrace001().runTest(argv, out); + new untrace001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.untrace.untrace001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch001/unwatch001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch001/unwatch001.java index b8c71645edb47..aff9890e58d8b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch001/unwatch001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch001/unwatch001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.unwatch.unwatch001.unwatch001a - * @run main/othervm + * @run driver * nsk.jdb.unwatch.unwatch001.unwatch001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -73,14 +73,10 @@ public class unwatch001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new unwatch001().runTest(argv, out); + new unwatch001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.unwatch.unwatch001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch002/unwatch002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch002/unwatch002.java index e32cc0b8e5dc6..1078e2b3da358 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch002/unwatch002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch002/unwatch002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.unwatch.unwatch002.unwatch002a - * @run main/othervm + * @run driver * nsk.jdb.unwatch.unwatch002.unwatch002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -74,14 +74,10 @@ public class unwatch002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new unwatch002().runTest(argv, out); + new unwatch002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.unwatch.unwatch002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/up/up002/up002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/up/up002/up002.java index 5b2cb393df4e8..78c01074abb1a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/up/up002/up002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/up/up002/up002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.up.up002.up002a - * @run main/othervm + * @run driver * nsk.jdb.up.up002.up002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -66,14 +66,10 @@ public class up002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new up002().runTest(argv, out); + new up002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.up.up002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/use/use001/use001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/use/use001/use001.java index 1454b39b2bf8e..81ad1dd48accb 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/use/use001/use001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/use/use001/use001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -43,7 +43,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.use.use001.use001a - * @run main/othervm + * @run driver * nsk.jdb.use.use001.use001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -67,14 +67,10 @@ public class use001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new use001().runTest(argv, out); + new use001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.use.use001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch001/watch001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch001/watch001.java index 8d434fcfc7444..dfc154d1b4186 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch001/watch001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch001/watch001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.watch.watch001.watch001a - * @run main/othervm + * @run driver * nsk.jdb.watch.watch001.watch001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -71,15 +71,11 @@ public class watch001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; compoundPromptIdent = COMPOUND_PROMPT_IDENT; - return new watch001().runTest(argv, out); + new watch001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.watch.watch001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch002/watch002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch002/watch002.java index cb0535117d9fd..84c80a59ebf73 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch002/watch002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch002/watch002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.watch.watch002.watch002a - * @run main/othervm + * @run driver * nsk.jdb.watch.watch002.watch002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -71,15 +71,11 @@ public class watch002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; compoundPromptIdent = COMPOUND_PROMPT_IDENT; - return new watch002().runTest(argv, out); + new watch002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.watch.watch002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where004/where004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where004/where004.java index e4cbf50e62f68..9002c35e16e5a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where004/where004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where004/where004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.where.where004.where004a - * @run main/othervm + * @run driver * nsk.jdb.where.where004.where004 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -64,14 +64,10 @@ public class where004 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new where004().runTest(argv, out); + new where004().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.where.where004"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where005/where005.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where005/where005.java index b949916aae74e..2fded98727291 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where005/where005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where005/where005.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.where.where005.where005a - * @run main/othervm + * @run driver * nsk.jdb.where.where005.where005 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -65,14 +65,10 @@ public class where005 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new where005(true).runTest(argv, out); + new where005(true).runTest(argv); } public where005 (boolean debuggeeShouldFail) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where006/where006.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where006/where006.java index bf7622c48b345..11dc185238f07 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where006/where006.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where006/where006.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.where.where006.where006a - * @run main/othervm + * @run driver * nsk.jdb.where.where006.where006 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -65,14 +65,10 @@ public class where006 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new where006().runTest(argv, out); + new where006().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.where.where006"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/wherei/wherei001/wherei001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/wherei/wherei001/wherei001.java index 431206b55510e..e4d75620f0b49 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/wherei/wherei001/wherei001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/wherei/wherei001/wherei001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.wherei.wherei001.wherei001a - * @run main/othervm + * @run driver * nsk.jdb.wherei.wherei001.wherei001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -60,14 +60,10 @@ public class wherei001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new wherei001().runTest(argv, out); + new wherei001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.wherei.wherei001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/JdbTest.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/JdbTest.java index c0edc58993bc1..b857268e75568 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/JdbTest.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/JdbTest.java @@ -127,14 +127,15 @@ protected void initJdb() { protected void afterJdbExit() { } - protected int runTest(String argv[], PrintStream out) { + protected void runTest(String argv[]) { + PrintStream out = System.out; try { argumentHandler = new JdbArgumentHandler(argv); log = new Log(out, argumentHandler); if (shouldPass()) { log.println("TEST PASSED"); - return PASSED; + return; } try { @@ -223,16 +224,14 @@ protected int runTest(String argv[], PrintStream out) { if (!success) { log.complain("TEST FAILED"); - return FAILED; + throw new RuntimeException("TEST FAILED"); } } catch (Exception e) { out.println("Caught unexpected exception while starting the test: " + e); e.printStackTrace(out); - out.println("TEST FAILED"); - return FAILED; + throw new RuntimeException("TEST FAILED", e); } out.println("TEST PASSED"); - return PASSED; } } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java index ff763ce72d621..22ae352daab49 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java @@ -171,10 +171,12 @@ private String[] makeJdbCmdLine (String classToExecute) { } else /* LaunchingConnector or DefaultConnector */ { connect.append("vmexec=" + argumentHandler.getLaunchExecName().trim()); + connect.append(",options="); + connect.append(" \"-cp\""); + connect.append(" \"" + System.getProperty("test.class.path") + "\""); + String debuggeeOpts = argumentHandler.getDebuggeeOptions(); if (debuggeeOpts.trim().length() > 0) { - //connect.append(",options=" + debuggeeOpts.trim()); - connect.append(",options="); for (String arg : debuggeeOpts.split("\\s+")) { connect.append(" \""); connect.append(arg); From d542d473238b54a3f0185680218e1114d5a9f04e Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Jul 2025 05:22:48 +0000 Subject: [PATCH 392/846] 8339834: Replace usages of -mx and -ms in some tests Backport-of: 1d392492311daceeae12769cb9494eae63289853 --- src/java.base/share/classes/sun/security/util/Cache.java | 2 +- .../intrinsics/string/TestStringIntrinsics2LargeArray.java | 4 ++-- .../beans/Introspector/8159696/UnloadClassBeanInfo.java | 4 ++-- test/jdk/java/beans/Introspector/Test5102804.java | 5 ++--- test/jdk/java/beans/Introspector/Test8027905.java | 5 ++--- test/jdk/java/beans/XMLEncoder/Test4646747.java | 5 ++--- test/jdk/java/lang/ref/SoftReference/Pin.java | 6 ++---- test/jdk/java/nio/Buffer/Chew.java | 4 ++-- test/jdk/tools/jimage/JImageToolTest.java | 4 ++-- 9 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/java.base/share/classes/sun/security/util/Cache.java b/src/java.base/share/classes/sun/security/util/Cache.java index 65bf6cc758112..ca8f731a6b640 100644 --- a/src/java.base/share/classes/sun/security/util/Cache.java +++ b/src/java.base/share/classes/sun/security/util/Cache.java @@ -55,7 +55,7 @@ * However, note that because of the way SoftReferences are implemented in * HotSpot at the moment, this may not work perfectly as it clears them fairly * eagerly. Performance may be improved if the Java heap size is set to larger - * value using e.g. java -ms64M -mx128M foo.Test + * value using e.g. java -Xms64M -Xmx128M foo.Test * * Cache sizing: the memory cache is implemented on top of a LinkedHashMap. * In its current implementation, the number of buckets (NOT entries) in diff --git a/test/hotspot/jtreg/resourcehogs/compiler/intrinsics/string/TestStringIntrinsics2LargeArray.java b/test/hotspot/jtreg/resourcehogs/compiler/intrinsics/string/TestStringIntrinsics2LargeArray.java index 598633d307f47..6ed778e6e0b28 100644 --- a/test/hotspot/jtreg/resourcehogs/compiler/intrinsics/string/TestStringIntrinsics2LargeArray.java +++ b/test/hotspot/jtreg/resourcehogs/compiler/intrinsics/string/TestStringIntrinsics2LargeArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -35,7 +35,7 @@ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * * @run main/othervm - * -mx8G + * -Xmx8G * -Xbootclasspath/a:. * -Xmixed * -XX:+UnlockDiagnosticVMOptions diff --git a/test/jdk/java/beans/Introspector/8159696/UnloadClassBeanInfo.java b/test/jdk/java/beans/Introspector/8159696/UnloadClassBeanInfo.java index 8c77b3565a8fc..0d9775d50d675 100644 --- a/test/jdk/java/beans/Introspector/8159696/UnloadClassBeanInfo.java +++ b/test/jdk/java/beans/Introspector/8159696/UnloadClassBeanInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ * @bug 8159696 * @library /javax/swing/regtesthelpers * @compile ./stub/Stub.java - * @run main/othervm -mx32M UnloadClassBeanInfo + * @run main/othervm -Xmx32M UnloadClassBeanInfo */ public class UnloadClassBeanInfo { diff --git a/test/jdk/java/beans/Introspector/Test5102804.java b/test/jdk/java/beans/Introspector/Test5102804.java index d5b38ea10d017..0563b1d306d77 100644 --- a/test/jdk/java/beans/Introspector/Test5102804.java +++ b/test/jdk/java/beans/Introspector/Test5102804.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,7 @@ * @test * @bug 5102804 * @summary Tests memory leak - * @author Sergey Malenkov - * @run main/othervm -ms16m -mx16m Test5102804 + * @run main/othervm -Xms16m -Xmx16m Test5102804 */ import java.beans.BeanInfo; diff --git a/test/jdk/java/beans/Introspector/Test8027905.java b/test/jdk/java/beans/Introspector/Test8027905.java index 60318f345553b..8ebf1c59574f9 100644 --- a/test/jdk/java/beans/Introspector/Test8027905.java +++ b/test/jdk/java/beans/Introspector/Test8027905.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,7 @@ * @test * @bug 8027905 * @summary Tests that GC does not affect a property type - * @author Sergey Malenkov - * @run main/othervm -mx16m Test8027905 + * @run main/othervm -Xmx16m Test8027905 */ public class Test8027905 { diff --git a/test/jdk/java/beans/XMLEncoder/Test4646747.java b/test/jdk/java/beans/XMLEncoder/Test4646747.java index 61f7c41c88269..467a015322815 100644 --- a/test/jdk/java/beans/XMLEncoder/Test4646747.java +++ b/test/jdk/java/beans/XMLEncoder/Test4646747.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,7 @@ * @test * @bug 4646747 * @summary Tests that persistence delegate is correct after memory stress - * @author Mark Davidson - * @run main/othervm -ms16m -mx16m Test4646747 + * @run main/othervm -Xms16m -Xmx16m Test4646747 */ import java.beans.DefaultPersistenceDelegate; diff --git a/test/jdk/java/lang/ref/SoftReference/Pin.java b/test/jdk/java/lang/ref/SoftReference/Pin.java index 5416b0f575a42..35aa4d9a51271 100644 --- a/test/jdk/java/lang/ref/SoftReference/Pin.java +++ b/test/jdk/java/lang/ref/SoftReference/Pin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,9 +24,7 @@ /* @test * @bug 4076287 * @summary Invoking get on a SoftReference shouldn't pin the referent - * @run main/othervm -ms16m -mx16m Pin - * @author Peter Jones - * @author Mark Reinhold + * @run main/othervm -Xms16m -Xmx16m Pin */ diff --git a/test/jdk/java/nio/Buffer/Chew.java b/test/jdk/java/nio/Buffer/Chew.java index b1afeabc472ab..30932be526afb 100644 --- a/test/jdk/java/nio/Buffer/Chew.java +++ b/test/jdk/java/nio/Buffer/Chew.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ * @summary Ensure that direct memory can be unreserved * as the reserving thread sleeps * - * @run main/othervm -mx16M Chew + * @run main/othervm -Xmx16M Chew */ import java.nio.*; diff --git a/test/jdk/tools/jimage/JImageToolTest.java b/test/jdk/tools/jimage/JImageToolTest.java index feb6a56a968c3..b1006c896794b 100644 --- a/test/jdk/tools/jimage/JImageToolTest.java +++ b/test/jdk/tools/jimage/JImageToolTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ public class JImageToolTest { private static void jimage(String... jimageArgs) throws Exception { ArrayList args = new ArrayList<>(); - args.add("-ms64m"); + args.add("-Xms64m"); args.add("jdk.tools.jimage.Main"); args.addAll(Arrays.asList(jimageArgs)); From 7e1b9f5e15ce31b3bc82eb38e0f373a04f328753 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Jul 2025 05:26:20 +0000 Subject: [PATCH 393/846] 8346998: Test nsk/jvmti/ResourceExhausted/resexhausted003 fails with java.lang.OutOfMemoryError when CDS is off Backport-of: 88fa3b2fe9bccf9cd4a4041732e2f6d425c19244 --- .../ResourceExhausted/resexhausted003/TestDescription.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003/TestDescription.java index b6ef5ab84870a..26cdf4473cf05 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, 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 @@ -39,10 +39,7 @@ * /test/lib * @run main/othervm/native * -agentlib:resexhausted=-waittime=5 - * -Xms64m - * -Xmx64m - * -XX:MaxMetaspaceSize=9m - * -XX:-UseGCOverheadLimit + * -XX:MaxMetaspaceSize=20m * nsk.jvmti.ResourceExhausted.resexhausted003 */ From 1ec596a4ab461011b2ee25a5f38270296126b777 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Jul 2025 05:27:54 +0000 Subject: [PATCH 394/846] 8348365: Bad format string in CLDRDisplayNamesTest Backport-of: d9d2e19f923217a6831a8697c62ebeef0cc5d3b8 --- test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java b/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java index 67a082410ecbf..7b2b7dc600da1 100644 --- a/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java +++ b/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java @@ -130,7 +130,7 @@ public static void main(String[] args) { String displayName = zi.getDisplayName(false, TimeZone.SHORT, Locale.US); Locale.setDefault(originalLocale); if (!displayName.equals("GMT+05:00")) { - System.err.printf("Wrong display name for timezone Etc/GMT-5 : expected GMT+05:00, Actual " + displayName); + System.err.println("Wrong display name for timezone Etc/GMT-5 : expected GMT+05:00, Actual " + displayName); errors++; } From 8636073b137980230b00b8a4a2c9a0afde40204a Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Jul 2025 05:30:08 +0000 Subject: [PATCH 395/846] 8334320: Replace vmTestbase/metaspace/share/TriggerUnloadingWithWhiteBox.java with ClassUnloadCommon from testlibrary Backport-of: 9b49597244f898400222cfc252f50a2401ca3e2f --- ...WhiteBox.java => TriggerUnloadingWithFullGC.java} | 12 +++++------- .../metaspace/staticReferences/StaticReferences.java | 6 +++--- .../common/StressHierarchyBaseClass.java | 6 +++--- 3 files changed, 11 insertions(+), 13 deletions(-) rename test/hotspot/jtreg/vmTestbase/metaspace/share/{TriggerUnloadingWithWhiteBox.java => TriggerUnloadingWithFullGC.java} (80%) diff --git a/test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingWithWhiteBox.java b/test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingWithFullGC.java similarity index 80% rename from test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingWithWhiteBox.java rename to test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingWithFullGC.java index 678e9551fa750..e861ac53c0c1b 100644 --- a/test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingWithWhiteBox.java +++ b/test/hotspot/jtreg/vmTestbase/metaspace/share/TriggerUnloadingWithFullGC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 @@ -20,19 +20,17 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package metaspace.share; +package metaspace.share; -import jdk.test.whitebox.WhiteBox; +import jdk.test.lib.classloader.ClassUnloadCommon; import nsk.share.test.ExecutionController; -public class TriggerUnloadingWithWhiteBox implements TriggerUnloadingHelper { - - private final static WhiteBox wb = WhiteBox.getWhiteBox(); +public class TriggerUnloadingWithFullGC implements TriggerUnloadingHelper { @Override public void triggerUnloading(ExecutionController stresser) { - wb.fullGC(); + ClassUnloadCommon.triggerUnloading(); } } diff --git a/test/hotspot/jtreg/vmTestbase/metaspace/staticReferences/StaticReferences.java b/test/hotspot/jtreg/vmTestbase/metaspace/staticReferences/StaticReferences.java index 7ea901abe06f1..cf430ad91b86c 100644 --- a/test/hotspot/jtreg/vmTestbase/metaspace/staticReferences/StaticReferences.java +++ b/test/hotspot/jtreg/vmTestbase/metaspace/staticReferences/StaticReferences.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 @@ -54,7 +54,7 @@ import java.util.Random; import metaspace.share.TriggerUnloadingHelper; -import metaspace.share.TriggerUnloadingWithWhiteBox; +import metaspace.share.TriggerUnloadingWithFullGC; import nsk.share.gc.GCTestBase; import nsk.share.test.ExecutionController; import nsk.share.test.Stresser; @@ -86,7 +86,7 @@ public class StaticReferences extends GCTestBase { private Random random; - private TriggerUnloadingHelper triggerUnloadingHelper = new TriggerUnloadingWithWhiteBox(); + private TriggerUnloadingHelper triggerUnloadingHelper = new TriggerUnloadingWithFullGC(); private String[] typesArray = new String[] {"Object object", "boolean boolean", "byte byte", "char char", "double double", "float float", "int int", "long long", "short short"}; diff --git a/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/StressHierarchyBaseClass.java b/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/StressHierarchyBaseClass.java index 20fcdabb13cf2..2f08fe70c0252 100644 --- a/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/StressHierarchyBaseClass.java +++ b/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/StressHierarchyBaseClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 @@ -27,7 +27,7 @@ import metaspace.share.HeapOOMEException; import metaspace.share.TriggerUnloadingByFillingMetaspace; import metaspace.share.TriggerUnloadingHelper; -import metaspace.share.TriggerUnloadingWithWhiteBox; +import metaspace.share.TriggerUnloadingWithFullGC; import metaspace.stressHierarchy.common.classloader.tree.Node; import metaspace.stressHierarchy.common.classloader.tree.Tree; import metaspace.stressHierarchy.common.exceptions.TimeIsOverException; @@ -48,7 +48,7 @@ abstract public class StressHierarchyBaseClass extends TestBase { protected static String[] args; - protected TriggerUnloadingHelper triggerUnloadingHelper = new TriggerUnloadingWithWhiteBox(); //default helper + protected TriggerUnloadingHelper triggerUnloadingHelper = new TriggerUnloadingWithFullGC(); //default helper protected PerformChecksHelper performChecksHelper = null; From dc37bab65cb052ecae715bc8e71efa116c16b034 Mon Sep 17 00:00:00 2001 From: Alexey Bakhtin Date: Mon, 23 Jun 2025 18:49:26 +0000 Subject: [PATCH 396/846] 8360147: Better Glyph drawing redux Reviewed-by: mbalao, andrew Backport-of: f57e6baf3b86a7ef0911223cccb47b96e2af0420 --- .../native/libawt_lwawt/font/CGGlyphImages.m | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m b/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m index 316f6e273f2d9..4dac06a8a5f08 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m @@ -974,23 +974,28 @@ @implementation CGGI_GlyphCanvas return; } - // just do one malloc, and carve it up for all the buffers - void *buffer = malloc((sizeof(CGRect) + sizeof(CGSize) + sizeof(CGGlyph) + sizeof(UnicodeScalarValue)) * len); - if (buffer == NULL) { + CGRect *bboxes = (CGRect*)calloc(len, sizeof(CGRect)); + CGSize *advances = (CGSize*)calloc(len, sizeof(CGSize)); + CGGlyph *glyphs = (CGGlyph*)calloc(len, sizeof(CGGlyph)); + UnicodeScalarValue *uniChars = (UnicodeScalarValue*)calloc(len, sizeof(UnicodeScalarValue)); + + if (bboxes == NULL || advances == NULL || glyphs == NULL || uniChars == NULL) { + free(bboxes); + free(advances); + free(glyphs); + free(uniChars); [[NSException exceptionWithName:NSMallocException reason:@"Failed to allocate memory for the temporary glyph strike and measurement buffers." userInfo:nil] raise]; } - CGRect *bboxes = (CGRect *)(buffer); - CGSize *advances = (CGSize *)(bboxes + sizeof(CGRect) * len); - CGGlyph *glyphs = (CGGlyph *)(advances + sizeof(CGGlyph) * len); - UnicodeScalarValue *uniChars = (UnicodeScalarValue *)(glyphs + sizeof(UnicodeScalarValue) * len); - CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode, rawGlyphCodes, uniChars, glyphs, advances, bboxes, len); - free(buffer); + free(bboxes); + free(advances); + free(glyphs); + free(uniChars); } #define TX_FIXED_UNSAFE(v) (isinf(v) || isnan(v) || fabs(v) >= (1<<30)) From c8aee9726533bbfa8d710762c4d622e3f5aaf40f Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Jul 2025 05:35:57 +0000 Subject: [PATCH 397/846] 8352509: Update jdk.test.lib.SecurityTools jar method to accept List parameter Backport-of: fa0b18bfde38ee2ffbab33a9eaac547fe8aa3c7c --- test/lib/jdk/test/lib/SecurityTools.java | 29 +++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/test/lib/jdk/test/lib/SecurityTools.java b/test/lib/jdk/test/lib/SecurityTools.java index bc198a712b843..c554ea4b15d12 100644 --- a/test/lib/jdk/test/lib/SecurityTools.java +++ b/test/lib/jdk/test/lib/SecurityTools.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -238,6 +238,17 @@ public static OutputAnalyzer kinit(String args) throws Exception { return execute(getProcessBuilder("kinit", makeList(args))); } + /** + * Runs jar. + * + * @param args arguments to jar in the list. + * @return an {@link OutputAnalyzer} object + * @throws Exception if there is an error + */ + public static OutputAnalyzer jar(final List args) throws Exception { + return execute(getProcessBuilder("jar", args)); + } + /** * Runs jar. * @@ -246,8 +257,20 @@ public static OutputAnalyzer kinit(String args) throws Exception { * @return an {@link OutputAnalyzer} object * @throws Exception if there is an error */ - public static OutputAnalyzer jar(String args) throws Exception { - return execute(getProcessBuilder("jar", makeList(args))); + public static OutputAnalyzer jar(final String args) throws Exception { + return jar(makeList(args)); + } + + /** + * Runs jar. + * + * @param args arguments to jar in multiple strings. + * Converted to be a List with List.of. + * @return an {@link OutputAnalyzer} object + * @throws Exception if there is an error + */ + public static OutputAnalyzer jar(final String... args) throws Exception { + return jar(List.of(args)); } /** From b956b89b7a18ce990e397868463155e1c0283110 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Wed, 9 Jul 2025 05:37:24 +0000 Subject: [PATCH 398/846] 8353235: Test jdk/jfr/api/metadata/annotations/TestPeriod.java fails with IllegalArgumentException Backport-of: b7ca76ef4bfc640668492e655acc6d755411a92f --- test/jdk/jdk/jfr/api/metadata/annotations/TestPeriod.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestPeriod.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestPeriod.java index 893b1ab4720d9..64bde5155b33c 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestPeriod.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestPeriod.java @@ -26,6 +26,7 @@ import jdk.jfr.Event; import jdk.jfr.EventType; import jdk.jfr.Period; +import jdk.jfr.FlightRecorder; import jdk.test.lib.Asserts; import jdk.test.lib.jfr.Events; @@ -44,6 +45,7 @@ static class PeriodicEvent extends Event { public static void main(String[] args) throws Exception { EventType periodicEvent = EventType.getEventType(PeriodicEvent.class); + FlightRecorder.addPeriodicEvent(PeriodicEvent.class, () -> {}); String defaultValue = Events.getSetting(periodicEvent, Period.NAME).getDefaultValue(); Asserts.assertEQ(defaultValue, "47 s", "Incorrect default value for period"); } From 162dbac82cf31c6948414944af836187aff9e6ca Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Wed, 9 Jul 2025 07:51:08 +0200 Subject: [PATCH 399/846] 8361674: [17u] Remove designator DEFAULT_PROMOTED_VERSION_PRE=ea for release 17.0.16 Reviewed-by: goetz --- make/conf/version-numbers.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf index 9e08390395aa1..c45d8c1ee1bd4 100644 --- a/make/conf/version-numbers.conf +++ b/make/conf/version-numbers.conf @@ -39,4 +39,4 @@ DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 DEFAULT_ACCEPTABLE_BOOT_VERSIONS="16 17" DEFAULT_JDK_SOURCE_TARGET_VERSION=17 -DEFAULT_PROMOTED_VERSION_PRE=ea +DEFAULT_PROMOTED_VERSION_PRE= From 29d46c30a47fdfa811d002af04908ae30d4f93e3 Mon Sep 17 00:00:00 2001 From: Satyen Subramaniam Date: Wed, 9 Jul 2025 21:59:14 +0000 Subject: [PATCH 400/846] 8345173: BlockLocationPrinter::print_location misses a ResourceMark Backport-of: f5ebda43709984214a25e23926860fea2ba5819a --- src/hotspot/share/gc/shared/locationPrinter.inline.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hotspot/share/gc/shared/locationPrinter.inline.hpp b/src/hotspot/share/gc/shared/locationPrinter.inline.hpp index f57a030deb764..72bb7b53e504f 100644 --- a/src/hotspot/share/gc/shared/locationPrinter.inline.hpp +++ b/src/hotspot/share/gc/shared/locationPrinter.inline.hpp @@ -27,6 +27,7 @@ #include "gc/shared/locationPrinter.hpp" +#include "memory/resourceArea.inline.hpp" #include "oops/compressedOops.inline.hpp" #include "oops/oopsHierarchy.hpp" @@ -51,6 +52,7 @@ oop BlockLocationPrinter::base_oop_or_null(void* addr) { template bool BlockLocationPrinter::print_location(outputStream* st, void* addr) { + ResourceMark rm; // Check if addr points into Java heap. if (CollectedHeapT::heap()->is_in(addr)) { oop o = base_oop_or_null(addr); From 4b270f58066bc70bcb8650858fc829c5061427b2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 10 Jul 2025 12:34:19 +0000 Subject: [PATCH 401/846] 8347302: Mark test tools/jimage/JImageToolTest.java as flagless Backport-of: e7e8f60c9bedd5622525cc4339300b438eedc9fd --- test/jdk/tools/jimage/JImageToolTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/jdk/tools/jimage/JImageToolTest.java b/test/jdk/tools/jimage/JImageToolTest.java index b1006c896794b..d7d1ee35ba1e0 100644 --- a/test/jdk/tools/jimage/JImageToolTest.java +++ b/test/jdk/tools/jimage/JImageToolTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test * @library /test/lib + * @requires vm.flagless * @build jdk.test.lib.process.ProcessTools * @summary Test to check if jimage tool exists and is working * @run main/timeout=360 JImageToolTest From eecdbf17828f2164e9af579c6dd3815da2ffc7d6 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 10 Jul 2025 12:36:04 +0000 Subject: [PATCH 402/846] 8347381: Upgrade jQuery UI to version 1.14.1 Backport-of: 64b73fbd08c1086ceca26c5724cde8c090246b80 --- .../html/resources/script-dir/jquery-ui.css | 9 +- .../html/resources/script-dir/jquery-ui.js | 168 ++++++------------ .../resources/script-dir/jquery-ui.min.css | 8 +- .../resources/script-dir/jquery-ui.min.js | 8 +- src/jdk.javadoc/share/legal/jqueryUI.md | 4 +- 5 files changed, 65 insertions(+), 132 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script-dir/jquery-ui.css b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script-dir/jquery-ui.css index dfef26182b04d..10e059174061b 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script-dir/jquery-ui.css +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script-dir/jquery-ui.css @@ -1,7 +1,7 @@ -/*! jQuery UI - v1.13.2 - 2023-02-27 -* http://jqueryui.com +/*! jQuery UI - v1.14.1 - 2025-01-13 +* https://jqueryui.com * Includes: core.css, autocomplete.css, menu.css -* Copyright jQuery Foundation and other contributors; Licensed MIT */ +* Copyright OpenJS Foundation and other contributors; Licensed MIT */ /* Layout helpers ----------------------------------*/ @@ -44,7 +44,6 @@ left: 0; position: absolute; opacity: 0; - -ms-filter: "alpha(opacity=0)"; /* support: IE8 */ } .ui-front { @@ -108,8 +107,6 @@ .ui-menu .ui-menu-item { margin: 0; cursor: pointer; - /* support: IE10, see #8844 */ - list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"); } .ui-menu .ui-menu-item-wrapper { position: relative; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script-dir/jquery-ui.js b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script-dir/jquery-ui.js index 95ec9f04fd265..b57de8a284ca2 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script-dir/jquery-ui.js +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script-dir/jquery-ui.js @@ -1,11 +1,11 @@ -/*! jQuery UI - v1.13.2 - 2023-02-27 -* http://jqueryui.com +/*! jQuery UI - v1.14.1 - 2025-01-13 +* https://jqueryui.com * Includes: widget.js, position.js, keycode.js, unique-id.js, widgets/autocomplete.js, widgets/menu.js -* Copyright jQuery Foundation and other contributors; Licensed MIT */ +* Copyright OpenJS Foundation and other contributors; Licensed MIT */ ( function( factory ) { "use strict"; - + if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. @@ -20,23 +20,23 @@ $.ui = $.ui || {}; -var version = $.ui.version = "1.13.2"; +var version = $.ui.version = "1.14.1"; /*! - * jQuery UI Widget 1.13.2 - * http://jqueryui.com + * jQuery UI Widget 1.14.1 + * https://jqueryui.com * - * Copyright jQuery Foundation and other contributors + * Copyright OpenJS Foundation and other contributors * Released under the MIT license. - * http://jquery.org/license + * https://jquery.org/license */ //>>label: Widget //>>group: Core //>>description: Provides a factory for creating stateful widgets with a common API. -//>>docs: http://api.jqueryui.com/jQuery.widget/ -//>>demos: http://jqueryui.com/widget/ +//>>docs: https://api.jqueryui.com/jQuery.widget/ +//>>demos: https://jqueryui.com/widget/ var widgetUuid = 0; @@ -67,6 +67,9 @@ $.widget = function( name, base, prototype ) { var namespace = name.split( "." )[ 0 ]; name = name.split( "." )[ 1 ]; + if ( name === "__proto__" || name === "constructor" ) { + return $.error( "Invalid widget name: " + name ); + } var fullName = namespace + "-" + name; if ( !prototype ) { @@ -766,21 +769,21 @@ var widget = $.widget; /*! - * jQuery UI Position 1.13.2 - * http://jqueryui.com + * jQuery UI Position 1.14.1 + * https://jqueryui.com * - * Copyright jQuery Foundation and other contributors + * Copyright OpenJS Foundation and other contributors * Released under the MIT license. - * http://jquery.org/license + * https://jquery.org/license * - * http://api.jqueryui.com/position/ + * https://api.jqueryui.com/position/ */ //>>label: Position //>>group: Core //>>description: Positions elements relative to other elements. -//>>docs: http://api.jqueryui.com/position/ -//>>demos: http://jqueryui.com/position/ +//>>docs: https://api.jqueryui.com/position/ +//>>demos: https://jqueryui.com/position/ ( function() { @@ -1263,18 +1266,18 @@ var position = $.ui.position; /*! - * jQuery UI Keycode 1.13.2 - * http://jqueryui.com + * jQuery UI Keycode 1.14.1 + * https://jqueryui.com * - * Copyright jQuery Foundation and other contributors + * Copyright OpenJS Foundation and other contributors * Released under the MIT license. - * http://jquery.org/license + * https://jquery.org/license */ //>>label: Keycode //>>group: Core //>>description: Provide keycodes as keynames -//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ +//>>docs: https://api.jqueryui.com/jQuery.ui.keyCode/ var keycode = $.ui.keyCode = { @@ -1298,18 +1301,18 @@ var keycode = $.ui.keyCode = { /*! - * jQuery UI Unique ID 1.13.2 - * http://jqueryui.com + * jQuery UI Unique ID 1.14.1 + * https://jqueryui.com * - * Copyright jQuery Foundation and other contributors + * Copyright OpenJS Foundation and other contributors * Released under the MIT license. - * http://jquery.org/license + * https://jquery.org/license */ //>>label: uniqueId //>>group: Core //>>description: Functions to generate and remove uniqueId's -//>>docs: http://api.jqueryui.com/uniqueId/ +//>>docs: https://api.jqueryui.com/uniqueId/ var uniqueId = $.fn.extend( { @@ -1335,57 +1338,27 @@ var uniqueId = $.fn.extend( { } ); - -var safeActiveElement = $.ui.safeActiveElement = function( document ) { - var activeElement; - - // Support: IE 9 only - // IE9 throws an "Unspecified error" accessing document.activeElement from an